diff --git a/cobalt/black_box_tests/black_box_tests.py b/cobalt/black_box_tests/black_box_tests.py
index 58e042f601b3..7ef22ec0a7e3 100755
--- a/cobalt/black_box_tests/black_box_tests.py
+++ b/cobalt/black_box_tests/black_box_tests.py
@@ -80,6 +80,7 @@
'h5vcc_watchdog_api_test',
'http_cache',
'javascript_profiler',
+ 'performance_resource_timing_test',
'persistent_cookie',
'scroll',
'service_worker_add_to_cache_test',
diff --git a/cobalt/black_box_tests/testdata/performance_resource_timing_test.html b/cobalt/black_box_tests/testdata/performance_resource_timing_test.html
new file mode 100644
index 000000000000..a7ffe19b7458
--- /dev/null
+++ b/cobalt/black_box_tests/testdata/performance_resource_timing_test.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/cobalt/black_box_tests/tests/performance_resource_timing_test.py b/cobalt/black_box_tests/tests/performance_resource_timing_test.py
new file mode 100644
index 000000000000..cf7815e860e1
--- /dev/null
+++ b/cobalt/black_box_tests/tests/performance_resource_timing_test.py
@@ -0,0 +1,28 @@
+# 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 performance.getEntries()."""
+
+from cobalt.black_box_tests import black_box_tests
+from cobalt.black_box_tests.threaded_web_server import ThreadedWebServer
+
+
+class CpuUsageTrackerTest(black_box_tests.BlackBoxTestCase):
+
+ def test_performance_resource_timing(self):
+ with ThreadedWebServer(binding_address=self.GetBindingAddress()) as server:
+ url = server.GetURL(
+ file_name='testdata/performance_resource_timing_test.html')
+ with self.CreateCobaltRunner(url=url) as runner:
+ runner.WaitForJSTestsSetup()
+ self.assertTrue(runner.JSTestsSucceeded())
diff --git a/cobalt/dom/performance_resource_timing.cc b/cobalt/dom/performance_resource_timing.cc
index 09e72a37d22d..c2f46fba2ef0 100644
--- a/cobalt/dom/performance_resource_timing.cc
+++ b/cobalt/dom/performance_resource_timing.cc
@@ -13,6 +13,9 @@
// limitations under the License.
#include "cobalt/dom/performance_resource_timing.h"
+
+#include
+
#include "cobalt/dom/performance.h"
namespace cobalt {
@@ -136,6 +139,16 @@ DOMHighResTimeStamp PerformanceResourceTiming::worker_start() const {
time_origin_, timing_info_.service_worker_start_time);
}
+std::string PerformanceResourceTiming::next_hop_protocol() const {
+ // Fallback to connection_info when alpn_negotiated_protocol is unknown.
+ std::string returnedProtocol =
+ (timing_info_.alpn_negotiated_protocol == "unknown")
+ ? timing_info_.connection_info_string
+ : timing_info_.alpn_negotiated_protocol;
+ // If connection_info is unknown, return the empty string.
+ return returnedProtocol == "unknown" ? "" : std::move(returnedProtocol);
+}
+
void PerformanceResourceTiming::SetResourceTimingEntry(
const net::LoadTimingInfo& timing_info, const std::string& initiator_type,
const std::string& requested_url, const std::string& cache_mode) {
diff --git a/cobalt/dom/performance_resource_timing.h b/cobalt/dom/performance_resource_timing.h
index a7fa31dc1ad9..0932d41a2070 100644
--- a/cobalt/dom/performance_resource_timing.h
+++ b/cobalt/dom/performance_resource_timing.h
@@ -19,7 +19,6 @@
#include "cobalt/dom/performance_entry.h"
#include "cobalt/dom/performance_high_resolution_time.h"
-
#include "cobalt/script/wrappable.h"
#include "net/base/load_timing_info.h"
@@ -58,6 +57,7 @@ class PerformanceResourceTiming : public PerformanceEntry {
uint64_t transfer_size() const;
uint64_t encoded_body_size() const;
DOMHighResTimeStamp worker_start() const;
+ std::string next_hop_protocol() const;
std::string entry_type() const override { return "resource"; }
PerformanceEntryType EntryTypeEnum() const override {
diff --git a/cobalt/dom/performance_resource_timing.idl b/cobalt/dom/performance_resource_timing.idl
index 511c43db87af..654a2629fad9 100644
--- a/cobalt/dom/performance_resource_timing.idl
+++ b/cobalt/dom/performance_resource_timing.idl
@@ -17,6 +17,7 @@
[Exposed=Window]
interface PerformanceResourceTiming : PerformanceEntry {
readonly attribute DOMString initiatorType;
+ readonly attribute DOMString nextHopProtocol;
readonly attribute DOMHighResTimeStamp fetchStart;
readonly attribute DOMHighResTimeStamp domainLookupStart;
readonly attribute DOMHighResTimeStamp domainLookupEnd;
diff --git a/net/base/load_timing_info.h b/net/base/load_timing_info.h
index bdfd91f2b722..1d32fd08bd0e 100644
--- a/net/base/load_timing_info.h
+++ b/net/base/load_timing_info.h
@@ -164,6 +164,8 @@ struct NET_EXPORT LoadTimingInfo {
#if defined(STARBOARD)
uint64_t encoded_body_size;
base::TimeTicks service_worker_start_time;
+ std::string alpn_negotiated_protocol;
+ std::string connection_info_string;
#endif // defined(STARBOARD)
};
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index e55c5040bba8..5b783a9aa49e 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -1166,7 +1166,13 @@ void URLRequest::NotifyRequestCompleted() {
return;
#if defined (STARBOARD)
- load_timing_info_.encoded_body_size = static_cast(GetTotalReceivedBytes());
+ load_timing_info_.encoded_body_size =
+ static_cast(GetTotalReceivedBytes());
+ load_timing_info_.alpn_negotiated_protocol =
+ response_info_.alpn_negotiated_protocol;
+ load_timing_info_.connection_info_string =
+ HttpResponseInfo::ConnectionInfoToString(
+ response_info_.connection_info);
if (load_timing_info_callback_) {
load_timing_info_callback_.Run(load_timing_info_);
}