diff --git a/cobalt/black_box_tests/black_box_tests.py b/cobalt/black_box_tests/black_box_tests.py
index 8b0d39755513..e9f2f868a4a8 100755
--- a/cobalt/black_box_tests/black_box_tests.py
+++ b/cobalt/black_box_tests/black_box_tests.py
@@ -74,6 +74,7 @@
# 'h5vcc_watchdog_api_test',
'http_cache',
'javascript_profiler',
+ 'navigator_test',
'performance_resource_timing_test',
'persistent_cookie',
'pointer_event_on_fixed_element_test',
diff --git a/cobalt/black_box_tests/testdata/navigator_test.html b/cobalt/black_box_tests/testdata/navigator_test.html
new file mode 100644
index 000000000000..46126c6319f2
--- /dev/null
+++ b/cobalt/black_box_tests/testdata/navigator_test.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/cobalt/black_box_tests/tests/navigator_test.py b/cobalt/black_box_tests/tests/navigator_test.py
new file mode 100644
index 000000000000..9ec99a5665e8
--- /dev/null
+++ b/cobalt/black_box_tests/tests/navigator_test.py
@@ -0,0 +1,47 @@
+# Copyright 2024 The Cobalt Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Test navigator API."""
+
+from cobalt.black_box_tests import black_box_tests
+from cobalt.black_box_tests.threaded_web_server import ThreadedWebServer
+import logging
+
+PLATFORMS_SUPPORTED = [
+ 'linux-x64x11',
+ 'linux-x64x11-egl',
+ 'linux-x64x11-gcc-6-3',
+ 'linux-x64x11-skia',
+ 'android-arm',
+ 'android-arm64',
+ 'android-arm64-vulkan',
+ 'android-x86',
+ 'raspi-2',
+ 'raspi-2-skia',
+ 'linux-x64x11-clang-crosstool',
+]
+
+
+class NavigatorTest(black_box_tests.BlackBoxTestCase):
+
+ def test_navigator(self):
+ if self.launcher_params.platform not in PLATFORMS_SUPPORTED:
+ logging.warning('Blackbox tests disabled for platform:%s',
+ self.launcher_params.platform)
+ return
+
+ with ThreadedWebServer(binding_address=self.GetBindingAddress()) as server:
+ url = server.GetURL(file_name='testdata/navigator_test.html')
+ with self.CreateCobaltRunner(url=url) as runner:
+ runner.WaitForJSTestsSetup()
+ self.assertTrue(runner.JSTestsSucceeded())
diff --git a/cobalt/browser/idl_files.gni b/cobalt/browser/idl_files.gni
index 0d0747ea5a6e..77116a71e9f2 100644
--- a/cobalt/browser/idl_files.gni
+++ b/cobalt/browser/idl_files.gni
@@ -399,6 +399,7 @@ dependency_idl_files = [
"//cobalt/dom/global_event_handlers.idl",
"//cobalt/dom/html_element_cssom_view.idl",
"//cobalt/dom/mouse_event_cssom_view.idl",
+ "//cobalt/dom/navigator_concurrent_hardware.idl",
"//cobalt/dom/navigator_licenses.idl",
"//cobalt/dom/navigator_plugins.idl",
"//cobalt/dom/navigator_storage_utils.idl",
diff --git a/cobalt/dom/navigator.cc b/cobalt/dom/navigator.cc
index 7ad053c7c7e5..0aabea2ccb9d 100644
--- a/cobalt/dom/navigator.cc
+++ b/cobalt/dom/navigator.cc
@@ -18,6 +18,7 @@
#include
#include "base/optional.h"
+#include "base/system/sys_info.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/dom/captions/system_caption_settings.h"
#include "cobalt/dom/dom_settings.h"
@@ -154,6 +155,10 @@ Navigator::Navigator(script::EnvironmentSettings* settings,
new media_capture::MediaDevices(settings, script_value_factory())),
system_caption_settings_(captions) {}
+uint64_t Navigator::hardware_concurrency() const {
+ return static_cast(base::SysInfo::NumberOfProcessors());
+}
+
const std::string Navigator::licenses() const {
GeneratedResourceMap resource_map;
DOMEmbeddedResources::GenerateMap(resource_map);
diff --git a/cobalt/dom/navigator.h b/cobalt/dom/navigator.h
index 73e928e99f15..30d393a46a54 100644
--- a/cobalt/dom/navigator.h
+++ b/cobalt/dom/navigator.h
@@ -47,6 +47,8 @@ class Navigator : public web::NavigatorBase {
Navigator(const Navigator&) = delete;
Navigator& operator=(const Navigator&) = delete;
+ uint64_t hardware_concurrency() const;
+
// Web API: NavigatorLicenses
const std::string licenses() const;
diff --git a/cobalt/dom/navigator.idl b/cobalt/dom/navigator.idl
index 6a215209dd09..8bd07f464b67 100644
--- a/cobalt/dom/navigator.idl
+++ b/cobalt/dom/navigator.idl
@@ -16,6 +16,7 @@
interface Navigator {};
+Navigator implements NavigatorConcurrentHardware;
Navigator implements NavigatorID;
Navigator implements NavigatorLanguage;
Navigator implements NavigatorPlugins;
diff --git a/cobalt/dom/navigator_concurrent_hardware.idl b/cobalt/dom/navigator_concurrent_hardware.idl
new file mode 100644
index 000000000000..39cde72516ef
--- /dev/null
+++ b/cobalt/dom/navigator_concurrent_hardware.idl
@@ -0,0 +1,18 @@
+// Copyright 2024 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+[NoInterfaceObject]
+interface NavigatorConcurrentHardware {
+ readonly attribute unsigned long long hardwareConcurrency;
+};
diff --git a/cobalt/dom/navigator_test.cc b/cobalt/dom/navigator_test.cc
index 297288a72452..7042c7897a07 100644
--- a/cobalt/dom/navigator_test.cc
+++ b/cobalt/dom/navigator_test.cc
@@ -16,6 +16,7 @@
#include
#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
#include "cobalt/bindings/testing/utils.h"
#include "cobalt/dom/testing/test_with_javascript.h"
#include "cobalt/web/testing/gtest_workarounds.h"
@@ -160,5 +161,15 @@ TEST_F(NavigatorTest, NavigatorOnline) {
EXPECT_EQ("true", result);
}
+TEST_F(NavigatorTest, NavigatorConcurrentHardware) {
+ std::string result;
+ EXPECT_TRUE(EvaluateScript("typeof navigator.hardwareConcurrency", &result));
+ EXPECT_EQ("number", result);
+ EXPECT_TRUE(EvaluateScript("navigator.hardwareConcurrency", &result));
+ int count = -1;
+ EXPECT_TRUE(base::StringToInt(result, &count));
+ EXPECT_GE(count, 0);
+}
+
} // namespace dom
} // namespace cobalt