Import Cobalt 23.lts.1.309312
diff --git a/base/BUILD.gn b/base/BUILD.gn index 8a5bc66..e6ccec8 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3195,7 +3195,7 @@ ":base_unittests_bundle_data", ] if (is_starboard){ - content_deps = [ + data_deps += [ ":base_unittests_bundle_data", "//third_party/icu:icudata", ]
diff --git a/cobalt/base/BUILD.gn b/cobalt/base/BUILD.gn index bd5c1d3..898475d 100644 --- a/cobalt/base/BUILD.gn +++ b/cobalt/base/BUILD.gn
@@ -124,5 +124,5 @@ "//testing/gmock", "//testing/gtest", ] - content_deps = [ "//third_party/icu:icudata" ] + data_deps = [ "//third_party/icu:icudata" ] }
diff --git a/cobalt/black_box_tests/black_box_tests.py b/cobalt/black_box_tests/black_box_tests.py index 7ac37d0..737c875 100644 --- a/cobalt/black_box_tests/black_box_tests.py +++ b/cobalt/black_box_tests/black_box_tests.py
@@ -63,8 +63,6 @@ 'allow_eval', 'compression_test', 'disable_eval_with_csp', - # http_cache is disabled due to flakiness. Planned update to make use of - # transferSize rather than load timings to make it more consistent. 'http_cache', 'persistent_cookie', 'soft_mic_platform_service_test',
diff --git a/cobalt/black_box_tests/testdata/web_worker_test.html b/cobalt/black_box_tests/testdata/web_worker_test.html index 2976cdf..9be8f5b 100644 --- a/cobalt/black_box_tests/testdata/web_worker_test.html +++ b/cobalt/black_box_tests/testdata/web_worker_test.html
@@ -37,9 +37,10 @@ console.log('running'); // This is expected trigger a an error event on window. - var worker_with_error = new Worker('web_worker_test_with_syntax_error.js'); + var worker_with_error = new Worker('web_worker_test_with_syntax_error.js', + { name : 'worker_with_error'}); - var worker = new Worker('web_worker_test.js'); + var worker = new Worker('web_worker_test.js', { name : 'test_worker'}); console.log(worker); worker.onmessage = function (event) { message_event_count += 1;
diff --git a/cobalt/browser/BUILD.gn b/cobalt/browser/BUILD.gn index e3ca3a6..4c30f02 100644 --- a/cobalt/browser/BUILD.gn +++ b/cobalt/browser/BUILD.gn
@@ -57,21 +57,21 @@ "//cobalt/base", "//net", ] - content_deps = [ + data_deps = [ "//cobalt/dom:licenses", "//cobalt/network:copy_ssl_certificates", "//third_party/icu:icudata", ] if (cobalt_font_package == "empty") { - content_deps += [ "//cobalt/content/fonts:copy_font_data" ] + data_deps += [ "//cobalt/content/fonts:copy_font_data" ] } else { - content_deps += [ + data_deps += [ "//cobalt/content/fonts:copy_fonts", "//cobalt/content/fonts:fonts_xml", ] } if (!is_gold) { - content_deps += [ + data_deps += [ "//cobalt/debug/backend/content:copy_backend_web_files", "//cobalt/debug/console/content:copy_console_web_files", "//cobalt/debug/remote/content:copy_remote_web_files", @@ -84,9 +84,6 @@ "//third_party/devtools:supported_css_properties", ] } - if (defined(platform_i18n_config_path)) { - content_deps += [ platform_i18n_config_path ] - } } ##############################
diff --git a/cobalt/browser/application.cc b/cobalt/browser/application.cc index b6a691f..21005ba 100644 --- a/cobalt/browser/application.cc +++ b/cobalt/browser/application.cc
@@ -512,12 +512,13 @@ "available trackers."; #endif // defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING) -bool AddCrashHandlerAnnotations() { +void AddCrashHandlerAnnotations() { auto crash_handler_extension = - SbSystemGetExtension(kCobaltExtensionCrashHandlerName); + static_cast<const CobaltExtensionCrashHandlerApi*>( + SbSystemGetExtension(kCobaltExtensionCrashHandlerName)); if (!crash_handler_extension) { LOG(INFO) << "No crash handler extension, not sending annotations."; - return false; + return; } auto platform_info = cobalt::browser::GetUserAgentPlatformInfoFromSystem(); @@ -541,23 +542,41 @@ product.push_back('\0'); version.push_back('\0'); - CrashpadAnnotations crashpad_annotations; - memset(&crashpad_annotations, 0, sizeof(CrashpadAnnotations)); - strncpy(crashpad_annotations.user_agent_string, user_agent.c_str(), - USER_AGENT_STRING_MAX_SIZE); - strncpy(crashpad_annotations.product, product.c_str(), - CRASHPAD_ANNOTATION_DEFAULT_LENGTH); - strncpy(crashpad_annotations.version, version.c_str(), - CRASHPAD_ANNOTATION_DEFAULT_LENGTH); - bool result = static_cast<const CobaltExtensionCrashHandlerApi*>( - crash_handler_extension) - ->OverrideCrashpadAnnotations(&crashpad_annotations); + bool result = true; + if (crash_handler_extension->version == 1) { + CrashpadAnnotations crashpad_annotations; + memset(&crashpad_annotations, 0, sizeof(CrashpadAnnotations)); + strncpy(crashpad_annotations.user_agent_string, user_agent.c_str(), + USER_AGENT_STRING_MAX_SIZE); + strncpy(crashpad_annotations.product, product.c_str(), + CRASHPAD_ANNOTATION_DEFAULT_LENGTH); + strncpy(crashpad_annotations.version, version.c_str(), + CRASHPAD_ANNOTATION_DEFAULT_LENGTH); + result = crash_handler_extension->OverrideCrashpadAnnotations( + &crashpad_annotations); + } else if (crash_handler_extension->version > 1) { + // These particular annotation key names (e.g., ver) are expected by + // Crashpad. + // TODO(b/201538792): figure out a clean way to define these constants once + // and use them everywhere. + if (!crash_handler_extension->SetString("user_agent_string", + user_agent.c_str())) { + result = false; + } + if (!crash_handler_extension->SetString("prod", product.c_str())) { + result = false; + } + if (!crash_handler_extension->SetString("ver", version.c_str())) { + result = false; + } + } else { + result = false; + } // Invalid extension version if (result) { LOG(INFO) << "Sent annotations to crash handler"; } else { - LOG(ERROR) << "Could not send annotations to crash handler."; + LOG(ERROR) << "Could not send some annotation(s) to crash handler."; } - return result; } } // namespace @@ -660,11 +679,10 @@ unconsumed_deep_link_ = GetInitialDeepLink(); DLOG(INFO) << "Initial deep link: " << unconsumed_deep_link_; - WebModule::Options web_options("MainWebModule"); storage::StorageManager::Options storage_manager_options; network::NetworkModule::Options network_module_options; // Create the main components of our browser. - BrowserModule::Options options(web_options); + BrowserModule::Options options; network_module_options.preferred_language = language; network_module_options.persistent_settings = persistent_settings_.get(); options.persistent_settings = persistent_settings_.get(); @@ -749,7 +767,7 @@ // Set callback to be notified when a navigation occurs that destroys the // underlying WebModule. options.web_module_created_callback = - base::Bind(&Application::WebModuleCreated, base::Unretained(this)); + base::Bind(&Application::MainWebModuleCreated, base::Unretained(this)); // The main web module's stat tracker tracks event stats. options.web_module_options.track_event_stats = true; @@ -1370,8 +1388,9 @@ } #endif -void Application::WebModuleCreated(WebModule* web_module) { - TRACE_EVENT0("cobalt::browser", "Application::WebModuleCreated()"); +void Application::MainWebModuleCreated(WebModule* web_module) { + TRACE_EVENT0("cobalt::browser", "Application::MainWebModuleCreated()"); + // Note: This is a callback function that runs in the MainWebModule thread. DCHECK(web_module); if (preload_timestamp_.has_value()) { web_module->SetApplicationStartOrPreloadTimestamp( @@ -1499,10 +1518,9 @@ // again after the next WebModule is created. unconsumed_deep_link_ = link; deep_link = unconsumed_deep_link_; + deep_link_timestamp_ = timestamp; } - deep_link_timestamp_ = timestamp; - LOG(INFO) << "Dispatching deep link: " << deep_link; DispatchEventInternal(new base::DeepLinkEvent( deep_link, base::Bind(&Application::OnDeepLinkConsumedCallback, @@ -1516,11 +1534,17 @@ void Application::DispatchDeepLinkIfNotConsumed() { std::string deep_link; +#if SB_API_VERSION >= 13 + SbTimeMonotonic timestamp; +#endif // SB_API_VERSION >= 13 // This block exists to ensure that the lock is held while accessing // unconsumed_deep_link_. { base::AutoLock auto_lock(unconsumed_deep_link_lock_); deep_link = unconsumed_deep_link_; +#if SB_API_VERSION >= 13 + timestamp = deep_link_timestamp_; +#endif // SB_API_VERSION >= 13 } if (!deep_link.empty()) { @@ -1531,7 +1555,7 @@ } #if SB_API_VERSION >= 13 if (browser_module_) { - browser_module_->SetDeepLinkTimestamp(deep_link_timestamp_); + browser_module_->SetDeepLinkTimestamp(timestamp); } #endif // SB_API_VERSION >= 13 }
diff --git a/cobalt/browser/application.h b/cobalt/browser/application.h index d2ad7ca..96480b7 100644 --- a/cobalt/browser/application.h +++ b/cobalt/browser/application.h
@@ -90,7 +90,7 @@ #endif // Called when a navigation occurs in the BrowserModule. - void WebModuleCreated(WebModule* web_module); + void MainWebModuleCreated(WebModule* web_module); void CollectUnloadEventTimingInfo(base::TimeTicks start_time, base::TimeTicks end_time);
diff --git a/cobalt/browser/browser_module.cc b/cobalt/browser/browser_module.cc index b80da96..780f86d 100644 --- a/cobalt/browser/browser_module.cc +++ b/cobalt/browser/browser_module.cc
@@ -341,11 +341,12 @@ // Setup our main web module to have the H5VCC API injected into it. DCHECK(!ContainsKey( + options_.web_module_options.injected_global_object_attributes, "h5vcc")); + DCHECK(!ContainsKey( options_.web_module_options.web_options.injected_global_object_attributes, "h5vcc")); - options_.web_module_options.web_options - .injected_global_object_attributes["h5vcc"] = - base::Bind(&BrowserModule::CreateH5vcc, base::Unretained(this)); + options_.web_module_options.injected_global_object_attributes["h5vcc"] = + base::Bind(&BrowserModule::CreateH5vccCallback, base::Unretained(this)); if (command_line->HasSwitch(switches::kDisableTimerResolutionLimit)) { options_.web_module_options.limit_performance_timer_resolution = false; @@ -515,7 +516,7 @@ if (web_module_) { lifecycle_observers_.RemoveObserver(web_module_.get()); } - web_module_.reset(NULL); + web_module_.reset(); // Increment the navigation generation so that we can attach it to event // callbacks as a way of identifying the new web module from the old ones. @@ -608,7 +609,8 @@ options.web_options.service_worker_jobs = service_worker_registry_.service_worker_jobs(); options.web_options.platform_info = platform_info_.get(); - web_module_.reset(new WebModule( + web_module_.reset(new WebModule("MainWebModule")); + web_module_->Run( url, application_state_, base::Bind(&BrowserModule::QueueOnRenderTreeProduced, base::Unretained(this), main_web_module_generation_), @@ -616,7 +618,7 @@ base::Bind(&BrowserModule::OnWindowClose, base::Unretained(this)), base::Bind(&BrowserModule::OnWindowMinimize, base::Unretained(this)), can_play_type_handler_.get(), media_module_.get(), viewport_size, - GetResourceProvider(), kLayoutMaxRefreshFrequencyInHz, options)); + GetResourceProvider(), kLayoutMaxRefreshFrequencyInHz, options); lifecycle_observers_.AddObserver(web_module_.get()); if (system_window_) { @@ -686,6 +688,7 @@ const base::Optional<math::Rect>& clip_rect, const base::Closure& done_callback) { TRACE_EVENT0("cobalt::browser", "BrowserModule::RequestScreenshotToFile()"); + DCHECK_EQ(base::MessageLoop::current(), self_message_loop_); DCHECK(screen_shot_writer_); scoped_refptr<render_tree::Node> render_tree; @@ -704,6 +707,7 @@ const base::Optional<math::Rect>& clip_rect, const ScreenShotWriter::ImageEncodeCompleteCallback& screenshot_ready) { TRACE_EVENT0("cobalt::browser", "BrowserModule::RequestScreenshotToMemory()"); + DCHECK_EQ(base::MessageLoop::current(), self_message_loop_); DCHECK(screen_shot_writer_); scoped_refptr<render_tree::Node> render_tree; @@ -898,6 +902,7 @@ } void BrowserModule::OnWindowSizeChanged(const ViewportSize& viewport_size) { + DCHECK_EQ(base::MessageLoop::current(), self_message_loop_); if (web_module_) { web_module_->SetSize(viewport_size); } @@ -964,6 +969,7 @@ void BrowserModule::OnCaptionSettingsChanged( const base::AccessibilityCaptionSettingsChangedEvent* event) { + DCHECK_EQ(base::MessageLoop::current(), self_message_loop_); if (web_module_) { web_module_->InjectCaptionSettingsChangedEvent(); } @@ -972,6 +978,7 @@ #if SB_API_VERSION >= 13 void BrowserModule::OnDateTimeConfigurationChanged( const base::DateTimeConfigurationChangedEvent* event) { + DCHECK_EQ(base::MessageLoop::current(), self_message_loop_); icu::TimeZone::adoptDefault(icu::TimeZone::detectHostTimeZone()); if (web_module_) { web_module_->UpdateDateTimeConfiguration(); @@ -1122,12 +1129,14 @@ } void BrowserModule::OnWindowOnOnlineEvent(const base::Event* event) { + DCHECK_EQ(base::MessageLoop::current(), self_message_loop_); if (web_module_) { web_module_->InjectWindowOnOnlineEvent(event); } } void BrowserModule::OnWindowOnOfflineEvent(const base::Event* event) { + DCHECK_EQ(base::MessageLoop::current(), self_message_loop_); if (web_module_) { web_module_->InjectWindowOnOfflineEvent(event); } @@ -2021,13 +2030,15 @@ } } -scoped_refptr<script::Wrappable> BrowserModule::CreateH5vcc( - script::EnvironmentSettings* settings) { - DCHECK(web_module_); +scoped_refptr<script::Wrappable> BrowserModule::CreateH5vccCallback( + WebModule* web_module, web::EnvironmentSettings* settings) { + DCHECK_NE(base::MessageLoop::current(), self_message_loop_); + // Note: This is a callback function that runs in the MainWebModule thread. + // The web_module_ member can not be safely used in this function. h5vcc::H5vcc::Settings h5vcc_settings; h5vcc_settings.set_media_source_setting_func = base::Bind( - &WebModule::SetMediaSourceSetting, base::Unretained(web_module_.get())); + &WebModule::SetMediaSourceSetting, base::Unretained(web_module)); h5vcc_settings.network_module = network_module_; #if SB_IS(EVERGREEN) h5vcc_settings.updater_module = updater_module_; @@ -2035,22 +2046,27 @@ h5vcc_settings.account_manager = account_manager_; h5vcc_settings.event_dispatcher = event_dispatcher_; - auto* dom_settings = base::polymorphic_downcast<dom::DOMSettings*>(settings); - - h5vcc_settings.user_agent_data = - dom_settings->window()->navigator()->user_agent_data(); - h5vcc_settings.global_environment = - dom_settings->context()->global_environment(); + h5vcc_settings.user_agent_data = settings->context() + ->GetWindowOrWorkerGlobalScope() + ->navigator_base() + ->user_agent_data(); + h5vcc_settings.global_environment = settings->context()->global_environment(); h5vcc_settings.persistent_settings = options_.persistent_settings; auto* h5vcc_object = new h5vcc::H5vcc(h5vcc_settings); if (!web_module_created_callback_.is_null()) { - web_module_created_callback_.Run(web_module_.get()); + web_module_created_callback_.Run(web_module); } return scoped_refptr<script::Wrappable>(h5vcc_object); } void BrowserModule::SetDeepLinkTimestamp(SbTimeMonotonic timestamp) { + if (base::MessageLoop::current() != self_message_loop_) { + self_message_loop_->task_runner()->PostTask( + FROM_HERE, base::Bind(&BrowserModule::SetDeepLinkTimestamp, + base::Unretained(this), timestamp)); + return; + } DCHECK(web_module_); web_module_->SetDeepLinkTimestamp(timestamp); }
diff --git a/cobalt/browser/browser_module.h b/cobalt/browser/browser_module.h index 6730fa2..646b750 100644 --- a/cobalt/browser/browser_module.h +++ b/cobalt/browser/browser_module.h
@@ -99,9 +99,8 @@ // All browser subcomponent options should have default constructors that // setup reasonable default options. struct Options { - explicit Options(const WebModule::Options& web_options) - : web_module_options(web_options), - command_line_auto_mem_settings( + Options() + : command_line_auto_mem_settings( memory_settings::AutoMemSettings::kTypeCommandLine), build_auto_mem_settings(memory_settings::AutoMemSettings::kTypeBuild), enable_splash_screen_on_reloads(true) {} @@ -465,9 +464,10 @@ // Returns the topic used, or an empty Optional if a topic isn't found. base::Optional<std::string> SetSplashScreenTopicFallback(const GURL& url); - // Function that creates the H5vcc object that will be injected into WebModule - scoped_refptr<script::Wrappable> CreateH5vcc( - script::EnvironmentSettings* settings); + // Callback function that creates the H5vcc object that will be injected into + // the MainWebModule. + scoped_refptr<script::Wrappable> CreateH5vccCallback( + WebModule* web_module, web::EnvironmentSettings* settings); // Validates the PersistentSettings for cache backend, if in use. void ValidateCacheBackendSettings();
diff --git a/cobalt/browser/debug_console.cc b/cobalt/browser/debug_console.cc index 72069e3..1f0bba5 100644 --- a/cobalt/browser/debug_console.cc +++ b/cobalt/browser/debug_console.cc
@@ -97,7 +97,7 @@ scoped_refptr<script::Wrappable> CreateDebugHub( const debug::console::DebugHub::GetHudModeCallback& get_hud_mode_function, const debug::CreateDebugClientCallback& create_debug_client_callback, - script::EnvironmentSettings* settings) { + web::EnvironmentSettings* settings) { return new debug::console::DebugHub(get_hud_mode_function, create_debug_client_callback); } @@ -116,7 +116,7 @@ const base::Closure& maybe_freeze_callback) { mode_ = GetInitialMode(); - WebModule::Options web_module_options("DebugConsoleWebModule"); + WebModule::Options web_module_options; // The debug console does not load any image assets. web_module_options.image_cache_capacity = 0; // Disable CSP for the Debugger's WebModule. This will also allow eval() in @@ -143,15 +143,15 @@ web_module_options.web_options.network_module = network_module; web_module_options.web_options.platform_info = platform_info; - web_module_.reset( - new WebModule(GURL(kInitialDebugConsoleUrl), initial_application_state, - render_tree_produced_callback, - base::Bind(&DebugConsole::OnError, base::Unretained(this)), - WebModule::CloseCallback(), /* window_close_callback */ - base::Closure(), /* window_minimize_callback */ - NULL /* can_play_type_handler */, NULL /* media_module */, - window_dimensions, resource_provider, layout_refresh_rate, - web_module_options)); + web_module_.reset(new WebModule("DebugConsoleWebModule")); + web_module_->Run(GURL(kInitialDebugConsoleUrl), initial_application_state, + render_tree_produced_callback, + base::Bind(&DebugConsole::OnError, base::Unretained(this)), + WebModule::CloseCallback(), /* window_close_callback */ + base::Closure(), /* window_minimize_callback */ + NULL /* can_play_type_handler */, NULL /* media_module */, + window_dimensions, resource_provider, layout_refresh_rate, + web_module_options); } DebugConsole::~DebugConsole() {}
diff --git a/cobalt/browser/on_screen_keyboard_starboard_bridge.cc b/cobalt/browser/on_screen_keyboard_starboard_bridge.cc index 39b998c..ccd818e 100644 --- a/cobalt/browser/on_screen_keyboard_starboard_bridge.cc +++ b/cobalt/browser/on_screen_keyboard_starboard_bridge.cc
@@ -96,5 +96,34 @@ return SbWindowSetOnScreenKeyboardKeepFocus(sb_window_provider_.Run(), keep_focus); } + +void OnScreenKeyboardStarboardBridge::SetBackgroundColor(uint8 r, uint8 g, + uint8 b) { + const CobaltExtensionOnScreenKeyboardApi* on_screen_keyboard_extension = + static_cast<const CobaltExtensionOnScreenKeyboardApi*>( + SbSystemGetExtension(kCobaltExtensionOnScreenKeyboardName)); + + if (on_screen_keyboard_extension && + strcmp(on_screen_keyboard_extension->name, + kCobaltExtensionOnScreenKeyboardName) == 0 && + on_screen_keyboard_extension->version >= 1) { + on_screen_keyboard_extension->SetBackgroundColor(sb_window_provider_.Run(), + r, g, b); + } +} + +void OnScreenKeyboardStarboardBridge::SetLightTheme(bool light_theme) { + const CobaltExtensionOnScreenKeyboardApi* on_screen_keyboard_extension = + static_cast<const CobaltExtensionOnScreenKeyboardApi*>( + SbSystemGetExtension(kCobaltExtensionOnScreenKeyboardName)); + + if (on_screen_keyboard_extension && + strcmp(on_screen_keyboard_extension->name, + kCobaltExtensionOnScreenKeyboardName) == 0 && + on_screen_keyboard_extension->version >= 1) { + on_screen_keyboard_extension->SetLightTheme(sb_window_provider_.Run(), + light_theme); + } +} } // namespace browser } // namespace cobalt
diff --git a/cobalt/browser/on_screen_keyboard_starboard_bridge.h b/cobalt/browser/on_screen_keyboard_starboard_bridge.h index f73cc11..682f2f4 100644 --- a/cobalt/browser/on_screen_keyboard_starboard_bridge.h +++ b/cobalt/browser/on_screen_keyboard_starboard_bridge.h
@@ -19,6 +19,7 @@ #include "base/callback.h" #include "cobalt/dom/on_screen_keyboard_bridge.h" +#include "cobalt/extension/on_screen_keyboard.h" #include "starboard/window.h" namespace cobalt { @@ -58,6 +59,10 @@ void SetKeepFocus(bool keep_focus) override; + void SetBackgroundColor(uint8 r, uint8 g, uint8 b) override; + + void SetLightTheme(bool light_theme) override; + private: base::Callback<SbWindow()> sb_window_provider_; };
diff --git a/cobalt/browser/splash_screen.cc b/cobalt/browser/splash_screen.cc index 2739ec0..952f790 100644 --- a/cobalt/browser/splash_screen.cc +++ b/cobalt/browser/splash_screen.cc
@@ -67,7 +67,7 @@ self_message_loop_(base::MessageLoop::current()), on_splash_screen_shutdown_complete_(on_splash_screen_shutdown_complete), shutdown_signaled_(false) { - WebModule::Options web_module_options("SplashScreenWebModule"); + WebModule::Options web_module_options; // We want the splash screen to load and appear as quickly as possible, so // we set it and its image decoding thread to be high priority. @@ -106,13 +106,14 @@ web_module_options.web_options.platform_info = platform_info; DCHECK(url_to_pass); - web_module_.reset(new WebModule( - *url_to_pass, initial_application_state, render_tree_produced_callback_, - base::Bind(&OnError), on_window_close, - base::Closure(), // window_minimize_callback - NULL /* can_play_type_handler */, NULL /* media_module */, - window_dimensions, resource_provider, layout_refresh_rate, - web_module_options)); + web_module_.reset(new WebModule("SplashScreenWebModule")); + web_module_->Run(*url_to_pass, initial_application_state, + render_tree_produced_callback_, base::Bind(&OnError), + on_window_close, + base::Closure(), // window_minimize_callback + NULL /* can_play_type_handler */, NULL /* media_module */, + window_dimensions, resource_provider, layout_refresh_rate, + web_module_options); } SplashScreen::~SplashScreen() {
diff --git a/cobalt/browser/web_module.cc b/cobalt/browser/web_module.cc index ecc0f56..a7cfd00 100644 --- a/cobalt/browser/web_module.cc +++ b/cobalt/browser/web_module.cc
@@ -1320,15 +1320,32 @@ } while (event && !layout_manager_->IsRenderTreePending()); } -WebModule::Options::Options(const std::string& name) - : web_options(name), - layout_trigger(layout::LayoutManager::kOnDocumentMutation), +WebModule::Options::Options() + : layout_trigger(layout::LayoutManager::kOnDocumentMutation), mesh_cache_capacity(configuration::Configuration::GetInstance() ->CobaltMeshCacheSizeInBytes()) { web_options.stack_size = cobalt::browser::kWebModuleStackSize; } -WebModule::WebModule( +WebModule::WebModule(const std::string& name) + : ui_nav_root_(new ui_navigation::NavItem( + ui_navigation::kNativeItemTypeContainer, + // Currently, events do not need to be processed for the root item. + base::Closure(), base::Closure(), base::Closure())) { + web_agent_.reset(new web::Agent(name)); +} + +WebModule::~WebModule() { + DCHECK(message_loop()); + DCHECK(web_agent_); + // This will cancel the timers for tasks, which help the thread exit + ClearAllIntervalsAndTimeouts(); + web_agent_->WaitUntilDone(); + web_agent_->Stop(); + web_agent_.reset(); +} + +void WebModule::Run( const GURL& initial_url, base::ApplicationState initial_application_state, const OnRenderTreeProducedCallback& render_tree_produced_callback, OnErrorCallback error_callback, const CloseCallback& window_close_callback, @@ -1336,11 +1353,7 @@ media::CanPlayTypeHandler* can_play_type_handler, media::MediaModule* media_module, const ViewportSize& window_dimensions, render_tree::ResourceProvider* resource_provider, float layout_refresh_rate, - const Options& options) - : ui_nav_root_(new ui_navigation::NavItem( - ui_navigation::kNativeItemTypeContainer, - // Currently, events do not need to be processed for the root item. - base::Closure(), base::Closure(), base::Closure())) { + const Options& options) { ConstructionData construction_data( initial_url, initial_application_state, render_tree_produced_callback, error_callback, window_close_callback, window_minimize_callback, @@ -1351,24 +1364,27 @@ #endif // defined(ENABLE_DEBUGGER) &synchronous_loader_interrupt_, options); - web_agent_.reset( - new web::Agent(options.web_options, - base::Bind(&WebModule::Initialize, base::Unretained(this), - construction_data), - this)); + web::Agent::Options web_options(options.web_options); + if (!options.injected_global_object_attributes.empty()) { + for (Options::InjectedGlobalObjectAttributes::const_iterator iter = + options.injected_global_object_attributes.begin(); + iter != options.injected_global_object_attributes.end(); ++iter) { + DCHECK(!ContainsKey(web_options.injected_global_object_attributes, + iter->first)); + // Trampoline to the given callback, adding a pointer to this WebModule. + web_options.injected_global_object_attributes[iter->first] = + base::Bind(iter->second, base::Unretained(this)); + } + } + + web_agent_->Run(web_options, + base::Bind(&WebModule::InitializeTaskInThread, + base::Unretained(this), construction_data), + this); } -WebModule::~WebModule() { - DCHECK(message_loop()); - DCHECK(web_agent_); - // This will cancel the timers for tasks, which help the thread exit - ClearAllIntervalsAndTimeouts(); - web_agent_->WaitUntilDone(); - web_agent_.reset(); -} - -void WebModule::Initialize(const ConstructionData& data, - web::Context* context) { +void WebModule::InitializeTaskInThread(const ConstructionData& data, + web::Context* context) { DCHECK_EQ(base::MessageLoop::current(), message_loop()); impl_.reset(new Impl(context, data)); }
diff --git a/cobalt/browser/web_module.h b/cobalt/browser/web_module.h index 3e442c8..a29c1bd 100644 --- a/cobalt/browser/web_module.h +++ b/cobalt/browser/web_module.h
@@ -55,6 +55,7 @@ #include "cobalt/web/blob.h" #include "cobalt/web/context.h" #include "cobalt/web/csp_delegate.h" +#include "cobalt/web/environment_settings.h" #include "cobalt/web/user_agent_platform_info.h" #include "cobalt/webdriver/session_driver.h" #include "starboard/atomic.h" @@ -90,9 +91,15 @@ public LifecycleObserver { public: struct Options { + typedef base::Callback<scoped_refptr<script::Wrappable>( + WebModule*, web::EnvironmentSettings*)> + CreateObjectFunction; + typedef base::hash_map<std::string, CreateObjectFunction> + InjectedGlobalObjectAttributes; + // All optional parameters defined in this structure should have their // values initialized in the default constructor to useful defaults. - explicit Options(const std::string& name); + Options(); web::Agent::Options web_options; @@ -240,6 +247,11 @@ // time. base::Callback<void(base::TimeTicks, base::TimeTicks)> collect_unload_event_time_callback; + + // injected_global_attributes contains a map of attributes to be injected + // into the Web Agent's window object upon construction. This provides + // a mechanism to inject custom APIs into the Web Agent object. + InjectedGlobalObjectAttributes injected_global_object_attributes; }; typedef layout::LayoutManager::LayoutResults LayoutResults; @@ -248,18 +260,19 @@ typedef base::Callback<void(const GURL&, const std::string&)> OnErrorCallback; typedef dom::Window::CloseCallback CloseCallback; - WebModule(const GURL& initial_url, - base::ApplicationState initial_application_state, - const OnRenderTreeProducedCallback& render_tree_produced_callback, - OnErrorCallback error_callback, - const CloseCallback& window_close_callback, - const base::Closure& window_minimize_callback, - media::CanPlayTypeHandler* can_play_type_handler, - media::MediaModule* media_module, - const cssom::ViewportSize& window_dimensions, - render_tree::ResourceProvider* resource_provider, - float layout_refresh_rate, const Options& options); + explicit WebModule(const std::string& name); ~WebModule(); + void Run(const GURL& initial_url, + base::ApplicationState initial_application_state, + const OnRenderTreeProducedCallback& render_tree_produced_callback, + OnErrorCallback error_callback, + const CloseCallback& window_close_callback, + const base::Closure& window_minimize_callback, + media::CanPlayTypeHandler* can_play_type_handler, + media::MediaModule* media_module, + const cssom::ViewportSize& window_dimensions, + render_tree::ResourceProvider* resource_provider, + float layout_refresh_rate, const Options& options); // Injects an on screen keyboard input event into the web module. The value // for type represents beforeinput or input. @@ -391,7 +404,7 @@ private: // Data required to construct a WebModule, initialized in the constructor and - // passed to |Initialize|. + // passed to |InitializeTaskInThread|. struct ConstructionData { ConstructionData(const GURL& initial_url, base::ApplicationState initial_application_state, @@ -453,9 +466,10 @@ // Forward declaration of the private implementation class. class Impl; - // Called by the constructor to create the private implementation object and + // Called by |Run| to create the private implementation object and // perform any other initialization required on the dedicated thread. - void Initialize(const ConstructionData& data, web::Context* context); + void InitializeTaskInThread(const ConstructionData& data, + web::Context* context); void ClearAllIntervalsAndTimeouts(); @@ -467,7 +481,7 @@ // The message loop this object is running on. base::MessageLoop* message_loop() const { DCHECK(web_agent_); - return web_agent_->message_loop(); + return web_agent_ ? web_agent_->message_loop() : nullptr; } // Private implementation object.
diff --git a/cobalt/build/build.id b/cobalt/build/build.id new file mode 100644 index 0000000..ce753b0 --- /dev/null +++ b/cobalt/build/build.id
@@ -0,0 +1 @@ +309312 \ No newline at end of file
diff --git a/cobalt/demos/content/watchdog-demo/index.html b/cobalt/demos/content/watchdog-demo/index.html index c5f17f8..d23e7d4 100644 --- a/cobalt/demos/content/watchdog-demo/index.html +++ b/cobalt/demos/content/watchdog-demo/index.html
@@ -63,7 +63,7 @@ } else if (watchdogFunction == 'unregister') { ret = h5vcc.crashLog.unregister('test-name'); } else if (watchdogFunction == 'ping') { - ret = h5vcc.crashLog.ping('test-name', `test-ping`); + ret = h5vcc.crashLog.ping('test-name', 'test-ping'); } else if (watchdogFunction == 'getWatchdogViolations') { ret = h5vcc.crashLog.getWatchdogViolations(); } else if (watchdogFunction == 'getPersistentSettingWatchdogEnable') {
diff --git a/cobalt/dom/BUILD.gn b/cobalt/dom/BUILD.gn index f014522..ff47acc 100644 --- a/cobalt/dom/BUILD.gn +++ b/cobalt/dom/BUILD.gn
@@ -439,5 +439,5 @@ "//url", ] - content_deps = [ ":licenses" ] + data_deps = [ ":licenses" ] }
diff --git a/cobalt/dom/on_screen_keyboard.cc b/cobalt/dom/on_screen_keyboard.cc index 54c2242..6f8da1b 100644 --- a/cobalt/dom/on_screen_keyboard.cc +++ b/cobalt/dom/on_screen_keyboard.cc
@@ -23,6 +23,63 @@ namespace cobalt { namespace dom { +namespace { +bool IsValidRGB(int r, int g, int b) { + if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { + return false; + } else { + return true; + } +} + +bool ParseColor(const char* color_str, int& r, int& g, int& b) { + size_t len = strlen(color_str); + if (len == 0) { + return false; + } + + // Handle hexadecimal color notation #RRGGBB + int r_tmp, g_tmp, b_tmp; + bool is_hex = + SbStringScanF(color_str, "#%02x%02x%02x", &r_tmp, &g_tmp, &b_tmp) == 3; + if (is_hex && IsValidRGB(r_tmp, g_tmp, b_tmp)) { + r = r_tmp; + g = g_tmp; + b = b_tmp; + return true; + } + + // Handle rgb color notation rgb(R, G, B) + if (!is_hex && len >= 10 && + SbStringCompareNoCaseN("rgb(", color_str, 4) == 0) { + int rgb_tmp[3] = {-1, -1, -1}; + const char* ptr = color_str + 4; + int i = 0; + while (*ptr) { + if (isdigit(*ptr)) { + char* end; + rgb_tmp[i++] = static_cast<int>(strtol(ptr, &end, 10)); + if (i == 3) { + break; + } + ptr = (const char*)end; + } else if (isspace(*ptr) || *ptr == ',') { + ptr++; + } else { + return false; + } + } + + if (IsValidRGB(rgb_tmp[0], rgb_tmp[1], rgb_tmp[2])) { + r = rgb_tmp[0]; + g = rgb_tmp[1]; + b = rgb_tmp[2]; + return true; + } + } + return false; +} +} // namespace OnScreenKeyboard::OnScreenKeyboard( script::EnvironmentSettings* settings, OnScreenKeyboardBridge* bridge, @@ -46,6 +103,21 @@ .second; DCHECK(is_emplaced); bridge_->Show(data_.c_str(), ticket); + + if (background_color_.has_value()) { + int r, g, b; + if (ParseColor(background_color_.value().c_str(), r, g, b)) { + bridge_->SetBackgroundColor(static_cast<uint8>(r), static_cast<uint8>(g), + static_cast<uint8>(b)); + } else { + LOG(WARNING) << "Invalid on-screen keyboard background color: " + << background_color_.value(); + } + } + if (light_theme_.has_value()) { + bridge_->SetLightTheme(light_theme_.value()); + } + return promise; }
diff --git a/cobalt/dom/on_screen_keyboard.h b/cobalt/dom/on_screen_keyboard.h index 8690c95..ecad6bf 100644 --- a/cobalt/dom/on_screen_keyboard.h +++ b/cobalt/dom/on_screen_keyboard.h
@@ -99,6 +99,18 @@ void set_keep_focus(bool keep_focus); bool keep_focus() const { return keep_focus_; } + void set_background_color(base::Optional<std::string>& background_color) { + background_color_ = background_color; + } + base::Optional<std::string> background_color() const { + return background_color_; + } + + void set_light_theme(base::Optional<bool> light_theme) { + light_theme_ = light_theme; + } + base::Optional<bool> light_theme() const { return light_theme_; } + // Called by the WebModule to dispatch DOM show, hide, focus, blur and // suggestions updated events. void DispatchHideEvent(int ticket); @@ -135,6 +147,10 @@ bool suggestions_supported_; + base::Optional<std::string> background_color_; + + base::Optional<bool> light_theme_; + DISALLOW_COPY_AND_ASSIGN(OnScreenKeyboard); }; } // namespace dom
diff --git a/cobalt/dom/on_screen_keyboard.idl b/cobalt/dom/on_screen_keyboard.idl index ebe632c..9487eec 100644 --- a/cobalt/dom/on_screen_keyboard.idl +++ b/cobalt/dom/on_screen_keyboard.idl
@@ -43,4 +43,15 @@ attribute EventHandler onfocus; attribute EventHandler onblur; attribute EventHandler oninput; + + // This attribute overrides the background color of on-screen keyboard. + // The attribute is only fully supported on Apple TV at the moment. + // backgroundColor should be a string of below formats: + // 1. hex color notation #RRGGBB, e.g. "#0000FF". + // 2. rgb color notation rgb(R, G, B), e.g. "rgb(0, 0, 255)". + attribute DOMString? backgroundColor; + + // This attribute overrides the light theme of on-screen keyboard. + // The attribute is only fully supported on Apple TV at the moment. + attribute boolean? lightTheme; };
diff --git a/cobalt/dom/on_screen_keyboard_bridge.h b/cobalt/dom/on_screen_keyboard_bridge.h index d58c0ad..ac6ad1c 100644 --- a/cobalt/dom/on_screen_keyboard_bridge.h +++ b/cobalt/dom/on_screen_keyboard_bridge.h
@@ -17,6 +17,7 @@ #include <string> +#include "base/basictypes.h" #include "cobalt/dom/dom_rect.h" namespace cobalt { @@ -39,6 +40,8 @@ virtual scoped_refptr<DOMRect> BoundingRect() const = 0; virtual void SetKeepFocus(bool keep_focus) = 0; virtual bool IsValidTicket(int ticket) const = 0; + virtual void SetBackgroundColor(uint8 r, uint8 g, uint8 b) = 0; + virtual void SetLightTheme(bool light_theme) = 0; }; } // namespace dom
diff --git a/cobalt/dom/on_screen_keyboard_test.cc b/cobalt/dom/on_screen_keyboard_test.cc index 4ab1e6f..8a8573c 100644 --- a/cobalt/dom/on_screen_keyboard_test.cc +++ b/cobalt/dom/on_screen_keyboard_test.cc
@@ -112,6 +112,10 @@ void SetKeepFocus(bool keep_focus) override { SetKeepFocusMock(keep_focus); } + void SetBackgroundColor(uint8 r, uint8 g, uint8 b) override {} + + void SetLightTheme(bool light_theme) override {} + MOCK_METHOD1(ShowMock, void(std::string)); MOCK_METHOD0(HideMock, void()); MOCK_METHOD0(BlurMock, void()); @@ -604,5 +608,49 @@ EXPECT_TRUE(EvaluateScript(script, NULL)); } +TEST_F(OnScreenKeyboardTest, SetBackgroundColor) { + if (SkipLocale()) return; + + std::string result; + EXPECT_TRUE( + EvaluateScript("window.onScreenKeyboard.backgroundColor;", &result)); + EXPECT_EQ("null", result); + + std::string color_str = "#0000FF"; + EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.backgroundColor = '" + + color_str + + "';" + "window.onScreenKeyboard.backgroundColor", + &result)); + + EXPECT_EQ(color_str, result); + + color_str = "rgb(0, 0, 100)"; + EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.backgroundColor = '" + + color_str + + "';" + "window.onScreenKeyboard.backgroundColor", + &result)); + + EXPECT_EQ(color_str, result); +} + +TEST_F(OnScreenKeyboardTest, SetLightTheme) { + if (SkipLocale()) return; + + std::string result; + EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.lightTheme;", &result)); + EXPECT_EQ("null", result); + + std::string light_theme_str = "true"; + EXPECT_TRUE( + EvaluateScript("window.onScreenKeyboard.lightTheme = " + light_theme_str + + ";" + "window.onScreenKeyboard.lightTheme", + &result)); + + EXPECT_EQ(light_theme_str, result); +} + } // namespace dom } // namespace cobalt
diff --git a/cobalt/encoding/BUILD.gn b/cobalt/encoding/BUILD.gn index e1f0665..904043f 100644 --- a/cobalt/encoding/BUILD.gn +++ b/cobalt/encoding/BUILD.gn
@@ -52,5 +52,5 @@ "//testing/gtest", ] - content_deps = [ "//third_party/icu:icudata" ] + data_deps = [ "//third_party/icu:icudata" ] }
diff --git a/cobalt/extension/crash_handler.h b/cobalt/extension/crash_handler.h index 8cf4732..912caba 100644 --- a/cobalt/extension/crash_handler.h +++ b/cobalt/extension/crash_handler.h
@@ -36,8 +36,15 @@ // The fields below this point were added in version 1 or later. + // Deprecated in version 2 and later. bool (*OverrideCrashpadAnnotations)( CrashpadAnnotations* crashpad_annotations); + + // The fields below this point were added in version 2 or later. + + // Sets a (key, value) pair for the handler to include when annotating a + // crash. Returns true on success and false on failure. + bool (*SetString)(const char* key, const char* value); } CobaltExtensionCrashHandlerApi; #ifdef __cplusplus
diff --git a/cobalt/extension/extension_test.cc b/cobalt/extension/extension_test.cc index cd7158d..58f051e 100644 --- a/cobalt/extension/extension_test.cc +++ b/cobalt/extension/extension_test.cc
@@ -221,9 +221,14 @@ } EXPECT_STREQ(extension_api->name, kExtensionName); - EXPECT_EQ(extension_api->version, 1u); + EXPECT_GE(extension_api->version, 1u); + EXPECT_LE(extension_api->version, 2u); EXPECT_NE(extension_api->OverrideCrashpadAnnotations, nullptr); + if (extension_api->version >= 2) { + EXPECT_NE(extension_api->SetString, nullptr); + } + const ExtensionApi* second_extension_api = static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName)); EXPECT_EQ(second_extension_api, extension_api)
diff --git a/cobalt/extension/on_screen_keyboard.h b/cobalt/extension/on_screen_keyboard.h new file mode 100644 index 0000000..315e2b7 --- /dev/null +++ b/cobalt/extension/on_screen_keyboard.h
@@ -0,0 +1,51 @@ +// Copyright 2022 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. + +#ifndef COBALT_EXTENSION_ON_SCREEN_KEYBOARD_H_ +#define COBALT_EXTENSION_ON_SCREEN_KEYBOARD_H_ + +#include "starboard/system.h" +#include "starboard/window.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define kCobaltExtensionOnScreenKeyboardName \ + "dev.cobalt.extension.OnScreenKeyboard" + +typedef struct CobaltExtensionOnScreenKeyboardApi { + // Name should be the string + // |kCobaltExtensionOnScreenKeyboardName|. This helps to validate that + // the extension API is correct. + const char* name; + + // This specifies the version of the API that is implemented. + uint32_t version; + + // The fields below this point were added in version 1 or later. + + // This function overrides the background color of on-screen keyboard in RGB + // color space, where r, g, b are between 0 and 255. + void (*SetBackgroundColor)(SbWindow window, uint8_t r, uint8_t g, uint8_t b); + + // This function overrides the light theme of on-screen keyboard. + void (*SetLightTheme)(SbWindow window, bool light_theme); +} CobaltExtensionOnScreenKeyboardApi; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // COBALT_EXTENSION_ON_SCREEN_KEYBOARD_H_
diff --git a/cobalt/h5vcc/h5vcc_crash_log.cc b/cobalt/h5vcc/h5vcc_crash_log.cc index 737d64c..a240d92 100644 --- a/cobalt/h5vcc/h5vcc_crash_log.cc +++ b/cobalt/h5vcc/h5vcc_crash_log.cc
@@ -20,6 +20,7 @@ #include "base/atomicops.h" #include "base/memory/singleton.h" #include "base/synchronization/lock.h" +#include "cobalt/extension/crash_handler.h" #if SB_HAS(CORE_DUMP_HANDLER_SUPPORT) #include STARBOARD_CORE_DUMP_HANDLER_INCLUDE @@ -97,6 +98,15 @@ bool H5vccCrashLog::SetString(const std::string& key, const std::string& value) { + auto crash_handler_extension = + static_cast<const CobaltExtensionCrashHandlerApi*>( + SbSystemGetExtension(kCobaltExtensionCrashHandlerName)); + if (crash_handler_extension && crash_handler_extension->version >= 2) { + return crash_handler_extension->SetString(key.c_str(), value.c_str()); + } + // The platform has not implemented a version of the CrashHandler Cobalt + // Extension appropriate for this use case. + // Forward the call to a global singleton so that we keep a consistent crash // log globally. CrashLogDictionary::GetInstance()->SetString(key, value);
diff --git a/cobalt/h5vcc/h5vcc_crash_log.idl b/cobalt/h5vcc/h5vcc_crash_log.idl index 7892219..e93caac 100644 --- a/cobalt/h5vcc/h5vcc_crash_log.idl +++ b/cobalt/h5vcc/h5vcc_crash_log.idl
@@ -56,9 +56,8 @@ boolean ping(DOMString name, DOMString ping_info); // Returns a json string containing the Watchdog violations since the last - // call, up to the 200 most recent. Clears internal cache of Watchdog - // violations to prevent duplicates. Timestamps are stored as strings due to - // int size constraints. + // call, up to 200. Clears internal cache of Watchdog violations to prevent + // duplicates. Timestamps are stored as strings due to int size constraints. // Example json: // { // "test-name":{
diff --git a/cobalt/layout_tests/BUILD.gn b/cobalt/layout_tests/BUILD.gn index 092b8df..328176d 100644 --- a/cobalt/layout_tests/BUILD.gn +++ b/cobalt/layout_tests/BUILD.gn
@@ -64,15 +64,15 @@ "//url", ] - content_deps = [ + data_deps = [ "//cobalt/layout_tests/testdata:layout_copy_test_data", "//cobalt/network:copy_ssl_certificates", "//third_party/icu:icudata", ] if (cobalt_font_package == "empty") { - content_deps += [ "//cobalt/content/fonts:copy_font_data" ] + data_deps += [ "//cobalt/content/fonts:copy_font_data" ] } else { - content_deps += [ + data_deps += [ "//cobalt/content/fonts:copy_fonts", "//cobalt/content/fonts:fonts_xml", ] @@ -99,5 +99,5 @@ "//url", ] - content_deps = [ "//cobalt/layout_tests/testdata:layout_copy_test_data" ] + data_deps = [ "//cobalt/layout_tests/testdata:layout_copy_test_data" ] }
diff --git a/cobalt/layout_tests/layout_snapshot.cc b/cobalt/layout_tests/layout_snapshot.cc index 57e3769..88d07f3 100644 --- a/cobalt/layout_tests/layout_snapshot.cc +++ b/cobalt/layout_tests/layout_snapshot.cc
@@ -83,7 +83,7 @@ // Use test runner mode to allow the content itself to dictate when it is // ready for layout should be performed. See cobalt/dom/test_runner.h. - browser::WebModule::Options web_module_options("SnapshotURL"); + browser::WebModule::Options web_module_options; web_module_options.layout_trigger = layout::LayoutManager::kTestRunnerMode; web_module_options.image_cache_capacity = kImageCacheCapacity; web_module_options.provide_screenshot_function = screenshot_provider; @@ -97,7 +97,8 @@ base::Optional<browser::WebModule::LayoutResults> results; // Create the WebModule and wait for a layout to occur. - browser::WebModule web_module( + browser::WebModule web_module("SnapshotURL"); + web_module.Run( url, base::kApplicationStateStarted, base::Bind(&WebModuleOnRenderTreeProducedCallback, &results, &run_loop, base::MessageLoop::current()),
diff --git a/cobalt/layout_tests/web_platform_tests.cc b/cobalt/layout_tests/web_platform_tests.cc index 520ed72..c5406bf 100644 --- a/cobalt/layout_tests/web_platform_tests.cc +++ b/cobalt/layout_tests/web_platform_tests.cc
@@ -209,7 +209,7 @@ web::kCspEnforcementEnable, CspDelegatePermissive::Create); // Use test runner mode to allow the content itself to dictate when it is // ready for layout should be performed. See cobalt/dom/test_runner.h. - browser::WebModule::Options web_module_options("RunWebPlatformTest"); + browser::WebModule::Options web_module_options; web_module_options.layout_trigger = layout::LayoutManager::kTestRunnerMode; // We assume that we won't suspend/resume while running the tests, and so // we take advantage of the convenience of inline script tags. @@ -222,7 +222,8 @@ base::RunLoop run_loop; // Create the WebModule and wait for a layout to occur. - browser::WebModule web_module( + browser::WebModule web_module("RunWebPlatformTest"); + web_module.Run( url, base::kApplicationStateStarted, base::Bind(&WebModuleOnRenderTreeProducedCallback, &results), base::Bind(&WebModuleErrorCallback, &run_loop,
diff --git a/cobalt/loader/BUILD.gn b/cobalt/loader/BUILD.gn index 9378b97..3b8f6e0 100644 --- a/cobalt/loader/BUILD.gn +++ b/cobalt/loader/BUILD.gn
@@ -203,8 +203,6 @@ ] data_deps = [ ":copy_loader_test_data" ] - - content_deps = [ ":copy_loader_test_data" ] } copy("copy_loader_test_data") {
diff --git a/cobalt/media/base/pipeline.h b/cobalt/media/base/pipeline.h index 9228cd3..4490669 100644 --- a/cobalt/media/base/pipeline.h +++ b/cobalt/media/base/pipeline.h
@@ -57,6 +57,7 @@ typedef ::media::PipelineStatistics PipelineStatistics; typedef ::media::PipelineStatus PipelineStatus; typedef ::media::PipelineStatusCallback PipelineStatusCallback; + typedef ::media::PipelineStatusCB PipelineStatusCB; typedef base::Callback<void(PipelineStatus status, bool is_initial_preroll, const std::string& error_message)> @@ -126,7 +127,7 @@ // It is an error to call this method after the pipeline has already started. virtual void Start(Demuxer* demuxer, const SetDrmSystemReadyCB& set_drm_system_ready_cb, - PipelineStatusCallback ended_cb, const ErrorCB& error_cb, + const PipelineStatusCB& ended_cb, const ErrorCB& error_cb, const SeekCB& seek_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& duration_change_cb, @@ -140,7 +141,7 @@ const OnEncryptedMediaInitDataEncounteredCB& encrypted_media_init_data_encountered_cb, const std::string& source_url, - PipelineStatusCallback ended_cb, const ErrorCB& error_cb, + const PipelineStatusCB& ended_cb, const ErrorCB& error_cb, const SeekCB& seek_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& duration_change_cb,
diff --git a/cobalt/media/base/sbplayer_pipeline.cc b/cobalt/media/base/sbplayer_pipeline.cc index dc3a212..9a8fb5b 100644 --- a/cobalt/media/base/sbplayer_pipeline.cc +++ b/cobalt/media/base/sbplayer_pipeline.cc
@@ -76,7 +76,7 @@ struct StartTaskParameters { Demuxer* demuxer; SetDrmSystemReadyCB set_drm_system_ready_cb; - PipelineStatusCallback ended_cb; + ::media::PipelineStatusCB ended_cb; ErrorCB error_cb; Pipeline::SeekCB seek_cb; Pipeline::BufferingStateCB buffering_state_cb; @@ -113,7 +113,7 @@ void Start(Demuxer* demuxer, const SetDrmSystemReadyCB& set_drm_system_ready_cb, - PipelineStatusCallback ended_cb, const ErrorCB& error_cb, + const PipelineStatusCB& ended_cb, const ErrorCB& error_cb, const SeekCB& seek_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& duration_change_cb, const base::Closure& output_mode_change_cb, @@ -123,7 +123,7 @@ void Start(const SetDrmSystemReadyCB& set_drm_system_ready_cb, const OnEncryptedMediaInitDataEncounteredCB& encrypted_media_init_data_encountered_cb, - const std::string& source_url, PipelineStatusCallback ended_cb, + const std::string& source_url, const PipelineStatusCB& ended_cb, const ErrorCB& error_cb, const SeekCB& seek_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& duration_change_cb, @@ -265,7 +265,7 @@ // Permanent callbacks passed in via Start(). SetDrmSystemReadyCB set_drm_system_ready_cb_; - PipelineStatusCallback ended_cb_; + PipelineStatusCB ended_cb_; ErrorCB error_cb_; BufferingStateCB buffering_state_cb_; base::Closure duration_change_cb_; @@ -441,7 +441,7 @@ void SbPlayerPipeline::Start(Demuxer* demuxer, const SetDrmSystemReadyCB& set_drm_system_ready_cb, - PipelineStatusCallback ended_cb, + const PipelineStatusCB& ended_cb, const ErrorCB& error_cb, const SeekCB& seek_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& duration_change_cb, @@ -462,7 +462,7 @@ StartTaskParameters parameters; parameters.demuxer = demuxer; parameters.set_drm_system_ready_cb = set_drm_system_ready_cb; - parameters.ended_cb = std::move(ended_cb); + parameters.ended_cb = ended_cb; parameters.error_cb = error_cb; parameters.seek_cb = seek_cb; parameters.buffering_state_cb = buffering_state_cb; @@ -484,7 +484,7 @@ const OnEncryptedMediaInitDataEncounteredCB& on_encrypted_media_init_data_encountered_cb, const std::string& source_url, - PipelineStatusCallback ended_cb, + const PipelineStatusCB& ended_cb, const ErrorCB& error_cb, const SeekCB& seek_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& duration_change_cb, @@ -504,7 +504,7 @@ StartTaskParameters parameters; parameters.demuxer = NULL; parameters.set_drm_system_ready_cb = set_drm_system_ready_cb; - parameters.ended_cb = std::move(ended_cb); + parameters.ended_cb = ended_cb; parameters.error_cb = error_cb; parameters.seek_cb = seek_cb; parameters.buffering_state_cb = buffering_state_cb; @@ -810,7 +810,7 @@ demuxer_ = parameters.demuxer; set_drm_system_ready_cb_ = parameters.set_drm_system_ready_cb; - ended_cb_ = std::move(parameters.ended_cb); + ended_cb_ = parameters.ended_cb; error_cb_ = parameters.error_cb; { base::AutoLock auto_lock(lock_); @@ -1327,7 +1327,7 @@ break; } case kSbPlayerStateEndOfStream: - std::move(ended_cb_).Run(::media::PIPELINE_OK); + ended_cb_.Run(::media::PIPELINE_OK); ended_ = true; break; case kSbPlayerStateDestroyed:
diff --git a/cobalt/media/base/starboard_player.cc b/cobalt/media/base/starboard_player.cc index ae7defd..8c97ffb 100644 --- a/cobalt/media/base/starboard_player.cc +++ b/cobalt/media/base/starboard_player.cc
@@ -565,12 +565,6 @@ bool is_visible = SbWindowIsValid(window_); SbMediaAudioCodec audio_codec = audio_sample_info_.codec; - SbMediaVideoCodec video_codec = kSbMediaVideoCodecNone; - // TODO: This is temporary for supporting background media playback. - // Need to be removed with media refactor. - if (is_visible) { - video_codec = video_sample_info_.codec; - } bool has_audio = audio_codec != kSbMediaAudioCodecNone;
diff --git a/cobalt/media/progressive/avc_parser.cc b/cobalt/media/progressive/avc_parser.cc index f9dcc0b..4c447db 100644 --- a/cobalt/media/progressive/avc_parser.cc +++ b/cobalt/media/progressive/avc_parser.cc
@@ -477,6 +477,7 @@ aac.GetChannelLayout(kSbrInMimetype), aac.GetOutputSamplesPerSecond(kSbrInMimetype), aac.codec_specific_data(), ::media::EncryptionScheme::kUnencrypted, base::TimeDelta(), 0); + audio_config_.set_aac_extra_data(aac.codec_specific_data()); } size_t AVCParser::CalculatePrependSize(DemuxerStream::Type type,
diff --git a/cobalt/renderer/BUILD.gn b/cobalt/renderer/BUILD.gn index 2fbc58b..21a89fc 100644 --- a/cobalt/renderer/BUILD.gn +++ b/cobalt/renderer/BUILD.gn
@@ -146,11 +146,10 @@ ":renderer_download_lottie_test_data", ] - content_deps = data_deps if (cobalt_font_package == "empty") { - content_deps += [ "//cobalt/content/fonts:copy_font_data" ] + data_deps += [ "//cobalt/content/fonts:copy_font_data" ] } else { - content_deps += [ + data_deps += [ "//cobalt/content/fonts:copy_fonts", "//cobalt/content/fonts:fonts_xml", ]
diff --git a/cobalt/renderer/sandbox/BUILD.gn b/cobalt/renderer/sandbox/BUILD.gn index faebec3..30d7def 100644 --- a/cobalt/renderer/sandbox/BUILD.gn +++ b/cobalt/renderer/sandbox/BUILD.gn
@@ -31,7 +31,7 @@ "//cobalt/trace_event", ] - content_deps = [ "//cobalt/renderer/test/scenes:scenes_copy_test_data" ] + data_deps = [ "//cobalt/renderer/test/scenes:scenes_copy_test_data" ] } # This target will build a sandbox application that allows for easy @@ -50,5 +50,5 @@ "//cobalt/trace_event", ] - content_deps = [ "//cobalt/renderer/test/scenes:scenes_copy_test_data" ] + data_deps = [ "//cobalt/renderer/test/scenes:scenes_copy_test_data" ] }
diff --git a/cobalt/speech/sandbox/BUILD.gn b/cobalt/speech/sandbox/BUILD.gn index 7853ac1..4b78a30 100644 --- a/cobalt/speech/sandbox/BUILD.gn +++ b/cobalt/speech/sandbox/BUILD.gn
@@ -41,5 +41,5 @@ deps += cobalt_platform_dependencies - content_deps = [ "//cobalt/speech:speech_testdata" ] + data_deps = [ "//cobalt/speech:speech_testdata" ] }
diff --git a/cobalt/web/agent.cc b/cobalt/web/agent.cc index f52e113..f44a345 100644 --- a/cobalt/web/agent.cc +++ b/cobalt/web/agent.cc
@@ -19,6 +19,7 @@ #include <utility> #include "base/observer_list.h" +#include "base/threading/thread_checker.h" #include "base/trace_event/trace_event.h" #include "cobalt/loader/fetcher_factory.h" #include "cobalt/loader/script_loader_factory.h" @@ -49,7 +50,7 @@ namespace { class Impl : public Context { public: - explicit Impl(const Agent::Options& options); + Impl(const std::string& name, const Agent::Options& options); virtual ~Impl(); void AddEnvironmentSettingsChangeObserver( @@ -222,7 +223,8 @@ environment_settings_change_observers_; }; -Impl::Impl(const Agent::Options& options) : name_(options.name) { +Impl::Impl(const std::string& name, const Agent::Options& options) + : name_(name) { TRACE_EVENT0("cobalt::web", "Agent::Impl::Impl()"); service_worker_jobs_ = options.service_worker_jobs; platform_info_ = options.platform_info; @@ -235,7 +237,7 @@ DCHECK(fetcher_factory_); script_loader_factory_.reset(new loader::ScriptLoaderFactory( - options.name.c_str(), fetcher_factory_.get(), options.thread_priority)); + name.c_str(), fetcher_factory_.get(), options.thread_priority)); DCHECK(script_loader_factory_); javascript_engine_ = @@ -469,9 +471,31 @@ void Agent::WillDestroyCurrentMessageLoop() { context_.reset(); } -Agent::Agent(const Options& options, InitializeCallback initialize_callback, - DestructionObserver* destruction_observer) - : thread_(options.name) { +Agent::Agent(const std::string& name) : thread_(name) {} + +void Agent::Stop() { + DCHECK(message_loop()); + DCHECK(thread_.IsRunning()); + + if (context() && context()->service_worker_jobs()) { + context()->service_worker_jobs()->UnregisterWebContext(context()); + } + + // Ensure that the destruction observer got added before stopping the thread. + destruction_observer_added_.Wait(); + // Stop the thread. This will cause the destruction observer to be notified. + thread_.Stop(); +} + +Agent::~Agent() { + DCHECK(!thread_.IsRunning()); + if (thread_.IsRunning()) { + Stop(); + } +} + +void Agent::Run(const Options& options, InitializeCallback initialize_callback, + DestructionObserver* destruction_observer) { // Start the dedicated thread and create the internal implementation // object on that thread. base::Thread::Options thread_options(base::MessageLoop::TYPE_DEFAULT, @@ -481,8 +505,9 @@ DCHECK(message_loop()); message_loop()->task_runner()->PostTask( - FROM_HERE, base::Bind(&Agent::Initialize, base::Unretained(this), options, - initialize_callback)); + FROM_HERE, + base::Bind(&Agent::InitializeTaskInThread, base::Unretained(this), + options, initialize_callback)); if (destruction_observer) { message_loop()->task_runner()->PostTask( @@ -507,30 +532,17 @@ base::Unretained(&destruction_observer_added_))); } -Agent::~Agent() { - DCHECK(message_loop()); - DCHECK(thread_.IsRunning()); - - if (context() && context()->service_worker_jobs()) { - context()->service_worker_jobs()->UnregisterWebContext(context()); - } - - // Ensure that the destruction observer got added before stopping the thread. - destruction_observer_added_.Wait(); - // Stop the thread. This will cause the destruction observer to be notified. - thread_.Stop(); -} - -void Agent::Initialize(const Options& options, - InitializeCallback initialize_callback) { +void Agent::InitializeTaskInThread(const Options& options, + InitializeCallback initialize_callback) { DCHECK_EQ(base::MessageLoop::current(), message_loop()); - context_.reset(CreateContext(options, thread_.message_loop())); + context_.reset( + CreateContext(thread_.thread_name(), options, thread_.message_loop())); initialize_callback.Run(context_.get()); } -Context* Agent::CreateContext(const Options& options, +Context* Agent::CreateContext(const std::string& name, const Options& options, base::MessageLoop* message_loop) { - auto* context = new Impl(options); + auto* context = new Impl(name, options); context->set_message_loop(message_loop); if (options.service_worker_jobs) { options.service_worker_jobs->RegisterWebContext(context);
diff --git a/cobalt/web/agent.h b/cobalt/web/agent.h index 956a6f6..aa48bb1 100644 --- a/cobalt/web/agent.h +++ b/cobalt/web/agent.h
@@ -40,19 +40,12 @@ class Agent : public base::MessageLoop::DestructionObserver { public: struct Options { - explicit Options(const std::string name) : name(name) {} typedef base::Callback<scoped_refptr<script::Wrappable>( - script::EnvironmentSettings*)> + web::EnvironmentSettings*)> CreateObjectFunction; typedef base::hash_map<std::string, CreateObjectFunction> InjectedGlobalObjectAttributes; - // The name of the Web Agent. This is useful for debugging purposes as - // in the case where multiple Web Agent objects exist, it can be used to - // differentiate which objects belong to which Web Agent. It is used - // to name some CVals. - std::string name; - // Specifies the priority of the web agent's thread. This is the thread // that is responsible for executing JavaScript. base::ThreadPriority thread_priority = base::ThreadPriority::NORMAL; @@ -83,14 +76,17 @@ JavaScriptHeapStatisticsCallback; typedef base::Callback<void(Context*)> InitializeCallback; - Agent(const Options& options, InitializeCallback initialize_callback, - DestructionObserver* destruction_observer = nullptr); + explicit Agent(const std::string& name); ~Agent(); - static Context* CreateContext(const Options& options, + void Run(const Options& options, InitializeCallback initialize_callback, + DestructionObserver* destruction_observer = nullptr); + void Stop(); + + static Context* CreateContext(const std::string& name, const Options& options, base::MessageLoop* message_loop = nullptr); static Context* CreateContext(const std::string& name) { - return CreateContext(Options(name)); + return CreateContext(name, Options()); } Context* context() { @@ -118,8 +114,8 @@ private: // Called by the constructor to create the private implementation object and // perform any other initialization required on the dedicated thread. - void Initialize(const Options& options, - InitializeCallback initialize_callback); + void InitializeTaskInThread(const Options& options, + InitializeCallback initialize_callback); // The thread created and owned by this Web Agent. // All sub-objects of this object are created on this thread, and all public
diff --git a/cobalt/web/url_utils.cc b/cobalt/web/url_utils.cc index 462c6f4..c69bc2d 100644 --- a/cobalt/web/url_utils.cc +++ b/cobalt/web/url_utils.cc
@@ -126,7 +126,8 @@ // https://www.w3.org/TR/2014/WD-url-1-20141209/#pre-update-steps void URLUtils::RunPreUpdateSteps(const GURL& new_url, const std::string& value) { - DLOG(INFO) << "Update URL to " << new_url.possibly_invalid_spec(); + DLOG(INFO) << "Update URL to " + << (value.empty() ? new_url.possibly_invalid_spec() : value); // 1. If value is not given, let value be the result of serializing the // associated url.
diff --git a/cobalt/webdriver/BUILD.gn b/cobalt/webdriver/BUILD.gn index abb1b08..e275c91 100644 --- a/cobalt/webdriver/BUILD.gn +++ b/cobalt/webdriver/BUILD.gn
@@ -155,6 +155,4 @@ ":copy_webdriver_data", ":webdriver_copy_test_data", ] - - content_deps = data_deps }
diff --git a/cobalt/webdriver/session_driver.cc b/cobalt/webdriver/session_driver.cc index 1c45c01..b04aa70 100644 --- a/cobalt/webdriver/session_driver.cc +++ b/cobalt/webdriver/session_driver.cc
@@ -14,6 +14,8 @@ #include "cobalt/webdriver/session_driver.h" +#include <utility> + #include "base/logging.h" #include "cobalt/base/log_message_handler.h" @@ -56,13 +58,13 @@ logging_callback_id_(0) { logging_callback_id_ = base::LogMessageHandler::GetInstance()->AddCallback( base::Bind(&SessionDriver::LogMessageHandler, base::Unretained(this))); - window_driver_ = create_window_driver_callback_.Run(GetUniqueWindowId()); + RefreshWindowDriver(); } void SessionDriver::RefreshWindowDriver() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - window_driver_ = - create_window_driver_callback_.Run(window_driver_->window_id()); + window_driver_ = create_window_driver_callback_.Run( + window_driver_ ? window_driver_->window_id() : GetUniqueWindowId()); } SessionDriver::~SessionDriver() {
diff --git a/cobalt/worker/dedicated_worker.cc b/cobalt/worker/dedicated_worker.cc index 0dff482..1daf030 100644 --- a/cobalt/worker/dedicated_worker.cc +++ b/cobalt/worker/dedicated_worker.cc
@@ -58,7 +58,7 @@ // allow the page to start dedicated workers). // 2. Let outside settings be the current settings object. // 3. Parse the scriptURL argument relative to outside settings. - Worker::Options options(kDedicatedWorkerName); + Worker::Options options; const GURL& base_url = environment_settings()->base_url(); options.url = base_url.Resolve(script_url_); @@ -83,7 +83,7 @@ options.web_options.service_worker_jobs = options.outside_settings->context()->service_worker_jobs(); - worker_.reset(new Worker(options)); + worker_.reset(new Worker(kDedicatedWorkerName, options)); // 10. Return worker. }
diff --git a/cobalt/worker/service_worker_object.cc b/cobalt/worker/service_worker_object.cc index 436f256..e63c421 100644 --- a/cobalt/worker/service_worker_object.cc +++ b/cobalt/worker/service_worker_object.cc
@@ -58,6 +58,7 @@ DCHECK(message_loop()); DCHECK(web_context_); web_agent_->WaitUntilDone(); + web_agent_->Stop(); web_agent_.reset(); web_context_ = nullptr; } @@ -123,10 +124,11 @@ void ServiceWorkerObject::ObtainWebAgentAndWaitUntilDone() { TRACE_EVENT0("cobalt::worker", "ServiceWorkerObject::ObtainWebAgentAndWaitUntilDone()"); - web_agent_.reset(new web::Agent( + web_agent_.reset(new web::Agent(options_.name)); + web_agent_->Run( options_.web_options, base::Bind(&ServiceWorkerObject::Initialize, base::Unretained(this)), - this)); + this); web_agent_->WaitUntilDone(); }
diff --git a/cobalt/worker/service_worker_object.h b/cobalt/worker/service_worker_object.h index 8b4daa6..a3cf5cb 100644 --- a/cobalt/worker/service_worker_object.h +++ b/cobalt/worker/service_worker_object.h
@@ -56,15 +56,16 @@ public: // Worker Options needed at thread run time. struct Options { - explicit Options( + Options( const std::string& name, network::NetworkModule* network_module, ServiceWorkerRegistrationObject* containing_service_worker_registration) - : web_options(name), + : name(name), containing_service_worker_registration( containing_service_worker_registration) { web_options.network_module = network_module; } + std::string name; web::Agent::Options web_options; ServiceWorkerRegistrationObject* containing_service_worker_registration; };
diff --git a/cobalt/worker/worker.cc b/cobalt/worker/worker.cc index a820c8f..a716910 100644 --- a/cobalt/worker/worker.cc +++ b/cobalt/worker/worker.cc
@@ -43,7 +43,7 @@ bool PermitAnyURL(const GURL&, bool) { return true; } } // namespace -Worker::Worker(const Options& options) : options_(options) { +Worker::Worker(const char* name, const Options& options) : options_(options) { // Algorithm for 'run a worker' // https://html.spec.whatwg.org/commit-snapshots/465a6b672c703054de278b0f8133eb3ad33d93f4/#run-a-worker // 1. Let is shared be true if worker is a SharedWorker object, and false @@ -57,9 +57,15 @@ // 6. Let agent be the result of obtaining a dedicated/shared worker agent // given outside settings and is shared. Run the rest of these steps in // that agent. - web_agent_.reset(new web::Agent( - options.web_options, - base::Bind(&Worker::Initialize, base::Unretained(this)), this)); + std::string agent_name(name); + if (!options.options.name().empty()) { + agent_name.push_back(':'); + agent_name.append(options.options.name()); + } + web_agent_.reset(new web::Agent(agent_name)); + web_agent_->Run(options.web_options, + base::Bind(&Worker::Initialize, base::Unretained(this)), + this); } void Worker::WillDestroyCurrentMessageLoop() { @@ -126,7 +132,7 @@ #endif // ENABLE_DEBUGGER // 10. Set worker global scope's name to the value of options's name member. - dedicated_worker_global_scope->set_name(options_.web_options.name); + dedicated_worker_global_scope->set_name(options_.options.name()); // 11. Append owner to worker global scope's owner set. // 12. If is shared is true, then: // 1. Set worker global scope's constructor origin to outside settings's @@ -309,6 +315,7 @@ if (web_agent_) { DCHECK(message_loop()); web_agent_->WaitUntilDone(); + web_agent_->Stop(); web_agent_.reset(); web_context_ = nullptr; }
diff --git a/cobalt/worker/worker.h b/cobalt/worker/worker.h index 2c488ec..feea239 100644 --- a/cobalt/worker/worker.h +++ b/cobalt/worker/worker.h
@@ -55,8 +55,6 @@ public: // Worker Options needed at thread run time. struct Options { - explicit Options(const std::string& name) : web_options(name) {} - web::Agent::Options web_options; // True if worker is a SharedWorker object, and false otherwise. @@ -70,7 +68,7 @@ WorkerOptions options; }; - explicit Worker(const Options& options); + Worker(const char* name, const Options& options); ~Worker(); Worker(const Worker&) = delete; Worker& operator=(const Worker&) = delete;
diff --git a/net/BUILD.gn b/net/BUILD.gn index 866c00e..1044e1d 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -4229,7 +4229,7 @@ ] if (is_starboard) { - content_deps = [ + data_deps = [ ":net_unittest_files", ":third_party_unittest_files", "//third_party/icu:icudata",
diff --git a/net/data/url_request_unittest/redirect302-to-echo-cacheable.mock-http-headers b/net/data/url_request_unittest/redirect302-to-echo-cacheable.mock-http-headers index fce2271..d41294c 100644 --- a/net/data/url_request_unittest/redirect302-to-echo-cacheable.mock-http-headers +++ b/net/data/url_request_unittest/redirect302-to-echo-cacheable.mock-http-headers
@@ -2,3 +2,4 @@ Location: /echo Content-Length: 1 Cache-control: max-age=60000 +Content-Type: example/unit_test
diff --git a/net/disk_cache/simple/simple_synchronous_entry.cc b/net/disk_cache/simple/simple_synchronous_entry.cc index c8ca20a..2a42726 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.cc +++ b/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -336,6 +336,7 @@ GetFilenameFromEntryFileKeyAndFileIndex(entry_file_key_, i)); #if defined(STARBOARD) ok = false; + // Note: Files can not be renamed on Starboard. #else ok = base::ReplaceFile(old_name, new_name, &out_error) && ok; #endif @@ -350,6 +351,7 @@ path_.AppendASCII(GetSparseFilenameFromEntryFileKey(entry_file_key_)); #if defined(STARBOARD) ok = false; + // Note: Files can not be renamed on Starboard. #else ok = base::ReplaceFile(old_name, new_name, &out_error) && ok; #endif
diff --git a/net/disk_cache/simple/simple_util.cc b/net/disk_cache/simple/simple_util.cc index 5c1f5a7..513de96 100644 --- a/net/disk_cache/simple/simple_util.cc +++ b/net/disk_cache/simple/simple_util.cc
@@ -63,20 +63,30 @@ std::string GetFilenameFromEntryFileKeyAndFileIndex( const SimpleFileTracker::EntryFileKey& key, int file_index) { +#if defined(STARBOARD) + return base::StringPrintf("%016" PRIx64 "_%1d", key.entry_hash, file_index); +#else + // Files are not renamed on Starboard. if (key.doom_generation == 0) return base::StringPrintf("%016" PRIx64 "_%1d", key.entry_hash, file_index); else return base::StringPrintf("todelete_%016" PRIx64 "_%1d_%" PRIu64, key.entry_hash, file_index, key.doom_generation); +#endif } std::string GetSparseFilenameFromEntryFileKey( const SimpleFileTracker::EntryFileKey& key) { +#if defined(STARBOARD) + return base::StringPrintf("%016" PRIx64 "_s", key.entry_hash); +#else + // Files are not renamed on Starboard. if (key.doom_generation == 0) return base::StringPrintf("%016" PRIx64 "_s", key.entry_hash); else return base::StringPrintf("todelete_%016" PRIx64 "_s_%" PRIu64, key.entry_hash, key.doom_generation); +#endif } std::string GetFilenameFromKeyAndFileIndex(const std::string& key,
diff --git a/net/http/http_cache_lookup_manager_unittest.cc b/net/http/http_cache_lookup_manager_unittest.cc index ac7dec9..d3776d7 100644 --- a/net/http/http_cache_lookup_manager_unittest.cc +++ b/net/http/http_cache_lookup_manager_unittest.cc
@@ -37,7 +37,8 @@ std::unique_ptr<MockTransaction> CreateMockTransaction(const GURL& url) { MockTransaction mock_trans = { url.spec().c_str(), "GET", base::Time(), "", LOAD_NORMAL, - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n", base::Time(), "<html><body>Google Blah Blah</body></html>",
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index 9f13b95..5758e00 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -68,7 +68,8 @@ static const char* const kMimeTypesCacheAllowlist[] = { "text/html", "text/css", "image/gif", "image/jpeg", "image/png", "image/svg+xml", "image/webp", "font/otf", - "font/ttf", "font/woff", "font/woff2", "text/javascript"}; + "font/ttf", "font/woff", "font/woff2", "text/javascript", + "example/unit_test", "application/javascript"}; #endif constexpr TimeDelta kStaleRevalidateTimeout = TimeDelta::FromSeconds(60); @@ -3085,14 +3086,11 @@ // Only allow caching for specific mime types. std::string mime_type; response_.headers->GetMimeType(&mime_type); - // TODO(b/243727663): Empty mime types should not get cached either. - bool is_allowed_mime_type = mime_type.empty(); - if (!is_allowed_mime_type) { - for (auto allowed_type : kMimeTypesCacheAllowlist) { - if (mime_type.compare(allowed_type) == 0) { - is_allowed_mime_type = true; - break; - } + bool is_allowed_mime_type = false; + for (auto allowed_type : kMimeTypesCacheAllowlist) { + if (mime_type.compare(allowed_type) == 0) { + is_allowed_mime_type = true; + break; } } #else
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index 0740dc8..0d887ad 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc
@@ -369,7 +369,8 @@ base::Time(), "", LOAD_VALIDATE_CACHE, - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test\n", "Cache-Control: max-age=10000\n", base::Time(), "<html><body>Google Blah Blah</body></html>", @@ -437,6 +438,10 @@ // AddHeadersFromString() (_not_ AddHeaderFromString()). #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n" +// Adds the unit_test MIME type to the EXTRA_HEADER for compatibility +// with http_cache_transaction that now will require a MIME type. +#define MIME_TYPE_EXTRA_HEADER "Content-Type: example/unit_test\r\n" EXTRA_HEADER + static const char kExtraHeaderKey[] = "Extra"; // Static. @@ -477,7 +482,10 @@ ranges.size() != 1) { // This is not a byte range request. We return 200. response_status->assign("HTTP/1.1 200 OK"); - response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT"); + // Adds the unit_test MIME type to the response_headers for compatibility + // with http_cache_transaction that now will require a MIME type. + response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT\n" + "Content-Type: example/unit_test"); response_data->assign("Not a range"); return; } @@ -537,7 +545,8 @@ const MockTransaction kRangeGET_TransactionOK = { "http://www.google.com/range", "GET", base::Time(), "Range: bytes = 40-49\r\n" EXTRA_HEADER, LOAD_NORMAL, - "HTTP/1.1 206 Partial Content", + "HTTP/1.1 206 Partial Content\n" + "Content-Type: example/unit_test", "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" "ETag: \"foo\"\n" "Accept-Ranges: bytes\n" @@ -4759,7 +4768,8 @@ MockHttpCache cache; ScopedMockTransaction transaction(kETagGET_Transaction); - transaction.status = "HTTP/1.0 200 OK"; + transaction.status = "HTTP/1.0 200 OK\n" + "Content-Type: example/unit_test\n"; // Write to the cache. RunTransactionTest(cache.http_cache(), transaction); @@ -4782,7 +4792,8 @@ MockHttpCache cache; ScopedMockTransaction transaction(kETagGET_Transaction); - transaction.status = "HTTP/1.0 200 OK"; + transaction.status = "HTTP/1.0 200 OK\n" + "Content-Type: example/unit_test\n"; // Write to the cache. RunTransactionTest(cache.http_cache(), transaction); @@ -4961,7 +4972,8 @@ TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache1) { // First network response for |kUrl|. static const Response kNetResponse1 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", "body1" @@ -4969,7 +4981,8 @@ // Second network response for |kUrl|. static const Response kNetResponse2 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", "body2" @@ -4987,7 +5000,8 @@ TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache2) { // First network response for |kUrl|. static const Response kNetResponse1 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" "Etag: \"ETAG1\"\n" "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire. @@ -4996,7 +5010,8 @@ // Second network response for |kUrl|. static const Response kNetResponse2 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Etag: \"ETAG2\"\n" "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire. @@ -5015,7 +5030,8 @@ TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache3) { // First network response for |kUrl|. static const Response kNetResponse1 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" "Server: server1\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", @@ -5024,7 +5040,8 @@ // Second network response for |kUrl|. static const Response kNetResponse2 = { - "HTTP/1.1 304 Not Modified", + "HTTP/1.1 304 Not Modified\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Server: server2\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", @@ -5035,7 +5052,8 @@ "HTTP/1.1 200 OK", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Server: server2\n" - "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", + "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n" + "Content-Type: example/unit_test\n", "body1" }; @@ -5055,7 +5073,8 @@ const char kUrl[] = "http://foobar.com/main.css"; static const Response kNetResponse = { - "HTTP/1.1 304 Not Modified", + "HTTP/1.1 304 Not Modified\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", "" @@ -5099,7 +5118,8 @@ const char kUrl[] = "http://foobar.com/main.css"; static const Response kNetResponse = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", "foobar!!!" @@ -5140,7 +5160,8 @@ // (the if-modified-since date is 2 days AFTER the cache's modification date). TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache6) { static const Response kNetResponse1 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" "Server: server1\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", @@ -5149,7 +5170,8 @@ // Second network response for |kUrl|. static const Response kNetResponse2 = { - "HTTP/1.1 304 Not Modified", + "HTTP/1.1 304 Not Modified\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Server: server2\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", @@ -5170,7 +5192,8 @@ // response (304) to update the cache. TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache7) { static const Response kNetResponse1 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" "Etag: \"Foo1\"\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", @@ -5179,7 +5202,8 @@ // Second network response for |kUrl|. static const Response kNetResponse2 = { - "HTTP/1.1 304 Not Modified", + "HTTP/1.1 304 Not Modified\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Etag: \"Foo2\"\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", @@ -5197,7 +5221,8 @@ // and if-modified-since updates the cache. TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache8) { static const Response kNetResponse1 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" "Etag: \"Foo1\"\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", @@ -5206,7 +5231,8 @@ // Second network response for |kUrl|. static const Response kNetResponse2 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Etag: \"Foo2\"\n" "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", @@ -5225,7 +5251,8 @@ // and if-modified-since does not update the cache with only one match. TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache9) { static const Response kNetResponse1 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" "Etag: \"Foo1\"\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", @@ -5234,7 +5261,8 @@ // Second network response for |kUrl|. static const Response kNetResponse2 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Etag: \"Foo2\"\n" "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", @@ -5254,7 +5282,8 @@ // and if-modified-since does not update the cache with only one match. TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache10) { static const Response kNetResponse1 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" "Etag: \"Foo1\"\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", @@ -5263,7 +5292,8 @@ // Second network response for |kUrl|. static const Response kNetResponse2 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Etag: \"Foo2\"\n" "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", @@ -5654,7 +5684,9 @@ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); - EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers); + EXPECT_EQ("HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test\n" + "Content-Length: 42\n", headers); RemoveMockTransaction(&transaction); } @@ -7050,7 +7082,8 @@ TEST_F(HttpCacheTest, RangeGET_301) { MockHttpCache cache; ScopedMockTransaction transaction(kRangeGET_TransactionOK); - transaction.status = "HTTP/1.1 301 Moved Permanently"; + transaction.status = "HTTP/1.1 301 Moved Permanently\n" + "Content-Type: example/unit_test"; transaction.response_headers = "Location: http://www.bar.com/\n"; transaction.data = ""; transaction.handler = NULL; @@ -8394,6 +8427,7 @@ ScopedMockTransaction transaction(kRangeGET_TransactionOK); std::string raw_headers("HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test\n" "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" "ETag: \"foo\"\n" "Accept-Ranges: bytes\n" @@ -8411,6 +8445,7 @@ "HTTP/1.1 200 OK\n" "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" "Accept-Ranges: bytes\n" + "Content-Type: example/unit_test\n" "ETag: \"foo\"\n" "Content-Length: 80\n"); @@ -8552,7 +8587,8 @@ // The server will return 200 instead of a byte range. std::string expected_headers( "HTTP/1.1 200 OK\n" - "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); + "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" + "Content-Type: example/unit_test\n"); EXPECT_EQ(expected_headers, headers); EXPECT_EQ(2, cache.network_layer()->transaction_count()); @@ -8607,6 +8643,7 @@ AddMockTransaction(&kRangeGET_TransactionOK); std::string raw_headers("HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test\n" "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" "ETag: \"foo\"\n" "Accept-Ranges: bytes\n" @@ -8699,7 +8736,7 @@ // Now make a regular request. std::string headers; - transaction.request_headers = EXTRA_HEADER; + transaction.request_headers = MIME_TYPE_EXTRA_HEADER; transaction.data = "Not a range"; RangeTransactionServer handler; handler.set_bad_200(true); @@ -8720,6 +8757,7 @@ ScopedMockTransaction transaction(kRangeGET_TransactionOK); std::string raw_headers("HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test\n" "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" "ETag: \"foo\"\n" "Accept-Ranges: bytes\n" @@ -8842,7 +8880,8 @@ MockHttpCache cache; ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction); - kTestTransaction.status = "HTTP/1.1 301 Moved Permanently"; + kTestTransaction.status = "HTTP/1.1 301 Moved Permanently\n" + "Content-Type: example/unit_test"; kTestTransaction.response_headers = "Location: http://www.bar.com/\n"; MockHttpRequest request(kTestTransaction); @@ -9138,7 +9177,8 @@ request.data = kData; static const Response kNetResponse1 = { - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", kData @@ -9154,7 +9194,8 @@ request.load_flags = LOAD_VALIDATE_CACHE; static const Response kNetResponse2 = { - "HTTP/1.1 304 Not Modified", + "HTTP/1.1 304 Not Modified\n" + "Content-Type: example/unit_test", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n", "" }; @@ -9178,6 +9219,7 @@ EXPECT_EQ("HTTP/1.1 200 OK\n" "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" + "Content-Type: example/unit_test\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", ToSimpleString(response.headers)); @@ -9673,6 +9715,7 @@ AddMockTransaction(&kRangeGET_TransactionOK); std::string raw_headers("HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test\n" "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" "ETag: \"foo\"\n" "Accept-Ranges: bytes\n" @@ -10091,6 +10134,7 @@ AddMockTransaction(&kRangeGET_TransactionOK); std::string raw_headers("HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test\n" "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" "ETag: \"foo\"\n" "Accept-Ranges: bytes\n"
diff --git a/net/http/http_transaction_test_util.cc b/net/http/http_transaction_test_util.cc index 9b9c92c..8914895 100644 --- a/net/http/http_transaction_test_util.cc +++ b/net/http/http_transaction_test_util.cc
@@ -48,7 +48,8 @@ base::Time(), "", LOAD_NORMAL, - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Cache-Control: max-age=10000\n", base::Time(), "<html><body>Google Blah Blah</body></html>", @@ -67,7 +68,8 @@ base::Time(), "", LOAD_NORMAL, - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "", base::Time(), "<html><body>Google Blah Blah</body></html>", @@ -86,7 +88,8 @@ base::Time(), "", LOAD_NORMAL, - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n", base::Time(), @@ -106,7 +109,8 @@ base::Time(), "", LOAD_NORMAL, - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Cache-Control: max-age=10000\n" "Etag: \"foopy\"\n", base::Time(), @@ -126,7 +130,8 @@ base::Time(), "Range: 0-100\r\n", LOAD_NORMAL, - "HTTP/1.1 200 OK", + "HTTP/1.1 200 OK\n" + "Content-Type: example/unit_test", "Cache-Control: max-age=10000\n", base::Time(), "<html><body>Google Blah Blah</body></html>",
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index b4a9ab4..e55c504 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -1156,12 +1156,6 @@ raw_header_size_ = GetTotalReceivedBytes(); ConvertRealLoadTimesToBlockingTimes(&load_timing_info_); -#if defined (STARBOARD) - load_timing_info_.encoded_body_size = static_cast<uint64_t>(GetTotalReceivedBytes()); - if (!load_timing_info_callback_.is_null()) { - load_timing_info_callback_.Run(load_timing_info_); - } -#endif // defined(STARBOARD) } } @@ -1171,6 +1165,13 @@ if (has_notified_completion_) return; + #if defined (STARBOARD) + load_timing_info_.encoded_body_size = static_cast<uint64_t>(GetTotalReceivedBytes()); + if (load_timing_info_callback_) { + load_timing_info_callback_.Run(load_timing_info_); + } + #endif // defined(STARBOARD) + is_pending_ = false; is_redirecting_ = false; has_notified_completion_ = true;
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc index fc7b92b..e0f4358 100644 --- a/net/url_request/url_request_http_job_unittest.cc +++ b/net/url_request/url_request_http_job_unittest.cc
@@ -494,6 +494,7 @@ { MockWrite writes[] = {MockWrite(kSimpleGetMockWrite)}; MockRead reads[] = {MockRead("HTTP/1.1 200 OK\r\n" + "Content-Type: example/unit_test\r\n" "Content-Length: 12\r\n\r\n"), MockRead("Test Content")};
diff --git a/starboard/android/apk/app/CMakeLists.txt b/starboard/android/apk/app/CMakeLists.txt index d5d598f..5b1cb17 100644 --- a/starboard/android/apk/app/CMakeLists.txt +++ b/starboard/android/apk/app/CMakeLists.txt
@@ -38,6 +38,13 @@ ) endif() +# Abort gracefully if the config has not been generated. This should only happen +# when building from Android Studio which builds all supported ABIs by default. +if(NOT EXISTS "${COBALT_PRODUCT_DIR}") + message(WARNING "android-${COBALT_ARCH}_${COBALT_CONFIG} not configured. Please run GN. Skipping config.") + return() +endif() + # If COBALT_CONTENT_DIR isn't set for a particular deploy target use the # 'content/data' directory. if(NOT COBALT_CONTENT_DIR) @@ -47,9 +54,9 @@ endif() # If COBALT_LIBRARY_DIR isn't set for a particular deploy target use the -# toplevel lib/ subdirectory. +# product root. if(NOT COBALT_LIBRARY_DIR) - set(COBALT_LIBRARY_DIR ${COBALT_PRODUCT_DIR}/lib) + set(COBALT_LIBRARY_DIR ${COBALT_PRODUCT_DIR}) endif() # For platform deploy builds, use the -n parameter to skip Cobalt ninja and @@ -76,9 +83,11 @@ # ("cobalt_content" never gets created, so this runs every time.) add_custom_command(OUTPUT cobalt_content DEPENDS coat_lib + COMMAND ${CMAKE_COMMAND} -E make_directory + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/../../../../${COBALT_CONFIG} COMMAND ${CMAKE_COMMAND} -E create_symlink ${COBALT_CONTENT_DIR} - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/../../../../cobalt_content + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/../../../../${COBALT_CONFIG}/cobalt_content ) # We need a target (not a file) for the phony native dependency below.
diff --git a/starboard/android/apk/app/build.gradle b/starboard/android/apk/app/build.gradle index 424a48d..5622927 100644 --- a/starboard/android/apk/app/build.gradle +++ b/starboard/android/apk/app/build.gradle
@@ -135,16 +135,16 @@ } // Add the directories symlinked by the CMake "cobalt_content" custom command. debug { - assets.srcDir "${buildDir}/intermediates/cxx/cobalt_content" + assets.srcDir "${buildDir}/intermediates/cxx/debug/cobalt_content" } devel { - assets.srcDir "${buildDir}/intermediates/cxx/cobalt_content" + assets.srcDir "${buildDir}/intermediates/cxx/devel/cobalt_content" } qa { - assets.srcDir "${buildDir}/intermediates/cxx/cobalt_content" + assets.srcDir "${buildDir}/intermediates/cxx/qa/cobalt_content" } release { - assets.srcDir "${buildDir}/intermediates/cxx/cobalt_content" + assets.srcDir "${buildDir}/intermediates/cxx/gold/cobalt_content" } } externalNativeBuild {
diff --git a/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java b/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java index eeed7a7..1478b37 100644 --- a/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java +++ b/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
@@ -781,6 +781,10 @@ Log.e(TAG, "Failed to set operating rate with invalid fps " + mFps); return; } + if (mMediaCodec == null) { + Log.e(TAG, "Failed to set operating rate when media codec is null."); + return; + } double operatingRate = mPlaybackRate * mFps; Bundle b = new Bundle(); b.putFloat(MediaFormat.KEY_OPERATING_RATE, (float) operatingRate);
diff --git a/starboard/android/apk/build.gradle b/starboard/android/apk/build.gradle index 3db6ad6..1247002 100644 --- a/starboard/android/apk/build.gradle +++ b/starboard/android/apk/build.gradle
@@ -42,17 +42,16 @@ } } -task clean(type: Delete) { - delete rootProject.buildDir -} - // Move the 'buildDir' for all projects into sub-directories of a shared top-level build directory, // which is either the root's original 'buildDir' or a custom location when building for platform // deploy. Note that the platform deploy action sets a custom 'cobaltGradleDir' property rather // than setting 'buildDir' directly on the command line since Gradle tries to get smart about // 'buildDir' which can end up putting it at the wrong depth in the file system. -def rootBuildDir = hasProperty('cobaltGradleDir') ? new File(cobaltGradleDir, 'build') : buildDir -allprojects { buildDir = new File(rootBuildDir, project.name).canonicalFile } +allprojects { buildDir = new File(gradle.ext.rootBuildDir, project.name).canonicalFile } + +task clean(type: Delete) { + delete gradle.ext.rootBuildDir +} // Android Studio Gradle plugin 3.5+ builds all supported ABIs for a connected device. Override the // property it sets to build just the first one, which is the preferred ABI for the device.
diff --git a/starboard/android/apk/settings.gradle b/starboard/android/apk/settings.gradle index 4fe2070..3b60efd 100644 --- a/starboard/android/apk/settings.gradle +++ b/starboard/android/apk/settings.gradle
@@ -15,3 +15,7 @@ include ':app' println "GRADLE VERSION: $gradle.gradleVersion" + +gradle.ext.rootBuildDir = hasProperty('cobaltGradleDir') + ? new File(cobaltGradleDir, 'build') + : new File(rootDir, "/../../../out/android_studio/gradle/build").canonicalFile
diff --git a/starboard/build/config/BUILDCONFIG.gn b/starboard/build/config/BUILDCONFIG.gn index 41086c5..774be60 100644 --- a/starboard/build/config/BUILDCONFIG.gn +++ b/starboard/build/config/BUILDCONFIG.gn
@@ -197,9 +197,7 @@ # content targets. import("//starboard/build/config/install.gni") -# Set up the method of generating the install targets as defined by the -# platform. -import("$install_target_path") +# Template for copying content files to the install directory. template("install_content") { target(invoker.target_type, target_name) { forward_variables_from(invoker, "*", [ "install_content" ]) @@ -209,6 +207,8 @@ } if (defined(invoker.install_content) && invoker.install_content) { + # We're using a custom script to copy the files here because rebase_path + # can't be used with {{}} expansions in the outputs of a copy target. action("${target_name}_install_content") { forward_variables_from(invoker, [ "testonly" ]) @@ -216,6 +216,14 @@ sources = get_target_outputs(":${invoker.target_name}") + # List of files in metadata so they can be forwarded for bundling. + metadata = { + install_content = sources + + # Don't inherit any metadata from upstream deps. + ignore_install_content = deps + } + install_content_dir = "$sb_install_output_dir/$sb_install_content_subdir" outputs = [] foreach(source, sources) { @@ -242,6 +250,9 @@ } } +# Set up the method of generating the install targets as defined by the +# platform. +import("$install_target_path") template("action") { install_content(target_name) { forward_variables_from(invoker, "*") @@ -266,68 +277,28 @@ template("executable") { target_with_platform_configs(target_name) { target_type = "executable" - forward_variables_from(invoker, - "*", - [ - "install_target", - "content_deps", - ]) + forward_variables_from(invoker, "*", [ "install_target" ]) } if (current_toolchain == default_toolchain && (!defined(invoker.install_target) || invoker.install_target)) { executable_target_name = target_name - content_deps = [] - if (defined(invoker.content_deps)) { - content_deps += invoker.content_deps + data_deps = [] + if (defined(invoker.data_deps)) { + data_deps += invoker.data_deps } if (defined(platform_i18n_config_path)) { - content_deps += [ platform_i18n_config_path ] + data_deps += [ platform_i18n_config_path ] } if (separate_install_targets_for_bundling) { - bundle_deps = [] - foreach(content_dep, content_deps) { - bundle_deps += [ "${content_dep}_install_content" ] - } - - # TODO(b/220024845): Make this much better. - action("${executable_target_name}_bundle_content") { + import("//starboard/build/config/bundle_content.gni") + bundle_content("${executable_target_name}_bundle_content") { forward_variables_from(invoker, [ "testonly" ]) - deps = [ ":$executable_target_name" ] - deps += bundle_deps - - sources = [] - foreach(bundle_dep, bundle_deps) { - # Split the target path and name. E.g. //path/to:target -> [ "//path/to", "target" ]. - target_path_and_name = string_split(bundle_dep, ":") - - # The content_dep target will place its file under the root gen dir. - content_dep_list_file = string_join("/", - [ - root_gen_dir, - target_path_and_name[1], - ]) - target_path_and_name = [] - - sources += [ "${content_dep_list_file}_files.tmp" ] - } - - bundle_content_dir = "$sb_install_output_dir/$executable_target_name/$sb_install_content_subdir" - - # TODO(b/220024845): We don't have the list of output files. - outputs = [ bundle_content_dir ] - - script = "//starboard/build/copy_bundle_content.py" - args = [ - "--output_dir", - rebase_path(bundle_content_dir, root_build_dir), - "--base_dir", - rebase_path(sb_static_contents_output_data_dir, root_build_dir), - ] - args += rebase_path(sources, root_build_dir) + bundle_name = executable_target_name + bundle_deps = data_deps } } @@ -339,12 +310,12 @@ if (defined(invoker.deps)) { deps += invoker.deps } + foreach(dep, data_deps) { + deps += [ "${dep}_install_content" ] + } if (separate_install_targets_for_bundling) { deps += [ ":${executable_target_name}_bundle_content" ] } - foreach(content_dep, content_deps) { - deps += [ "${content_dep}_install_content" ] - } } } } @@ -352,68 +323,29 @@ template("shared_library") { target_with_platform_configs(target_name) { target_type = "shared_library" - forward_variables_from(invoker, - "*", - [ - "install_target", - "content_deps", - ]) + forward_variables_from(invoker, "*", [ "install_target" ]) } if (current_toolchain == default_toolchain && (!defined(invoker.install_target) || invoker.install_target)) { shared_library_target_name = target_name - content_deps = [] - if (defined(invoker.content_deps)) { - content_deps += invoker.content_deps + data_deps = [] + if (defined(invoker.data_deps)) { + data_deps += invoker.data_deps } if (defined(platform_i18n_config_path)) { - content_deps += [ platform_i18n_config_path ] + data_deps += [ platform_i18n_config_path ] } if (separate_install_targets_for_bundling) { - bundle_deps = [] - foreach(content_dep, content_deps) { - bundle_deps += [ "${content_dep}_install_content" ] - } - - # TODO(b/220024845): Make this much better. - action("${shared_library_target_name}_bundle_content") { + import("//starboard/build/config/bundle_content.gni") + bundle_content("${shared_library_target_name}_bundle_content") { forward_variables_from(invoker, [ "testonly" ]) - deps = [ ":$shared_library_target_name" ] - deps += bundle_deps - - sources = [] - foreach(bundle_dep, bundle_deps) { - # Split the target path and name. E.g. //path/to:target -> [ "//path/to", "target" ]. - target_path_and_name = string_split(bundle_dep, ":") - - # The content_dep target will place its file under the root gen dir. - content_dep_list_file = string_join("/", - [ - root_gen_dir, - target_path_and_name[1], - ]) - target_path_and_name = [] - - sources += [ "${content_dep_list_file}_files.tmp" ] - } - - bundle_content_dir = "$sb_install_output_dir/$shared_library_target_name/$sb_install_content_subdir" - - # TODO(b/220024845): We don't have the list of output files. - outputs = [ bundle_content_dir ] - - script = "//starboard/build/copy_bundle_content.py" - args = [ - "--output_dir", - rebase_path(bundle_content_dir, root_build_dir), - "--base_dir", - rebase_path(sb_static_contents_output_data_dir, root_build_dir), - ] - args += rebase_path(sources, root_build_dir) + bundle_name = shared_library_target_name + bundle_deps = [] + bundle_deps = data_deps } } @@ -425,12 +357,12 @@ if (defined(invoker.deps)) { deps += invoker.deps } + foreach(dep, data_deps) { + deps += [ "${dep}_install_content" ] + } if (separate_install_targets_for_bundling) { deps += [ ":${shared_library_target_name}_bundle_content" ] } - foreach(content_dep, content_deps) { - deps += [ "${content_dep}_install_content" ] - } } } }
diff --git a/starboard/build/config/bundle_content.gni b/starboard/build/config/bundle_content.gni new file mode 100644 index 0000000..2008c95 --- /dev/null +++ b/starboard/build/config/bundle_content.gni
@@ -0,0 +1,69 @@ +# Copyright 2022 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. + +template("bundle_content") { + bundle_name = invoker.bundle_name + bundle_deps = invoker.bundle_deps + + bundle_content_list_file = "$root_gen_dir/${target_name}_files.txt" + file_format = "list lines" + + # If the platform bundles content the list of content files can be collected + # from the metadata field of the generated install_content targets. + generated_file("list_$target_name") { + forward_variables_from(invoker, [ "testonly" ]) + + # Rebase the paths the script working directory. + rebase = root_build_dir + + data_keys = [ "install_content" ] + + walk_keys = [ "ignore_install_content" ] + + deps = [] + foreach(dep, bundle_deps) { + deps += [ "${dep}_install_content" ] + } + + output_conversion = file_format + outputs = [ bundle_content_list_file ] + } + + action(target_name) { + forward_variables_from(invoker, [ "testonly" ]) + + deps = [ ":list_$target_name" ] + + inputs = [ bundle_content_list_file ] + + bundle_content_dir = + "$sb_install_output_dir/$bundle_name/$sb_install_content_subdir" + + # TODO(b/220024845): We don't have the list of output files. The files + # are listed in `bundle_content_list_file` but can't be accessed in GN + # as `read_file` can't reliably access files generated by + # `generated_file` targets. + outputs = [ bundle_content_dir ] + + script = "//starboard/build/copy_install_content.py" + args = [ + "--output_dir", + rebase_path(bundle_content_dir, root_build_dir), + "--base_dir", + rebase_path(sb_static_contents_output_data_dir, root_build_dir), + "--files_list", + rebase_path(bundle_content_list_file, root_build_dir), + ] + } +}
diff --git a/starboard/build/copy_bundle_content.py b/starboard/build/copy_bundle_content.py deleted file mode 100644 index 859dd08..0000000 --- a/starboard/build/copy_bundle_content.py +++ /dev/null
@@ -1,87 +0,0 @@ -# Copyright 2022 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. - -# TODO(b/216341587): Refactor install_content to get rid of this file. - -# This file is loosely based on starboard/build/copy_data.py -"""Copies all input files to the output directory. - -The folder structure of the input files is maintained in the output relative -to the 'base_dir' parameter. -""" - -import argparse -import os -import shutil - - -class InvalidArgumentException(Exception): - pass - - -def copy_files(files_to_copy, base_dir, output_dir): - if not os.path.exists(output_dir): - os.makedirs(output_dir) - - for path in files_to_copy: - # In certain cases, files would fail to open on windows if relative paths - # were provided. Using absolute paths fixes this. - filename = os.path.abspath(path) - - # Get the path of the file relative to the source base_dir. - rel_path = os.path.relpath(path, base_dir) - output_dir = os.path.abspath(output_dir) - # Use rel_path to preserve the input folder structure in the output. - output_filename = os.path.abspath(os.path.join(output_dir, rel_path)) - - # In cases where a directory has turned into a file or vice versa, delete it - # before copying it below. - if os.path.exists(output_dir) and not os.path.isdir(output_dir): - os.remove(output_dir) - if os.path.exists(output_filename) and os.path.isdir(output_filename): - shutil.rmtree(output_filename) - - if not os.path.exists(os.path.dirname(output_filename)): - os.makedirs(os.path.dirname(output_filename)) - - if os.path.isfile(filename): - shutil.copy(filename, output_filename) - else: - # TODO(b/211909342): Remove this branch once lottie files are listed. - shutil.copytree(filename, output_filename) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument( - '--output_dir', dest='output_dir', required=True, help='output directory') - parser.add_argument( - '--base_dir', - dest='base_dir', - required=True, - help='source base directory') - parser.add_argument( - 'input_paths', - metavar='path', - nargs='*', - help='path to a file containing the list of files to copy') - options = parser.parse_args() - - # Load file names from the files containing the list of file names. - file_names = [] - for input_path in options.input_paths: - with open(input_path.strip()) as files_list: - file_names.extend([line.strip() for line in files_list]) - - copy_files(file_names, options.base_dir, options.output_dir)
diff --git a/starboard/build/copy_install_content.py b/starboard/build/copy_install_content.py index 767079b..1e29cbf 100644 --- a/starboard/build/copy_install_content.py +++ b/starboard/build/copy_install_content.py
@@ -31,6 +31,9 @@ def copy_files(files_to_copy, base_dir, output_dir): + if not os.path.exists(output_dir): + os.makedirs(output_dir) + for path in files_to_copy: # All input paths must point at files. # TODO(b/211909342): Re-enable once lottie test files are listed. @@ -53,8 +56,8 @@ if os.path.exists(output_filename) and os.path.isdir(output_filename): shutil.rmtree(output_filename) - if not os.path.exists(output_dir): - os.makedirs(output_dir) + if not os.path.exists(os.path.dirname(output_filename)): + os.makedirs(os.path.dirname(output_filename)) if os.path.isfile(filename): shutil.copy(filename, output_filename)
diff --git a/starboard/client_porting/eztime/BUILD.gn b/starboard/client_porting/eztime/BUILD.gn index 5611ee1..df579de 100644 --- a/starboard/client_porting/eztime/BUILD.gn +++ b/starboard/client_porting/eztime/BUILD.gn
@@ -42,5 +42,5 @@ "//testing/gtest", ] - content_deps = [ "//third_party/icu:icudata" ] + data_deps = [ "//third_party/icu:icudata" ] }
diff --git a/starboard/elf_loader/BUILD.gn b/starboard/elf_loader/BUILD.gn index 68af8bd..07974b0 100644 --- a/starboard/elf_loader/BUILD.gn +++ b/starboard/elf_loader/BUILD.gn
@@ -87,11 +87,11 @@ } target(final_executable_type, "elf_loader_sandbox") { - content_deps = [ "//third_party/icu:icudata" ] + data_deps = [ "//third_party/icu:icudata" ] if (cobalt_font_package == "empty") { - content_deps += [ "//cobalt/content/fonts:copy_font_data" ] + data_deps += [ "//cobalt/content/fonts:copy_font_data" ] } else { - content_deps += [ + data_deps += [ "//cobalt/content/fonts:copy_fonts", "//cobalt/content/fonts:fonts_xml", ] @@ -170,7 +170,7 @@ ":elf_loader", ] - content_deps = [ ":copy_elf_loader_testdata" ] + data_deps = [ ":copy_elf_loader_testdata" ] } }
diff --git a/starboard/elf_loader/sandbox.cc b/starboard/elf_loader/sandbox.cc index 019309f..2f2eb05 100644 --- a/starboard/elf_loader/sandbox.cc +++ b/starboard/elf_loader/sandbox.cc
@@ -79,13 +79,16 @@ if (!get_user_agent_func) { SB_LOG(ERROR) << "Failed to get user agent string"; } else { - CrashpadAnnotations cobalt_version_info; - memset(&cobalt_version_info, 0, sizeof(CrashpadAnnotations)); - starboard::strlcpy(cobalt_version_info.user_agent_string, - get_user_agent_func(), USER_AGENT_STRING_MAX_SIZE); - third_party::crashpad::wrapper::AddAnnotationsToCrashpad( - cobalt_version_info); - SB_DLOG(INFO) << "Added user agent string to Crashpad."; + std::vector<char> buffer(USER_AGENT_STRING_MAX_SIZE); + starboard::strlcpy(buffer.data(), get_user_agent_func(), + USER_AGENT_STRING_MAX_SIZE); + if (third_party::crashpad::wrapper::InsertCrashpadAnnotation( + third_party::crashpad::wrapper::kCrashpadUserAgentStringKey, + buffer.data())) { + SB_DLOG(INFO) << "Added user agent string to Crashpad."; + } else { + SB_DLOG(INFO) << "Failed to add user agent string to Crashpad."; + } } if (!g_sb_event_func) {
diff --git a/starboard/examples/window/BUILD.gn b/starboard/examples/window/BUILD.gn index beb0040..93c3aae 100644 --- a/starboard/examples/window/BUILD.gn +++ b/starboard/examples/window/BUILD.gn
@@ -17,5 +17,5 @@ sources = [ "main.cc" ] public_deps = [ "//starboard" ] - content_deps = [ "//third_party/icu:icudata" ] + data_deps = [ "//third_party/icu:icudata" ] }
diff --git a/starboard/loader_app/loader_app.cc b/starboard/loader_app/loader_app.cc index 8bae605..fcb2975 100644 --- a/starboard/loader_app/loader_app.cc +++ b/starboard/loader_app/loader_app.cc
@@ -160,13 +160,16 @@ if (!get_user_agent_func) { SB_LOG(ERROR) << "Failed to get user agent string"; } else { - CrashpadAnnotations cobalt_version_info; - memset(&cobalt_version_info, 0, sizeof(CrashpadAnnotations)); - starboard::strlcpy(cobalt_version_info.user_agent_string, - get_user_agent_func(), USER_AGENT_STRING_MAX_SIZE); - third_party::crashpad::wrapper::AddAnnotationsToCrashpad( - cobalt_version_info); - SB_DLOG(INFO) << "Added user agent string to Crashpad."; + std::vector<char> buffer(USER_AGENT_STRING_MAX_SIZE); + starboard::strlcpy(buffer.data(), get_user_agent_func(), + USER_AGENT_STRING_MAX_SIZE); + if (third_party::crashpad::wrapper::InsertCrashpadAnnotation( + third_party::crashpad::wrapper::kCrashpadUserAgentStringKey, + buffer.data())) { + SB_DLOG(INFO) << "Added user agent string to Crashpad."; + } else { + SB_DLOG(INFO) << "Failed to add user agent string to Crashpad."; + } } g_sb_event_func = reinterpret_cast<void (*)(const SbEvent*)>(
diff --git a/starboard/loader_app/slot_management.cc b/starboard/loader_app/slot_management.cc index 9f76b11..fc5549a 100644 --- a/starboard/loader_app/slot_management.cc +++ b/starboard/loader_app/slot_management.cc
@@ -28,6 +28,7 @@ #include "starboard/loader_app/installation_manager.h" #include "starboard/memory.h" #include "starboard/string.h" +#include "third_party/crashpad/wrapper/annotations.h" #include "third_party/crashpad/wrapper/wrapper.h" namespace starboard { @@ -315,13 +316,16 @@ if (!get_user_agent_func) { SB_LOG(ERROR) << "Failed to get user agent string"; } else { - CrashpadAnnotations cobalt_version_info; - memset(&cobalt_version_info, 0, sizeof(CrashpadAnnotations)); - starboard::strlcpy(cobalt_version_info.user_agent_string, - get_user_agent_func(), USER_AGENT_STRING_MAX_SIZE); - third_party::crashpad::wrapper::AddAnnotationsToCrashpad( - cobalt_version_info); - SB_DLOG(INFO) << "Added user agent string to Crashpad."; + std::vector<char> buffer(USER_AGENT_STRING_MAX_SIZE); + starboard::strlcpy(buffer.data(), get_user_agent_func(), + USER_AGENT_STRING_MAX_SIZE); + if (third_party::crashpad::wrapper::InsertCrashpadAnnotation( + third_party::crashpad::wrapper::kCrashpadUserAgentStringKey, + buffer.data())) { + SB_DLOG(INFO) << "Added user agent string to Crashpad."; + } else { + SB_DLOG(INFO) << "Failed to add user agent string to Crashpad."; + } } SB_DLOG(INFO) << "Successfully loaded Cobalt!\n";
diff --git a/starboard/nplb/BUILD.gn b/starboard/nplb/BUILD.gn index c96b0d5..7b44620 100644 --- a/starboard/nplb/BUILD.gn +++ b/starboard/nplb/BUILD.gn
@@ -291,11 +291,6 @@ data_deps = [ "//starboard/nplb/testdata/file_tests:nplb_file_tests_data", "//starboard/shared/starboard/player:player_download_test_data", - ] - - content_deps = [ - "//starboard/nplb/testdata/file_tests:nplb_file_tests_data", - "//starboard/shared/starboard/player:player_download_test_data", "//third_party/icu:icudata", ] }
diff --git a/starboard/nplb/nplb_evergreen_compat_tests/BUILD.gn b/starboard/nplb/nplb_evergreen_compat_tests/BUILD.gn index 705025b..f22104c 100644 --- a/starboard/nplb/nplb_evergreen_compat_tests/BUILD.gn +++ b/starboard/nplb/nplb_evergreen_compat_tests/BUILD.gn
@@ -37,5 +37,5 @@ "//testing/gmock", ] - content_deps = [ "//third_party/icu:icudata" ] + data_deps = [ "//third_party/icu:icudata" ] }
diff --git a/starboard/shared/starboard/crash_handler.cc b/starboard/shared/starboard/crash_handler.cc index 572a022..0d6ec2d 100644 --- a/starboard/shared/starboard/crash_handler.cc +++ b/starboard/shared/starboard/crash_handler.cc
@@ -25,14 +25,16 @@ namespace { bool OverrideCrashpadAnnotations(CrashpadAnnotations* crashpad_annotations) { - CrashpadAnnotations annotations; - memset(&annotations, 0, sizeof(CrashpadAnnotations)); - memcpy(&annotations, crashpad_annotations, sizeof(CrashpadAnnotations)); - return third_party::crashpad::wrapper::AddAnnotationsToCrashpad(annotations); + return false; // Deprecated +} + +bool SetString(const char* key, const char* value) { + return third_party::crashpad::wrapper::InsertCrashpadAnnotation(key, value); } const CobaltExtensionCrashHandlerApi kCrashHandlerApi = { - kCobaltExtensionCrashHandlerName, 1, &OverrideCrashpadAnnotations, + kCobaltExtensionCrashHandlerName, 2, &OverrideCrashpadAnnotations, + &SetString, }; } // namespace
diff --git a/starboard/shared/starboard/player/filter/adaptive_audio_decoder_internal.h b/starboard/shared/starboard/player/filter/adaptive_audio_decoder_internal.h index 3f6e7c0..8a997a8 100644 --- a/starboard/shared/starboard/player/filter/adaptive_audio_decoder_internal.h +++ b/starboard/shared/starboard/player/filter/adaptive_audio_decoder_internal.h
@@ -62,9 +62,6 @@ void Reset() override; private: - void ProcessOneInputBuffer(const scoped_refptr<InputBuffer>& input_buffer, - const ConsumedCB& consumed_cb); - void InitializeAudioDecoder(const SbMediaAudioSampleInfo& audio_sample_info); void TeardownAudioDecoder(); void OnDecoderOutput();
diff --git a/starboard/shared/starboard/player/filter/testing/BUILD.gn b/starboard/shared/starboard/player/filter/testing/BUILD.gn index 15ca8b9..a126ef0 100644 --- a/starboard/shared/starboard/player/filter/testing/BUILD.gn +++ b/starboard/shared/starboard/player/filter/testing/BUILD.gn
@@ -41,7 +41,7 @@ deps = cobalt_platform_dependencies - content_deps = + data_deps = [ "//starboard/shared/starboard/player:player_download_test_data" ] }
diff --git a/starboard/shared/starboard/player/filter/tools/BUILD.gn b/starboard/shared/starboard/player/filter/tools/BUILD.gn index 698d480..4e59d2f 100644 --- a/starboard/shared/starboard/player/filter/tools/BUILD.gn +++ b/starboard/shared/starboard/player/filter/tools/BUILD.gn
@@ -27,7 +27,7 @@ "//starboard", "//starboard/shared/starboard/player:player_download_test_data", ] - content_deps = [ + data_deps = [ "//starboard/shared/starboard/player:player_download_test_data", "//third_party/icu:icudata", ]
diff --git a/third_party/crashpad/client/BUILD.gn b/third_party/crashpad/client/BUILD.gn index 19aa8db..6ecd5c5 100644 --- a/third_party/crashpad/client/BUILD.gn +++ b/third_party/crashpad/client/BUILD.gn
@@ -90,12 +90,13 @@ "../util", ] + deps = [] + if (crashpad_is_in_starboard) { public_deps += [ "//starboard/elf_loader:evergreen_info" ] + deps += [ "../wrapper/proto:crashpad_annotations_proto" ] } - deps = [] - if (crashpad_is_win) { libs = [ "rpcrt4.lib" ] cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
diff --git a/third_party/crashpad/client/crashpad_client.h b/third_party/crashpad/client/crashpad_client.h index 9dd12dd..4cf5a0e 100644 --- a/third_party/crashpad/client/crashpad_client.h +++ b/third_party/crashpad/client/crashpad_client.h
@@ -41,7 +41,6 @@ #if defined(STARBOARD) #include "starboard/elf_loader/evergreen_info.h" #include "third_party/crashpad/snapshot/sanitized/sanitization_information.h" -#include "third_party/crashpad/wrapper/annotations.h" #endif namespace crashpad { @@ -391,14 +390,17 @@ //! \return `true` on success, `false` on failure with a message logged. static bool SendEvergreenInfoToHandler(EvergreenInfo evergreen_info); - //! \brief Sends mapping info to the handler + //! \brief Inserts annotation mapping info for the handler //! - //! A handler must have already been installed before calling this method. - //! \param[in] annotations A CrashpadAnnotations struct, whose information - //! was created on Evergreen startup. + //! A signal handler must have already been installed before calling this + //! method. Whether or not the annotation is sent to the Crashpad handler, + //! or just prepared to be sent, depends on whether the Crashpad handler is + //! started at launch or at crash. + //! \param[in] key The annotation's key. + //! \param[in] value The annotation's value. //! //! \return `true` on success, `false` on failure with a message logged. - static bool SendAnnotationsToHandler(CrashpadAnnotations annotations); + static bool InsertAnnotationForHandler(const char* key, const char* value); //! \brief Sends mapping info to the handler //!
diff --git a/third_party/crashpad/client/crashpad_client_linux.cc b/third_party/crashpad/client/crashpad_client_linux.cc index 5738668..1b579bf 100644 --- a/third_party/crashpad/client/crashpad_client_linux.cc +++ b/third_party/crashpad/client/crashpad_client_linux.cc
@@ -26,6 +26,7 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" #include "client/client_argv_handling.h" +#include "starboard/common/mutex.h" #include "third_party/lss/lss.h" #include "util/file/file_io.h" #include "util/file/filesystem.h" @@ -37,6 +38,15 @@ #include "util/misc/from_pointer_cast.h" #include "util/posix/double_fork_and_exec.h" #include "util/posix/signals.h" +// TODO(b/201538792): resolve conflict between mini_chromium and base functions. +#ifdef LogMessage +#define LOG_MESSAGE_DEFINED +#undef LogMessage +#endif +#include "third_party/crashpad/wrapper/proto/crashpad_annotations.pb.h" +#ifdef LOG_MESSAGE_DEFINED +#define LogMessage MLogMessage +#endif namespace crashpad { @@ -44,9 +54,7 @@ #if defined(STARBOARD) constexpr char kEvergreenInfoKey[] = "evergreen-information"; -constexpr char kProductKey[] = "annotation=prod"; -constexpr char kVersionKey[] = "annotation=ver"; -constexpr char kUAKey[] = "annotation=user_agent_string"; +constexpr char kAnnotationKey[] = "annotation=%s"; #endif std::string FormatArgumentInt(const std::string& name, int value) { @@ -183,10 +191,10 @@ return SendEvergreenInfoImpl(); } - bool SendAnnotations(CrashpadAnnotations annotations) { - annotations_ = annotations; - return SendAnnotationsImpl(); + bool InsertAnnotation(const char* key, const char* value) { + return InsertAnnotationImpl(key, value); } + #endif // The base implementation for all signal handlers, suitable for calling @@ -227,7 +235,6 @@ #if defined(STARBOARD) const EvergreenInfo& GetEvergreenInfo() { return evergreen_info_; } - const CrashpadAnnotations& GetAnnotations() { return annotations_; } const SanitizationInformation& GetSanitizationInformation() { return sanitization_information_; } @@ -239,7 +246,7 @@ #if defined(STARBOARD) virtual bool SendEvergreenInfoImpl() = 0; - virtual bool SendAnnotationsImpl() = 0; + virtual bool InsertAnnotationImpl(const char* key, const char* value) = 0; #endif virtual void HandleCrashImpl() = 0; @@ -262,7 +269,6 @@ #if defined(STARBOARD) EvergreenInfo evergreen_info_; - CrashpadAnnotations annotations_; SanitizationInformation sanitization_information_; #endif @@ -297,12 +303,18 @@ argv_strings_.push_back(FormatArgumentAddress("trace-parent-with-exception", &GetExceptionInfo())); +#if defined(STARBOARD) + argv_strings_.push_back("--handler-started-at-crash"); +#endif + StringVectorToCStringVector(argv_strings_, &argv_); return Install(unhandled_signals); } #if defined(STARBOARD) bool SendEvergreenInfoImpl() override { + starboard::ScopedLock scoped_lock(argv_lock_); + bool updated = false; for (auto& s : argv_strings_) { if (s.compare(2, strlen(kEvergreenInfoKey), kEvergreenInfoKey) == 0) { @@ -324,27 +336,19 @@ return true; } - bool SendAnnotationsImpl() override { - bool updated_product = false; - bool updated_version = false; - bool updated_user_agent_string = false; + bool InsertAnnotationImpl(const char* key, const char* value) override { + starboard::ScopedLock scoped_lock(argv_lock_); + + std::string formatted_key = base::StringPrintf(kAnnotationKey, key); + bool updated_annotation = false; for (auto& s : argv_strings_) { - if (UpdateAnnotation(s, kProductKey, GetAnnotations().product)) { - updated_product = true; - } else if (UpdateAnnotation(s, kVersionKey, GetAnnotations().version)) { - updated_version = true; - } else if (UpdateAnnotation(s, kUAKey, GetAnnotations().user_agent_string)) { - updated_user_agent_string = true; + if (UpdateAnnotation(s, formatted_key, value)) { + updated_annotation = true; } } - if (!updated_product) { - AddAnnotation(argv_strings_, kProductKey, GetAnnotations().product); - } - if (!updated_version) { - AddAnnotation(argv_strings_, kVersionKey, GetAnnotations().version); - } - if (!updated_user_agent_string) { - AddAnnotation(argv_strings_, kUAKey, GetAnnotations().user_agent_string); + + if (!updated_annotation) { + AddAnnotation(argv_strings_, formatted_key, value); } StringVectorToCStringVector(argv_strings_, &argv_); @@ -382,6 +386,10 @@ std::vector<std::string> argv_strings_; std::vector<const char*> argv_; +#if defined(STARBOARD) + // Protects access to both argv_strings_ and argv_. + starboard::Mutex argv_lock_; +#endif std::vector<std::string> envp_strings_; std::vector<const char*> envp_; bool set_envp_ = false; @@ -446,6 +454,10 @@ } #if defined(STARBOARD) + char* GetSerializedAnnotations() { + return serialized_annotations_.data(); + } + bool SendEvergreenInfoImpl() override { ExceptionHandlerClient client(sock_to_handler_.get(), true); ExceptionHandlerProtocol::ClientInformation info = {}; @@ -455,13 +467,36 @@ return true; } - bool SendAnnotationsImpl() override { + bool InsertAnnotationImpl(const char* key, const char* value) override { + starboard::ScopedLock scoped_lock(annotations_lock_); + + std::string key_str(key); + std::string value_str(value); + + if (strcmp(key, "ver") == 0) { + annotations_.set_ver(value_str); + } else if (strcmp(key, "prod") == 0) { + annotations_.set_prod(value_str); + } else if (strcmp(key, "user_agent_string") == 0) { + annotations_.set_user_agent_string(value_str); + } else { + (*annotations_.mutable_runtime_annotations())[key_str] = value_str; + } + + serialized_annotations_.resize(annotations_.ByteSize()); + annotations_.SerializeToArray(serialized_annotations_.data(), + annotations_.ByteSize()); + ExceptionHandlerClient client(sock_to_handler_.get(), true); ExceptionHandlerProtocol::ClientInformation info = {}; - info.annotations_address = FromPointerCast<VMAddress>(&GetAnnotations()); + info.serialized_annotations_address = FromPointerCast<VMAddress>( + GetSerializedAnnotations()); + info.serialized_annotations_size = serialized_annotations_.size(); client.SendAnnotations(info); + return true; } + #endif void HandleCrashImpl() override { @@ -471,9 +506,12 @@ #if defined(STARBOARD) info.sanitization_information_address = FromPointerCast<VMAddress>(&GetSanitizationInformation()); - info.annotations_address = FromPointerCast<VMAddress>(&GetAnnotations()); + info.serialized_annotations_address = FromPointerCast<VMAddress>( + GetSerializedAnnotations()); + info.serialized_annotations_size = serialized_annotations_.size(); info.evergreen_information_address = FromPointerCast<VMAddress>(&GetEvergreenInfo()); + info.handler_start_type = ExceptionHandlerProtocol::kStartAtLaunch; #endif #if defined(OS_CHROMEOS) @@ -497,6 +535,13 @@ ScopedFileHandle sock_to_handler_; pid_t handler_pid_ = -1; +#if defined(STARBOARD) + crashpad::wrapper::CrashpadAnnotations annotations_; + std::vector<char> serialized_annotations_; + + // Protects access to both annotations_ and serialized_annotations_; + starboard::Mutex annotations_lock_; +#endif #if defined(OS_CHROMEOS) // An optional UNIX timestamp passed to us from Chrome. @@ -694,14 +739,14 @@ return SignalHandler::Get()->SendEvergreenInfo(evergreen_info); } -bool CrashpadClient::SendAnnotationsToHandler( - CrashpadAnnotations annotations) { +bool CrashpadClient::InsertAnnotationForHandler( + const char* key, const char* value) { if (!SignalHandler::Get()) { DLOG(ERROR) << "Crashpad isn't enabled"; return false; } - return SignalHandler::Get()->SendAnnotations(annotations); + return SignalHandler::Get()->InsertAnnotation(key, value); } bool CrashpadClient::SendSanitizationInformationToHandler(
diff --git a/third_party/crashpad/handler/BUILD.gn b/third_party/crashpad/handler/BUILD.gn index 80b7378..10582a8 100644 --- a/third_party/crashpad/handler/BUILD.gn +++ b/third_party/crashpad/handler/BUILD.gn
@@ -172,7 +172,7 @@ if (crashpad_is_in_starboard) { install_target = !crashpad_is_android check_includes = false - content_deps = [ "//third_party/icu:icudata" ] + data_deps = [ "//third_party/icu:icudata" ] } sources = [ "main.cc" ]
diff --git a/third_party/crashpad/handler/handler_main.cc b/third_party/crashpad/handler/handler_main.cc index 51bd64e..cbf9bb5 100644 --- a/third_party/crashpad/handler/handler_main.cc +++ b/third_party/crashpad/handler/handler_main.cc
@@ -172,6 +172,9 @@ #if defined(STARBOARD) " --evergreen-information=EVERGREEN_INFORMATION_ADDRESS\n" " the address of a EvegreenInfo struct.\n" +" --handler-started-at-crash\n" +" the handler was started at time of crash, as\n" +" opposed to time of launch\n" #endif " --url=URL send crash reports to this Breakpad server URL,\n" " only if uploads are enabled for the database\n" @@ -214,6 +217,7 @@ bool shared_client_connection; #if defined(STARBOARD) VMAddress evergreen_information_address; + bool handler_started_at_crash = false; #endif // defined(STARBOARD) #if defined(OS_ANDROID) bool write_minidump_to_log; @@ -590,6 +594,7 @@ kOptionTraceParentWithException, #if defined(STARBOARD) kOptionEvergreenInformaton, + kOptionHandlerStartedAtCrash, #endif // defined(STARBOARD) #endif kOptionURL, @@ -676,6 +681,10 @@ required_argument, nullptr, kOptionEvergreenInformaton}, + {"handler-started-at-crash", + no_argument, + nullptr, + kOptionHandlerStartedAtCrash}, #endif {"url", required_argument, nullptr, kOptionURL}, #if defined(OS_CHROMEOS) @@ -850,6 +859,10 @@ } break; } + case kOptionHandlerStartedAtCrash: { + options.handler_started_at_crash = true; + break; + } #endif // defined(STARBOARD) #endif // OS_LINUX || OS_ANDROID case kOptionURL: { @@ -1070,6 +1083,9 @@ #if defined(STARBOARD) info.evergreen_information_address = options.evergreen_information_address; + if (options.handler_started_at_crash) { + info.handler_start_type = ExceptionHandlerProtocol::kStartAtCrash; + } #endif // defined(STARBOARD) return exception_handler->HandleException(getppid(), geteuid(), info) ? EXIT_SUCCESS
diff --git a/third_party/crashpad/handler/linux/capture_snapshot.cc b/third_party/crashpad/handler/linux/capture_snapshot.cc index 8fb0735..59350fd 100644 --- a/third_party/crashpad/handler/linux/capture_snapshot.cc +++ b/third_party/crashpad/handler/linux/capture_snapshot.cc
@@ -31,19 +31,15 @@ VMAddress requesting_thread_stack_address, pid_t* requesting_thread_id, std::unique_ptr<ProcessSnapshotLinux>* snapshot, - std::unique_ptr<ProcessSnapshotSanitized>* sanitized_snapshot -#if defined(STARBOARD) - , - VMAddress evergreen_information_address, - VMAddress annotations_address -#endif - ) { + std::unique_ptr<ProcessSnapshotSanitized>* sanitized_snapshot) { std::unique_ptr<ProcessSnapshotLinux> process_snapshot( new ProcessSnapshotLinux()); #if defined(STARBOARD) if (!process_snapshot->Initialize(connection, info.evergreen_information_address, - info.annotations_address)) { + info.serialized_annotations_address, + info.serialized_annotations_size, + info.handler_start_type)) { #else if (!process_snapshot->Initialize(connection)) { #endif
diff --git a/third_party/crashpad/handler/linux/capture_snapshot.h b/third_party/crashpad/handler/linux/capture_snapshot.h index 51eca35..b01e316 100644 --- a/third_party/crashpad/handler/linux/capture_snapshot.h +++ b/third_party/crashpad/handler/linux/capture_snapshot.h
@@ -64,13 +64,7 @@ VMAddress requesting_thread_stack_address, pid_t* requesting_thread_id, std::unique_ptr<ProcessSnapshotLinux>* process_snapshot, - std::unique_ptr<ProcessSnapshotSanitized>* sanitized_snapshot -#if defined(STARBOARD) - , - VMAddress evergreen_information_address, - VMAddress annotations_address -#endif - ); + std::unique_ptr<ProcessSnapshotSanitized>* sanitized_snapshot); } // namespace crashpad
diff --git a/third_party/crashpad/handler/linux/crash_report_exception_handler.cc b/third_party/crashpad/handler/linux/crash_report_exception_handler.cc index b0f68ce..9a86073 100644 --- a/third_party/crashpad/handler/linux/crash_report_exception_handler.cc +++ b/third_party/crashpad/handler/linux/crash_report_exception_handler.cc
@@ -89,7 +89,8 @@ bool CrashReportExceptionHandler::AddAnnotations( const ExceptionHandlerProtocol::ClientInformation& info) { - annotations_address_ = info.annotations_address; + serialized_annotations_address_ = info.serialized_annotations_address; + serialized_annotations_size_ = info.serialized_annotations_size; return true; } #endif @@ -153,13 +154,7 @@ requesting_thread_stack_address, requesting_thread_id, &process_snapshot, - &sanitized_snapshot -#if defined(STARBOARD) - , - evergreen_info_, - annotations_address_ -#endif - )) { + &sanitized_snapshot)) { return false; }
diff --git a/third_party/crashpad/handler/linux/crash_report_exception_handler.h b/third_party/crashpad/handler/linux/crash_report_exception_handler.h index 5cca2ad..7a32ac0 100644 --- a/third_party/crashpad/handler/linux/crash_report_exception_handler.h +++ b/third_party/crashpad/handler/linux/crash_report_exception_handler.h
@@ -122,7 +122,8 @@ const UserStreamDataSources* user_stream_data_sources_; // weak #if defined(STARBOARD) VMAddress evergreen_info_; - VMAddress annotations_address_; + VMAddress serialized_annotations_address_; + int serialized_annotations_size_; #endif DISALLOW_COPY_AND_ASSIGN(CrashReportExceptionHandler);
diff --git a/third_party/crashpad/snapshot/linux/process_snapshot_linux.cc b/third_party/crashpad/snapshot/linux/process_snapshot_linux.cc index 5fe900b..48fdb11 100644 --- a/third_party/crashpad/snapshot/linux/process_snapshot_linux.cc +++ b/third_party/crashpad/snapshot/linux/process_snapshot_linux.cc
@@ -20,7 +20,16 @@ #include "util/linux/exception_information.h" #if defined(STARBOARD) -#include "third_party/crashpad/wrapper/annotations.h" +#include "third_party/crashpad/util/linux/exception_handler_protocol.h" +// TODO(b/201538792): resolve conflict between mini_chromium and base functions. +#ifdef LogMessage +#define LOG_MESSAGE_DEFINED +#undef LogMessage +#endif +#include "third_party/crashpad/wrapper/proto/crashpad_annotations.pb.h" +#ifdef LOG_MESSAGE_DEFINED +#define LogMessage MLogMessage +#endif #endif namespace crashpad { @@ -56,7 +65,9 @@ #if defined(STARBOARD) bool ProcessSnapshotLinux::Initialize(PtraceConnection* connection, VMAddress evergreen_information_address, - VMAddress annotations_address) { + VMAddress serialized_annotations_address, + int serialized_annotations_size, + ExceptionHandlerProtocol::HandlerStartType handler_start_type) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); if (gettimeofday(&snapshot_time_, nullptr) != 0) { @@ -70,15 +81,10 @@ return false; } - CrashpadAnnotations annotations; - if (!memory_range_.Read( - annotations_address, sizeof(CrashpadAnnotations), &annotations)) { - LOG(ERROR) << "Could not read annotations"; + if (handler_start_type == ExceptionHandlerProtocol::kStartAtCrash) { + LOG(INFO) << "Annotations do not need to be read from client process"; } else { - AddAnnotation("user_agent_string", - std::string(annotations.user_agent_string)); - AddAnnotation("prod", std::string(annotations.product)); - AddAnnotation("ver", std::string(annotations.version)); + AddAnnotations(serialized_annotations_address, serialized_annotations_size); } system_.Initialize(&process_reader_, &snapshot_time_); @@ -90,6 +96,33 @@ INITIALIZATION_STATE_SET_VALID(initialized_); return true; } + +void ProcessSnapshotLinux::AddAnnotations( + VMAddress serialized_annotations_address, int serialized_annotations_size) { + std::vector<char> buffer(serialized_annotations_size); + if (!memory_range_.Read(serialized_annotations_address, + serialized_annotations_size, + buffer.data())) { + LOG(ERROR) << "Could not read annotations"; + return; + } + + crashpad::wrapper::CrashpadAnnotations annotations; + if (!annotations.ParseFromArray(buffer.data(), serialized_annotations_size)) { + LOG(ERROR) << "Could not parse annotations"; + return; + } + + AddAnnotation("user_agent_string", + std::string(annotations.user_agent_string())); + AddAnnotation("prod", std::string(annotations.prod())); + AddAnnotation("ver", std::string(annotations.ver())); + + for (auto& runtime_annotation : annotations.runtime_annotations()) { + AddAnnotation(runtime_annotation.first, runtime_annotation.second); + } + LOG(INFO) << "Annotations successfully added from client process"; +} #endif pid_t ProcessSnapshotLinux::FindThreadWithStackAddress(
diff --git a/third_party/crashpad/snapshot/linux/process_snapshot_linux.h b/third_party/crashpad/snapshot/linux/process_snapshot_linux.h index 8cd9ef5..0d20528 100644 --- a/third_party/crashpad/snapshot/linux/process_snapshot_linux.h +++ b/third_party/crashpad/snapshot/linux/process_snapshot_linux.h
@@ -45,6 +45,7 @@ #if defined(STARBOARD) #include "snapshot/module_snapshot_evergreen.h" #include "starboard/elf_loader/evergreen_info.h" +#include "third_party/crashpad/util/linux/exception_handler_protocol.h" #endif namespace crashpad { @@ -77,7 +78,9 @@ //! an appropriate message logged. bool Initialize(PtraceConnection* connnection, VMAddress evergreen_information_address, - VMAddress annotations_address); + VMAddress serialized_annotations_address, + int serialized_annotations_size, + ExceptionHandlerProtocol::HandlerStartType handler_start_type); #endif //! \brief Finds the thread whose stack contains \a stack_address. @@ -158,6 +161,8 @@ void InitializeModules(); #if defined(STARBOARD) void InitializeModules(VMAddress evergreen_information_address); + void AddAnnotations(VMAddress serialized_annotations_address, + int serialized_annotations_size); #endif void InitializeAnnotations();
diff --git a/third_party/crashpad/util/linux/exception_handler_protocol.cc b/third_party/crashpad/util/linux/exception_handler_protocol.cc index b139017..5f58721 100644 --- a/third_party/crashpad/util/linux/exception_handler_protocol.cc +++ b/third_party/crashpad/util/linux/exception_handler_protocol.cc
@@ -26,7 +26,9 @@ #if defined(STARBOARD) , evergreen_information_address(0), - annotations_address(0) + serialized_annotations_address(0), + serialized_annotations_size(0), + handler_start_type(kStartAtLaunch) #endif { }
diff --git a/third_party/crashpad/util/linux/exception_handler_protocol.h b/third_party/crashpad/util/linux/exception_handler_protocol.h index 4cc1662..4f94bd9 100644 --- a/third_party/crashpad/util/linux/exception_handler_protocol.h +++ b/third_party/crashpad/util/linux/exception_handler_protocol.h
@@ -38,6 +38,12 @@ //! \brief A boolean status suitable for communication between processes. enum Bool : char { kBoolFalse, kBoolTrue }; +#if defined(STARBOARD) + //! \brief Describes when, in the client process lifecycle, the Crashpad + //! handler was or will be started. + enum HandlerStartType : char { kStartAtCrash, kStartAtLaunch }; +#endif + //! \brief Information about a client registered with an //! ExceptionHandlerServer. struct ClientInformation { @@ -57,9 +63,15 @@ //! struct, or 0 if there is no such struct. VMAddress evergreen_information_address; - //! \brief The address in the client's address space of an - //! CrashpadAnnotations struct, or 0 if there is no such struct. - VMAddress annotations_address; + //! \brief The address in the client's address space of a character array + //! containing a serialized CrashpadAnnotations proto, or 0 if there is + //! no such address. + VMAddress serialized_annotations_address; + + //! \brief The byte size of the serialized annotations. + int serialized_annotations_size; + + HandlerStartType handler_start_type; #endif #if defined(OS_LINUX)
diff --git a/third_party/crashpad/wrapper/proto/BUILD.gn b/third_party/crashpad/wrapper/proto/BUILD.gn new file mode 100644 index 0000000..4819e31 --- /dev/null +++ b/third_party/crashpad/wrapper/proto/BUILD.gn
@@ -0,0 +1,20 @@ +# Copyright 2022 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. + +import("//third_party/protobuf/proto_library.gni") + +proto_library("crashpad_annotations_proto") { + sources = [ "crashpad_annotations.proto" ] + generate_python = false +}
diff --git a/third_party/crashpad/wrapper/proto/crashpad_annotations.proto b/third_party/crashpad/wrapper/proto/crashpad_annotations.proto new file mode 100644 index 0000000..8eb6205 --- /dev/null +++ b/third_party/crashpad/wrapper/proto/crashpad_annotations.proto
@@ -0,0 +1,36 @@ +// Copyright 2022 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. + +syntax = "proto3"; + +option optimize_for = LITE_RUNTIME; + +package crashpad.wrapper; + +// Annotations that can be shared between Cobalt and Crashpad handler processes. +// Next id: 5 +message CrashpadAnnotations { + // The product name. + string prod = 1; + + // The product version. + string ver = 2; + + // The User-Agent string that identifies brand, model, etc. + string user_agent_string = 3; + + // Annotations with keys that are unknown at compile time. + map<string, string> runtime_annotations = 4; +} +
diff --git a/third_party/crashpad/wrapper/wrapper.cc b/third_party/crashpad/wrapper/wrapper.cc index 8f19a70..700f9b7 100644 --- a/third_party/crashpad/wrapper/wrapper.cc +++ b/third_party/crashpad/wrapper/wrapper.cc
@@ -33,8 +33,11 @@ namespace crashpad { namespace wrapper { -namespace { +const char kCrashpadVersionKey[] = "ver"; +const char kCrashpadProductKey[] = "prod"; +const char kCrashpadUserAgentStringKey[] = "user_agent_string"; +namespace { // TODO: Get evergreen information from installation. const std::string kCrashpadVersion = "1.0.0.0"; #if defined(STARBOARD_BUILD_TYPE_GOLD) @@ -215,9 +218,9 @@ return client->SendEvergreenInfoToHandler(evergreen_info); } -bool AddAnnotationsToCrashpad(CrashpadAnnotations annotations) { +bool InsertCrashpadAnnotation(const char* key, const char* value) { ::crashpad::CrashpadClient* client = GetCrashpadClient(); - return client->SendAnnotationsToHandler(annotations); + return client->InsertAnnotationForHandler(key, value); } } // namespace wrapper
diff --git a/third_party/crashpad/wrapper/wrapper.h b/third_party/crashpad/wrapper/wrapper.h index 4def1a8..be60fec 100644 --- a/third_party/crashpad/wrapper/wrapper.h +++ b/third_party/crashpad/wrapper/wrapper.h
@@ -16,17 +16,28 @@ #define THIRD_PARTY_CRASHPAD_WRAPPER_WRAPPER_H_ #include "starboard/elf_loader/evergreen_info.h" // nogncheck -#include "third_party/crashpad/wrapper/annotations.h" namespace third_party { namespace crashpad { namespace wrapper { +// The key name used in Crashpad for the version annotation. +extern const char kCrashpadVersionKey[]; + +// The key name used in Crashpad for the version annotation. +extern const char kCrashpadProductKey[]; + +// The key name used in Crashpad for the user_agent_string annotation. +extern const char kCrashpadUserAgentStringKey[]; + void InstallCrashpadHandler(bool start_at_crash); bool AddEvergreenInfoToCrashpad(EvergreenInfo evergreen_info); -bool AddAnnotationsToCrashpad(CrashpadAnnotations annotations); +// Associates the given value with the given key in Crashpad's map of +// annotations, updating the existing value if the map already contains the +// key. Returns true on success and false on failure. +bool InsertCrashpadAnnotation(const char* key, const char* value); } // namespace wrapper } // namespace crashpad
diff --git a/third_party/crashpad/wrapper/wrapper_stub.cc b/third_party/crashpad/wrapper/wrapper_stub.cc index bf3c093..f96dd94 100644 --- a/third_party/crashpad/wrapper/wrapper_stub.cc +++ b/third_party/crashpad/wrapper/wrapper_stub.cc
@@ -18,13 +18,17 @@ namespace crashpad { namespace wrapper { +const char kCrashpadVersionKey[] = ""; +const char kCrashpadProductKey[] = ""; +const char kCrashpadUserAgentStringKey[] = ""; + void InstallCrashpadHandler(bool start_at_crash) {} bool AddEvergreenInfoToCrashpad(EvergreenInfo evergreen_info) { return false; } -bool AddAnnotationsToCrashpad(CrashpadAnnotations annotations) { +bool InsertCrashpadAnnotation(const char* key, const char* value) { return false; }
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn index 67b9d7b..132c555 100644 --- a/third_party/zlib/BUILD.gn +++ b/third_party/zlib/BUILD.gn
@@ -542,6 +542,6 @@ configs -= [ "//starboard/build/config:size" ] configs += [ "//starboard/build/config:speed" ] - content_deps = [ "//third_party/zlib/google/test:zip_unittest_files" ] + data_deps = [ "//third_party/zlib/google/test:zip_unittest_files" ] } }