Import Cobalt 22.master.0.305773
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index cc6dd4e..07c259b 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -5,7 +5,18 @@
 default_language_version:
     python: python3
 
-exclude: '^(base|build|testing|third_party|tools/gyp)/'
+exclude: |
+    (?x)^(
+        (
+            base|
+            build|
+            testing|
+            third_party|
+            tools/gyp
+        )/
+        |
+        components/update_client/((?!cobalt).)*$
+    )
 
 repos:
 -   repo: https://cobalt.googlesource.com/pre-commit-hooks
@@ -21,7 +32,11 @@
     hooks:
     -   id: codespell
         name: Spell Check
-        args: [-x, .codespellignorelines]
+        args: [-x, .codespellignorelines,
+               # The --ignore-words-list argument has a bug where it needs to
+               # be lowercase, see
+               # https://github.com/codespell-project/codespell/issues/1390
+               --ignore-words-list, atleast]
         exclude: '^cobalt/content/i18n/platform/'
 
 -   repo: local
diff --git a/base/BUILD.gn b/base/BUILD.gn
index b838736..6fb1b34 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -18,20 +18,22 @@
 # huge sequence of random-looking conditionals.
 
 import("//build/buildflag_header.gni")
-import("//build/config/allocator.gni")
 import("//build/config/arm.gni")
 import("//build/config/c++/c++.gni")
 import("//build/config/chromecast_build.gni")
 import("//build/config/compiler/compiler.gni")
 import("//build/config/dcheck_always_on.gni")
-import("//build/config/jumbo.gni")
 import("//build/config/nacl/config.gni")
 import("//build/config/sysroot.gni")
 import("//build/config/ui.gni")
 import("//build/nocompile.gni")
-import("//build/timestamp.gni")
-import("//testing/libfuzzer/fuzzer_test.gni")
-import("//testing/test.gni")
+if (!is_starboard) {
+  import("//build/config/allocator.gni")
+  import("//build/config/jumbo.gni")
+  import("//build/timestamp.gni")
+  import("//testing/libfuzzer/fuzzer_test.gni")
+  import("//testing/test.gni")
+}
 
 declare_args() {
   # Indicates if the Location object contains the source code information
@@ -80,6 +82,9 @@
       # https://groups.google.com/a/chromium.org/d/topic/chromium-dev/B9Q5KTD7iCo/discussion
       "-Wglobal-constructors",
     ]
+    if (is_starboard) {
+      cflags -= [ "-Wglobal-constructors" ]
+    }
   }
 }
 
@@ -131,7 +136,7 @@
 # to be linked in where they wouldn't have otherwise. This does not include
 # test code (test support and anything in the test directory) which should use
 # source_set as is recommended for GN targets).
-jumbo_component("base") {
+component("base") {
   if (is_nacl_nonsfi) {
     # TODO(phosek) bug 570839: If field_trial.cc is in a static library,
     # nacl_helper_nonsfi doesn't link properly on Linux in debug builds. The
@@ -1070,80 +1075,431 @@
     "win/wrapped_window_proc.h",
   ]
 
-  if (is_posix) {
-    sources += [
-      "base_paths_posix.h",
-      "debug/debugger_posix.cc",
-      "debug/stack_trace_posix.cc",
-      "file_descriptor_posix.h",
-      "files/dir_reader_posix.h",
-      "files/file_descriptor_watcher_posix.cc",
-      "files/file_descriptor_watcher_posix.h",
-      "files/file_enumerator_posix.cc",
-      "files/file_posix.cc",
-      "files/file_util_posix.cc",
-      "files/memory_mapped_file_posix.cc",
-      "memory/protected_memory_posix.cc",
-      "message_loop/watchable_io_message_pump_posix.cc",
-      "message_loop/watchable_io_message_pump_posix.h",
-      "native_library_posix.cc",
-      "posix/eintr_wrapper.h",
-      "posix/file_descriptor_shuffle.cc",
-      "posix/file_descriptor_shuffle.h",
-      "posix/global_descriptors.cc",
-      "posix/global_descriptors.h",
-      "posix/safe_strerror.cc",
-      "posix/safe_strerror.h",
-      "posix/unix_domain_socket.cc",
-      "posix/unix_domain_socket.h",
-      "process/kill_posix.cc",
-      "process/launch_posix.cc",
-      "process/process_handle_posix.cc",
-      "process/process_metrics_posix.cc",
-      "process/process_posix.cc",
-      "profiler/native_stack_sampler_posix.cc",
-      "rand_util_posix.cc",
-      "sampling_heap_profiler/module_cache_posix.cc",
-      "strings/string_util_posix.h",
-      "strings/sys_string_conversions_posix.cc",
-      "sync_socket_posix.cc",
-      "synchronization/condition_variable_posix.cc",
-      "synchronization/lock_impl_posix.cc",
-      "synchronization/waitable_event_posix.cc",
-      "synchronization/waitable_event_watcher_posix.cc",
-      "sys_info_posix.cc",
-      "task/task_scheduler/task_tracker_posix.cc",
-      "task/task_scheduler/task_tracker_posix.h",
-      "threading/platform_thread_internal_posix.cc",
-      "threading/platform_thread_internal_posix.h",
-      "threading/platform_thread_posix.cc",
-      "threading/thread_local_storage_posix.cc",
-      "timer/hi_res_timer_manager_posix.cc",
+  if (is_starboard) {
+    # Delete platform specific source files.
+    sources -= [
+      "allocator/allocator_interception_mac.h",
+      "allocator/allocator_interception_mac.mm",
+      "allocator/allocator_shim.h",
+      "allocator/malloc_zone_functions_mac.cc",
+      "allocator/malloc_zone_functions_mac.h",
+      "base_switches.h",
+      "cpu.cc",
+      "cpu.h",
+      "critical_closure_internal_ios.mm",
+      "debug/activity_analyzer.cc",
+      "debug/activity_analyzer.h",
+      "debug/close_handle_hook_win.cc",
+      "debug/close_handle_hook_win.h",
+      "debug/debugger_win.cc",
+      "debug/gdi_debug_util_win.cc",
+      "debug/gdi_debug_util_win.h",
+      "debug/invalid_access_win.cc",
+      "debug/invalid_access_win.h",
+      "debug/proc_maps_linux.cc",
+      "debug/proc_maps_linux.h",
+      "debug/stack_trace_android.cc",
+      "debug/stack_trace_win.cc",
+      "file_descriptor_store.cc",
+      "file_descriptor_store.h",
+      "file_version_info_mac.h",
+      "file_version_info_mac.mm",
+      "file_version_info_win.cc",
+      "file_version_info_win.h",
+      "files/dir_reader_linux.h",
+      "files/file_path_watcher.cc",
+      "files/file_path_watcher.h",
+      "files/file_path_watcher_linux.cc",
+      "files/file_path_watcher_mac.cc",
+      "files/file_path_watcher_win.cc",
+      "files/file_util_android.cc",
+      "files/file_util_linux.cc",
+      "files/file_util_mac.mm",
+      "files/file_util_win.cc",
+      "files/file_win.cc",
+      "files/memory_mapped_file.cc",
+      "files/memory_mapped_file.h",
+      "files/memory_mapped_file_win.cc",
+      "linux_util.cc",
+      "linux_util.h",
+      "logging_win.cc",
+      "logging_win.h",
+      "mac/authorization_util.h",
+      "mac/authorization_util.mm",
+      "mac/availability.h",
+      "mac/bundle_locations.h",
+      "mac/bundle_locations.mm",
+      "mac/call_with_eh_frame.cc",
+      "mac/call_with_eh_frame.h",
+      "mac/call_with_eh_frame_asm.S",
+      "mac/close_nocancel.cc",
+      "mac/dispatch_source_mach.cc",
+      "mac/dispatch_source_mach.h",
+      "mac/foundation_util.h",
+      "mac/foundation_util.mm",
+      "mac/launch_services_util.h",
+      "mac/launch_services_util.mm",
+      "mac/launchd.cc",
+      "mac/launchd.h",
+      "mac/mac_logging.h",
+      "mac/mac_logging.mm",
+      "mac/mac_util.h",
+      "mac/mac_util.mm",
+      "mac/mach_logging.cc",
+      "mac/mach_logging.h",
+      "mac/mach_port_broker.h",
+      "mac/mach_port_broker.mm",
+      "mac/mach_port_util.cc",
+      "mac/mach_port_util.h",
+      "mac/objc_release_properties.h",
+      "mac/objc_release_properties.mm",
+      "mac/os_crash_dumps.cc",
+      "mac/os_crash_dumps.h",
+      "mac/scoped_aedesc.h",
+      "mac/scoped_authorizationref.h",
+      "mac/scoped_block.h",
+      "mac/scoped_cffiledescriptorref.h",
+      "mac/scoped_cftyperef.h",
+      "mac/scoped_dispatch_object.h",
+      "mac/scoped_ionotificationportref.h",
+      "mac/scoped_ioobject.h",
+      "mac/scoped_ioplugininterface.h",
+      "mac/scoped_launch_data.h",
+      "mac/scoped_mach_port.cc",
+      "mac/scoped_mach_port.h",
+      "mac/scoped_mach_vm.cc",
+      "mac/scoped_mach_vm.h",
+      "mac/scoped_nsautorelease_pool.h",
+      "mac/scoped_nsautorelease_pool.mm",
+      "mac/scoped_nsobject.h",
+      "mac/scoped_nsobject.mm",
+      "mac/scoped_objc_class_swizzler.h",
+      "mac/scoped_objc_class_swizzler.mm",
+      "mac/scoped_sending_event.h",
+      "mac/scoped_sending_event.mm",
+      "mac/sdk_forward_declarations.h",
+      "mac/sdk_forward_declarations.mm",
+      "memory/discardable_shared_memory.cc",
+      "memory/discardable_shared_memory.h",
+      "memory/memory_pressure_monitor_chromeos.cc",
+      "memory/memory_pressure_monitor_chromeos.h",
+      "memory/memory_pressure_monitor_mac.cc",
+      "memory/memory_pressure_monitor_mac.h",
+      "memory/memory_pressure_monitor_win.cc",
+      "memory/memory_pressure_monitor_win.h",
+      "memory/platform_shared_memory_region.cc",
+      "memory/platform_shared_memory_region.h",
+      "memory/protected_memory_cfi.h",
+      "memory/protected_memory_win.cc",
+      "memory/shared_memory_handle.cc",
+      "memory/shared_memory_handle.h",
+      "memory/shared_memory_helper.cc",
+      "memory/shared_memory_helper.h",
+      "memory/shared_memory_mapping.cc",
+      "memory/shared_memory_mapping.h",
+      "memory/shared_memory_tracker.cc",
+      "memory/shared_memory_tracker.h",
+      "memory/unsafe_shared_memory_region.cc",
+      "memory/unsafe_shared_memory_region.h",
+      "memory/writable_shared_memory_region.cc",
+      "memory/writable_shared_memory_region.h",
+      "message_loop/message_pump_android.cc",
+      "message_loop/message_pump_android.h",
+      "message_loop/message_pump_for_io.h",
+      "message_loop/message_pump_for_ui.h",
+      "message_loop/message_pump_glib.cc",
+      "message_loop/message_pump_glib.h",
+      "message_loop/message_pump_io_ios.cc",
+      "message_loop/message_pump_io_ios.h",
+      "message_loop/message_pump_mac.h",
+      "message_loop/message_pump_mac.mm",
+      "message_loop/message_pump_win.cc",
+      "message_loop/message_pump_win.h",
+      "metrics/field_trial.cc",
+      "metrics/field_trial.h",
+      "metrics/field_trial_param_associator.cc",
+      "metrics/field_trial_param_associator.h",
+      "metrics/field_trial_params.cc",
+      "metrics/field_trial_params.h",
+      "native_library.cc",
+      "native_library.h",
+      "native_library_ios.mm",
+      "native_library_mac.mm",
+      "native_library_win.cc",
+      "os_compat_android.cc",
+      "os_compat_android.h",
+      "process/internal_linux.cc",
+      "process/internal_linux.h",
+      "process/kill.cc",
+      "process/kill.h",
+      "process/kill_mac.cc",
+      "process/kill_win.cc",
+      "process/launch.cc",
+      "process/launch.h",
+      "process/launch_ios.cc",
+      "process/launch_mac.cc",
+      "process/launch_win.cc",
+      "process/memory_linux.cc",
+      "process/memory_mac.mm",
+      "process/memory_win.cc",
+      "process/port_provider_mac.cc",
+      "process/port_provider_mac.h",
+      "process/process_handle_linux.cc",
+      "process/process_handle_mac.cc",
+      "process/process_handle_win.cc",
+      "process/process_info_linux.cc",
+      "process/process_info_mac.cc",
+      "process/process_info_win.cc",
+      "process/process_iterator.cc",
+      "process/process_iterator.h",
+      "process/process_iterator_linux.cc",
+      "process/process_iterator_mac.cc",
+      "process/process_iterator_win.cc",
+      "process/process_linux.cc",
+      "process/process_mac.cc",
+      "process/process_metrics.cc",
+      "process/process_metrics.h",
+      "process/process_metrics_ios.cc",
+      "process/process_metrics_linux.cc",
+      "process/process_metrics_mac.cc",
+      "process/process_metrics_win.cc",
+      "process/process_win.cc",
+      "profiler/native_stack_sampler_mac.cc",
+      "profiler/native_stack_sampler_win.cc",
+      "sampling_heap_profiler/module_cache_mac.cc",
+      "sampling_heap_profiler/module_cache_win.cc",
+      "sampling_heap_profiler/poisson_allocation_sampler.cc",
+      "sampling_heap_profiler/poisson_allocation_sampler.h",
+      "sampling_heap_profiler/sampling_heap_profiler.cc",
+      "sampling_heap_profiler/sampling_heap_profiler.h",
+      "scoped_clear_last_error_win.cc",
+      "scoped_native_library.cc",
+      "scoped_native_library.h",
+      "strings/string_util_win.h",
+      "strings/stringize_macros.h",
+      "strings/sys_string_conversions_mac.mm",
+      "strings/sys_string_conversions_win.cc",
+      "sync_socket_win.cc",
+      "synchronization/condition_variable_win.cc",
+      "synchronization/lock_impl_win.cc",
+      "synchronization/waitable_event_mac.cc",
+      "synchronization/waitable_event_watcher_mac.cc",
+      "synchronization/waitable_event_watcher_win.cc",
+      "synchronization/waitable_event_win.cc",
+      "task/task_scheduler/platform_native_worker_pool_win.cc",
+      "task/task_scheduler/platform_native_worker_pool_win.h",
+      "threading/platform_thread_android.cc",
+      "threading/platform_thread_linux.cc",
+      "threading/platform_thread_mac.mm",
+      "threading/platform_thread_win.cc",
+      "threading/platform_thread_win.h",
+      "threading/thread_local_storage_win.cc",
+      "timer/hi_res_timer_manager_win.cc",
+      "trace_event/cpufreq_monitor_android.cc",
+      "trace_event/cpufreq_monitor_android.h",
+      "trace_event/java_heap_dump_provider_android.cc",
+      "trace_event/java_heap_dump_provider_android.h",
+      "trace_event/memory_dump_manager.cc",
+      "trace_event/memory_dump_manager.h",
+      "trace_event/trace_event_android.cc",
+      "trace_event/trace_event_etw_export_win.cc",
+      "trace_event/trace_event_etw_export_win.h",
+      "win/async_operation.h",
+      "win/atl.h",
+      "win/com_init_check_hook.cc",
+      "win/com_init_check_hook.h",
+      "win/com_init_util.cc",
+      "win/com_init_util.h",
+      "win/core_winrt_util.cc",
+      "win/core_winrt_util.h",
+      "win/current_module.h",
+      "win/enum_variant.cc",
+      "win/enum_variant.h",
+      "win/event_trace_consumer.h",
+      "win/event_trace_controller.cc",
+      "win/event_trace_controller.h",
+      "win/event_trace_provider.cc",
+      "win/event_trace_provider.h",
+      "win/i18n.cc",
+      "win/i18n.h",
+      "win/iat_patch_function.cc",
+      "win/iat_patch_function.h",
+      "win/iunknown_impl.cc",
+      "win/iunknown_impl.h",
+      "win/message_window.cc",
+      "win/message_window.h",
+      "win/object_watcher.cc",
+      "win/object_watcher.h",
+      "win/patch_util.cc",
+      "win/patch_util.h",
+      "win/process_startup_helper.cc",
+      "win/process_startup_helper.h",
+      "win/propvarutil.h",
+      "win/reference.h",
+      "win/registry.cc",
+      "win/registry.h",
+      "win/resource_util.cc",
+      "win/resource_util.h",
+      "win/scoped_bstr.cc",
+      "win/scoped_bstr.h",
+      "win/scoped_co_mem.h",
+      "win/scoped_com_initializer.cc",
+      "win/scoped_com_initializer.h",
+      "win/scoped_gdi_object.h",
+      "win/scoped_handle.cc",
+      "win/scoped_handle.h",
+      "win/scoped_handle_verifier.cc",
+      "win/scoped_handle_verifier.h",
+      "win/scoped_hdc.h",
+      "win/scoped_hglobal.h",
+      "win/scoped_hstring.cc",
+      "win/scoped_hstring.h",
+      "win/scoped_process_information.cc",
+      "win/scoped_process_information.h",
+      "win/scoped_propvariant.h",
+      "win/scoped_select_object.h",
+      "win/scoped_variant.cc",
+      "win/scoped_variant.h",
+      "win/scoped_windows_thread_environment.h",
+      "win/scoped_winrt_initializer.cc",
+      "win/scoped_winrt_initializer.h",
+      "win/shlwapi.h",
+      "win/shortcut.cc",
+      "win/shortcut.h",
+      "win/sphelper.h",
+      "win/startup_information.cc",
+      "win/startup_information.h",
+      "win/typed_event_handler.h",
+      "win/vector.cc",
+      "win/vector.h",
+      "win/wait_chain.cc",
+      "win/wait_chain.h",
+      "win/win_util.cc",
+      "win/win_util.h",
+      "win/wincrypt_shim.h",
+      "win/windows_defines.inc",
+      "win/windows_types.h",
+      "win/windows_undefines.inc",
+      "win/windows_version.cc",
+      "win/windows_version.h",
+      "win/winrt_storage_util.cc",
+      "win/winrt_storage_util.h",
+      "win/wmi.cc",
+      "win/wmi.h",
+      "win/wrapped_window_proc.cc",
+      "win/wrapped_window_proc.h",
     ]
-  }
 
-  if (!is_nacl) {
+    # Add starboard related source files.
     sources += [
       "base_paths.cc",
       "base_paths.h",
-      "base_paths_android.cc",
-      "base_paths_android.h",
-      "base_paths_mac.h",
-      "base_paths_mac.mm",
-      "base_paths_posix.h",
-      "base_paths_win.cc",
-      "base_paths_win.h",
+      "base_paths_starboard.cc",
+      "base_paths_starboard.h",
+      "debug/debugger_starboard.cc",
+      "debug/stack_trace_starboard.cc",
+      "files/file_enumerator_starboard.cc",
+      "files/file_starboard.cc",
+      "files/file_util_starboard.cc",
+      "message_loop/message_pump_io_starboard.cc",
+      "message_loop/message_pump_io_starboard.h",
+      "message_loop/message_pump_ui_starboard.cc",
+      "message_loop/message_pump_ui_starboard.h",
       "metrics/persistent_histogram_storage.cc",
       "metrics/persistent_histogram_storage.h",
+      "process/memory_starboard.cc",
+      "process/process_starboard.cc",
+      "profiler/native_stack_sampler_starboard.cc",
+      "rand_util_starboard.cc",
+      "sampling_heap_profiler/module_cache_starboard.cc",
+      "single_thread_task_runner.cc",
+      "strings/string_util_starboard.h",
+      "strings/sys_string_conversions_starboard.cc",
+      "synchronization/condition_variable_starboard.cc",
+      "synchronization/lock_impl_starboard.cc",
+      "synchronization/waitable_event_starboard.cc",
+      "sys_info_starboard.cc",
+      "threading/platform_thread_starboard.cc",
+      "threading/thread_local_storage_starboard.cc",
+      "time/time_now_starboard.cc",
+      "time/time_starboard.cc",
     ]
-
-    if (is_linux) {
+  } else {
+    if (is_posix) {
       sources += [
-        "base_paths_posix.cc",
-        "debug/elf_reader_linux.cc",
-        "debug/elf_reader_linux.h",
+        "base_paths_posix.h",
+        "debug/debugger_posix.cc",
+        "debug/stack_trace_posix.cc",
+        "file_descriptor_posix.h",
+        "files/dir_reader_posix.h",
+        "files/file_descriptor_watcher_posix.cc",
+        "files/file_descriptor_watcher_posix.h",
+        "files/file_enumerator_posix.cc",
+        "files/file_posix.cc",
+        "files/file_util_posix.cc",
+        "files/memory_mapped_file_posix.cc",
+        "memory/protected_memory_posix.cc",
+        "message_loop/watchable_io_message_pump_posix.cc",
+        "message_loop/watchable_io_message_pump_posix.h",
+        "native_library_posix.cc",
+        "posix/eintr_wrapper.h",
+        "posix/file_descriptor_shuffle.cc",
+        "posix/file_descriptor_shuffle.h",
+        "posix/global_descriptors.cc",
+        "posix/global_descriptors.h",
+        "posix/safe_strerror.cc",
+        "posix/safe_strerror.h",
+        "posix/unix_domain_socket.cc",
+        "posix/unix_domain_socket.h",
+        "process/kill_posix.cc",
+        "process/launch_posix.cc",
+        "process/process_handle_posix.cc",
+        "process/process_metrics_posix.cc",
+        "process/process_posix.cc",
+        "profiler/native_stack_sampler_posix.cc",
+        "rand_util_posix.cc",
+        "sampling_heap_profiler/module_cache_posix.cc",
+        "strings/string_util_posix.h",
+        "strings/sys_string_conversions_posix.cc",
+        "sync_socket_posix.cc",
+        "synchronization/condition_variable_posix.cc",
+        "synchronization/lock_impl_posix.cc",
+        "synchronization/waitable_event_posix.cc",
+        "synchronization/waitable_event_watcher_posix.cc",
+        "sys_info_posix.cc",
+        "task/task_scheduler/task_tracker_posix.cc",
+        "task/task_scheduler/task_tracker_posix.h",
+        "threading/platform_thread_internal_posix.cc",
+        "threading/platform_thread_internal_posix.h",
+        "threading/platform_thread_posix.cc",
+        "threading/thread_local_storage_posix.cc",
+        "timer/hi_res_timer_manager_posix.cc",
       ]
     }
+
+    if (!is_nacl) {
+      sources += [
+        "base_paths.cc",
+        "base_paths.h",
+        "base_paths_android.cc",
+        "base_paths_android.h",
+        "base_paths_mac.h",
+        "base_paths_mac.mm",
+        "base_paths_posix.h",
+        "base_paths_win.cc",
+        "base_paths_win.h",
+        "metrics/persistent_histogram_storage.cc",
+        "metrics/persistent_histogram_storage.h",
+      ]
+
+      if (is_linux) {
+        sources += [
+          "base_paths_posix.cc",
+          "debug/elf_reader_linux.cc",
+          "debug/elf_reader_linux.h",
+        ]
+      }
+    }
   }
 
   all_dependent_configs = []
@@ -1179,6 +1535,27 @@
     "//base/numerics:base_numerics",
   ]
 
+  if (is_starboard) {
+    configs += [ "//build/config/compiler:chromium_code" ]
+    configs -= [
+      "//build/config/compiler:noshadowing",
+    ]
+    deps += [
+      "//nb",
+      "//starboard/client_porting/eztime",
+      "//starboard/common",
+      "//starboard:starboard_headers_only",
+    ]
+    deps -= [
+      "//base/allocator",
+      "//base/allocator:buildflags",
+    ]
+    public_deps -= [
+      ":build_date",
+      ":partition_alloc_buildflags",
+    ]
+  }
+
   # Needed for <atomic> if using newer C++ library than sysroot, except if
   # building inside the cros_sdk environment - use host_toolchain as a
   # more robust check for this.
@@ -1187,7 +1564,7 @@
     libs += [ "atomic" ]
   }
 
-  if (use_allocator_shim) {
+  if (!is_starboard && use_allocator_shim) {
     sources += [
       "allocator/allocator_shim.cc",
       "allocator/allocator_shim.h",
@@ -1240,7 +1617,7 @@
   }
 
   # Android.
-  if (is_android) {
+  if (is_android && !is_starboard) {
     sources -= [ "debug/stack_trace_posix.cc" ]
     sources += [
       "android/android_hardware_buffer_compat.cc",
@@ -1384,7 +1761,7 @@
   }
 
   # Fuchsia.
-  if (is_fuchsia) {
+  if (is_fuchsia && !is_starboard) {
     sources += [
       "base_paths_fuchsia.cc",
       "base_paths_fuchsia.h",
@@ -1480,7 +1857,7 @@
   }
 
   # NaCl.
-  if (is_nacl) {
+  if (is_nacl && !is_starboard) {
     # We reset sources_assignment_filter in order to explicitly include
     # the linux file (which would otherwise be filtered out).
     set_sources_assignment_filter([])
@@ -1564,7 +1941,7 @@
       "rand_util_nacl.cc",
     ]
 
-    if (use_partition_alloc) {
+    if (!is_starboard && use_partition_alloc) {
       # Add stuff that doesn't work in NaCl.
       sources += [
         # PartitionAlloc uses SpinLock, which doesn't work in NaCl (see below).
@@ -1604,7 +1981,7 @@
   }
 
   # Windows.
-  if (is_win) {
+  if (is_win && !is_starboard) {
     sources += [
       "files/file_enumerator_win.cc",
       "memory/platform_shared_memory_region_win.cc",
@@ -1661,7 +2038,7 @@
   }
 
   # Desktop Mac.
-  if (is_mac) {
+  if (is_mac && !is_starboard) {
     sources -= [
       "profiler/native_stack_sampler_posix.cc",
       "sampling_heap_profiler/module_cache_posix.cc",
@@ -1693,7 +2070,7 @@
   }
 
   # Mac or iOS.
-  if (is_mac || is_ios) {
+  if ((is_mac || is_ios) && !is_starboard) {
     sources -= [
       "native_library_posix.cc",
       "strings/sys_string_conversions_posix.cc",
@@ -1714,23 +2091,25 @@
     configs += linux_configs
     all_dependent_configs += linux_configs
 
-    sources += [
-      "nix/mime_util_xdg.cc",
-      "nix/mime_util_xdg.h",
-      "nix/xdg_util.cc",
-      "nix/xdg_util.h",
-      "sys_info_linux.cc",
-    ]
+    if (!is_starboard) {
+      sources += [
+        "nix/mime_util_xdg.cc",
+        "nix/mime_util_xdg.h",
+        "nix/xdg_util.cc",
+        "nix/xdg_util.h",
+        "sys_info_linux.cc",
+      ]
 
-    defines += [ "USE_SYMBOLIZE" ]
+      defines += [ "USE_SYMBOLIZE" ]
 
-    # These dependencies are not required on Android, and in the case
-    # of xdg_mime must be excluded due to licensing restrictions.
-    deps += [
-      "//base/third_party/symbolize",
-      "//base/third_party/xdg_mime",
-      "//base/third_party/xdg_user_dirs",
-    ]
+      # These dependencies are not required on Android, and in the case
+      # of xdg_mime must be excluded due to licensing restrictions.
+      deps += [
+        "//base/third_party/symbolize",
+        "//base/third_party/xdg_mime",
+        "//base/third_party/xdg_user_dirs",
+      ]
+    }
   } else {
     if (!is_android) {
       sources -= [
@@ -1741,7 +2120,7 @@
   }
 
   # iOS
-  if (is_ios) {
+  if (is_ios && !is_starboard) {
     set_sources_assignment_filter([])
 
     sources -= [
@@ -1810,11 +2189,11 @@
     set_sources_assignment_filter(sources_assignment_filter)
   }
 
-  if (dep_libevent) {
+  if (dep_libevent && !is_starboard) {
     deps += [ "//base/third_party/libevent" ]
   }
 
-  if (use_libevent) {
+  if (use_libevent && !is_starboard) {
     sources += [
       "message_loop/message_pump_libevent.cc",
       "message_loop/message_pump_libevent.h",
@@ -1823,18 +2202,18 @@
 
   # Android and MacOS have their own custom shared memory handle
   # implementations. e.g. due to supporting both POSIX and native handles.
-  if (is_posix && !is_android && !is_mac) {
+  if (is_posix && !is_android && !is_mac && !is_starboard) {
     sources += [
       "memory/platform_shared_memory_region_posix.cc",
       "memory/shared_memory_handle_posix.cc",
     ]
   }
 
-  if (is_posix && !is_mac && !is_nacl) {
+  if (is_posix && !is_mac && !is_nacl && !is_starboard) {
     sources += [ "memory/shared_memory_posix.cc" ]
   }
 
-  if (is_posix && !is_mac && !is_ios) {
+  if (is_posix && !is_mac && !is_ios && !is_starboard) {
     sources += [
       "time/time_conversion_posix.cc",
       "time/time_exploded_posix.cc",
@@ -1842,7 +2221,7 @@
     ]
   }
 
-  if (is_posix && !is_mac && !is_ios && !is_nacl) {
+  if (is_posix && !is_mac && !is_ios && !is_nacl && !is_starboard) {
     sources += [
       "posix/can_lower_nice_to.cc",
       "posix/can_lower_nice_to.h",
@@ -1854,7 +2233,7 @@
     sources += [ "power_monitor/power_monitor_device_source_stub.cc" ]
   }
 
-  if (!use_glib) {
+  if (!use_glib && !is_starboard) {
     sources -= [
       "message_loop/message_pump_glib.cc",
       "message_loop/message_pump_glib.h",
@@ -1873,7 +2252,9 @@
 
   configs += [ "//build/config/compiler:wexit_time_destructors" ]
   if (!is_debug) {
-    configs -= [ "//build/config/compiler:default_optimization" ]
+    if (!is_starboard) {
+      configs -= [ "//build/config/compiler:default_optimization" ]
+    }
     configs += [ "//build/config/compiler:optimize_max" ]
   }
 }
@@ -1945,11 +2326,13 @@
   ]
 }
 
-buildflag_header("partition_alloc_buildflags") {
-  header = "partition_alloc_buildflags.h"
-  header_dir = "base"
+if (!is_starboard) {
+  buildflag_header("partition_alloc_buildflags") {
+    header = "partition_alloc_buildflags.h"
+    header_dir = "base"
 
-  flags = [ "USE_PARTITION_ALLOC=$use_partition_alloc" ]
+    flags = [ "USE_PARTITION_ALLOC=$use_partition_alloc" ]
+  }
 }
 
 # This is the subset of files from base that should not be used with a dynamic
@@ -1974,13 +2357,17 @@
   }
 
   if (!is_debug) {
-    configs -= [ "//build/config/compiler:default_optimization" ]
+    if (!is_starboard) {
+      configs -= [ "//build/config/compiler:default_optimization" ]
+    }
     configs += [ "//build/config/compiler:optimize_max" ]
   }
 }
 
 component("i18n") {
   output_name = "base_i18n"
+  check_includes = false
+
   sources = [
     "i18n/base_i18n_export.h",
     "i18n/base_i18n_switches.cc",
@@ -2036,8 +2423,14 @@
     "//base/third_party/dynamic_annotations",
   ]
 
+  if (is_starboard) {
+    public_deps -= [ "//third_party/ced" ]
+  }
+
   if (!is_debug) {
-    configs -= [ "//build/config/compiler:default_optimization" ]
+    if (!is_starboard) {
+      configs -= [ "//build/config/compiler:default_optimization" ]
+    }
     configs += [ "//build/config/compiler:optimize_max" ]
   }
 
@@ -2049,46 +2442,48 @@
   }
 }
 
-test("base_perftests") {
-  sources = [
-    "message_loop/message_loop_perftest.cc",
-    "message_loop/message_loop_task_runner_perftest.cc",
-    "message_loop/message_pump_perftest.cc",
-    "observer_list_perftest.cc",
-    "task/sequence_manager/sequence_manager_perftest.cc",
+if (!is_starboard) {
+  test("base_perftests") {
+    sources = [
+      "message_loop/message_loop_perftest.cc",
+      "message_loop/message_loop_task_runner_perftest.cc",
+      "message_loop/message_pump_perftest.cc",
+      "observer_list_perftest.cc",
+      "task/sequence_manager/sequence_manager_perftest.cc",
 
-    # "test/run_all_unittests.cc",
-    "json/json_perftest.cc",
-    "synchronization/waitable_event_perftest.cc",
-    "threading/thread_perftest.cc",
-  ]
-  deps = [
-    ":base",
-    "//base/test:test_support",
-    "//base/test:test_support_perf",
-    "//testing/gtest",
-    "//testing/perf",
-  ]
+      # "test/run_all_unittests.cc",
+      "json/json_perftest.cc",
+      "synchronization/waitable_event_perftest.cc",
+      "threading/thread_perftest.cc",
+    ]
+    deps = [
+      ":base",
+      "//base/test:test_support",
+      "//base/test:test_support_perf",
+      "//testing/gtest",
+      "//testing/perf",
+    ]
 
-  if (is_android) {
-    deps += [ "//testing/android/native_test:native_test_native_code" ]
+    if (is_android) {
+      deps += [ "//testing/android/native_test:native_test_native_code" ]
+    }
+  }
+
+  test("base_i18n_perftests") {
+    sources = [
+      "i18n/streaming_utf8_validator_perftest.cc",
+    ]
+    deps = [
+      ":base",
+      ":i18n",
+      "//base/test:test_support",
+      "//base/test:test_support_perf",
+      "//testing/gtest",
+    ]
   }
 }
 
-test("base_i18n_perftests") {
-  sources = [
-    "i18n/streaming_utf8_validator_perftest.cc",
-  ]
-  deps = [
-    ":base",
-    ":i18n",
-    "//base/test:test_support",
-    "//base/test:test_support_perf",
-    "//testing/gtest",
-  ]
-}
-
-if (!is_ios) {
+if (!is_ios && !is_starboard) {
   executable("build_utf8_validator_tables") {
     sources = [
       "i18n/build_utf8_validator_tables.cc",
@@ -2181,9 +2576,12 @@
     "{{bundle_resources_dir}}/" +
         "{{source_root_relative_dir}}/{{source_file_part}}",
   ]
+  if (is_starboard) {
+    sources -= [ "//tools/metrics/histograms/enums.xml" ]
+  }
 }
 
-if (is_ios || is_mac) {
+if ((is_ios || is_mac) && !is_starboard) {
   source_set("base_unittests_arc") {
     testonly = true
     set_sources_assignment_filter([])
@@ -2221,7 +2619,8 @@
   ]
 }
 
-test("base_unittests") {
+target(gtest_target_type, "base_unittests") {
+  testonly = true
   sources = [
     "allocator/allocator_interception_mac_unittest.mm",
     "allocator/malloc_zone_functions_mac_unittest.cc",
@@ -2586,6 +2985,149 @@
     "//base/test:test_shared_library",
   ]
 
+  if (is_starboard) {
+    sources -= [
+      "allocator/allocator_interception_mac_unittest.mm",
+      "allocator/malloc_zone_functions_mac_unittest.cc",
+      "allocator/tcmalloc_unittest.cc",
+      "android/android_image_reader_compat_unittest.cc",
+      "android/application_status_listener_unittest.cc",
+      "android/content_uri_utils_unittest.cc",
+      "android/jni_android_unittest.cc",
+      "android/jni_array_unittest.cc",
+      "android/jni_string_unittest.cc",
+      "android/library_loader/library_prefetcher_unittest.cc",
+      "android/path_utils_unittest.cc",
+      "android/scoped_java_ref_unittest.cc",
+      "android/sys_utils_unittest.cc",
+      "android/unguessable_token_android_unittest.cc",
+      "build_time_unittest.cc",
+      "cpu_unittest.cc",
+      "debug/activity_analyzer_unittest.cc",
+      "debug/activity_tracker_unittest.cc",
+      "debug/crash_logging_unittest.cc",
+      "debug/elf_reader_linux_unittest.cc",
+      "debug/proc_maps_linux_unittest.cc",
+      "debug/stack_trace_unittest.cc",
+      "debug/thread_heap_usage_tracker_unittest.cc",
+      "environment_unittest.cc",
+      "feature_list_unittest.cc",
+      "file_version_info_win_unittest.cc",
+      "files/file_path_watcher_unittest.cc",
+      "files/memory_mapped_file_unittest.cc",
+      "ios/crb_protocol_observers_unittest.mm",
+      "ios/device_util_unittest.mm",
+      "ios/weak_nsobject_unittest.mm",
+      "mac/bind_objc_block_unittest.mm",
+      "mac/dispatch_source_mach_unittest.cc",
+      "mac/foundation_util_unittest.mm",
+      "mac/mac_util_unittest.mm",
+      "mac/mach_port_broker_unittest.cc",
+      "mac/objc_release_properties_unittest.mm",
+      "mac/scoped_nsobject_unittest.mm",
+      "mac/scoped_objc_class_swizzler_unittest.mm",
+      "mac/scoped_sending_event_unittest.mm",
+      "memory/discardable_shared_memory_unittest.cc",
+      "memory/memory_pressure_listener_unittest.cc",
+      "memory/memory_pressure_monitor_chromeos_unittest.cc",
+      "memory/memory_pressure_monitor_mac_unittest.cc",
+      "memory/memory_pressure_monitor_unittest.cc",
+      "memory/memory_pressure_monitor_win_unittest.cc",
+      "memory/platform_shared_memory_region_unittest.cc",
+      "memory/protected_memory_unittest.cc",
+      "memory/shared_memory_mac_unittest.cc",
+      "memory/shared_memory_mapping_unittest.cc",
+      "memory/shared_memory_region_unittest.cc",
+      "memory/shared_memory_unittest.cc",
+      "memory/shared_memory_win_unittest.cc",
+      "message_loop/message_pump_glib_unittest.cc",
+      "message_loop/message_pump_io_ios_unittest.cc",
+      "message_loop/message_pump_mac_unittest.mm",
+      "metrics/field_trial_params_unittest.cc",
+      "metrics/field_trial_unittest.cc",
+      "metrics/histogram_delta_serialization_unittest.cc",
+      "metrics/histogram_macros_unittest.cc",
+      "metrics/histogram_snapshot_manager_unittest.cc",
+      "metrics/single_sample_metrics_unittest.cc",
+      "native_library_unittest.cc",
+      "os_compat_android_unittest.cc",
+      "process/launch_unittest_win.cc",
+      "process/memory_unittest.cc",
+      "process/memory_unittest_mac.h",
+      "process/memory_unittest_mac.mm",
+      "process/process_info_unittest.cc",
+      "process/process_metrics_unittest.cc",
+      "process/process_unittest.cc",
+      "process/process_util_unittest.cc",
+      "profiler/stack_sampling_profiler_unittest.cc",
+      "sync_socket_unittest.cc",
+      "synchronization/waitable_event_watcher_unittest.cc",
+      "task_runner_util_unittest.cc",
+      "test/metrics/histogram_enum_reader_unittest.cc",
+      "test/scoped_feature_list_unittest.cc",
+      "test/test_reg_util_win_unittest.cc",
+      "time/time_win_unittest.cc",
+      "trace_event/cpufreq_monitor_android_unittest.cc",
+      "trace_event/heap_profiler_allocation_context_tracker_unittest.cc",
+      "trace_event/java_heap_dump_provider_android_unittest.cc",
+      "trace_event/memory_allocator_dump_unittest.cc",
+      "trace_event/memory_dump_manager_unittest.cc",
+      "trace_event/memory_dump_scheduler_unittest.cc",
+      "trace_event/process_memory_dump_unittest.cc",
+      "trace_event/trace_config_unittest.cc",
+      "win/async_operation_unittest.cc",
+      "win/com_init_check_hook_unittest.cc",
+      "win/com_init_util_unittest.cc",
+      "win/core_winrt_util_unittest.cc",
+      "win/dllmain.cc",
+      "win/enum_variant_unittest.cc",
+      "win/event_trace_consumer_unittest.cc",
+      "win/event_trace_controller_unittest.cc",
+      "win/event_trace_provider_unittest.cc",
+      "win/i18n_unittest.cc",
+      "win/iunknown_impl_unittest.cc",
+      "win/message_window_unittest.cc",
+      "win/object_watcher_unittest.cc",
+      "win/pe_image_unittest.cc",
+      "win/reference_unittest.cc",
+      "win/registry_unittest.cc",
+      "win/scoped_bstr_unittest.cc",
+      "win/scoped_handle_unittest.cc",
+      "win/scoped_hstring_unittest.cc",
+      "win/scoped_process_information_unittest.cc",
+      "win/scoped_variant_unittest.cc",
+      "win/scoped_winrt_initializer_unittest.cc",
+      "win/shortcut_unittest.cc",
+      "win/startup_information_unittest.cc",
+      "win/typed_event_handler_unittest.cc",
+      "win/vector_unittest.cc",
+      "win/wait_chain_unittest.cc",
+      "win/win_includes_unittest.cc",
+      "win/win_util_unittest.cc",
+      "win/windows_version_unittest.cc",
+      "win/winrt_storage_util_unittest.cc",
+      "win/wmi_unittest.cc",
+      "win/wrapped_window_proc_unittest.cc",
+    ]
+    sources += [
+      "log_once_unittest.cc",
+      "log_once_unittest_1.h",
+      "log_once_unittest_2.h",
+    ]
+    deps -= [
+      "//base/allocator:buildflags",
+      "//base/test:run_all_base_unittests",
+    ]
+    deps += [
+      "//base/test:run_all_unittests",
+    ]
+    defines += [
+      "BASE_DONT_ENFORCE_THREAD_NAME_LENGTH",
+      "GMOCK_NO_MOVE_MOCK",
+    ]
+    data_deps -= [ "//base/test:test_child_process" ]
+  }
+
   if (is_ios || is_mac) {
     deps += [ ":base_unittests_arc" ]
   }
@@ -2599,7 +3141,7 @@
     "//tools/metrics/histograms/enums.xml",
   ]
 
-  if (is_posix) {
+  if (is_posix && !is_starboard) {
     sources += [
       "files/dir_reader_posix_unittest.cc",
       "files/file_descriptor_watcher_posix_unittest.cc",
@@ -2616,7 +3158,7 @@
     defines += [ "SYSTEM_NATIVE_UTF8" ]
   }
 
-  if (is_android) {
+  if (is_android && !is_starboard) {
     # Add unwind tables in base_unittests_apk test apk. The unwind tables are
     # generated from debug info in the binary. Removing "default_symbols" and
     # adding symbols config removes the "strip_debug" config that strips the
@@ -2642,7 +3184,7 @@
     ]
   }
 
-  if (is_ios) {
+  if (is_ios && !is_starboard) {
     sources -= [
       "files/file_path_watcher_unittest.cc",
       "memory/discardable_shared_memory_unittest.cc",
@@ -2669,7 +3211,7 @@
     # TODO(GYP): dep on copy_test_data_ios action.
   }
 
-  if (use_partition_alloc) {
+  if (!is_starboard && use_partition_alloc) {
     sources += [
       "allocator/partition_allocator/address_space_randomization_unittest.cc",
       "allocator/partition_allocator/page_allocator_unittest.cc",
@@ -2688,7 +3230,7 @@
     }
   }
 
-  if (is_linux) {
+  if (is_linux && !is_starboard) {
     if (is_desktop_linux) {
       sources += [ "nix/xdg_util_unittest.cc" ]
     }
@@ -2705,16 +3247,16 @@
     }
   }
 
-  if (!use_glib) {
+  if (!use_glib && !is_starboard) {
     sources -= [ "message_loop/message_pump_glib_unittest.cc" ]
   }
 
-  if (use_libevent) {
+  if (use_libevent && !is_starboard) {
     sources += [ "message_loop/message_pump_libevent_unittest.cc" ]
     deps += [ "//base/third_party/libevent" ]
   }
 
-  if (is_fuchsia) {
+  if (is_fuchsia && !is_starboard) {
     sources += [
       "files/dir_reader_posix_unittest.cc",
       "files/file_descriptor_watcher_posix_unittest.cc",
@@ -2739,11 +3281,11 @@
     ]
   }
 
-  if (!is_fuchsia && !is_ios) {
+  if (!is_fuchsia && !is_ios && !is_starboard) {
     sources += [ "files/file_locking_unittest.cc" ]
   }
 
-  if (is_android) {
+  if (is_android && !is_starboard) {
     deps += [ "//testing/android/native_test:native_test_native_code" ]
     set_sources_assignment_filter([])
     sources += [
@@ -2762,7 +3304,7 @@
     }
   }
 
-  if (use_allocator_shim) {
+  if (!is_starboard && use_allocator_shim) {
     sources += [
       "allocator/allocator_shim_unittest.cc",
       "sampling_heap_profiler/sampling_heap_profiler_unittest.cc",
@@ -2783,20 +3325,22 @@
   }
 }
 
-action("build_date") {
-  script = "//build/write_build_date_header.py"
+if (!is_starboard) {
+  action("build_date") {
+    script = "//build/write_build_date_header.py"
 
-  outputs = [
-    "$target_gen_dir/generated_build_date.h",
-  ]
+    outputs = [
+      "$target_gen_dir/generated_build_date.h",
+    ]
 
-  args = [
-    rebase_path("$target_gen_dir/generated_build_date.h", root_build_dir),
-    build_timestamp,
-  ]
+    args = [
+      rebase_path("$target_gen_dir/generated_build_date.h", root_build_dir),
+      build_timestamp,
+    ]
+  }
 }
 
-if (enable_nocompile_tests) {
+if (!is_starboard && enable_nocompile_tests) {
   nocompile_test("base_nocompile_tests") {
     sources = [
       "bind_unittest.nc",
@@ -2824,7 +3368,7 @@
   }
 }
 
-if (is_android) {
+if (is_android && !is_starboard) {
   generate_jni("base_jni_headers") {
     sources = [
       "android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java",
@@ -3197,77 +3741,79 @@
   }
 }
 
-# Keep the list of fuzzer_tests in alphabetical order.
-fuzzer_test("base64_decode_fuzzer") {
-  sources = [
-    "base64_decode_fuzzer.cc",
-  ]
-  deps = [
-    "//base",
-  ]
-}
+if (!is_starboard) {
+  # Keep the list of fuzzer_tests in alphabetical order.
+  fuzzer_test("base64_decode_fuzzer") {
+    sources = [
+      "base64_decode_fuzzer.cc",
+    ]
+    deps = [
+      "//base",
+    ]
+  }
 
-fuzzer_test("base64_encode_fuzzer") {
-  sources = [
-    "base64_encode_fuzzer.cc",
-  ]
-  deps = [
-    "//base",
-  ]
-}
+  fuzzer_test("base64_encode_fuzzer") {
+    sources = [
+      "base64_encode_fuzzer.cc",
+    ]
+    deps = [
+      "//base",
+    ]
+  }
 
-fuzzer_test("base_json_correctness_fuzzer") {
-  sources = [
-    "json/json_correctness_fuzzer.cc",
-  ]
-  deps = [
-    ":base",
-  ]
-  dict = "//testing/libfuzzer/fuzzers/dicts/json.dict"
-}
+  fuzzer_test("base_json_correctness_fuzzer") {
+    sources = [
+      "json/json_correctness_fuzzer.cc",
+    ]
+    deps = [
+      ":base",
+    ]
+    dict = "//testing/libfuzzer/fuzzers/dicts/json.dict"
+  }
 
-fuzzer_test("base_json_reader_fuzzer") {
-  sources = [
-    "json/json_reader_fuzzer.cc",
-  ]
-  deps = [
-    "//base",
-  ]
-  dict = "//testing/libfuzzer/fuzzers/dicts/json.dict"
-}
+  fuzzer_test("base_json_reader_fuzzer") {
+    sources = [
+      "json/json_reader_fuzzer.cc",
+    ]
+    deps = [
+      "//base",
+    ]
+    dict = "//testing/libfuzzer/fuzzers/dicts/json.dict"
+  }
 
-fuzzer_test("base_json_string_escape_fuzzer") {
-  sources = [
-    "json/string_escape_fuzzer.cc",
-  ]
-  deps = [
-    "//base",
-  ]
-}
+  fuzzer_test("base_json_string_escape_fuzzer") {
+    sources = [
+      "json/string_escape_fuzzer.cc",
+    ]
+    deps = [
+      "//base",
+    ]
+  }
 
-fuzzer_test("string_number_conversions_fuzzer") {
-  sources = [
-    "strings/string_number_conversions_fuzzer.cc",
-  ]
-  deps = [
-    "//base",
-  ]
-}
+  fuzzer_test("string_number_conversions_fuzzer") {
+    sources = [
+      "strings/string_number_conversions_fuzzer.cc",
+    ]
+    deps = [
+      "//base",
+    ]
+  }
 
-fuzzer_test("string_tokenizer_fuzzer") {
-  sources = [
-    "strings/string_tokenizer_fuzzer.cc",
-  ]
-  deps = [
-    "//base",
-  ]
-}
+  fuzzer_test("string_tokenizer_fuzzer") {
+    sources = [
+      "strings/string_tokenizer_fuzzer.cc",
+    ]
+    deps = [
+      "//base",
+    ]
+  }
 
-fuzzer_test("utf_string_conversions_fuzzer") {
-  sources = [
-    "strings/utf_string_conversions_fuzzer.cc",
-  ]
-  deps = [
-    "//base",
-  ]
+  fuzzer_test("utf_string_conversions_fuzzer") {
+    sources = [
+      "strings/utf_string_conversions_fuzzer.cc",
+    ]
+    deps = [
+      "//base",
+    ]
+  }
 }
diff --git a/base/numerics/BUILD.gn b/base/numerics/BUILD.gn
index 0bb8dd1..9bc69a8 100644
--- a/base/numerics/BUILD.gn
+++ b/base/numerics/BUILD.gn
@@ -25,4 +25,8 @@
     "safe_conversions.h",
     "safe_math.h",
   ]
+
+  if (is_starboard) {
+    deps = [ "//starboard:starboard_headers_only" ]
+  }
 }
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn
index 83914f2..d26d11e 100644
--- a/base/test/BUILD.gn
+++ b/base/test/BUILD.gn
@@ -158,9 +158,9 @@
     "values_test_util.h",
   ]
 
-  if (is_ios) {
+  if (is_ios && !is_starboard) {
     sources += [ "launcher/unit_test_launcher_ios.cc" ]
-  } else if (!is_nacl_nonsfi) {
+  } else if (!is_nacl_nonsfi && !is_starboard) {
     sources += [
       "launcher/test_launcher.cc",
       "launcher/test_launcher.h",
@@ -194,7 +194,78 @@
     "//third_party/libxml",
   ]
 
-  if (is_posix || is_fuchsia) {
+  if (is_starboard) {
+    sources -= [
+      "android/java_handler_thread_helpers.cc",
+      "android/java_handler_thread_helpers.h",
+      "android/url_utils.cc",
+      "android/url_utils.h",
+      "gtest_xml_unittest_result_printer.cc",
+      "gtest_xml_unittest_result_printer.h",
+      "gtest_xml_util.cc",
+      "gtest_xml_util.h",
+      "ios/wait_util.h",
+      "ios/wait_util.mm",
+      "launcher/test_result.cc",
+      "launcher/test_result.h",
+      "launcher/test_results_tracker.h",
+      "launcher/unit_test_launcher.h",
+      "metrics/histogram_enum_reader.cc",
+      "metrics/histogram_enum_reader.h",
+      "mock_chrome_application_mac.h",
+      "mock_chrome_application_mac.mm",
+      "mock_entropy_provider.cc",
+      "mock_entropy_provider.h",
+      "move_only_int.h",
+      "multiprocess_test.h",
+      "multiprocess_test_android.cc",
+      "perf_log.cc",
+      "perf_log.h",
+      "perf_test_suite.cc",
+      "perf_test_suite.h",
+      "perf_time_logger.cc",
+      "perf_time_logger.h",
+      "scoped_command_line.cc",
+      "scoped_command_line.h",
+      "scoped_environment_variable_override.cc",
+      "scoped_environment_variable_override.h",
+      "scoped_os_info_override_win.cc",
+      "scoped_os_info_override_win.h",
+      "scoped_path_override.cc",
+      "scoped_path_override.h",
+      "test_discardable_memory_allocator.cc",
+      "test_discardable_memory_allocator.h",
+      "test_file_util.cc",
+      "test_file_util.h",
+      "test_file_util_android.cc",
+      "test_file_util_linux.cc",
+      "test_file_util_mac.cc",
+      "test_file_util_win.cc",
+      "test_listener_ios.h",
+      "test_listener_ios.mm",
+      "test_message_loop.cc",
+      "test_message_loop.h",
+      "test_reg_util_win.cc",
+      "test_reg_util_win.h",
+      "test_shared_memory_util.cc",
+      "test_shared_memory_util.h",
+      "test_shortcut_win.cc",
+      "test_shortcut_win.h",
+      "test_support_android.cc",
+      "test_support_android.h",
+      "test_support_ios.h",
+      "test_support_ios.mm",
+      "thread_test_helper.cc",
+      "thread_test_helper.h",
+    ]
+    sources += [
+      "time_helpers.cc",
+      "time_helpers.h",
+    ]
+    deps += [ "//third_party/libxml:libxml_utils" ]
+  }
+
+  if ((is_posix || is_fuchsia) && !is_starboard) {
     sources += [
       "scoped_locale.cc",
       "scoped_locale.h",
@@ -206,7 +277,7 @@
     deps += [ "//third_party/fuchsia-sdk:zx" ]
   }
 
-  if (is_linux) {
+  if (is_linux && !is_starboard) {
     public_deps += [ ":fontconfig_util_linux" ]
     data_deps = [
       "//third_party/test_fonts",
@@ -226,7 +297,7 @@
     libs = [ "AppKit.framework" ]
   }
 
-  if (is_android) {
+  if (is_android && !is_starboard) {
     set_sources_assignment_filter([])
     sources += [ "test_file_util_linux.cc" ]
     set_sources_assignment_filter(sources_assignment_filter)
@@ -237,7 +308,7 @@
     public_deps += [ ":test_support_java" ]
   }
 
-  if (is_nacl_nonsfi) {
+  if (is_nacl_nonsfi && !is_starboard) {
     sources += [
       "launcher/test_launcher.h",
       "launcher/test_result.h",
@@ -294,15 +365,17 @@
   public_configs = [ ":perf_test_config" ]
 }
 
-static_library("test_launcher_nacl_nonsfi") {
-  testonly = true
-  sources = [
-    "launcher/test_launcher_nacl_nonsfi.cc",
-    "launcher/test_launcher_nacl_nonsfi.h",
-  ]
-  deps = [
-    ":test_support",
-  ]
+if (!is_starboard) {
+  static_library("test_launcher_nacl_nonsfi") {
+    testonly = true
+    sources = [
+      "launcher/test_launcher_nacl_nonsfi.cc",
+      "launcher/test_launcher_nacl_nonsfi.h",
+    ]
+    deps = [
+      ":test_support",
+    ]
+  }
 }
 
 static_library("run_all_unittests") {
@@ -337,20 +410,22 @@
   ]
 }
 
-static_library("run_all_base_unittests") {
-  # Only targets in base should depend on this, targets outside base
-  # should depend on run_all_unittests above.
-  visibility = [ "//base/*" ]
-  testonly = true
-  sources = [
-    "run_all_base_unittests.cc",
-  ]
-  deps = [
-    ":test_support",
-  ]
+if (!is_starboard) {
+  static_library("run_all_base_unittests") {
+    # Only targets in base should depend on this, targets outside base
+    # should depend on run_all_unittests above.
+    visibility = [ "//base/*" ]
+    testonly = true
+    sources = [
+      "run_all_base_unittests.cc",
+    ]
+    deps = [
+      ":test_support",
+    ]
+  }
 }
 
-if (is_linux) {
+if (is_linux && !is_starboard) {
   source_set("fontconfig_util_linux") {
     sources = [
       "fontconfig_util_linux.cc",
@@ -399,7 +474,7 @@
   }
 }
 
-if (is_android) {
+if (is_android && !is_starboard) {
   generate_jni("base_unittests_jni_headers") {
     sources = [
       "android/java/src/org/chromium/base/ContentUriTestUtils.java",
@@ -453,11 +528,13 @@
   }
 }
 
-# Trivial executable which outputs space-delimited argv to stdout,
-# used for testing.
-executable("test_child_process") {
-  testonly = true
-  sources = [
-    "test_child_process.cc",
-  ]
+if (!is_starboard) {
+  # Trivial executable which outputs space-delimited argv to stdout,
+  # used for testing.
+  executable("test_child_process") {
+    testonly = true
+    sources = [
+      "test_child_process.cc",
+    ]
+  }
 }
diff --git a/base/third_party/dynamic_annotations/BUILD.gn b/base/third_party/dynamic_annotations/BUILD.gn
index 0fc4bf7..9985d35 100644
--- a/base/third_party/dynamic_annotations/BUILD.gn
+++ b/base/third_party/dynamic_annotations/BUILD.gn
@@ -20,7 +20,9 @@
       "dynamic_annotations.h",
     ]
     if (is_android && !is_debug) {
-      configs -= [ "//build/config/compiler:default_optimization" ]
+      if (!is_starboard) {
+        configs -= [ "//build/config/compiler:default_optimization" ]
+      }
       configs += [ "//build/config/compiler:optimize_max" ]
     }
   }
diff --git a/base/third_party/libevent/BUILD.gn b/base/third_party/libevent/BUILD.gn
index e934454..63a97cd 100644
--- a/base/third_party/libevent/BUILD.gn
+++ b/base/third_party/libevent/BUILD.gn
@@ -75,6 +75,10 @@
     include_dirs = [ "nacl_nonsfi" ]
   }
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  if (is_starboard) {
+    deps = [ "//starboard:starboard_headers_only" ]
+  } else {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+  }
   configs += [ "//build/config/compiler:no_chromium_code" ]
 }
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index ed94a16..a78ddc5 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -249,7 +249,7 @@
     public_deps += [ "//build/config/sanitizers:deps" ]
   }
 
-  if (use_custom_libcxx) {
+  if (!is_starboard && use_custom_libcxx) {
     public_deps += [ "//buildtools/third_party/libc++" ]
   }
 
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index e9e393d..eceb12b 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1641,7 +1641,14 @@
 # part of Chromium.
 
 config("chromium_code") {
-  if (is_win) {
+  if (is_starboard) {
+    # TODO(b/205790602): Revisit this code to be more compatible with platforms.
+    defines = [
+      "__STDC_CONSTANT_MACROS",
+      "__STDC_FORMAT_MACROS",
+    ]
+    cflags = [ "-Werror" ]
+  } else if (is_win) {
     cflags = [ "/W4" ]  # Warning level 4.
 
     if (is_clang) {
@@ -1721,7 +1728,7 @@
       # Temporarily disable -Wextra-semi for Chrome on Chrome OS.
     } else if (is_chromecast && chromecast_branding != "public") {
       # Temporarily disable -Wextra-semi for Chromecast.
-    } else {
+    } else if (!is_starboard) {
       cflags += [ "-Wextra-semi" ]
     }
   }
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn
index aaaad02..2fbfe97 100644
--- a/build/config/sanitizers/BUILD.gn
+++ b/build/config/sanitizers/BUILD.gn
@@ -115,10 +115,12 @@
   ]
   sources = [ "//build/sanitizers/sanitizer_options.cc" ]
 
-  # Don't compile this target with any sanitizer code. It can be called from
-  # the sanitizer runtimes, so instrumenting these functions could cause
-  # recursive calls into the runtime if there is an error.
-  configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
+  if (!is_starboard) {
+    # Don't compile this target with any sanitizer code. It can be called from
+    # the sanitizer runtimes, so instrumenting these functions could cause
+    # recursive calls into the runtime if there is an error.
+    configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
+  }
 
   if (is_asan) {
     if (!defined(asan_suppressions_file)) {
diff --git a/build/config/ui.gni b/build/config/ui.gni
index cc7a10f..b0a4f30 100644
--- a/build/config/ui.gni
+++ b/build/config/ui.gni
@@ -44,7 +44,7 @@
 
   # TODO(crbug.com/1171629): Remove is_chromeos_lacros.
   # Whether we should use glib, a low level C utility library.
-  use_glib = (is_linux || is_chromeos_lacros) && !is_chromecast
+  use_glib = (is_linux || is_chromeos_lacros) && !is_chromecast && !is_starboard
 }
 
 # TODO(crbug.com/1171629): Remove is_chromeos_lacros.
diff --git a/build/nocompile.gni b/build/nocompile.gni
index 4f17837..d36b5a1 100644
--- a/build/nocompile.gni
+++ b/build/nocompile.gni
@@ -61,7 +61,9 @@
 import("//build/config/clang/clang.gni")
 import("//build/config/python.gni")
 import("//build/toolchain/toolchain.gni")
-import("//testing/test.gni")
+if (!is_starboard) {
+  import("//testing/test.gni")
+}
 
 declare_args() {
   # TODO(crbug.com/105388): make sure no-compile test is not flaky.
diff --git a/cobalt/BUILD.gn b/cobalt/BUILD.gn
index 5206049..e4a1726 100644
--- a/cobalt/BUILD.gn
+++ b/cobalt/BUILD.gn
@@ -16,9 +16,21 @@
   testonly = true
 
   deps = [
+    "//cobalt/account",
+    "//cobalt/base",
+    "//cobalt/math",
     "//cobalt/network_bridge",
+    "//cobalt/renderer:default_options",
+    "//cobalt/renderer/rasterizer/egl/shaders",
     "//cobalt/storage:storage_constants",
+    "//content/browser/speech",
     "//nb",
+    "//third_party/brotli:dec",
+    "//third_party/brotli:dec_no_dictionary_data",
+    "//third_party/flac",
+    "//third_party/libpng",
     "//third_party/libwebp",
+    "//third_party/sqlite",
+    "//third_party/woff2:woff2_dec",
   ]
 }
diff --git a/cobalt/CHANGELOG.md b/cobalt/CHANGELOG.md
index 015db28..9e4ea3e 100644
--- a/cobalt/CHANGELOG.md
+++ b/cobalt/CHANGELOG.md
@@ -2,6 +2,12 @@
 
 This document records all notable changes made to Cobalt since the last release.
 
+## Version 23
+ - **Deleted deprecated --webdriver_listen_ip switch.**
+
+   The `--webdriver_listen_ip` switch was deprecated in Cobalt 22 in favor of
+   `--dev_servers_listen_ip`.
+
 ## Version 22
  - **C++14 is required to compile Cobalt 22.**
 
diff --git a/cobalt/account/BUILD.gn b/cobalt/account/BUILD.gn
new file mode 100644
index 0000000..02cce3e
--- /dev/null
+++ b/cobalt/account/BUILD.gn
@@ -0,0 +1,24 @@
+# Copyright 2021 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.
+
+static_library("account") {
+  has_pedantic_warnings = true
+
+  sources = [
+    "account_manager.cc",
+    "account_manager.h",
+  ]
+
+  deps = [ "//starboard:starboard_headers_only" ]
+}
diff --git a/cobalt/account/account.gyp b/cobalt/account/account.gyp
index 710a7f2..bd42634 100644
--- a/cobalt/account/account.gyp
+++ b/cobalt/account/account.gyp
@@ -24,9 +24,6 @@
         'account_manager.h',
         'account_manager.cc',
       ],
-      'dependencies': [
-        '<(DEPTH)/cobalt/base/base.gyp:base',
-      ],
     },
   ],
 }
diff --git a/cobalt/account/account_manager.cc b/cobalt/account/account_manager.cc
index 72d5b4e..bff7bf1 100644
--- a/cobalt/account/account_manager.cc
+++ b/cobalt/account/account_manager.cc
@@ -13,13 +13,10 @@
 // limitations under the License.
 
 #include <memory>
+#include <string>
 
 #include "cobalt/account/account_manager.h"
 
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "cobalt/base/event_dispatcher.h"
 #include "starboard/user.h"
 
 namespace cobalt {
diff --git a/cobalt/account/account_manager.h b/cobalt/account/account_manager.h
index 9f63bbc..d3b9de3 100644
--- a/cobalt/account/account_manager.h
+++ b/cobalt/account/account_manager.h
@@ -17,9 +17,6 @@
 
 #include <string>
 
-#include "base/basictypes.h"
-#include "cobalt/base/event_dispatcher.h"
-
 namespace cobalt {
 namespace account {
 
@@ -28,6 +25,8 @@
 class AccountManager {
  public:
   AccountManager();
+  AccountManager(const AccountManager&) = delete;
+  AccountManager& operator=(const AccountManager&) = delete;
 
   ~AccountManager() {}
 
@@ -40,9 +39,6 @@
 
   // Get the user ID associated with the account.
   std::string GetUserId();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AccountManager);
 };
 
 }  // namespace account
diff --git a/cobalt/base/BUILD.gn b/cobalt/base/BUILD.gn
new file mode 100644
index 0000000..3f1db22
--- /dev/null
+++ b/cobalt/base/BUILD.gn
@@ -0,0 +1,125 @@
+# Copyright 2021 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.
+
+config("base_config") {
+  defines = [ "COBALT_ENABLE_VERSION_COMPATIBILITY_VALIDATIONS" ]
+
+  if (is_debug || is_devel) {
+    defines += [
+      "ENABLE_DEBUG_C_VAL",
+      "ENABLE_TOKEN_ALPHABETICAL_SORTING",
+    ]
+  } else if (is_qa) {
+    defines += [ "ENABLE_DEBUG_C_VAL" ]
+  }
+}
+
+static_library("base") {
+  sources = [
+    "accessibility_caption_settings_changed_event.h",
+    "accessibility_settings_changed_event.h",
+    "accessibility_text_to_speech_settings_changed_event.h",
+    "address_sanitizer.h",
+    "c_val.cc",
+    "c_val.h",
+    "c_val_collection_entry_stats.h",
+    "c_val_collection_timer_stats.h",
+    "c_val_time_interval_entry_stats.h",
+    "c_val_time_interval_timer_stats.h",
+    "camera_transform.h",
+    "circular_buffer_shell.cc",
+    "circular_buffer_shell.h",
+    "clock.h",
+    "cobalt_paths.h",
+    "compiler.h",
+    "console_log.h",
+    "date_time_configuration_changed_event.h",
+    "deep_link_event.h",
+    "event.h",
+    "event_dispatcher.cc",
+    "event_dispatcher.h",
+    "get_application_key.cc",
+    "get_application_key.h",
+    "init_cobalt.cc",
+    "init_cobalt.h",
+    "language.cc",
+    "language.h",
+    "localized_strings.cc",
+    "localized_strings.h",
+    "log_message_handler.cc",
+    "log_message_handler.h",
+    "message_queue.h",
+    "on_screen_keyboard_hidden_event.h",
+    "on_screen_keyboard_shown_event.h",
+    "path_provider.cc",
+    "path_provider.h",
+    "poller.h",
+    "polymorphic_downcast.h",
+    "polymorphic_equatable.h",
+    "ref_counted_lock.h",
+    "source_location.cc",
+    "source_location.h",
+    "startup_timer.cc",
+    "startup_timer.h",
+    "stop_watch.cc",
+    "stop_watch.h",
+    "token.cc",
+    "token.h",
+    "tokens.cc",
+    "tokens.h",
+    "type_id.h",
+    "unicode/character.cc",
+    "unicode/character.h",
+    "unicode/character_values.h",
+    "unused.h",
+    "version_compatibility.cc",
+    "version_compatibility.h",
+    "window_size_changed_event.h",
+    "wrap_main.h",
+    "wrap_main_starboard.h",
+  ]
+
+  public_configs = [ ":base_config" ]
+
+  public_deps = [ "//base" ]
+
+  deps = [
+    "//base:i18n",
+    "//starboard/common",
+    "//third_party/icu",
+    "//third_party/libxml",
+  ]
+}
+
+target(gtest_target_type, "base_test") {
+  testonly = true
+  sources = [
+    "c_val_collection_entry_stats_test.cc",
+    "c_val_collection_timer_stats_test.cc",
+    "c_val_test.cc",
+    "c_val_time_interval_entry_stats_test.cc",
+    "c_val_time_interval_timer_stats_test.cc",
+    "circular_buffer_shell_unittest.cc",
+    "fixed_size_lru_cache_test.cc",
+    "token_test.cc",
+  ]
+
+  deps = [
+    ":base",
+    "//cobalt/test:run_all_unittests",
+    "//starboard",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+}
diff --git a/cobalt/browser/application.cc b/cobalt/browser/application.cc
index c0995fe..f795082 100644
--- a/cobalt/browser/application.cc
+++ b/cobalt/browser/application.cc
@@ -186,23 +186,6 @@
 #endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
   return webdriver_port;
 }
-
-std::string GetWebDriverListenIp() {
-  // The default IP on which the webdriver server should listen for incoming
-  // connections.
-  std::string webdriver_listen_ip = GetDevServersListenIp();
-#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kWebDriverListenIp)) {
-    DLOG(WARNING) << "The \"--" << switches::kWebDriverListenIp
-                  << "\" switch is deprecated; please use \"--"
-                  << switches::kDevServersListenIp << "\" instead.";
-    webdriver_listen_ip =
-        command_line->GetSwitchValueASCII(switches::kWebDriverListenIp);
-  }
-#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
-  return webdriver_listen_ip;
-}
 #endif  // ENABLE_WEBDRIVER
 
 GURL GetInitialURL(bool should_preload) {
@@ -924,7 +907,7 @@
 #endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
   if (create_webdriver_module) {
     web_driver_module_.reset(new webdriver::WebDriverModule(
-        GetWebDriverPort(), GetWebDriverListenIp(),
+        GetWebDriverPort(), GetDevServersListenIp(),
         base::Bind(&BrowserModule::CreateSessionDriver,
                    base::Unretained(browser_module_.get())),
         base::Bind(&BrowserModule::RequestScreenshotToMemory,
@@ -1009,14 +992,14 @@
 void Application::Start(SbTimeMonotonic timestamp) {
   if (base::MessageLoop::current() != message_loop_) {
     message_loop_->task_runner()->PostTask(
-        FROM_HERE, base::Bind(&Application::Start, base::Unretained(this),
-                              timestamp));
+        FROM_HERE,
+        base::Bind(&Application::Start, base::Unretained(this), timestamp));
     return;
   }
 
   OnApplicationEvent(kSbEventTypeStart, timestamp);
-  browser_module_->SetApplicationStartOrPreloadTimestamp(
-      false /*is_preload*/, timestamp);
+  browser_module_->SetApplicationStartOrPreloadTimestamp(false /*is_preload*/,
+                                                         timestamp);
 }
 
 void Application::Quit() {
@@ -1095,10 +1078,10 @@
     case kSbEventTypeLink: {
 #if SB_API_VERSION >= 13
       DispatchDeepLink(static_cast<const char*>(starboard_event->data),
-                                                starboard_event->timestamp);
-#else  // SB_API_VERSION >= 13
+                       starboard_event->timestamp);
+#else   // SB_API_VERSION >= 13
       DispatchDeepLink(static_cast<const char*>(starboard_event->data),
-                                                SbTimeGetMonotonicNow());
+                       SbTimeGetMonotonicNow());
 #endif  // SB_API_VERSION >= 13
       break;
     }
diff --git a/cobalt/browser/switches.cc b/cobalt/browser/switches.cc
index ff63221..a56990c 100644
--- a/cobalt/browser/switches.cc
+++ b/cobalt/browser/switches.cc
@@ -213,12 +213,6 @@
     "speech synthesis API. If the platform doesn't have speech synthesis, "
     "TTSLogger will be used instead.";
 
-const char kWebDriverListenIp[] = "webdriver_listen_ip";
-const char kWebDriverListenIpHelp[] =
-    "IP that the WebDriver server should be listening on. (INADDR_ANY if "
-    "unspecified). This is deprecated in favor of --dev_servers_listen_ip (if "
-    "both are specified, --webdriver_listen_ip is used).";
-
 const char kWebDriverPort[] = "webdriver_port";
 const char kWebDriverPortHelp[] =
     "Port that the WebDriver server should be listening on.";
@@ -471,8 +465,7 @@
         {kUserAgent, kUserAgentHelp},
         {kUserAgentClientHints, kUserAgentClientHintsHelp},
         {kUserAgentOsNameVersion, kUserAgentOsNameVersionHelp},
-        {kUseTTS, kUseTTSHelp}, {kWebDriverListenIp, kWebDriverListenIpHelp},
-        {kWebDriverPort, kWebDriverPortHelp},
+        {kUseTTS, kUseTTSHelp}, {kWebDriverPort, kWebDriverPortHelp},
 #if SB_API_VERSION >= 12 || SB_HAS(ON_SCREEN_KEYBOARD)
         {kDisableOnScreenKeyboard, kDisableOnScreenKeyboardHelp},
 #endif  // SB_API_VERSION >= 12 ||
diff --git a/cobalt/browser/switches.h b/cobalt/browser/switches.h
index 9786622..814e89a 100644
--- a/cobalt/browser/switches.h
+++ b/cobalt/browser/switches.h
@@ -86,8 +86,6 @@
 extern const char kUserAgentOsNameVersionHelp[];
 extern const char kUseTTS[];
 extern const char kUseTTSHelp[];
-extern const char kWebDriverListenIp[];
-extern const char kWebDriverListenIpHelp[];
 extern const char kWebDriverPort[];
 extern const char kWebDriverPortHelp[];
 
diff --git a/cobalt/doc/deep_links.md b/cobalt/doc/deep_links.md
new file mode 100644
index 0000000..69080ca
--- /dev/null
+++ b/cobalt/doc/deep_links.md
@@ -0,0 +1,135 @@
+# Cobalt Deep Links
+
+- [Cobalt Deep Links](#cobalt-deep-links)
+  - [Deep Links](#deep-links)
+  - [Web API](#web-api)
+  - [Platform (Starboard) API](#platform-starboard-api)
+  - [Behavior details](#behavior-details)
+## Deep Links
+
+For Cobalt, a deep link is a string that can be sent from the platform to an
+application running in Cobalt. Generally, it can be used as any string value
+signal, but typically deep links are used to specify a view, page, or content
+to be shown by the application. While these strings typically are URI formatted
+values, when deep link strings are received by Cobalt they are forwarded to the
+running application without separate validation or modification.
+
+Applications should interpret received deep links as superseding previous deep
+links. Deep links received by Cobalt in rapid succession are not guaranteed to
+all be delivered to the application. On a busy or slow device, intermediate
+deep links can be dropped before they are delivered to the application.
+
+The startup URL passed to Cobalt determines which application Cobalt will load.
+Web deep links intended as a signal to the application should not be sent to
+Cobalt as a startup URL because that would result in a different application
+being loaded. Since a deep link is a string that may originate from an
+untrusted source on the device, it should not be used directly to determine
+what application Cobalt will load.
+
+Deep links are made visible to applications by Cobalt with a Web API that is
+separate from the Location interface web API. Cobalt will never directly
+navigate as a result of a received deep link, even if the link matches the
+current application location, for example with a query or fragment identifier.
+Applications that wish to navigate as a result of incoming deep links should do
+so explicitly when they are received.
+
+## Web API
+
+The deep link Web API consists of two parts: The
+`h5vcc.runtime.initialDeepLink` property and `h5vcc.runtime.onDeepLink` event
+target.
+
+Applications can read the value of `initialDeepLink`, and/or they can use
+`h5vcc.runtime.onDeepLink.addListener(foo)` to register callback functions to
+be called when deep links are received.
+
+A deep link is considered 'consumed' when it is read from `initialDeepLink`, or
+when it is reported to a callback function registered to `onDeepLink`.
+
+The IDL for this Cobalt specific interface can be found in cobalt/h5vcc, and is
+repeated below.
+
+```
+interface H5vccRuntime {
+  readonly attribute DOMString initialDeepLink;
+  readonly attribute H5vccDeepLinkEventTarget onDeepLink;
+}
+interface H5vccDeepLinkEventTarget {
+  void addListener(H5vccDeepLinkEventCallback callback);
+};
+callback H5vccDeepLinkEventCallback = void(DOMString link);
+interface H5vcc {
+  readonly attribute H5vccRuntime runtime;
+}
+```
+
+## Platform (Starboard) API
+
+Deep links can be passed into Cobalt in two ways:
+ * As the 'Startup Link':
+   * When Cobalt is first started, a deep link can be passed in with the
+     initial event (either `kSbEventTypePreload` or `kSbEventTypeStart`). This
+     can be achieved by calling `Application::SetStartLink` or by using and
+     overload of `Application::Run` that has the 'link_data' parameter to start
+     Cobalt. The value passed in there is then passed into Cobalt via the
+     'link' member of the SbEventStartData event parameter, constructed in
+     `Application::CreateInitialEvent`.
+ * As a 'Deep Link Event':
+   * At any time while Cobalt is running, it can be sent as the string value
+     passed with a kSbEventTypeLink event. The `Application::Link` method can
+     be called to inject such an event.
+
+On many platforms, the 'Startup Link' value can also be set with the `--link`
+command-line parameter (See `kLinkSwitch` in `Application::Run`).
+
+The `Application` class mentioned above can be found at
+`starboard/shared/starboard/application.cc`.
+
+## Behavior details
+
+Both the 'Startup Link' and 'Deep Link Event' values are treated the same by
+Cobalt: A 'Startup Link' is treated as a 'Deep Link Event' that was received
+immediately at startup. For the application, it is transparent whether a deep
+link was received as a 'Startup Link' or arrived from a 'Deep Link Event'. Deep
+link values of either type are made available as soon as they are known, with
+the same Web API interface.
+
+The most recently received deep link is remembered by Cobalt until it is
+consumed by the application. This includes deep links received by Cobalt while
+the application is still being fetched and loaded, including during page
+redirects or reloads, and after the application is loaded, if it has not
+consumed the deep link.
+
+Deep link values are considered consumed when the application either reads them
+from the `initialDeepLink` attribute or receives them in a callback to an
+`onDeepLink` listener. An application can use either or both reads of
+`initialDeepLink` or `onDeepLink` listeners to consume the most recently
+received deep link value.
+
+Calls to `onDeepLink` listeners are done as soon as deep links are available.
+Specifically, they can be called before `document.onreadystatechange`,
+`document.onload` & `window.onload` event handlers are called. As a result,
+deep link values can be consumed in synchronously loaded JavaScript that
+executes before the `document.onload` event.
+
+Until the first `onDeepLink` listener is added, the `initialDeepLink` property
+will return the most recently received deep link value. When an `onDeepLink`
+listener is added, the `initialDeepLink` value will no longer be updated, even
+when additional deep link events are received subsequently.
+
+An application can decide to never register an `onDeepLink` listener and poll
+the `initialDeepLink` value instead. This will then always return the value of
+the most recently received deep link.
+
+An application can decide to register an `onDeepLink` listener without reading
+the `initialDeepLink` value. Upon registering, the most recently received deep
+link, which may be the 'Startup Link' or from a 'Deep Link Event', will be
+reported to the listener.
+
+If a deep link value is consumed, it will not be made available again if the
+page is navigated (e.g. redirected or reloaded). When a deep link is consumed
+before a page redirect or reload, the deep link will not be repeated later.
+
+If a deep link value is not consumed, it will be made available again if the
+page is navigated (e.g. redirected or reloaded). A deep link will not be lost
+if a page redirect or reload is done without consuming it.
diff --git a/cobalt/dom/html_link_element.cc b/cobalt/dom/html_link_element.cc
index 8e94b1b..8bce236 100644
--- a/cobalt/dom/html_link_element.cc
+++ b/cobalt/dom/html_link_element.cc
@@ -315,7 +315,6 @@
 
 void HTMLLinkElement::ReleaseLoader() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(loader_);
   loader_.reset();
 }
 
diff --git a/cobalt/dom/html_script_element.cc b/cobalt/dom/html_script_element.cc
index fe37061..0fc8836 100644
--- a/cobalt/dom/html_script_element.cc
+++ b/cobalt/dom/html_script_element.cc
@@ -72,7 +72,6 @@
       is_ready_(false),
       load_option_(0),
       inline_script_location_(GetSourceLocationName(), 1, 1),
-      is_sync_load_successful_(false),
       should_execute_(true),
       synchronous_loader_interrupt_(
           document->html_element_context()->synchronous_loader_interrupt()) {
@@ -122,7 +121,7 @@
 scoped_refptr<Node> HTMLScriptElement::Duplicate() const {
   // The cloning steps for script elements must set the "already started" flag
   // on the copy if it is set on the element being cloned.
-  //   https://www.w3.org/TR/html50/scripting-1.html#already-started
+  //   https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#already-started
   scoped_refptr<HTMLScriptElement> new_script = HTMLElement::Duplicate()
                                                     ->AsElement()
                                                     ->AsHTMLElement()
@@ -137,20 +136,21 @@
   // exists when the script element is destroyed.
   // NOTE: While the garbage collection prevention logic will typically protect
   // from this, it is still possible during shutdown.
-  if (node_document()) {
+  if (document_) {
     std::deque<HTMLScriptElement*>* scripts_to_be_executed =
-        node_document()->scripts_to_be_executed();
+        document_->scripts_to_be_executed();
 
     std::deque<HTMLScriptElement*>::iterator it = std::find(
         scripts_to_be_executed->begin(), scripts_to_be_executed->end(), this);
     if (it != scripts_to_be_executed->end()) {
       scripts_to_be_executed->erase(it);
     }
+    ExecuteSyncScripts();
   }
 }
 
 // Algorithm for Prepare:
-//   https://www.w3.org/TR/html50/scripting-1.html#prepare-a-script
+//   https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#prepare-a-script
 void HTMLScriptElement::Prepare() {
   TRACK_MEMORY_SCOPE("DOM");
   // Custom, not in any spec.
@@ -159,8 +159,11 @@
   DCHECK(!loader_ || is_already_started_);
   TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::Prepare()");
 
-  // If the script element is marked as having "already started", then the user
-  // agent must abort these steps at this point. The script is not executed.
+  error_.reset();
+
+  // If the script element is marked as having "already started", then the
+  // user agent must abort these steps at this point. The script is not
+  // executed.
   if (is_already_started_) {
     return;
   }
@@ -214,7 +217,7 @@
   //   2. If src is the empty string, queue a task to fire a simple event
   // named error at the element, and abort these steps.
   if (HasAttribute("src") && src() == "") {
-    LOG(WARNING) << "src attribute of script element is empty.";
+    LOG(ERROR) << "src attribute of script element is empty.";
 
     PreventGarbageCollectionAndPostToDispatchEvent(
         FROM_HERE, base::Tokens::error(),
@@ -228,7 +231,7 @@
   const GURL& base_url = document_->url_as_gurl();
   url_ = base_url.Resolve(src());
   if (!url_.is_valid()) {
-    LOG(WARNING) << src() << " cannot be resolved based on " << base_url << ".";
+    LOG(ERROR) << src() << " cannot be resolved based on " << base_url << ".";
 
     PreventGarbageCollectionAndPostToDispatchEvent(
         FROM_HERE, base::Tokens::error(),
@@ -318,8 +321,6 @@
       // loader below.  If that completion callback never fires, the variable
       // will stay false.  This can happen if the loader was interrupted, or
       // failed for another reason.
-      is_sync_load_successful_ = false;
-
       loader::LoadSynchronously(
           html_element_context()->sync_load_thread()->message_loop(),
           synchronous_loader_interrupt_,
@@ -336,18 +337,14 @@
           base::Bind(&HTMLScriptElement::OnSyncLoadingComplete,
                      base::Unretained(this)));
 
-      if (is_sync_load_successful_) {
+      // This block exists to ensure that garbage collection is prevented while
+      // executing the script.
+      {
         script::GlobalEnvironment::ScopedPreventGarbageCollection
             scoped_prevent_gc(
                 html_element_context()->script_runner()->GetGlobalEnvironment(),
                 this);
         ExecuteExternal();
-        // Release the content string now that we're finished with it.
-        content_.reset();
-      } else {
-        // Executing the script block must just consist of firing a simple event
-        // named error at the element.
-        DispatchEvent(new Event(base::Tokens::error()));
       }
     } break;
     case 4: {
@@ -365,9 +362,10 @@
           document_->scripts_to_be_executed();
       scripts_to_be_executed->push_back(this);
 
-      // Fetching an external script must delay the load event of the element's
-      // document until the task that is queued by the networking task source
-      // once the resource has been fetched (defined above) has been run.
+      // Fetching an external script must delay the load event
+      // of the element's document until the task that is
+      // queued by the networking task source once the resource
+      // has been fetched (defined above) has been run.
       document_->IncreaseLoadingCounter();
 
       loader::Origin origin = document_->location()
@@ -422,6 +420,7 @@
         fetched_last_url_origin_ = document_->location()->GetOriginAsObject();
         ExecuteInternal();
       } else {
+        LOG(ERROR) << " empty synchronous script.";
         PreventGarbageCollectionAndPostToDispatchEvent(
             FROM_HERE, base::Tokens::error(),
             &prevent_gc_until_error_event_dispatch_);
@@ -437,37 +436,119 @@
   TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnSyncContentProduced()");
   fetched_last_url_origin_ = last_url_origin;
   content_ = std::move(content);
-  is_sync_load_successful_ = true;
 }
 
 void HTMLScriptElement::OnSyncLoadingComplete(
     const base::Optional<std::string>& error) {
+  error_ = error;
   if (!error) return;
-
   TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnSyncLoadingComplete()");
   LOG(ERROR) << "Error during synchronous script load referenced from \""
              << inline_script_location_ << "\" : " << *error;
 }
 
 // Algorithm for OnContentProduced:
-//   https://www.w3.org/TR/html50/scripting-1.html#prepare-a-script
+//   https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#prepare-a-script
 void HTMLScriptElement::OnContentProduced(
     const loader::Origin& last_url_origin,
     std::unique_ptr<std::string> content) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(load_option_ == 4 || load_option_ == 5);
+  // From Algorithm for OnContentProduced:
+  //   https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#prepare-a-script
+  // 15. Then, the first of the following options that describes the situation
+  // must be followed:
+  //
   DCHECK(content);
   TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnContentProduced()");
-  if (!document_) {
-    AllowGCAfterLoadComplete();
-    return;
-  }
 
   fetched_last_url_origin_ = last_url_origin;
   content_ = std::move(content);
 
+  OnReadyToExecute();
+}
+
+// Algorithm for OnLoadingComplete:
+//   https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#prepare-a-script
+void HTMLScriptElement::OnLoadingComplete(
+    const base::Optional<std::string>& error) {
+  error_ = error;
+  // GetLoadTimingInfo and create resource timing before loader released.
+  GetLoadTimingInfoAndCreateResourceTiming();
+
+  TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnLoadingComplete()");
+
+  if (!error_) return;
+
+  OnReadyToExecute();
+}
+
+void HTMLScriptElement::ExecuteSyncScripts() {
+  // From Algorithm for OnContentProduced:
+  //   https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#prepare-a-script
+  DCHECK(document_);
+
+  std::deque<HTMLScriptElement*>* scripts_to_be_executed =
+      document_->scripts_to_be_executed();
+  if (scripts_to_be_executed->empty() ||
+      scripts_to_be_executed->front() != this) {
+    return;
+  }
+
+  while (true) {
+    // 2. Execution: Execute the script block corresponding to the first
+    // script element in this list of scripts that will execute in order as
+    // soon as possible.
+    HTMLScriptElement* script = scripts_to_be_executed->front();
+    script->ExecuteExternal();
+
+    // NOTE: Must disable warning 6011 on Windows. It mysteriously believes
+    // that a NULL pointer is being dereferenced with this comparison.
+    MSVC_PUSH_DISABLE_WARNING(6011);
+    // If this script isn't the current object, then allow it to be garbage
+    // collected now that it has executed.
+    if (script != this) {
+      script->AllowGCAfterLoadComplete();
+    }
+    MSVC_POP_WARNING();
+
+    // 3. Remove the first element from this list of scripts that will
+    // execute in order as soon as possible.
+    scripts_to_be_executed->pop_front();
+
+    // Fetching an external script must delay the load event of the
+    //  element's document until the task that is queued by the networking
+    // task source once the resource has been fetched (defined above)
+    // has been run.
+    document_->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
+
+    // 4. If this list of scripts that will execute in order as soon as
+    // possible is still not empty and the first entry has already been
+    // marked
+    // as ready, then jump back to the step labeled execution.
+    if (scripts_to_be_executed->empty() ||
+        !scripts_to_be_executed->front()->is_ready_) {
+      break;
+    }
+  }
+
+  // Allow garbage collection on the current script object now that it has
+  // finished executing both itself and other pending scripts.
+  AllowGCAfterLoadComplete();
+}
+
+void HTMLScriptElement::OnReadyToExecute() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(load_option_ == 4 || load_option_ == 5);
+  if (!document_) {
+    error_ = "No document";
+    AllowGCAfterLoadComplete();
+    return;
+  }
+
   switch (load_option_) {
     case 4: {
+      // From Algorithm for OnContentProduced:
+      //   https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#script-processing-src-sync
+
       // If the element has a src attribute, does not have an async attribute,
       // and does not have the "force-async" flag set.
 
@@ -477,53 +558,16 @@
       //   that will execute in order as soon as possible to which it was added
       //   above, then mark the element as ready but abort these steps without
       //   executing the script yet.
-      std::deque<HTMLScriptElement*>* scripts_to_be_executed =
-          document_->scripts_to_be_executed();
-      if (scripts_to_be_executed->front() != this) {
+      if (document_->scripts_to_be_executed()->front() != this) {
         is_ready_ = true;
-        return;
+      } else {
+        ExecuteSyncScripts();
       }
-      while (true) {
-        // 2. Execution: Execute the script block corresponding to the first
-        // script element in this list of scripts that will execute in order as
-        // soon as possible.
-        HTMLScriptElement* script = scripts_to_be_executed->front();
-        script->ExecuteExternal();
-
-        // NOTE: Must disable warning 6011 on Windows. It mysteriously believes
-        // that a NULL pointer is being dereferenced with this comparison.
-        MSVC_PUSH_DISABLE_WARNING(6011);
-        // If this script isn't the current object, then allow it to be garbage
-        // collected now that it has executed.
-        if (script != this) {
-          script->AllowGCAfterLoadComplete();
-        }
-        MSVC_POP_WARNING();
-
-        // 3. Remove the first element from this list of scripts that will
-        // execute in order as soon as possible.
-        scripts_to_be_executed->pop_front();
-
-        // Fetching an external script must delay the load event of the
-        //  element's document until the task that is queued by the networking
-        // task source once the resource has been fetched (defined above)
-        // has been run.
-        document_->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
-
-        // 4. If this list of scripts that will execute in order as soon as
-        // possible is still not empty and the first entry has already been
-        // marked
-        // as ready, then jump back to the step labeled execution.
-        if (scripts_to_be_executed->empty() ||
-            !scripts_to_be_executed->front()->is_ready_) {
-          break;
-        }
-      }
-      // Allow garbage collection on the current script object now that it has
-      // finished executing both itself and other pending scripts.
-      AllowGCAfterLoadComplete();
     } break;
     case 5: {
+      // From Algorithm for OnContentProduced:
+      //   https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#script-processing-src
+
       // If the element has a src attribute.
 
       // The task that the networking task source places on the task queue once
@@ -543,78 +587,35 @@
     } break;
   }
 
-  // Release the content string now that we're finished with it.
-  content_.reset();
-
-  // Post a task to release the loader.
-  base::MessageLoop::current()->task_runner()->PostTask(
-      FROM_HERE, base::Bind(&HTMLScriptElement::ReleaseLoader, this));
-}
-
-// Algorithm for OnLoadingComplete:
-//   https://www.w3.org/TR/html50/scripting-1.html#prepare-a-script
-void HTMLScriptElement::OnLoadingComplete(
-    const base::Optional<std::string>& error) {
-  // GetLoadTimingInfo and create resource timing before loader released.
-  GetLoadTimingInfoAndCreateResourceTiming();
-
-  if (!error) return;
-
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(load_option_ == 4 || load_option_ == 5);
-  TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnLoadingComplete()");
-
-  if (!document_) {
-    AllowGCAfterLoadComplete();
-    return;
-  }
-
-  LOG(ERROR) << *error;
-
-  // Executing the script block must just consist of firing a simple event
-  // named error at the element.
-  DispatchEvent(new Event(base::Tokens::error()));
-  AllowGCAfterLoadComplete();
-
-  switch (load_option_) {
-    case 4: {
-      // If the element has a src attribute, does not have an async attribute,
-      // and does not have the "force-async" flag set.
-      std::deque<HTMLScriptElement*>* scripts_to_be_executed =
-          document_->scripts_to_be_executed();
-
-      std::deque<HTMLScriptElement*>::iterator it = std::find(
-          scripts_to_be_executed->begin(), scripts_to_be_executed->end(), this);
-      if (it != scripts_to_be_executed->end()) {
-        scripts_to_be_executed->erase(it);
-      }
-    } break;
-    case 5: {
-      // If the element has a src attribute.
-    } break;
-  }
-
-  // Fetching an external script must delay the load event of the element's
-  // document until the task that is queued by the networking task source
-  // once the resource has been fetched (defined above) has been run.
-  document_->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
-
   // Post a task to release the loader.
   base::MessageLoop::current()->task_runner()->PostTask(
       FROM_HERE, base::Bind(&HTMLScriptElement::ReleaseLoader, this));
 }
 
 void HTMLScriptElement::ExecuteExternal() {
-  DCHECK(content_);
-  Execute(*content_, base::SourceLocation(url_.spec(), 1, 1), true);
+  if (error_) {
+    LOG(ERROR) << *error_;
+    // If the load resulted in an error (for example a DNS error, or an HTTP
+    // 404 error)
+    // Executing the script block must just consist of firing a simple event
+    // named error at the element.
+    DispatchEvent(new Event(base::Tokens::error()));
+  } else {
+    DCHECK(content_);
+    Execute(*content_, base::SourceLocation(url_.spec(), 1, 1), true);
+  }
+
+  // Release the content string now that we're finished with it.
+  content_.reset();
 }
 
 void HTMLScriptElement::ExecuteInternal() {
+  DCHECK(!error_);
   Execute(text_content().value(), inline_script_location_, false);
 }
 
 // Algorithm for Execute:
-//   https://www.w3.org/TR/html50/scripting-1.html#execute-the-script-block
+//   https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#execute-the-script-block
 void HTMLScriptElement::Execute(const std::string& content,
                                 const base::SourceLocation& script_location,
                                 bool is_external) {
@@ -624,18 +625,20 @@
   // When inserted using the document.write() method, script elements execute
   // (typically synchronously), but when inserted using innerHTML and
   // outerHTML attributes, they do not execute at all.
-  // https://www.w3.org/TR/html50/scripting-1.html#the-script-element.
+  // https://www.w3.org/TR/2018/SPSD-html5-20180327/scripting-1.html#the-script-element.
   if (!should_execute_) {
     return;
   }
 
-  // The script is now being run. Track it in the global stats.
-  GlobalStats::GetInstance()->StartJavaScriptEvent();
-
   TRACE_EVENT2("cobalt::dom", "HTMLScriptElement::Execute()", "file_path",
                script_location.file_path, "line_number",
                script_location.line_number);
+
   // Since error is already handled, it is guaranteed the load is successful.
+  DCHECK(!error_);
+
+  // The script is now being run. Track it in the global stats.
+  GlobalStats::GetInstance()->StartJavaScriptEvent();
 
   // For |currentScript| logic, see
   // https://html.spec.whatwg.org/commit-snapshots/20a0ddc6841176adab93efefb76b23e0a1e6fa43/#execute-the-script-block
@@ -730,7 +733,7 @@
   if (html_element_context()->performance() == nullptr) return;
   if (loader_) {
     html_element_context()->performance()->CreatePerformanceResourceTiming(
-      loader_->get_load_timing_info(), kTagName, url_.spec());
+        loader_->get_load_timing_info(), kTagName, url_.spec());
   }
 }
 
diff --git a/cobalt/dom/html_script_element.h b/cobalt/dom/html_script_element.h
index 9ee5754..7c5fa14 100644
--- a/cobalt/dom/html_script_element.h
+++ b/cobalt/dom/html_script_element.h
@@ -92,6 +92,8 @@
  protected:
   scoped_refptr<Node> Duplicate() const override;
 
+  void ExecuteSyncScripts();
+
  private:
   ~HTMLScriptElement() override;
 
@@ -103,6 +105,7 @@
                              std::unique_ptr<std::string> content);
   void OnSyncLoadingComplete(const base::Optional<std::string>& error);
 
+  void OnReadyToExecute();
   void OnContentProduced(const loader::Origin& last_url_origin,
                          std::unique_ptr<std::string> content);
   void OnLoadingComplete(const base::Optional<std::string>& error);
@@ -131,6 +134,8 @@
   bool is_parser_inserted_;
   // Whether the script is ready to be executed.
   bool is_ready_;
+  // If the script failed, contains the error message.
+  base::Optional<std::string> error_;
   // The option that defines how the script should be loaded and executed.
   int load_option_;
   // SourceLocation for inline script.
@@ -143,8 +148,6 @@
   base::WeakPtr<Document> document_;
   // The loader that is used for asynchronous loads.
   std::unique_ptr<loader::Loader> loader_;
-  // Whether the sync load is successful.
-  bool is_sync_load_successful_;
   // Resolved URL of the script.
   GURL url_;
   // Content of the script. Released after Execute is called.
diff --git a/cobalt/math/BUILD.gn b/cobalt/math/BUILD.gn
new file mode 100644
index 0000000..59c4494
--- /dev/null
+++ b/cobalt/math/BUILD.gn
@@ -0,0 +1,103 @@
+# Copyright 2021 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.
+
+static_library("math") {
+  sources = [
+    "box_f.cc",
+    "box_f.h",
+    "clamp.h",
+    "cubic_bezier.cc",
+    "cubic_bezier.h",
+    "insets.cc",
+    "insets.h",
+    "insets_base.h",
+    "insets_f.cc",
+    "insets_f.h",
+    "linear_interpolator.h",
+    "matrix3_f.cc",
+    "matrix3_f.h",
+    "matrix_interpolation.cc",
+    "matrix_interpolation.h",
+    "point.cc",
+    "point.h",
+    "point3_f.cc",
+    "point3_f.h",
+    "point_base.h",
+    "point_conversions.cc",
+    "point_conversions.h",
+    "point_f.cc",
+    "point_f.h",
+    "quad_f.cc",
+    "quad_f.h",
+    "rational.h",
+    "rect.cc",
+    "rect.h",
+    "rect_base.h",
+    "rect_base_impl.h",
+    "rect_conversions.cc",
+    "rect_conversions.h",
+    "rect_f.cc",
+    "rect_f.h",
+    "safe_integer_conversions.h",
+    "size.cc",
+    "size.h",
+    "size_base.h",
+    "size_conversions.cc",
+    "size_conversions.h",
+    "size_f.cc",
+    "size_f.h",
+    "transform_2d.cc",
+    "transform_2d.h",
+    "vector2d.cc",
+    "vector2d.h",
+    "vector2d_conversions.cc",
+    "vector2d_conversions.h",
+    "vector2d_f.cc",
+    "vector2d_f.h",
+    "vector3d_f.cc",
+    "vector3d_f.h",
+  ]
+  deps = [
+    "//base",
+    "//starboard:starboard_headers_only",
+  ]
+}
+
+target(gtest_target_type, "math_test") {
+  testonly = true
+  sources = [
+    "box_unittest.cc",
+    "cubic_bezier_unittest.cc",
+    "insets_unittest.cc",
+    "linear_interpolator_unittest.cc",
+    "matrix3_unittest.cc",
+    "matrix_interpolation_unittest.cc",
+    "point3_unittest.cc",
+    "point_unittest.cc",
+    "quad_unittest.cc",
+    "rect_unittest.cc",
+    "safe_integer_conversions_unittest.cc",
+    "size_unittest.cc",
+    "transform_2d_test.cc",
+    "vector2d_unittest.cc",
+    "vector3d_unittest.cc",
+  ]
+  deps = [
+    ":math",
+    "//base",
+    "//cobalt/base",
+    "//cobalt/test:run_all_unittests",
+    "//testing/gtest",
+  ]
+}
diff --git a/cobalt/media_integration_tests/endurance/endurance_test.py b/cobalt/media_integration_tests/endurance/endurance_test.py
index 18cc902..edc6552 100644
--- a/cobalt/media_integration_tests/endurance/endurance_test.py
+++ b/cobalt/media_integration_tests/endurance/endurance_test.py
@@ -168,7 +168,7 @@
     logging.info('Send random action (%s).', action_name)
     actions[action_name](app)
 
-  def test_playback_endurance(self):
+  def test_playback_endurance(self):  # pylint: disable=invalid-name
     self.start_time = time.time()
     self.player_identifier = ''
     self.playback_is_playing = False
@@ -260,5 +260,6 @@
           # Play the previous playback again.
           app.PlayPrevious()
           self.last_action_time = current_running_time
+          logging.info('Play previous playback to keep app active.')
 
       app.RemovePlayerStateChangeHandler(self.OnPlayerStateChanged)
diff --git a/cobalt/media_integration_tests/test_app.py b/cobalt/media_integration_tests/test_app.py
index 8503dd5..b1fac98 100644
--- a/cobalt/media_integration_tests/test_app.py
+++ b/cobalt/media_integration_tests/test_app.py
@@ -59,7 +59,7 @@
 
   # CVal returns unicode, so we need to decode them before using.
   if default_value_type in (bool, int, float):
-    if value_type in (str, unicode):
+    if value_type in (str, unicode):  # pylint: disable=undefined-variable
       try:
         # Try to parse numbers and booleans.
         parsed_value = json.loads(value)
@@ -69,10 +69,10 @@
       return parsed_value
 
   elif default_value_type is str:
-    if value_type == unicode:
+    if value_type == unicode:  # pylint: disable=undefined-variable
       return value.encode('utf-8')
 
-  raise NotImplementedError('Convertion from (%s) to (%s) is not suppoted.' %
+  raise NotImplementedError('Convertion from (%s) to (%s) is not supported.' %
                             (value_type, default_value_type))
 
 
@@ -253,7 +253,11 @@
       const primary_pipeline_keys = h5vcc.cVal.keys().filter(key =>
         key.startsWith("Media.Pipeline.") &&
         key.endsWith("MaxVideoCapabilities") &&
-        h5vcc.cVal.getValue(key).length === 0);
+        h5vcc.cVal.getValue(key).length === 0 &&
+        h5vcc.cVal.getValue(key.replace('MaxVideoCapabilities', 'Started'))
+            === 'true' &&
+        h5vcc.cVal.getValue(key.replace('MaxVideoCapabilities', 'Stopped'))
+            === 'false');
       if (primary_pipeline_keys.length == 0) {
         return "null";
       }
@@ -304,15 +308,15 @@
   PLAYING = 2
 
   @staticmethod
-  def FromString(str):
-    if str == 'none':
+  def FromString(string):
+    if string == 'none':
       return 0
-    if str == 'paused':
+    if string == 'paused':
       return 1
-    if str == 'playing':
+    if string == 'playing':
       return 2
     raise NotImplementedError(
-        '"%s" is not a valid media session playback state.' % str)
+        '"%s" is not a valid media session playback state.' % string)
 
 
 class MediaSessionState():
@@ -483,6 +487,7 @@
       self._NotifyHandlersOnStateChanged()
 
 
+# pylint: disable=bad-string-format-type
 class AdsState(int):
   """Set of ads states. The numeric values are used in ads state query."""
   NONE = 0
@@ -525,7 +530,7 @@
   def __enter__(self):
     try:
       self.runner.__enter__()
-    except Exception:
+    except Exception:  # pylint: disable=broad-except
       # Potentially from thread.interrupt_main(). No need to start
       # query thread.
       return self
@@ -542,8 +547,8 @@
   def ExecuteScript(self, script):
     try:
       result = self.runner.webdriver.execute_script(script)
-    except Exception as e:
-      raise RuntimeError('Fail to excute script with error (%s).' % (str(e)))
+    except Exception as e:  # pylint: disable=broad-except
+      raise RuntimeError('Fail to execute script with error (%s).' % (str(e)))
     return result
 
   def _OnNewLogLine(self, line):
@@ -642,12 +647,11 @@
         js_code = self._GeneratePeriodicQueryJsCode(local_is_queries_changed,
                                                     local_periodic_queries)
         result = self.ExecuteScript(js_code)
-        for query_name in local_periodic_queries.keys():
-          if not result.get(query_name):
+        for name, query in local_periodic_queries.items():
+          if not result.get(name):
             raise RuntimeError(
                 'There\'s something wrong in the queries result.')
-          local_periodic_queries[query_name][1](self, query_name,
-                                                result[query_name])
+          query[1](self, name, result[name])
 
       time.sleep(PERIODIC_QUERIES_INTERVAL_SECONDS)
 
@@ -716,7 +720,7 @@
                        active_element_label_attr)
           self.SendKeys(webdriver_keys.Keys.ENTER)
         else:
-          logging.info('Current selected item is "Add acount", move to next'
+          logging.info('Current selected item is "Add account", move to next'
                        ' item.')
           self.SendKeys(webdriver_keys.Keys.ARROW_RIGHT)
         return False
@@ -756,10 +760,7 @@
         lambda _app: _app.PlayerState().pipeline_state.identifier !=
         current_identifier, timeout)
 
-  """
-    The return values of the query, exact mapping of AdsState defined earlier
-    in this file.
-  """
+  # The return values exact mapping of AdsState defined earlier in this file.
   _GET_ADS_STATE_QUERY_JS_CODE = """
     if (document.getElementsByTagName("YTLR-AD-PREVIEW-RENDERER").length > 0) {
       return 1;
diff --git a/cobalt/network_bridge/BUILD.gn b/cobalt/network_bridge/BUILD.gn
index 4c83d97..8c40423 100644
--- a/cobalt/network_bridge/BUILD.gn
+++ b/cobalt/network_bridge/BUILD.gn
@@ -20,4 +20,6 @@
     "net_poster.cc",
     "net_poster.h",
   ]
+
+  deps = [ "//base" ]
 }
diff --git a/cobalt/renderer/BUILD.gn b/cobalt/renderer/BUILD.gn
new file mode 100644
index 0000000..528802e
--- /dev/null
+++ b/cobalt/renderer/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright 2021 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.
+
+static_library("default_options") {
+  sources = [ "//cobalt/renderer/get_default_rasterizer_for_platform.cc" ]
+  deps = [ "//starboard:starboard_headers_only" ]
+}
diff --git a/cobalt/renderer/rasterizer/egl/shaders/BUILD.gn b/cobalt/renderer/rasterizer/egl/shaders/BUILD.gn
new file mode 100644
index 0000000..c02d283
--- /dev/null
+++ b/cobalt/renderer/rasterizer/egl/shaders/BUILD.gn
@@ -0,0 +1,84 @@
+# Copyright 2021 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.
+
+_output_dir = "$root_gen_dir/egl"
+_shader_impl_header = "$_output_dir/generated_shader_impl.h"
+_shader_impl_source = "$_output_dir/generated_shader_impl.cc"
+
+action("create_shader_classes") {
+  shader_sources = [
+    "fragment_color.glsl",
+    "fragment_color_blur.glsl",
+    "fragment_color_blur_rrects.glsl",
+    "fragment_color_include.glsl",
+    "fragment_color_texcoord.glsl",
+    "fragment_color_texcoord_yuv3.glsl",
+    "fragment_opacity_texcoord1d.glsl",
+    "fragment_rcorner2_color.glsl",
+    "fragment_rcorner_color.glsl",
+    "fragment_rcorner_texcoord_color.glsl",
+    "fragment_rcorner_texcoord_color_yuv3.glsl",
+    "fragment_texcoord.glsl",
+    "fragment_texcoord_yuv3.glsl",
+    "function_gaussian_integral.inc",
+    "function_is_outside_rcorner.inc",
+    "image_sampler_rgba.inc",
+    "image_sampler_rgba_with_clamp.inc",
+    "image_sampler_yuv3.inc",
+    "image_sampler_yuv3_with_clamp.inc",
+    "vertex_color.glsl",
+    "vertex_color_offset.glsl",
+    "vertex_color_texcoord.glsl",
+    "vertex_offset.glsl",
+    "vertex_offset_rcorner.glsl",
+    "vertex_rcorner.glsl",
+    "vertex_rcorner2.glsl",
+    "vertex_rcorner_texcoord.glsl",
+    "vertex_texcoord.glsl",
+  ]
+
+  input_shader_files_file = "${target_gen_dir}/generate_shader_impl_inputs.tmp"
+  write_file(input_shader_files_file,
+             rebase_path(shader_sources, root_build_dir))
+
+  script = "generate_shader_impl.py"
+
+  inputs = [ input_shader_files_file ]
+
+  outputs = [
+    _shader_impl_header,
+    _shader_impl_source,
+  ]
+
+  args = rebase_path(outputs, root_build_dir) +
+         [ rebase_path(input_shader_files_file, root_build_dir) ]
+}
+
+config("shaders_config") {
+  include_dirs = [ "$target_gen_dir" ]
+}
+
+static_library("shaders") {
+  sources = [
+    _shader_impl_header,
+    _shader_impl_source,
+  ]
+
+  public_configs = [ ":shaders_config" ]
+
+  deps = [
+    ":create_shader_classes",
+    "//starboard:starboard_headers_only",
+  ]
+}
diff --git a/cobalt/renderer/rasterizer/egl/shaders/generate_shader_impl.py b/cobalt/renderer/rasterizer/egl/shaders/generate_shader_impl.py
index 90505cc..f1f684d 100644
--- a/cobalt/renderer/rasterizer/egl/shaders/generate_shader_impl.py
+++ b/cobalt/renderer/rasterizer/egl/shaders/generate_shader_impl.py
@@ -96,14 +96,13 @@
 
   with open(filename, 'rb') as f:
     # Read the file and strip comments.
-    file_contents = f.read()
+    file_contents_bytes = f.read()
+    file_contents = file_contents_bytes.decode('utf-8')
     file_contents = re.sub(r'/\*.*?\*/', '', file_contents, flags=re.DOTALL)
     file_contents = re.sub(r'(\s)*//.*', '', file_contents)
-
     # Parse #include directives. This must be done after stripping comments as
     # it's possible to have multi-line comments that encompass #includes.
     lines = [HandleInclude(x) for x in file_contents.splitlines()]
-
     # Join non-empty lines.
     return '\n'.join(filter(None, lines))
 
@@ -114,14 +113,14 @@
 
   def GetChunk(contents, chunk_size):
     # Yield successive |chunk_size|-sized chunks from |contents|.
-    for i in xrange(0, len(contents), chunk_size):
+    for i in range(0, len(contents), chunk_size):
       yield contents[i:i + chunk_size]
 
   # Break up the data into chunk sizes such that the produced output lines
   # representing the data in the .h file are less than 80 characters long.
   length_of_output_byte_string = 6
   max_characters_per_line = 80
-  chunk_size = max_characters_per_line / length_of_output_byte_string
+  chunk_size = int(max_characters_per_line / length_of_output_byte_string)
 
   # Convert each byte to ASCII hexadecimal form and output that to the C++
   # header file, line-by-line.
diff --git a/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md b/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md
index 8fc180c..76eda31 100644
--- a/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md
+++ b/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md
@@ -108,7 +108,7 @@
 because it makes rebasing to future versions of Cobalt more difficult but has
 been possible because porters have historically built **both** Cobalt and
 Starboard. However, Cobalt is moving toward Evergreen
-(<a href="https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/doc/evergreen/cobalt_evergreen_overview.md">overview</a>),
+(<a href="https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/doc/evergreen/cobalt_evergreen_overview.md">overview</a>),
 an architecture that enables automatic Cobalt updates on devices by separating a
 Google-built, Cobalt core shared library from the partner-built Starboard layer
 and Cobalt loader app. Because Cobalt core code is built by Google, custom
diff --git a/cobalt/site/docs/development/setup-android.md b/cobalt/site/docs/development/setup-android.md
index f999d81..b2ddb55 100644
--- a/cobalt/site/docs/development/setup-android.md
+++ b/cobalt/site/docs/development/setup-android.md
@@ -224,9 +224,7 @@
 run that on a device, it needs to be packaged into an APK, which is done by the
 associated "deploy" target (e.g. nplb_deploy). The Starboard test runner does
 all this for you, so just use that to build and run tests. For example, to
-build and run "devel" NPLB on an ARM64 device, from the top 'src' directory
-(if you've unnested the 'src' directory, just run this from your top-level
-directory):
+build and run "devel" NPLB on an ARM64 device, from the top-level directory:
 
 ```
 starboard/tools/testing/test_runner.py -p android-arm64 -c devel -b -r -t nplb
diff --git a/cobalt/site/docs/development/setup-linux.md b/cobalt/site/docs/development/setup-linux.md
index 014394d..288711b 100644
--- a/cobalt/site/docs/development/setup-linux.md
+++ b/cobalt/site/docs/development/setup-linux.md
@@ -57,23 +57,17 @@
 
 ### Set up Developer Tools
 
-Cobalt's developer tools require a different file structure which we are in the
-process of moving to. For now, if you want to use these tools, you must unnest
-the `src/` directory like so:
+1.  Enter your new `cobalt` directory:
 
-```
-$ cd cobalt
-$ mv src/* ./
-$ mv src/.* ./
-```
+    ```
+    $ cd cobalt
+    ```
 
-Once you do that, you'll be able to follow the following two steps to have C++
-and Python linting and formatting as well as other helpful checks enabled. Keep
-in mind that after doing this, you'll want to run following commands in the
-top-level directory instead of the `src/` subdirectory.
-
-Git will track this as a large change, we recommend that you create a commit
-for it and rebase that commit of our upstream continuously for now.
+<aside class="note">
+<b>Note:</b> Pre-commit is only available on branches later than 22.lts.1+,
+including trunk. The below commands will fail on 22.lts.1+ and earlier branches.
+For earlier branches, run `cd src` and move on to the next section.
+</aside>
 
 1.  Create a Python 3 virtual environment for working on Cobalt (feel free to use `virtualenvwrapper` instead):
 
@@ -87,15 +81,14 @@
 
     ```
     $ pre-commit install -t post-checkout -t pre-commit -t pre-push --allow-missing-config
-    $ git checkout -b <my-branch-name> origin/COBALT
+    $ git checkout -b <my-branch-name> origin/master
     ```
 
 ## Build and Run Cobalt
 
-1.  Build the code by navigating to the `src` directory in your new
-    `cobalt` directory and running the following command. You must
-    specify a platform when running this command. On Ubuntu Linux, the
-    canonical platform is `linux-x64x11`.
+1.  Build the code running the following command in the top-level `cobalt`
+    directory. You must specify a platform when running this command. On Ubuntu
+    Linux, the canonical platform is `linux-x64x11`.
 
     You can also use the `-C` command-line flag to specify a `build_type`.
     Valid build types are `debug`, `devel`, `qa`, and `gold`. If you
@@ -109,7 +102,7 @@
     <aside class="note"><b>Important:</b> You need to rerun gyp_cobalt every
     time a change is made to a `.gyp` file.</aside>
 
-1.  Compile the code from the `src/` directory:
+1.  Compile the code from the `cobalt/` directory:
 
     ```
     $ ninja -C out/<platform>_<build_type> <target_name>
@@ -155,7 +148,7 @@
 
     The flags in the following table are frequently used, and the full set
     of flags that this command supports are in <code><a
-    href="https://cobalt.googlesource.com/cobalt/+/master/src/cobalt/browser/switches.cc">cobalt/browser/switches.cc</a></code>.
+    href="https://cobalt.googlesource.com/cobalt/+/master/cobalt/browser/switches.cc">cobalt/browser/switches.cc</a></code>.
 
     <table class="details responsive">
       <tr>
diff --git a/cobalt/site/docs/development/setup-raspi.md b/cobalt/site/docs/development/setup-raspi.md
index 0e58a7d..48ca4cc 100644
--- a/cobalt/site/docs/development/setup-raspi.md
+++ b/cobalt/site/docs/development/setup-raspi.md
@@ -106,19 +106,14 @@
 
 ## Build, install, and run Cobalt for Raspberry Pi
 
-<aside class="note">
-<b>Note:</b> If you've unnested the 'src' directory, build and compile the code
-in your top-level checkout of Cobalt instead of the 'src' subdirectory.
-</aside>
-
-1.  Build the code by navigating to the src directory in your cobalt directory and run the
-    following command :
+1.  Build the code by navigating to the `cobalt` directory and run the
+    following command:
 
     ```
     $ cobalt/build/gyp_cobalt raspi-2
     ```
 
-1.  Compile the code from the `src/` directory:
+1.  Compile the code from the `cobalt/` directory:
 
     ```
     $ ninja -C out/raspi-2_debug cobalt
diff --git a/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md b/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md
index e4b9c0a..3a9c87e 100644
--- a/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md
+++ b/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md
@@ -83,7 +83,7 @@
 ```
 
 You also may need to remove default configs. The default configs are listed in
-[BUILDCONFIG.gn](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/build/config/BUILDCONFIG.gn).
+[BUILDCONFIG.gn](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/config/BUILDCONFIG.gn).
 You remove a config like so:
 
 ```
@@ -149,7 +149,7 @@
 
 Instead of implicitly searching directories for certain files like GYP did, we
 explicitly enumerate our ports and their locations.
-[platforms.gni](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/build/platforms.gni)
+[platforms.gni](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/platforms.gni)
 contains all of this information, and you'll need to add your platform to that
 list following the same format.
 
@@ -177,10 +177,10 @@
 
 You may define a toolchain from scratch following the [reference][gn_toolchain],
 or you can use the
-[gcc/clang templates](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/build/toolchain/gcc_toolchain.gni)
+[gcc/clang templates](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/build/toolchain/gcc_toolchain.gni)
 provided. Almost all of the reference platforms use these templates, so look to
 those as examples for how to use it correctly. Here's the linux-x64x11
-[toolchain/BUILD.gn file](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/linux/x64x11/toolchain/BUILD.gn).
+[toolchain/BUILD.gn file](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/linux/x64x11/toolchain/BUILD.gn).
 
 ## Checking Your Migration
 
@@ -206,7 +206,7 @@
 
 If this was equivalent to a GYP target, you can compare the ninja compilation
 databases by using
-[format_ninja.py](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/tools/format_ninja.py)
+[format_ninja.py](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/tools/format_ninja.py)
 and a comparison tool, i.e. [meld](https://meldmerge.org/). This will allow you
 to see any changes in commands, i.e. with flags or otherwise.
 
diff --git a/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md b/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md
index 38d8477..83f3dfa 100644
--- a/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md
+++ b/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md
@@ -19,6 +19,7 @@
 `has_drm_system_extension`                | `is_internal_build` (true/false)                     | (global)
 `has_cdm`                                 | `is_internal_build` (true/false)                     | (global)
 `has_private_system_properties`           | `is_internal_build` (true/false)                     | (global)
+`sb_pedantic_warnings` (0/1)              | `has_pedantic_warnings` (true/false)                 | (global, see "Compiler Options" note)
 `sb_deploy_output_dir`                    | `sb_install_output_dir`                              | `//starboard/build/config/base_configuration.gni`
 `sb_evergreen` (0/1)                      | `sb_is_evergreen` (true/false)                       | `//starboard/build/config/base_configuration.gni`
 `sb_evergreen_compatible` (0/1)           | `sb_is_evergreen_compatible` (true/false)            | `//starboard/build/config/base_configuration.gni`
@@ -42,10 +43,8 @@
 `optimize_target_for_speed` (1) | `"//starboard/build/config:speed"`                    | Optimizations
 `compiler_flags_*_speed`        | `speed_config_path`                                   | Optimizations
 `compiler_flags_*_size`         | `size_config_path`                                    | Optimizations
-`sb_pedantic_warnings`          | `pedantic_warnings_config_path`                       | Compiler Options
-`sb_pedantic_warnings`          | `no_pedantic_warnings_config_path`                    | Compiler Options
 
-Notes:
+## Notes:
 
 *   *Starboard Implementation:* If your platform defined
     `STARBOARD_IMPLENTATION` in its implementation, you would now add the above
@@ -60,13 +59,12 @@
     correct ones for `speed_config_path` and `size_config_path` in your
     platform's `platform_configuration/configuration.gni` file.
 
-*   *Compiler Options:* Cobalt compiles some targets with stricter settings
-    than others, depending on the platform. Before these targets would opt into
-    the stricter settings by settings `sb_pedantic_warnings: 1` in their
-    `variables` section. Now they will add the appropriate config like so:
-    `configs += [ "//starboard/build/config:pedantic_warnings" ]` and remove
-    the default: `configs -= [ "//starboard/build/config:no_pedantic_warnings"
-    ]`. The additional config that is used to compile these targets is
-    specified with the `pedantic_warnings_config_path` and
-    `no_pedantic_warnings_config_path` variables in your platform's
-    `platform_configuration/configuration.gni` file.
+*   *Compiler Options:* Cobalt compiles some targets with stricter,
+    platform-dependent settings than others. Before these targets would opt into
+    the stricter settings by setting `sb_pedantic_warnings: 1` in their
+    `variables` section. Now targets will be compiled with pedantic warnings if
+    the target sets `has_pedantic_warnings=true`. The additional config that is
+    used to compile these targets is specified with the
+    `pedantic_warnings_config_path` and `no_pedantic_warnings_config_path`
+    variables in your platform's `platform_configuration/configuration.gni`
+    file.
diff --git a/cobalt/site/docs/gen/starboard/doc/c99.md b/cobalt/site/docs/gen/starboard/doc/c99.md
index ad2f0c7..433e1d5 100644
--- a/cobalt/site/docs/gen/starboard/doc/c99.md
+++ b/cobalt/site/docs/gen/starboard/doc/c99.md
@@ -35,13 +35,63 @@
 * tolower
 * toupper
 ### <math.h>
+* acos
+* acosf
+* asin
+* asinf
+* atan
+* atan2
+* atan2f
+* atanf
+* cbrt
+* cbrtf
+* ceil
+* ceilf
+* cos
+* cosf
+* div
+* erf
+* erff
+* exp
+* expf
+* exp2f
 * fabs
 * floor
+* floorf
+* fmod
+* fmodf
+* frexp
 * isfinite
 * isnan
+* labs
+* llround
+* llroundf
+* log
+* log10
+* log10f
+* log2
+* log2f
+* ldexp
+* lrint
+* lrintf
+* modf
+* nearbyint
+* nearbyintf
+* nextafter
+* nextafterf
 * pow
+* powf
+* round
+* roundf
+* scalbn
+* sin
+* sinf
 * sqrt
 * sqrtf
+* tan
+* tanf
+* trunc
+* truncf
 ### <stdlib.h>
 * abs
 * atoi
@@ -72,6 +122,9 @@
 * strrchr
 * strstr
 * strspn
+### <tgmath.h>
+* ceill
+* logl
 ### <wchar.h>
 * wcscat
 * wcschr
diff --git a/cobalt/site/docs/starboard/porting.md b/cobalt/site/docs/starboard/porting.md
index aee5b59..c6e635a 100644
--- a/cobalt/site/docs/starboard/porting.md
+++ b/cobalt/site/docs/starboard/porting.md
@@ -71,9 +71,9 @@
 Add the following directories to the source tree for the `<family-name>`
 that you selected in step 1:
 
-*   `src/third_party/starboard/<family-name>/`
+*   `third_party/starboard/<family-name>/`
 
-*   `src/third_party/starboard/<family-name>/shared/`
+*   `third_party/starboard/<family-name>/shared/`
 
     This subdirectory contains code that is shared between architectures
     within a product family. For example, if BobBox devices run on many
@@ -82,15 +82,15 @@
     Starboard function implementation, BobCo can put that function in the
     `shared` directory to make it accessible in every binary variant.
 
-*   `src/third_party/starboard/<family-name>/<binary-variant>/`
+*   `third_party/starboard/<family-name>/<binary-variant>/`
 
     You should create one directory for _each_ `<binary-variant>`. So, for
     example, BobCo could create the following directories:
 
-    *   `src/third_party/starboard/bobbox/shared/`
-    *   `src/third_party/starboard/bobbox/armeb/`
-    *   `src/third_party/starboard/bobbox/armel/`
-    *   `src/third_party/starboard/bobbox/armel/gles/`
+    *   `third_party/starboard/bobbox/shared/`
+    *   `third_party/starboard/bobbox/armeb/`
+    *   `third_party/starboard/bobbox/armel/`
+    *   `third_party/starboard/bobbox/armel/gles/`
 
 Again, functions that work for all of the configurations would go in the
 `shared` directory. Functions that work for all little-endian devices would go
@@ -110,7 +110,7 @@
 *   `thread_types_public.h`
 
 We recommend that you copy the files from the Stub reference implementation,
-located at `src/starboard/stub/` to your `binary-variant` directories.
+located at `starboard/stub/` to your `binary-variant` directories.
 In this approach, you will essentially start with a clean slate of stub
 interfaces that need to be modified to work with your platform.
 
@@ -122,8 +122,8 @@
 command for each `binary-variant` directory:
 
 ```sh
-cp -R src/starboard/stub
-      src/third_party/starboard/<family-name>/<binary-variant>
+cp -R starboard/stub
+      third_party/starboard/<family-name>/<binary-variant>
 ```
 
 After copying these files, you should be able to compile Cobalt and link it
@@ -304,20 +304,20 @@
 The `starboard_platform.gyp` file points to all of the source files included
 in your new Starboard implementation. If you are starting with a copy of the
 Stub implementation, then that file will initially include a lot of files
-from the `src/starboard/shared/stub/` directory. Similarly, if you are starting
+from the `starboard/shared/stub/` directory. Similarly, if you are starting
 starting with a copy of the Desktop Linux port, then that file will initially
-point to files in the `src/starboard/shared/posix` directory.
+point to files in the `starboard/shared/posix` directory.
 
 The modules are defined so that each one has a set of functions, and each
 function is defined in its own file with a consistent naming convention.
 For example, the `SbSystemBreakIntoDebugger()` function is defined in the
 `system_break_into_debugger.cc` file. The list of files in the
-`src/starboard/shared/stub/` directory represents an authoritative list of
+`starboard/shared/stub/` directory represents an authoritative list of
 supported functions.
 
 Function-by-function and module-by-module, you can now replace stub
 implementations with either custom implementations or with other ported
-implementations from the `src/starboard/shared/` directory until you have
+implementations from the `starboard/shared/` directory until you have
 gone through all of the modules. As you do, update the
 `starboard_platform.gyp` file to identify the appropriate source files.
 
diff --git a/cobalt/site/docs/starboard/testing.md b/cobalt/site/docs/starboard/testing.md
index fd2f502..16eea52 100644
--- a/cobalt/site/docs/starboard/testing.md
+++ b/cobalt/site/docs/starboard/testing.md
@@ -21,11 +21,11 @@
 
 ## Test Organization
 
-NPLB tests can be found in the `src/starboard/nplb/` directory and are broken
+NPLB tests can be found in the `starboard/nplb/` directory and are broken
 out into files by Starboard module and function:
 
 ```
-src/starboard/nplb/<module>_<function>_test.cc
+starboard/nplb/<module>_<function>_test.cc
 ```
 
 Although each test may incidentally test other functions, there is an attempt
@@ -36,4 +36,4 @@
 For example, the `SbSocketSendTo` and `SbSocketReceiveFrom` are tested
 together, ensuring that the API is self-consistent on both sides of a
 connection. Therefore, only one set of tests exist to cover those use cases,
-in `src/starboard/nplb/socket_receive_from_test.cc`.
+in `starboard/nplb/socket_receive_from_test.cc`.
diff --git a/cobalt/test/BUILD.gn b/cobalt/test/BUILD.gn
new file mode 100644
index 0000000..eb22794
--- /dev/null
+++ b/cobalt/test/BUILD.gn
@@ -0,0 +1,23 @@
+# Copyright 2021 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.
+
+static_library("run_all_unittests") {
+  testonly = true
+  sources = [ "run_all_unittests.cc" ]
+  deps = [
+    "//base/test:test_support",
+    "//cobalt/base",
+    "//testing/gtest",
+  ]
+}
diff --git a/components/update_client/crx_downloader_unittest.cc b/components/update_client/crx_downloader_unittest.cc
index e0cb5f9..1ff4634 100644
--- a/components/update_client/crx_downloader_unittest.cc
+++ b/components/update_client/crx_downloader_unittest.cc
@@ -22,6 +22,7 @@
 #include "components/update_client/utils.h"
 #include "net/base/net_errors.h"
 #if defined(STARBOARD)
+#include "components/update_client/test_configurator.h"
 #include "net/url_request/test_url_request_interceptor.h"
 #include "net/url_request/url_request_test_util.h"
 #else
@@ -72,17 +73,20 @@
 
   void DownloadProgress(int crx_context);
 
+#if !defined(STARBOARD)
   int GetInterceptorCount() { return interceptor_count_; }
 
   void AddResponse(const GURL& url,
                    const base::FilePath& file_path,
                    int net_error);
-
+#endif
  protected:
   std::unique_ptr<CrxDownloader> crx_downloader_;
-
+#if defined(STARBOARD)
+  std::unique_ptr<GetInterceptor> get_interceptor_;
+#else
   network::TestURLLoaderFactory test_url_loader_factory_;
-
+#endif
   CrxDownloader::DownloadCallback callback_;
   CrxDownloader::ProgressCallback progress_callback_;
 
@@ -94,16 +98,22 @@
   // These members are updated by DownloadProgress.
   int num_progress_calls_;
 
+#if !defined(STARBOARD)
   // Accumulates the number of loads triggered.
   int interceptor_count_ = 0;
+#endif
 
   // A magic value for the context to be used in the tests.
   static const int kExpectedContext = 0xaabb;
 
  private:
   base::test::ScopedTaskEnvironment scoped_task_environment_;
+#if defined(STARBOARD)
+  scoped_refptr<net::TestURLRequestContextGetter> context_;
+#else
   scoped_refptr<network::SharedURLLoaderFactory>
       test_shared_url_loader_factory_;
+#endif
   base::OnceClosure quit_closure_;
 };
 
@@ -121,18 +131,40 @@
       num_progress_calls_(0),
       scoped_task_environment_(
           base::test::ScopedTaskEnvironment::MainThreadType::IO),
+#if defined(STARBOARD)
+      context_(base::MakeRefCounted<net::TestURLRequestContextGetter>(
+          base::ThreadTaskRunnerHandle::Get())) {
+}
+
+CrxDownloaderTest::~CrxDownloaderTest() {
+  context_ = nullptr;
+
+  // The GetInterceptor requires the message loop to run to destruct correctly.
+  get_interceptor_.reset();
+  RunThreadsUntilIdle();
+}
+#else
       test_shared_url_loader_factory_(
           base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-              &test_url_loader_factory_)) {}
+              &test_url_loader_factory_)) {
+}
 
 CrxDownloaderTest::~CrxDownloaderTest() {}
-
+#endif
 void CrxDownloaderTest::SetUp() {
   num_download_complete_calls_ = 0;
   download_complete_result_ = CrxDownloader::Result();
   num_progress_calls_ = 0;
 
-  // Do not use the background downloader in these tests.
+// Do not use the background downloader in these tests.
+#if defined(STARBOARD)
+  auto config = base::MakeRefCounted<TestConfigurator>();
+  crx_downloader_ = CrxDownloader::Create(false, config);
+  crx_downloader_->set_progress_callback(progress_callback_);
+
+  get_interceptor_ = std::make_unique<GetInterceptor>(
+      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get());
+#else
   crx_downloader_ = CrxDownloader::Create(
       false, base::MakeRefCounted<NetworkFetcherChromiumFactory>(
                  test_shared_url_loader_factory_));
@@ -140,6 +172,7 @@
 
   test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
       [&](const network::ResourceRequest& request) { interceptor_count_++; }));
+#endif
 }
 
 void CrxDownloaderTest::TearDown() {
@@ -162,7 +195,7 @@
 void CrxDownloaderTest::DownloadProgress(int crx_context) {
   ++num_progress_calls_;
 }
-
+#if !defined(STARBOARD)
 void CrxDownloaderTest::AddResponse(const GURL& url,
                                     const base::FilePath& file_path,
                                     int net_error) {
@@ -182,7 +215,7 @@
       url, network::ResourceResponseHead(), std::string(),
       network::URLLoaderCompletionStatus(net_error));
 }
-
+#endif
 void CrxDownloaderTest::RunThreads() {
   base::RunLoop runloop;
   quit_closure_ = runloop.QuitClosure();
@@ -236,14 +269,19 @@
       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+  get_interceptor_->SetResponse(expected_crx_url, test_file);
+#else
   AddResponse(expected_crx_url, test_file, net::OK);
-
+#endif
   crx_downloader_->StartDownloadFromUrl(
       expected_crx_url, std::string(hash_jebg), std::move(callback_));
   RunThreads();
-
+#if defined(STARBOARD)
+  EXPECT_EQ(1, get_interceptor_->GetHitCount());
+#else
   EXPECT_EQ(1, GetInterceptorCount());
-
+#endif
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(0, download_complete_result_.error);
@@ -262,17 +300,22 @@
       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+  get_interceptor_->SetResponse(expected_crx_url, test_file);
+#else
   AddResponse(expected_crx_url, test_file, net::OK);
-
+#endif
   crx_downloader_->StartDownloadFromUrl(
       expected_crx_url,
       std::string(
           "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9"),
       std::move(callback_));
   RunThreads();
-
+#if defined(STARBOARD)
+  EXPECT_EQ(1, get_interceptor_->GetHitCount());
+#else
   EXPECT_EQ(1, GetInterceptorCount());
-
+#endif
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(static_cast<int>(CrxDownloaderError::BAD_HASH),
@@ -289,8 +332,11 @@
       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+  get_interceptor_->SetResponse(expected_crx_url, test_file);
+#else
   AddResponse(expected_crx_url, test_file, net::OK);
-
+#endif
   std::vector<GURL> urls;
   urls.push_back(expected_crx_url);
   urls.push_back(expected_crx_url);
@@ -299,8 +345,11 @@
                                  std::move(callback_));
   RunThreads();
 
+#if defined(STARBOARD)
+  EXPECT_EQ(1, get_interceptor_->GetHitCount());
+#else
   EXPECT_EQ(1, GetInterceptorCount());
-
+#endif
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(0, download_complete_result_.error);
@@ -320,9 +369,14 @@
       GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+  get_interceptor_->SetResponse(expected_crx_url, test_file);
+  get_interceptor_->SetResponse(no_file_url,
+                                base::FilePath(FILE_PATH_LITERAL("no-file")));
+#else
   AddResponse(expected_crx_url, test_file, net::OK);
   AddResponse(no_file_url, base::FilePath(), net::ERR_FILE_NOT_FOUND);
-
+#endif
   std::vector<GURL> urls;
   urls.push_back(no_file_url);
   urls.push_back(expected_crx_url);
@@ -331,8 +385,11 @@
                                  std::move(callback_));
   RunThreads();
 
+#if defined(STARBOARD)
+  EXPECT_EQ(2, get_interceptor_->GetHitCount());
+#else
   EXPECT_EQ(2, GetInterceptorCount());
-
+#endif
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(0, download_complete_result_.error);
@@ -365,8 +422,14 @@
       GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+  get_interceptor_->SetResponse(expected_crx_url, test_file);
+  get_interceptor_->SetResponse(no_file_url,
+                                base::FilePath(FILE_PATH_LITERAL("no-file")));
+#else
   AddResponse(expected_crx_url, test_file, net::OK);
   AddResponse(no_file_url, base::FilePath(), net::ERR_FILE_NOT_FOUND);
+#endif
 
   std::vector<GURL> urls;
   urls.push_back(expected_crx_url);
@@ -376,8 +439,11 @@
                                  std::move(callback_));
   RunThreads();
 
+#if defined(STARBOARD)
+  EXPECT_EQ(1, get_interceptor_->GetHitCount());
+#else
   EXPECT_EQ(1, GetInterceptorCount());
-
+#endif
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(0, download_complete_result_.error);
@@ -396,7 +462,12 @@
   const GURL expected_crx_url =
       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
+#if defined(STARBOARD)
+  get_interceptor_->SetResponse(expected_crx_url,
+                                base::FilePath(FILE_PATH_LITERAL("no-file")));
+#else
   AddResponse(expected_crx_url, base::FilePath(), net::ERR_FILE_NOT_FOUND);
+#endif
 
   std::vector<GURL> urls;
   urls.push_back(expected_crx_url);
@@ -406,8 +477,11 @@
                                  std::move(callback_));
   RunThreads();
 
+#if defined(STARBOARD)
+  EXPECT_EQ(2, get_interceptor_->GetHitCount());
+#else
   EXPECT_EQ(2, GetInterceptorCount());
-
+#endif
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_NE(0, download_complete_result_.error);
diff --git a/components/update_client/net/network_impl_cobalt.cc b/components/update_client/net/network_impl_cobalt.cc
index 02acd0f..088dc25 100644
--- a/components/update_client/net/network_impl_cobalt.cc
+++ b/components/update_client/net/network_impl_cobalt.cc
@@ -53,7 +53,7 @@
 }
 
 // Returns the integral value of a header of the server response or -1 if
-// if the header is not available or a conversion error has occured.
+// if the header is not available or a conversion error has occurred.
 int64_t GetInt64Header(const net::HttpResponseHeaders* headers,
                        const char* header_name) {
   if (!headers) {
@@ -132,6 +132,13 @@
   url_fetcher_->Start();
 }
 
+void NetworkFetcherCobaltImpl::CancelDownloadToFile() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  SB_LOG(INFO) << "Canceling DownloadToFile";
+  url_fetcher_.reset();
+}
+
 void NetworkFetcherCobaltImpl::OnURLFetchResponseStarted(
     const net::URLFetcher* source) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/components/update_client/net/network_impl_cobalt.h b/components/update_client/net/network_impl_cobalt.h
index c30f3ad..757cc7e 100644
--- a/components/update_client/net/network_impl_cobalt.h
+++ b/components/update_client/net/network_impl_cobalt.h
@@ -71,6 +71,7 @@
                       ProgressCallback progress_callback,
                       DownloadToFileCompleteCallback
                           download_to_file_complete_callback) override;
+  void CancelDownloadToFile() override;
 
   // net::URLFetcherDelegate interface.
   void OnURLFetchResponseStarted(const net::URLFetcher* source) override;
diff --git a/components/update_client/test_configurator.h b/components/update_client/test_configurator.h
index c3fbda1..6a9e5eb 100644
--- a/components/update_client/test_configurator.h
+++ b/components/update_client/test_configurator.h
@@ -85,7 +85,7 @@
  public:
   TestConfigurator();
 
-  // Overrrides for Configurator.
+  // Overrides for Configurator.
   int InitialDelay() const override;
   int NextCheckDelay() const override;
   int OnDemandDelay() const override;
@@ -127,8 +127,14 @@
   void SetAppGuid(const std::string& app_guid);
 
 #if defined(STARBOARD)
+  // TODO: add unit tests for updater channels and status
   void SetChannel(const std::string& channel) override {}
   void CompareAndSwapChannelChanged(int old_value, int new_value) override {}
+  std::string GetUpdaterStatus() const override { return ""; }
+  void SetUpdaterStatus(const std::string& status) override {}
+
+  std::string GetPreviousUpdaterStatus() const override { return ""; }
+  void SetPreviousUpdaterStatus(const std::string& status) override {}
 #else
   network::TestURLLoaderFactory* test_url_loader_factory() {
     return &test_url_loader_factory_;
diff --git a/components/update_client/update_client.gyp b/components/update_client/update_client.gyp
index 3b9edd7..efd729d 100644
--- a/components/update_client/update_client.gyp
+++ b/components/update_client/update_client.gyp
@@ -148,7 +148,7 @@
       'sources': [
         'component_unpacker_unittest.cc',
         # TODO: enable the tests commented out
-        # 'crx_downloader_unittest.cc',
+        'crx_downloader_unittest.cc',
         'persisted_data_unittest.cc',
         'ping_manager_unittest.cc',
         'protocol_parser_json_unittest.cc',
diff --git a/content/browser/speech/BUILD.gn b/content/browser/speech/BUILD.gn
new file mode 100644
index 0000000..15390fd
--- /dev/null
+++ b/content/browser/speech/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2021 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.
+
+static_library("speech") {
+  sources = [
+    "audio_buffer.cc",
+    "audio_buffer.h",
+    "chunked_byte_buffer.cc",
+    "chunked_byte_buffer.h",
+    "endpointer/endpointer.cc",
+    "endpointer/endpointer.h",
+    "endpointer/energy_endpointer.cc",
+    "endpointer/energy_endpointer.h",
+    "endpointer/energy_endpointer_params.cc",
+    "endpointer/energy_endpointer_params.h",
+  ]
+  deps = [ "//base" ]
+}
diff --git a/docker-compose.yml b/docker-compose.yml
index b2f6912..ee4e00e 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -155,22 +155,19 @@
       - build-base-bionic
     scale: 0
 
-  linux-x64x11-gcc-6-3:
+  linux-x64x11-gcc:
     <<: *common-definitions
     <<: *build-volumes
     build:
       context: ./docker/linux
       dockerfile: gcc-6-3/Dockerfile
-      args:
-        - FROM_IMAGE=build-base-bionic
-    image: linux-x64x11-gcc-6-3
+    image: cobalt-build-linux-gcc
     environment:
       <<: *shared-build-env
       PLATFORM: linux-x64x11-gcc-6-3
       CONFIG: ${CONFIG:-debug}
     depends_on:
-      - build-base-bionic
-    scale: 0
+      - linux-x64x11-bionic
 
   linux-x64x11-clang-3-9:
     <<: *common-definitions
@@ -195,7 +192,6 @@
       PLATFORM: linux-x64x11-clang-3-9
       CONFIG: ${CONFIG:-debug}
       USE_CCACHE: ${USE_CCACHE:-1}
-      NINJA_STATUS: ${NINJA_STATUS}
 
   # Define common build container for Android
   build-android:
diff --git a/docker/linux/base/build/Dockerfile b/docker/linux/base/build/Dockerfile
index 390b969..9a27bc2 100644
--- a/docker/linux/base/build/Dockerfile
+++ b/docker/linux/base/build/Dockerfile
@@ -55,7 +55,7 @@
 
 # === Configure common env vars
 ENV OUTDIR=out \
-    NINJA_STATUS="[%f/%t %c/sec] " \
+    NINJA_STATUS="[%e sec | %f/%t %u remaining | %c/sec | j%r] " \
     NINJA_PARALLEL=4 \
     IS_CI=0 \
     CCACHE_DIR=/root/ccache \
diff --git a/docker/linux/gcc-6-3/Dockerfile b/docker/linux/gcc-6-3/Dockerfile
index 702db8d..ad098e8 100644
--- a/docker/linux/gcc-6-3/Dockerfile
+++ b/docker/linux/gcc-6-3/Dockerfile
@@ -17,26 +17,11 @@
 ARG DEBIAN_FRONTEND=noninteractive
 
 RUN apt update -qqy \
-    # Install the |add-apt-repository| command for convenience.
-    && apt install -qqy software-properties-common \
-    # Add zesty archive repository, and remove universe repository.
-    && echo "deb http://old-releases.ubuntu.com/ubuntu zesty main" \
-      | tee /etc/apt/sources.list.d/zesty.list \
-    && apt-add-repository -r universe \
-    # Install gcc 6.3 from zesty repo.
-    && apt update -qqy \
     && apt install -qqy gcc-6 g++-6 \
-    && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 1 \
-    && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-6 1 \
-    # Remove zesty repo, and restore universe repo.
-    # Also remove unnecessary software-properties-common.
-    && rm /etc/apt/sources.list.d/zesty.list \
-    && apt-add-repository universe \
-    && apt purge -qqy software-properties-common \
-    && apt autoremove -qqy --purge \
     && /opt/clean-after-apt.sh
 
 CMD /code/cobalt/build/gyp_cobalt -v -C ${CONFIG} ${PLATFORM} && \
     ccache -z && \
-    ninja -v -j ${NINJA_PARALLEL} -C ${OUTDIR}/${PLATFORM}_${CONFIG} ${TARGET:-cobalt_deploy} && \
+    ninja -v -j ${NINJA_PARALLEL} -C ${OUTDIR}/${PLATFORM}_${CONFIG} \
+                ${TARGET:-cobalt_deploy} && \
     ccache -s
diff --git a/starboard/BUILD.gn b/starboard/BUILD.gn
index 04693d8..d90c2c2 100644
--- a/starboard/BUILD.gn
+++ b/starboard/BUILD.gn
@@ -95,7 +95,7 @@
   }
 }
 
-static_library("starboard_headers_only") {
+source_set("starboard_headers_only") {
   # We include starboard/common/log.h in starboard_headers, but some common
   # files include starboard headers.
   check_includes = false
diff --git a/starboard/android/apk/BUILD.gn b/starboard/android/apk/BUILD.gn
index e0b3819..cd95c13 100644
--- a/starboard/android/apk/BUILD.gn
+++ b/starboard/android/apk/BUILD.gn
@@ -16,5 +16,5 @@
   script = "//starboard/build/touch.py"
   sources = [ "cobalt-gradle.sh" ]
   outputs = [ "$root_out_dir/gradle/apk_sources.stamp" ]
-  args = outputs
+  args = rebase_path(outputs, root_build_dir)
 }
diff --git a/starboard/android/apk/app/cobalt-ninja.sh b/starboard/android/apk/app/cobalt-ninja.sh
index f1edba2..7cd85ce 100755
--- a/starboard/android/apk/app/cobalt-ninja.sh
+++ b/starboard/android/apk/app/cobalt-ninja.sh
@@ -16,7 +16,7 @@
 # This wrapper allows us to run ninja without any assumptions about the
 # environment having been setup correctly to build Cobalt, since that won't
 # happen when started from Android Studio. See:
-# https://cobalt.googlesource.com/cobalt/+/master/src/#Building-and-Running-the-Code
+# https://cobalt.googlesource.com/cobalt/+/master/#Building-and-Running-the-Code
 
 # Allow for a developer-specific environment setup from .cobaltrc
 local_rc=$(dirname $0)/.cobaltrc
diff --git a/starboard/android/apk/app/src/main/java/dev/cobalt/util/DisplayUtil.java b/starboard/android/apk/app/src/main/java/dev/cobalt/util/DisplayUtil.java
index 9ec58e5..29a2f80 100644
--- a/starboard/android/apk/app/src/main/java/dev/cobalt/util/DisplayUtil.java
+++ b/starboard/android/apk/app/src/main/java/dev/cobalt/util/DisplayUtil.java
@@ -14,6 +14,7 @@
 
 package dev.cobalt.util;
 
+import android.app.Activity;
 import android.content.Context;
 import android.util.DisplayMetrics;
 import android.util.Size;
@@ -29,6 +30,7 @@
   private DisplayUtil() {}
 
   private static Display defaultDisplay;
+  private static DisplayMetrics cachedDisplayMetrics = null;
 
   /** Returns the physical pixels per inch of the screen in the X and Y dimensions. */
   public static SizeF getDisplayDpi() {
@@ -48,11 +50,15 @@
     }
   }
 
-  /** Cache the default display, this will be triggered when a NativeActivity starts. */
+  /**
+   * Cache the default display and display metrics, this will be triggered when a NativeActivity
+   * starts.
+   */
   public static void cacheDefaultDisplay(Context context) {
     Display display = getDisplayFromContext(context);
     synchronized (DisplayUtil.class) {
       defaultDisplay = display;
+      cachedDisplayMetrics = ((Activity) context).getResources().getDisplayMetrics();
     }
   }
 
@@ -130,16 +136,7 @@
     return null;
   }
 
-  private static DisplayMetrics cachedDisplayMetrics = null;
-
   private static DisplayMetrics getDisplayMetrics() {
-    if (cachedDisplayMetrics == null) {
-      cachedDisplayMetrics = new DisplayMetrics();
-      Display display = getDefaultDisplay();
-      if (display != null) {
-        display.getRealMetrics(cachedDisplayMetrics);
-      }
-    }
     return cachedDisplayMetrics;
   }
 }
diff --git a/starboard/android/shared/android_media_session_client.cc b/starboard/android/shared/android_media_session_client.cc
index 42db59a..3ddd6f6 100644
--- a/starboard/android/shared/android_media_session_client.cc
+++ b/starboard/android/shared/android_media_session_client.cc
@@ -14,7 +14,7 @@
 
 #include "starboard/android/shared/android_media_session_client.h"
 
-#include "base/time/time.h"
+#include "base/time/time.h"  // nogncheck
 #include "starboard/android/shared/jni_env_ext.h"
 #include "starboard/android/shared/jni_utils.h"
 #include "starboard/common/log.h"
diff --git a/starboard/android/shared/install_target.gni b/starboard/android/shared/install_target.gni
index 1442c9f..dbfe29c 100644
--- a/starboard/android/shared/install_target.gni
+++ b/starboard/android/shared/install_target.gni
@@ -28,6 +28,7 @@
     ]
 
     target_output = "$root_out_dir/lib${installable_target_name}.so"
+    gradle_content_dir = "$sb_install_output_dir/$content_dir"
     gradle_files_dir = "$root_out_dir/gradle/$installable_target_name"
     if (is_gold) {
       gradle_build_type = "release"
@@ -42,30 +43,12 @@
 
     outputs = [ "$root_out_dir/${installable_target_name}.apk" ]
 
-    cobalt_project_dir =
-        string_join("/",
-                    [
-                      root_build_dir,
-                      rebase_path("//starboard/android/apk", root_build_dir),
-                    ])
-    cobalt_deploy_apk = string_join("/",
-                                    [
-                                      root_build_dir,
-                                      rebase_path(outputs[0], root_build_dir),
-                                    ])
-    cobalt_content_dir =
-        string_join("/",
-                    [
-                      root_build_dir,
-                      rebase_path("$sb_install_output_dir/$content_dir",
-                                  root_build_dir),
-                    ])
-    cobalt_gradle_dir =
-        string_join("/",
-                    [
-                      root_build_dir,
-                      rebase_path(gradle_files_dir, root_build_dir),
-                    ])
+    cobalt_project_dir = rebase_path("//starboard/android/apk")
+    cobalt_deploy_apk = rebase_path(outputs[0])
+    cobalt_content_dir = rebase_path(gradle_content_dir)
+    cobalt_gradle_dir = rebase_path(gradle_files_dir)
+    cobalt_product_dir = rebase_path(root_out_dir)
+    cobalt_library_dir = rebase_path(root_out_dir)
 
     script = "//starboard/build/run_bash.py"
     bash_script =
@@ -75,7 +58,7 @@
       "--sdk",
       android_sdk_path,
       "--cache",
-      cobalt_gradle_dir,
+      rebase_path(root_build_dir),
       "--project-dir",
       cobalt_project_dir,
       "-P",
@@ -87,9 +70,9 @@
       "-P",
       "cobaltGradleDir=$cobalt_gradle_dir",
       "-P",
-      "cobaltProductDir=$root_out_dir",
+      "cobaltProductDir=$cobalt_product_dir",
       "-P",
-      "cobaltLibraryDir=$root_out_dir",
+      "cobaltLibraryDir=$cobalt_library_dir",
       "-P",
       "cobaltTarget=$installable_target_name",
       "-P",
diff --git a/starboard/android/shared/platform_configuration/BUILD.gn b/starboard/android/shared/platform_configuration/BUILD.gn
index c8da86a..f2f9739 100644
--- a/starboard/android/shared/platform_configuration/BUILD.gn
+++ b/starboard/android/shared/platform_configuration/BUILD.gn
@@ -89,7 +89,6 @@
       # Other flags
       "-fsigned-char",
       "-fno-limit-debug-info",
-      "-fno-exceptions",
       "-fcolor-diagnostics",
       "-fno-strict-aliasing",  # See http://crbug.com/32204
 
diff --git a/starboard/build/config/BUILD.gn b/starboard/build/config/BUILD.gn
index e903cb3..2164afa 100644
--- a/starboard/build/config/BUILD.gn
+++ b/starboard/build/config/BUILD.gn
@@ -90,7 +90,10 @@
 }
 
 config("starboard") {
-  defines = [ "STARBOARD" ]
+  defines = [
+    "STARBOARD",
+    "COBALT",  # TODO: See if this can be replaced by STARBOARD macro.
+  ]
 
   if (gl_type == "none") {
     defines += [ "SB_GN_GL_TYPE_IS_NONE=1" ]
diff --git a/starboard/build/config/components.gni b/starboard/build/config/components.gni
index d983e19..7aef3d1 100644
--- a/starboard/build/config/components.gni
+++ b/starboard/build/config/components.gni
@@ -50,6 +50,16 @@
   target(_component_mode, target_name) {
     forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
     forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
+
+    if (is_starboard) {
+      if (_component_mode == "source_set") {
+        configs += source_set_configs
+      } else if (_component_mode == "static_library") {
+        configs += static_library_configs
+      } else if (_component_mode == "shared_library") {
+        configs += shared_library_configs
+      }
+    }
   }
 }
 
diff --git a/starboard/build/doc/migrating_gyp_to_gn.md b/starboard/build/doc/migrating_gyp_to_gn.md
index 5834300..276bc92 100644
--- a/starboard/build/doc/migrating_gyp_to_gn.md
+++ b/starboard/build/doc/migrating_gyp_to_gn.md
@@ -79,7 +79,7 @@
 ```
 
 You also may need to remove default configs. The default configs are listed in
-[BUILDCONFIG.gn](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/build/config/BUILDCONFIG.gn).
+[BUILDCONFIG.gn](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/config/BUILDCONFIG.gn).
 You remove a config like so:
 
 ```
@@ -145,7 +145,7 @@
 
 Instead of implicitly searching directories for certain files like GYP did, we
 explicitly enumerate our ports and their locations.
-[platforms.gni](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/build/platforms.gni)
+[platforms.gni](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/platforms.gni)
 contains all of this information, and you'll need to add your platform to that
 list following the same format.
 
@@ -173,10 +173,10 @@
 
 You may define a toolchain from scratch following the [reference][gn_toolchain],
 or you can use the
-[gcc/clang templates](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/build/toolchain/gcc_toolchain.gni)
+[gcc/clang templates](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/build/toolchain/gcc_toolchain.gni)
 provided. Almost all of the reference platforms use these templates, so look to
 those as examples for how to use it correctly. Here's the linux-x64x11
-[toolchain/BUILD.gn file](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/linux/x64x11/toolchain/BUILD.gn).
+[toolchain/BUILD.gn file](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/linux/x64x11/toolchain/BUILD.gn).
 
 ## Checking Your Migration
 
@@ -202,7 +202,7 @@
 
 If this was equivalent to a GYP target, you can compare the ninja compilation
 databases by using
-[format_ninja.py](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/tools/format_ninja.py)
+[format_ninja.py](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/tools/format_ninja.py)
 and a comparison tool, i.e. [meld](https://meldmerge.org/). This will allow you
 to see any changes in commands, i.e. with flags or otherwise.
 
diff --git a/starboard/contrib/stadia/clients/vendor/public/stadia_export.h b/starboard/contrib/stadia/clients/vendor/public/stadia_export.h
index 234e17c..9406054 100644
--- a/starboard/contrib/stadia/clients/vendor/public/stadia_export.h
+++ b/starboard/contrib/stadia/clients/vendor/public/stadia_export.h
@@ -26,5 +26,5 @@
 #define STADIA_EXPORT_FUNCTION(return_type, name, parameters) \
   return_type name parameters;                                \
   constexpr const char* k##name = #name;                      \
-  typedef return_type(*name##Function) parameters
+  typedef return_type(*name##FunctionPtr) parameters
 #endif  // STARBOARD_CONTRIB_STADIA_CLIENTS_VENDOR_PUBLIC_STADIA_EXPORT_H_
diff --git a/starboard/contrib/stadia/clients/vendor/public/stadia_lifecycle.h b/starboard/contrib/stadia/clients/vendor/public/stadia_lifecycle.h
index efdd0b7..c495e80 100644
--- a/starboard/contrib/stadia/clients/vendor/public/stadia_lifecycle.h
+++ b/starboard/contrib/stadia/clients/vendor/public/stadia_lifecycle.h
@@ -21,6 +21,6 @@
 
 // An initialization call for Stadia Plugins that should be called when the
 // application window is created.
-STADIA_EXPORT_FUNCTION(void, StadiaInitialize, ());
+STADIA_EXPORT_FUNCTION(void, StadiaInitialize, (void* window));
 }
 #endif  // STARBOARD_CONTRIB_STADIA_CLIENTS_VENDOR_PUBLIC_STADIA_LIFECYCLE_H_
diff --git a/starboard/contrib/stadia/stadia_interface.cc b/starboard/contrib/stadia/stadia_interface.cc
index 3b607d7..34b54e0 100644
--- a/starboard/contrib/stadia/stadia_interface.cc
+++ b/starboard/contrib/stadia/stadia_interface.cc
@@ -43,15 +43,15 @@
     SB_LOG(ERROR) << "Failed to open streaming client library: " << dlerror();
   }
   // Try look up the library's entry point.
-  StadiaPluginHas = reinterpret_cast<StadiaPluginHasFunction>(
+  StadiaPluginHas = reinterpret_cast<StadiaPluginHasFunctionPtr>(
       LookupSymbol(lib_ptr, kStadiaPluginHas));
-  StadiaPluginOpen = reinterpret_cast<StadiaPluginOpenFunction>(
+  StadiaPluginOpen = reinterpret_cast<StadiaPluginOpenFunctionPtr>(
       LookupSymbol(lib_ptr, kStadiaPluginOpen));
-  StadiaPluginSendTo = reinterpret_cast<StadiaPluginSendToFunction>(
+  StadiaPluginSendTo = reinterpret_cast<StadiaPluginSendToFunctionPtr>(
       LookupSymbol(lib_ptr, kStadiaPluginSendTo));
-  StadiaPluginClose = reinterpret_cast<StadiaPluginCloseFunction>(
+  StadiaPluginClose = reinterpret_cast<StadiaPluginCloseFunctionPtr>(
       LookupSymbol(lib_ptr, kStadiaPluginClose));
-  StadiaInitialize = reinterpret_cast<StadiaInitializeFunction>(
+  StadiaInitialize = reinterpret_cast<StadiaInitializeFunctionPtr>(
       LookupSymbol(lib_ptr, kStadiaInitialize));
 
   // Return an empty optional if any entry point wasn't found.
diff --git a/starboard/contrib/stadia/stadia_interface.h b/starboard/contrib/stadia/stadia_interface.h
index 0fadb6e..c6d8518 100644
--- a/starboard/contrib/stadia/stadia_interface.h
+++ b/starboard/contrib/stadia/stadia_interface.h
@@ -23,12 +23,12 @@
 namespace stadia {
 
 struct StadiaInterface {
-  StadiaPluginHasFunction StadiaPluginHas;
-  StadiaPluginOpenFunction StadiaPluginOpen;
-  StadiaPluginSendToFunction StadiaPluginSendTo;
-  StadiaPluginCloseFunction StadiaPluginClose;
+  StadiaPluginHasFunctionPtr StadiaPluginHas;
+  StadiaPluginOpenFunctionPtr StadiaPluginOpen;
+  StadiaPluginSendToFunctionPtr StadiaPluginSendTo;
+  StadiaPluginCloseFunctionPtr StadiaPluginClose;
 
-  StadiaInitializeFunction StadiaInitialize;
+  StadiaInitializeFunctionPtr StadiaInitialize;
 
   StadiaInterface();
 };
diff --git a/starboard/contrib/stadia/x11/application_stadia_x11.cc b/starboard/contrib/stadia/x11/application_stadia_x11.cc
index 3cf0d36..1ae19b3 100644
--- a/starboard/contrib/stadia/x11/application_stadia_x11.cc
+++ b/starboard/contrib/stadia/x11/application_stadia_x11.cc
@@ -37,7 +37,7 @@
 
   if (GetCommandLine()->HasSwitch(kEnableStadia)) {
     g_stadia_interface = new starboard::contrib::stadia::StadiaInterface();
-    g_stadia_interface->StadiaInitialize();
+    g_stadia_interface->StadiaInitialize(&window);
   }
   return window;
 }
diff --git a/starboard/linux/x64x11/gcc/6.3/gyp_configuration.py b/starboard/linux/x64x11/gcc/6.3/gyp_configuration.py
index 80e976f..8c52888 100644
--- a/starboard/linux/x64x11/gcc/6.3/gyp_configuration.py
+++ b/starboard/linux/x64x11/gcc/6.3/gyp_configuration.py
@@ -25,7 +25,7 @@
 
 # Directory for GCC 6.3 if it is installed as a system dependency.
 _DEFAULT_GCC_6_3_BIN_DIR = '/usr/bin'
-_DEFAULT_GCC_6_3_LIB_DIR = '/usr/lib/gcc/x86_64-linux-gnu/6.3.0'
+_DEFAULT_GCC_6_3_LIB_DIR = '/usr/lib/gcc/x86_64-linux-gnu/6'
 
 
 class LinuxX64X11Gcc63Configuration(shared_configuration.LinuxConfiguration):
@@ -41,8 +41,8 @@
     self.toolchain_lib_dir = _DEFAULT_GCC_6_3_LIB_DIR
 
   def SetupPlatformTools(self, build_number):  # pylint: disable=unused-argument
-    if not (os.path.exists(os.path.join(self.toolchain_bin_dir, 'g++')) and
-            os.path.exists(os.path.join(self.toolchain_bin_dir, 'gcc'))):
+    if not (os.path.exists(os.path.join(self.toolchain_bin_dir, 'g++-6')) and
+            os.path.exists(os.path.join(self.toolchain_bin_dir, 'gcc-6'))):
       raise RuntimeError('GCC 6.3 dependency is not present on this system.')
 
   def GetVariables(self, config_name):
@@ -60,16 +60,16 @@
     env_variables = {
         'CC':
             self.build_accelerator + ' ' +
-            os.path.join(self.toolchain_bin_dir, 'gcc'),
+            os.path.join(self.toolchain_bin_dir, 'gcc-6'),
         'CXX':
             self.build_accelerator + ' ' +
-            os.path.join(self.toolchain_bin_dir, 'g++'),
+            os.path.join(self.toolchain_bin_dir, 'g++-6'),
         'CC_HOST':
             self.build_accelerator + ' ' +
-            os.path.join(self.toolchain_bin_dir, 'gcc'),
+            os.path.join(self.toolchain_bin_dir, 'gcc-6'),
         'CXX_HOST':
             self.build_accelerator + ' ' +
-            os.path.join(self.toolchain_bin_dir, 'g++'),
+            os.path.join(self.toolchain_bin_dir, 'g++-6'),
     }
     return env_variables
 
diff --git a/starboard/raspi/2/skia/toolchain/BUILD.gn b/starboard/raspi/2/skia/toolchain/BUILD.gn
index 653ad00..53ae193 100644
--- a/starboard/raspi/2/skia/toolchain/BUILD.gn
+++ b/starboard/raspi/2/skia/toolchain/BUILD.gn
@@ -25,7 +25,6 @@
   ld = cxx
 
   ar = "$gcc_toolchain_ar"
-  strip = "$gcc_toolchain_strip"
 
   toolchain_args = {
     is_clang = false
diff --git a/starboard/raspi/2/toolchain/BUILD.gn b/starboard/raspi/2/toolchain/BUILD.gn
index 7e872a6..ffd79f7 100644
--- a/starboard/raspi/2/toolchain/BUILD.gn
+++ b/starboard/raspi/2/toolchain/BUILD.gn
@@ -26,7 +26,6 @@
 
   # We use whatever 'ar' resolves to in gyp.
   ar = "$gcc_toolchain_ar"
-  strip = "$gcc_toolchain_strip"
 
   toolchain_args = {
     is_clang = false
diff --git a/starboard/raspi/shared/platform_configuration/BUILD.gn b/starboard/raspi/shared/platform_configuration/BUILD.gn
index b1b060c..988df3e 100644
--- a/starboard/raspi/shared/platform_configuration/BUILD.gn
+++ b/starboard/raspi/shared/platform_configuration/BUILD.gn
@@ -60,9 +60,6 @@
   ]
 
   cflags += [
-    # Generated by Audio Renderer and Audio Sink implementations.
-    "-Wno-reorder",
-
     # Generated by code in the raspi/shared/open_max.
     "-Wno-sign-compare",
 
@@ -121,6 +118,9 @@
   cflags_cc += [
     "-std=gnu++14",
     "-Wno-literal-suffix",
+
+    # Generated by Audio Renderer and Audio Sink implementations.
+    "-Wno-reorder",
   ]
 }
 
diff --git a/starboard/raspi/shared/toolchain/raspi_shared_toolchain.gni b/starboard/raspi/shared/toolchain/raspi_shared_toolchain.gni
index d773598..1b0b0e4 100644
--- a/starboard/raspi/shared/toolchain/raspi_shared_toolchain.gni
+++ b/starboard/raspi/shared/toolchain/raspi_shared_toolchain.gni
@@ -23,4 +23,3 @@
 gcc_toolchain_ar = "ar"
 gcc_toolchain_cc = "$_raspi_toolchain_path/arm-linux-gnueabihf-gcc"
 gcc_toolchain_cxx = "$_raspi_toolchain_path/arm-linux-gnueabihf-g++"
-gcc_toolchain_strip = "$_raspi_toolchain_path/arm-linux-gnueabihf-strip"
diff --git a/starboard/shared/libdav1d/dav1d_video_decoder.cc b/starboard/shared/libdav1d/dav1d_video_decoder.cc
index 80ce0d5..1f793ac 100644
--- a/starboard/shared/libdav1d/dav1d_video_decoder.cc
+++ b/starboard/shared/libdav1d/dav1d_video_decoder.cc
@@ -37,21 +37,8 @@
 using starboard::player::JobThread;
 using starboard::player::filter::CpuVideoFrame;
 
-int AllocatePicture(Dav1dPicture* picture, void* context) {
-  SB_DCHECK(picture);
-  SB_DCHECK(context);
-
-  VideoDecoder* decoder = static_cast<VideoDecoder*>(context);
-  return decoder->AllocatePicture(picture);
-}
-
-void ReleasePicture(Dav1dPicture* picture, void* context) {
-  SB_DCHECK(picture);
-  SB_DCHECK(context);
-
-  VideoDecoder* decoder = static_cast<VideoDecoder*>(context);
-  decoder->ReleasePicture(picture);
-}
+constexpr int kMaxDecodedFrameWidth = 3840;
+constexpr int kMaxDecodedFrameHeight = 2160;
 
 void ReleaseInputBuffer(const uint8_t* buf, void* context) {
   SB_DCHECK(context);
@@ -154,52 +141,6 @@
   frames_ = std::queue<scoped_refptr<CpuVideoFrame>>();
 }
 
-int VideoDecoder::AllocatePicture(Dav1dPicture* picture) const {
-  SB_DCHECK(decoder_thread_);
-  SB_DCHECK(decoder_thread_->job_queue()->BelongsToCurrentThread());
-  SB_DCHECK(picture->data[0] == NULL);
-  SB_DCHECK(picture->data[1] == NULL);
-  SB_DCHECK(picture->data[2] == NULL);
-
-  // dav1d requires that the allocated width and height is a multiple of 128.
-  // NOTE: UV resolution is half that of Y resolution.
-  int uv_width = (((picture->p.w + 127) / 128) * 128) / 2;
-  int uv_height = (((picture->p.h + 127) / 128) * 128) / 2;
-  // dav1d requires DAV1D_PICTURE_ALIGNMENT padded to allocated memory areas.
-  int uv_size = uv_width * uv_height + DAV1D_PICTURE_ALIGNMENT;
-
-  // This guarantees that the Y dimension is double the UV dimension.
-  int y_width = uv_width * 2;
-  int y_height = uv_height * 2;
-  int y_size = y_width * y_height + DAV1D_PICTURE_ALIGNMENT;
-
-  picture->stride[0] = y_width;
-  picture->stride[1] = uv_width;
-
-  void* ptr =
-      SbMemoryAllocateAligned(DAV1D_PICTURE_ALIGNMENT, y_size + uv_size * 2);
-  if (ptr == NULL) {
-    return DAV1D_ERR(ENOMEM);
-  }
-  picture->data[0] = ptr;
-  picture->data[1] = static_cast<uint8_t*>(ptr) + y_size;
-  picture->data[2] = static_cast<uint8_t*>(ptr) + y_size + uv_size;
-  return 0;
-}
-
-void VideoDecoder::ReleasePicture(Dav1dPicture* picture) const {
-  SB_DCHECK(picture->data[0]);
-  SB_DCHECK(picture->data[1]);
-  SB_DCHECK(picture->data[2]);
-  SB_DCHECK(picture->data[0] < picture->data[1]);
-  SB_DCHECK(picture->data[1] < picture->data[2]);
-
-  SbMemoryDeallocateAligned(picture->data[0]);
-  for (int i = 0; i < 3; ++i) {
-    picture->data[i] = NULL;
-  }
-}
-
 void VideoDecoder::UpdateDecodeTarget_Locked(
     const scoped_refptr<CpuVideoFrame>& frame) {
   SbDecodeTarget decode_target = DecodeTargetCreate(
@@ -229,13 +170,8 @@
   // TODO: Verify this setting is optimal.
   dav1d_settings.n_threads = 8;
 
-  Dav1dPicAllocator allocator;
-  allocator.cookie = this;  // dav1d refers to context pointers as "cookie".
-  allocator.alloc_picture_callback =
-      &::starboard::shared::libdav1d::AllocatePicture;
-  allocator.release_picture_callback =
-      &::starboard::shared::libdav1d::ReleasePicture;
-  dav1d_settings.allocator = allocator;
+  dav1d_settings.frame_size_limit =
+      kMaxDecodedFrameHeight * kMaxDecodedFrameWidth;
 
   int result = dav1d_open(&dav1d_context_, &dav1d_settings);
   if (result != kDav1dSuccess) {
diff --git a/starboard/shared/libdav1d/dav1d_video_decoder.h b/starboard/shared/libdav1d/dav1d_video_decoder.h
index 0cc2c3f..49d590a 100644
--- a/starboard/shared/libdav1d/dav1d_video_decoder.h
+++ b/starboard/shared/libdav1d/dav1d_video_decoder.h
@@ -54,9 +54,6 @@
   void WriteEndOfStream() override;
   void Reset() override;
 
-  int AllocatePicture(Dav1dPicture* picture) const;
-  void ReleasePicture(Dav1dPicture* picture) const;
-
  private:
   typedef ::starboard::shared::starboard::player::filter::CpuVideoFrame
       CpuVideoFrame;
diff --git a/starboard/shared/starboard/player/filter/testing/audio_renderer_internal_test.cc b/starboard/shared/starboard/player/filter/testing/audio_renderer_internal_test.cc
index 0facea7..f36b5d7 100644
--- a/starboard/shared/starboard/player/filter/testing/audio_renderer_internal_test.cc
+++ b/starboard/shared/starboard/player/filter/testing/audio_renderer_internal_test.cc
@@ -17,7 +17,7 @@
 #include <functional>
 #include <set>
 
-#include "base/logging.h"
+#include "starboard/common/log.h"
 #include "starboard/common/scoped_ptr.h"
 #include "starboard/media.h"
 #include "starboard/memory.h"
diff --git a/starboard/shared/stub/accessibility_get_caption_settings.cc b/starboard/shared/stub/accessibility_get_caption_settings.cc
index ac3be68..ddabf2e 100644
--- a/starboard/shared/stub/accessibility_get_caption_settings.cc
+++ b/starboard/shared/stub/accessibility_get_caption_settings.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "base/compiler_specific.h"
+#include "base/compiler_specific.h"  // nogncheck
 
 #include "starboard/accessibility.h"
 #include "starboard/common/memory.h"
diff --git a/testing/gmock_mutant.h b/testing/gmock_mutant.h
index 2a41cf5..c39ccf5 100644
--- a/testing/gmock_mutant.h
+++ b/testing/gmock_mutant.h
@@ -85,7 +85,7 @@
 //        &Demiurge::DecreaseMonsters, base::Unretained(&mock->demiurge_)))));
 //
 
-#include "base/bind.h"
+#include "base/bind.h"    // nogncheck
 
 namespace testing {
 
diff --git a/third_party/brotli/BUILD.gn b/third_party/brotli/BUILD.gn
new file mode 100644
index 0000000..62e61e8
--- /dev/null
+++ b/third_party/brotli/BUILD.gn
@@ -0,0 +1,262 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+if (!is_starboard) {
+  import("//testing/libfuzzer/fuzzer_test.gni")
+}
+
+if (is_win) {
+  import("//build/config/win/visual_studio_version.gni")
+}
+
+config("includes") {
+  if (is_starboard) {
+    include_dirs = [ "c/include" ]
+  } else {
+    include_dirs = [ "include" ]
+  }
+}
+
+static_library("headers") {
+  if (is_starboard) {
+    sources = [
+      "c/include/brotli/decode.h",
+      "c/include/brotli/encode.h",
+      "c/include/brotli/port.h",
+      "c/include/brotli/types.h",
+    ]
+  } else {
+    sources = [
+      "include/brotli/decode.h",
+      "include/brotli/encode.h",
+      "include/brotli/port.h",
+      "include/brotli/types.h",
+    ]
+  }
+}
+
+if (is_starboard) {
+  common_sources = [
+    "c/common/constants.h",
+    "c/common/dictionary.c",
+    "c/common/dictionary.h",
+    "c/common/platform.h",
+    "c/common/version.h",
+  ]
+} else {
+  common_sources = [
+    "common/constants.c",
+    "common/constants.h",
+    "common/context.c",
+    "common/context.h",
+    "common/dictionary.c",
+    "common/dictionary.h",
+    "common/platform.c",
+    "common/platform.h",
+    "common/transform.c",
+    "common/transform.h",
+    "common/version.h",
+  ]
+}
+
+static_library("common") {
+  sources = common_sources
+  public_configs = [ ":includes" ]
+  deps = [ ":headers" ]
+}
+
+static_library("common_no_dictionary_data") {
+  sources = common_sources
+  public_configs = [ ":includes" ]
+  deps = [ ":headers" ]
+  defines = [ "BROTLI_EXTERNAL_DICTIONARY_DATA" ]
+}
+
+if (is_starboard) {
+  dec_sources = [
+    "c/dec/bit_reader.c",
+    "c/dec/bit_reader.h",
+    "c/dec/context.h",
+    "c/dec/decode.c",
+    "c/dec/huffman.c",
+    "c/dec/huffman.h",
+    "c/dec/prefix.h",
+    "c/dec/state.c",
+    "c/dec/state.h",
+    "c/dec/transform.h",
+  ]
+} else {
+  dec_sources = [
+    "dec/bit_reader.c",
+    "dec/bit_reader.h",
+    "dec/decode.c",
+    "dec/huffman.c",
+    "dec/huffman.h",
+    "dec/prefix.h",
+    "dec/state.c",
+    "dec/state.h",
+  ]
+
+  enc_sources = [
+    "enc/backward_references_hq.c",
+    "enc/backward_references_hq.h",
+    "enc/backward_references_inc.h",
+    "enc/backward_references.c",
+    "enc/backward_references.h",
+    "enc/bit_cost_inc.h",
+    "enc/bit_cost.c",
+    "enc/bit_cost.h",
+    "enc/block_encoder_inc.h",
+    "enc/block_splitter_inc.h",
+    "enc/block_splitter.c",
+    "enc/block_splitter.h",
+    "enc/brotli_bit_stream.c",
+    "enc/brotli_bit_stream.h",
+    "enc/cluster_inc.h",
+    "enc/cluster.c",
+    "enc/cluster.h",
+    "enc/command.c",
+    "enc/command.h",
+    "enc/compress_fragment_two_pass.c",
+    "enc/compress_fragment_two_pass.h",
+    "enc/compress_fragment.c",
+    "enc/compress_fragment.h",
+    "enc/dictionary_hash.c",
+    "enc/dictionary_hash.h",
+    "enc/encode.c",
+    "enc/encoder_dict.c",
+    "enc/encoder_dict.h",
+    "enc/entropy_encode_static.h",
+    "enc/entropy_encode.c",
+    "enc/entropy_encode.h",
+    "enc/fast_log.c",
+    "enc/fast_log.h",
+    "enc/find_match_length.h",
+    "enc/hash_composite_inc.h",
+    "enc/hash_forgetful_chain_inc.h",
+    "enc/hash_longest_match_inc.h",
+    "enc/hash_longest_match_quickly_inc.h",
+    "enc/hash_longest_match64_inc.h",
+    "enc/hash_rolling_inc.h",
+    "enc/hash_to_binary_tree_inc.h",
+    "enc/hash.h",
+    "enc/histogram_inc.h",
+    "enc/histogram.c",
+    "enc/histogram.h",
+    "enc/literal_cost.c",
+    "enc/literal_cost.h",
+    "enc/memory.c",
+    "enc/memory.h",
+    "enc/metablock_inc.h",
+    "enc/metablock.c",
+    "enc/metablock.h",
+    "enc/params.h",
+    "enc/prefix.h",
+    "enc/quality.h",
+    "enc/ringbuffer.h",
+    "enc/static_dict_lut.h",
+    "enc/static_dict.c",
+    "enc/static_dict.h",
+    "enc/utf8_util.c",
+    "enc/utf8_util.h",
+    "enc/write_bits.h",
+  ]
+}
+
+static_library("dec") {
+  sources = dec_sources
+  public_configs = [ ":includes" ]
+  public_deps = [ ":headers" ]
+  deps = [ ":common" ]
+
+  if (is_starboard) {
+    configs -= [ "//starboard/build/config:size" ]
+    configs += [ "//starboard/build/config:speed" ]
+
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  } else {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+
+    # Since we never debug brotli, freeze the optimizations to -O2.
+    configs -= [ "//build/config/compiler:default_optimization" ]
+    configs += [ "//build/config/compiler:optimize_max" ]
+  }
+}
+
+static_library("dec_no_dictionary_data") {
+  sources = dec_sources
+  public_configs = [ ":includes" ]
+  public_deps = [ ":headers" ]
+  deps = [ ":common_no_dictionary_data" ]
+
+  if (is_starboard) {
+    configs -= [ "//starboard/build/config:size" ]
+    configs += [ "//starboard/build/config:speed" ]
+
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  } else {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+
+    # Since we never debug brotli, freeze the optimizations to -O2.
+    configs -= [ "//build/config/compiler:default_optimization" ]
+    configs += [ "//build/config/compiler:optimize_max" ]
+  }
+}
+
+if (!is_starboard) {
+  static_library("enc") {
+    sources = enc_sources
+    public_configs = [ ":includes" ]
+
+    public_deps = [ ":headers" ]
+    deps = [ ":common" ]
+
+    if (is_starboard) {
+      configs -= [ "//starboard/build/config:size" ]
+      configs += [ "//starboard/build/config:speed" ]
+    } else {
+      configs -= [ "//build/config/compiler:chromium_code" ]
+      configs += [ "//build/config/compiler:no_chromium_code" ]
+      # Since we never debug brotli, freeze the optimizations to -O2.
+
+      configs -= [ "//build/config/compiler:default_optimization" ]
+      configs += [ "//build/config/compiler:optimize_max" ]
+    }
+  }
+
+  if (current_toolchain == host_toolchain) {
+    executable("brotli") {
+      sources = [ "tools/brotli.c" ]
+      public_configs = [ ":includes" ]
+
+      deps = [
+        ":common",
+        ":dec",
+        ":enc",
+        ":headers",
+        "//build/win:default_exe_manifest",
+      ]
+
+      if (is_win && visual_studio_version == "2015") {
+        # Disabling "result of 32-bit shift implicitly converted to 64 bits",
+        # caused by code like: foo |= (1 << i);   // warning 4334
+        cflags = [ "/wd4334" ]
+      }
+
+      # Always build release since this is a build tool.
+      if (is_debug) {
+        configs -= [ "//build/config:debug" ]
+        configs += [ "//build/config:release" ]
+      }
+    }
+  }
+
+  fuzzer_test("brotli_fuzzer") {
+    sources = [ "fuzz/decode_fuzzer.cc" ]
+    deps = [ ":dec" ]
+    libfuzzer_options = [ "max_len=1280" ]
+  }
+}
diff --git a/third_party/brotli/METADATA b/third_party/brotli/METADATA
index 39964c6..496321b 100644
--- a/third_party/brotli/METADATA
+++ b/third_party/brotli/METADATA
@@ -18,4 +18,8 @@
     day: 8
   }
   license_type: NOTICE
+  local_modifications:
+    '11/3/21 - Added BUILD.gn as part of GN migration.'
+    'Contents taken from https://chromium.googlesource.com/chromium/src/+/771ce89fc8532b9782271e52318eb42bd062ce53/third_party/brotli/BUILD.gn'
+    'and modified for Cobalt.'
 }
diff --git a/third_party/crashpad/client/BUILD.gn b/third_party/crashpad/client/BUILD.gn
index 0e20db5..19aa8db 100644
--- a/third_party/crashpad/client/BUILD.gn
+++ b/third_party/crashpad/client/BUILD.gn
@@ -15,6 +15,8 @@
 import("../build/crashpad_buildconfig.gni")
 
 static_library("client") {
+  check_includes = false
+
   sources = [
     "annotation.cc",
     "annotation.h",
diff --git a/third_party/crashpad/handler/BUILD.gn b/third_party/crashpad/handler/BUILD.gn
index 91a0f06..f9b3211 100644
--- a/third_party/crashpad/handler/BUILD.gn
+++ b/third_party/crashpad/handler/BUILD.gn
@@ -15,6 +15,8 @@
 import("../build/crashpad_buildconfig.gni")
 
 static_library("handler") {
+  check_includes = false
+
   sources = [
     "crash_report_upload_thread.cc",
     "crash_report_upload_thread.h",
diff --git a/third_party/crashpad/minidump/BUILD.gn b/third_party/crashpad/minidump/BUILD.gn
index 9e423a7..83da927 100644
--- a/third_party/crashpad/minidump/BUILD.gn
+++ b/third_party/crashpad/minidump/BUILD.gn
@@ -15,6 +15,8 @@
 import("../build/crashpad_buildconfig.gni")
 
 static_library("minidump") {
+  check_includes = false
+
   sources = [
     "minidump_annotation_writer.cc",
     "minidump_annotation_writer.h",
@@ -129,6 +131,7 @@
 
 source_set("minidump_test") {
   testonly = true
+  check_includes = false
 
   sources = [
     "minidump_annotation_writer_test.cc",
diff --git a/third_party/crashpad/snapshot/BUILD.gn b/third_party/crashpad/snapshot/BUILD.gn
index c2308a1..9c46636 100644
--- a/third_party/crashpad/snapshot/BUILD.gn
+++ b/third_party/crashpad/snapshot/BUILD.gn
@@ -280,6 +280,7 @@
 
 static_library("test_support") {
   testonly = true
+  check_includes = false
 
   sources = [
     "test/test_cpu_context.cc",
diff --git a/third_party/crashpad/test/BUILD.gn b/third_party/crashpad/test/BUILD.gn
index c0ec1c1..4f2f683 100644
--- a/third_party/crashpad/test/BUILD.gn
+++ b/third_party/crashpad/test/BUILD.gn
@@ -16,6 +16,7 @@
 
 static_library("test") {
   testonly = true
+  check_includes = false
 
   sources = [
     "errors.cc",
@@ -236,6 +237,8 @@
 
 static_library("gmock_main") {
   testonly = true
+  check_includes = false
+
   sources = [ "gtest_main.cc" ]
   configs += [ "../build:crashpad_is_in_chromium" ]
   defines = [ "CRASHPAD_TEST_LAUNCHER_GMOCK" ]
@@ -253,6 +256,8 @@
 
 static_library("gtest_main") {
   testonly = true
+  check_includes = false
+
   sources = [ "gtest_main.cc" ]
   configs += [ "../build:crashpad_is_in_chromium" ]
   defines = [ "CRASHPAD_TEST_LAUNCHER_GTEST" ]
diff --git a/third_party/crashpad/tools/BUILD.gn b/third_party/crashpad/tools/BUILD.gn
index 1eca9d2..ae8b2c4 100644
--- a/third_party/crashpad/tools/BUILD.gn
+++ b/third_party/crashpad/tools/BUILD.gn
@@ -15,6 +15,8 @@
 import("../build/crashpad_buildconfig.gni")
 
 source_set("tool_support") {
+  check_includes = false
+
   sources = [
     "tool_support.cc",
     "tool_support.h",
diff --git a/third_party/crashpad/wrapper/BUILD.gn b/third_party/crashpad/wrapper/BUILD.gn
index fc985cb..ddf52aa 100644
--- a/third_party/crashpad/wrapper/BUILD.gn
+++ b/third_party/crashpad/wrapper/BUILD.gn
@@ -17,6 +17,8 @@
 # targets.
 
 static_library("wrapper") {
+  check_includes = false
+
   sources = [
     "wrapper.cc",
     "wrapper.h",
@@ -34,4 +36,4 @@
     "wrapper.h",
   ]
   deps = [ "//starboard/elf_loader:evergreen_info" ]
-}
\ No newline at end of file
+}
diff --git a/third_party/flac/BUILD.gn b/third_party/flac/BUILD.gn
new file mode 100644
index 0000000..fef5807
--- /dev/null
+++ b/third_party/flac/BUILD.gn
@@ -0,0 +1,95 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+config("flac_config") {
+  defines = [
+    "FLAC__NO_DLL",
+  ]
+}
+source_set("flac") {
+  sources = [
+    "include/FLAC/all.h",
+    "include/FLAC/assert.h",
+    "include/FLAC/callback.h",
+    "include/FLAC/export.h",
+    "include/FLAC/format.h",
+    "include/FLAC/metadata.h",
+    "include/FLAC/ordinals.h",
+    "include/FLAC/stream_decoder.h",
+    "include/FLAC/stream_encoder.h",
+    "include/share/alloc.h",
+    "src/libFLAC/alloc.c",
+    "src/libFLAC/bitmath.c",
+    "src/libFLAC/bitreader.c",
+    "src/libFLAC/bitwriter.c",
+    "src/libFLAC/cpu.c",
+    "src/libFLAC/crc.c",
+    "src/libFLAC/fixed.c",
+    "src/libFLAC/float.c",
+    "src/libFLAC/format.c",
+    "src/libFLAC/lpc.c",
+    "src/libFLAC/md5.c",
+    "src/libFLAC/memory.c",
+    "src/libFLAC/stream_decoder.c",
+    "src/libFLAC/stream_encoder.c",
+    "src/libFLAC/stream_encoder_framing.c",
+    "src/libFLAC/window.c",
+    "src/libFLAC/include/private/all.h",
+    "src/libFLAC/include/private/bitmath.h",
+    "src/libFLAC/include/private/bitreader.h",
+    "src/libFLAC/include/private/bitwriter.h",
+    "src/libFLAC/include/private/cpu.h",
+    "src/libFLAC/include/private/crc.h",
+    "src/libFLAC/include/private/fixed.h",
+    "src/libFLAC/include/private/float.h",
+    "src/libFLAC/include/private/format.h",
+    "src/libFLAC/include/private/lpc.h",
+    "src/libFLAC/include/private/md5.h",
+    "src/libFLAC/include/private/memory.h",
+    "src/libFLAC/include/private/metadata.h",
+    "src/libFLAC/include/private/stream_encoder_framing.h",
+    "src/libFLAC/include/private/window.h",
+    "src/libFLAC/include/protected/all.h",
+    "src/libFLAC/include/protected/stream_decoder.h",
+    "src/libFLAC/include/protected/stream_encoder.h",
+  ]
+
+  if (is_starboard) {
+    deps = [
+      "//starboard:starboard_headers_only",
+      "//starboard/common",
+    ]
+  }
+
+  if (is_starboard) {
+    public_configs = [ ":flac_config" ]
+  } else {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    direct_dependent_configs = [ ":flac_config" ]
+  }
+
+  configs += [
+    ":flac_config",
+    "//build/config/compiler:no_chromium_code",
+  ]
+
+  include_dirs = [
+    "include",
+    "src/libFLAC/include",
+  ]
+
+  defines = [
+    "FLAC__OVERFLOW_DETECT",
+    "VERSION=\"1.2.1\"",
+  ]
+
+  if (is_clang) {
+    # libflac converts between FLAC__StreamDecoderState and
+    # FLAC__StreamDecoderInitStatus a lot in stream_decoder.c.
+    cflags = [
+      "-Wno-conversion",
+    ]
+  }
+}
+
diff --git a/third_party/flac/METADATA b/third_party/flac/METADATA
index 8b4c4ee..734dcd0 100644
--- a/third_party/flac/METADATA
+++ b/third_party/flac/METADATA
@@ -18,4 +18,8 @@
     day: 9
   }
   license_type: NOTICE
+  local_modifications:
+    '11/2/21 - Added BUILD.gn as part of GN migration.'
+    'Contents taken from https://chromium.googlesource.com/chromium/deps/flac/+/0635a091379d9677f1ddde5f2eec85d0f096f219/BUILD.gn'
+    'and modified for Cobalt.'
 }
diff --git a/third_party/icu/BUILD.gn b/third_party/icu/BUILD.gn
index 1d15fb4..a283a60 100644
--- a/third_party/icu/BUILD.gn
+++ b/third_party/icu/BUILD.gn
@@ -44,6 +44,13 @@
     # to avoid performance issues.
     "U_ENABLE_TRACING=1",
     "U_ENABLE_RESOURCE_TRACING=0",
+
+    # Disable unused ICU code
+    "UCONFIG_ONLY_HTML_CONVERSION",
+    "UCONFIG_NO_COLLATION",
+    "UCONFIG_NO_LEGACY_CONVERSION",
+    "UCONFIG_NO_TRANSLITERATION",
+    "UCONFIG_NO_REGULAR_EXPRESSIONS"
   ]
 
   if (!is_component_build) {
diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn
new file mode 100644
index 0000000..b7339f9
--- /dev/null
+++ b/third_party/libpng/BUILD.gn
@@ -0,0 +1,110 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+config("libpng_config") {
+  include_dirs = [ "." ]
+
+  defines = [
+    "CHROME_PNG_WRITE_SUPPORT",
+    "PNG_USER_CONFIG",
+  ]
+
+  if (is_starboard) {
+    defines += [ "PNG_SKIP_SETJMP_CHECK" ]
+  }
+
+  if (is_win && is_component_build) {
+    defines += [ "PNG_USE_DLL" ]
+  }
+}
+
+# Must be in a config because of how GN orders flags (otherwise -Wall will
+# appear after this, and turn it back on).
+config("clang_warnings") {
+  if (is_clang) {
+    cflags = [
+      # libpng checks that the width is not greater than PNG_SIZE_MAX.
+      # On platforms where size_t is 64-bits, this comparison will always
+      # be false.
+      "-Wno-tautological-compare",
+    ]
+  }
+}
+
+source_set("libpng_sources") {
+  sources = [
+    "png.c",
+    "png.h",
+    "pngconf.h",
+    "pngerror.c",
+    "pngget.c",
+    "pnginfo.h",
+    "pnglibconf.h",
+    "pngmem.c",
+    "pngpread.c",
+    "pngprefix.h",
+    "pngpriv.h",
+    "pngread.c",
+    "pngrio.c",
+    "pngrtran.c",
+    "pngrutil.c",
+    "pngset.c",
+    "pngstruct.h",
+    "pngtrans.c",
+    "pngwio.c",
+    "pngwrite.c",
+    "pngwtran.c",
+    "pngwutil.c",
+  ]
+
+  if (is_starboard) {
+    sources -= [
+      "pnginfo.h",
+      "pnglibconf.h",
+      "pngprefix.h",
+      "pngpriv.h",
+      "pngread.c",
+      "pngstruct.h",
+    ]
+    sources += [
+      "pnggccrd.c",
+      "pngusr.h",
+      "pngvcrd.c",
+    ]
+  }
+
+  if (!is_win) {
+    output_name = "png"
+  }
+
+  defines = []
+  if (is_win && is_component_build) {
+    defines += [
+      "PNG_BUILD_DLL",
+      "PNG_NO_MODULEDEF",
+    ]
+  }
+
+  configs += [ ":clang_warnings" ]
+
+  if (is_starboard) {
+    configs -= [ "//starboard/build/config:size" ]
+    configs += [ "//starboard/build/config:speed" ]
+    deps = [ "//starboard:starboard_headers_only" ]
+  }
+
+  public_deps = [ "//third_party/zlib" ]
+
+  public_configs = [ ":libpng_config" ]
+}
+
+if (is_win) {
+  component("libpng") {
+    public_deps = [ ":libpng_sources" ]
+  }
+} else {
+  group("libpng") {
+    public_deps = [ ":libpng_sources" ]
+  }
+}
diff --git a/third_party/libpng/METADATA b/third_party/libpng/METADATA
index 8dd6fcb..feddcf2 100644
--- a/third_party/libpng/METADATA
+++ b/third_party/libpng/METADATA
@@ -14,4 +14,8 @@
     day: 7
   }
   license_type: NOTICE
+  local_modifications:
+    "11/5/21 - Added BUILD.gn as part of GN migration."
+    "Contents taken from https://chromium.googlesource.com/chromium/src/+/0ddf78a46654c13f9ee7de921a820087f45375e3/third_party/libpng/BUILD.gn"
+    "and modified for Cobalt."
 }
diff --git a/third_party/libvpx/platforms/linux-x64/libvpx.a b/third_party/libvpx/platforms/linux-x64/libvpx.a
new file mode 100644
index 0000000..c8f685f
--- /dev/null
+++ b/third_party/libvpx/platforms/linux-x64/libvpx.a
Binary files differ
diff --git a/third_party/libxml/BUILD.gn b/third_party/libxml/BUILD.gn
index 3fe4dfd..fddad6f 100644
--- a/third_party/libxml/BUILD.gn
+++ b/third_party/libxml/BUILD.gn
@@ -4,7 +4,9 @@
 
 # Define an "os_include" variable that points at the OS-specific generated
 # headers.  These were generated by running the configure script offline.
-if (is_linux || is_android || is_nacl || is_fuchsia) {
+if (is_starboard) {
+  os_include = "starboard"
+} else if (is_linux || is_android || is_nacl || is_fuchsia) {
   os_include = "linux"
 } else if (is_mac || is_ios) {
   os_include = "mac"
@@ -75,41 +77,43 @@
   }
 }
 
-static_library("xml_reader") {
-  # Do not expand this visibility list without first consulting with the
-  # Security Team.
-  visibility = [
-    "//base/test:test_support",
-    "//components/policy/core/common:unit_tests",
-    "//services/data_decoder:*",
-    "//tools/traffic_annotation/auditor:auditor_sources",
-  ]
-  if (is_win) {
-    visibility += [ "//components/wifi" ]
+if (!is_starboard) {
+  static_library("xml_reader") {
+    # Do not expand this visibility list without first consulting with the
+    # Security Team.
+    visibility = [
+      "//base/test:test_support",
+      "//components/policy/core/common:unit_tests",
+      "//services/data_decoder:*",
+      "//tools/traffic_annotation/auditor:auditor_sources",
+    ]
+    if (is_win) {
+      visibility += [ "//components/wifi" ]
+    }
+    sources = [
+      "chromium/xml_reader.cc",
+      "chromium/xml_reader.h",
+    ]
+    deps = [
+      ":libxml",
+      ":libxml_utils",
+    ]
+    configs += [ ":libxml_config" ]
   }
-  sources = [
-    "chromium/xml_reader.cc",
-    "chromium/xml_reader.h",
-  ]
-  deps = [
-    ":libxml",
-    ":libxml_utils",
-  ]
-  configs += [ ":libxml_config" ]
-}
 
-static_library("xml_writer") {
-  # The XmlWriter is considered safe to use from any target.
-  visibility = [ "*" ]
-  sources = [
-    "chromium/xml_writer.cc",
-    "chromium/xml_writer.h",
-  ]
-  deps = [
-    ":libxml",
-    ":libxml_utils",
-  ]
-  configs += [ ":libxml_config" ]
+  static_library("xml_writer") {
+    # The XmlWriter is considered safe to use from any target.
+    visibility = [ "*" ]
+    sources = [
+      "chromium/xml_writer.cc",
+      "chromium/xml_writer.h",
+    ]
+    deps = [
+      ":libxml",
+      ":libxml_utils",
+    ]
+    configs += [ ":libxml_config" ]
+  }
 }
 
 static_library("libxml_utils") {
@@ -142,6 +146,12 @@
     "//third_party/fontconfig",
     "//third_party/libxslt",
   ]
+  if (is_starboard) {
+    visibility += [
+      "//base/test:test_support",
+      "//cobalt/base",
+     ]
+  }
   if (is_ios) {
     foreach(tgt, ios_libxml_visibility_additions) {
       visibility += [ "//ios_internal/$tgt" ]
@@ -282,7 +292,9 @@
     "win32/include/libxml/xmlversion.h",
   ]
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  if (!is_starboard) {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+  }
   configs += [
     "//build/config/compiler:no_chromium_code",
 
diff --git a/third_party/opus/starboard/config.h b/third_party/opus/starboard/config.h
new file mode 100644
index 0000000..7c67f29
--- /dev/null
+++ b/third_party/opus/starboard/config.h
@@ -0,0 +1,64 @@
+/***********************************************************************
+Copyright (c) 2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define USE_ALLOCA            0
+
+/* Comment out the next line for floating-point code */
+/*#define FIXED_POINT           1 */
+
+#define OPUS_BUILD            1
+
+#if defined(_M_IX86) || defined(_M_X64)
+/* Can always compile SSE intrinsics (no special compiler flags necessary) */
+#define OPUS_X86_MAY_HAVE_SSE
+#define OPUS_X86_MAY_HAVE_SSE2
+#define OPUS_X86_MAY_HAVE_SSE4_1
+
+/* Presume SSE functions, if compiled to use SSE/SSE2/AVX (note that AMD64 implies SSE2, and AVX
+   implies SSE4.1) */
+#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1)) || defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE 1
+#endif
+#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE2 1
+#endif
+#if defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE4_1 1
+#endif
+
+#if !defined(OPUS_X86_PRESUME_SSE4_1) || !defined(OPUS_X86_PRESUME_SSE2) || !defined(OPUS_X86_PRESUME_SSE)
+#define OPUS_HAVE_RTCD 1
+#endif
+
+#endif
+
+#include "version.h"
+
+#endif /* CONFIG_H */
diff --git a/third_party/opus/starboard/version.h b/third_party/opus/starboard/version.h
new file mode 100644
index 0000000..eb110f7
--- /dev/null
+++ b/third_party/opus/starboard/version.h
@@ -0,0 +1 @@
+#define OPUS_VERSION "1.3-rc-2-gc1c247d-dirty"
diff --git a/third_party/opus/win32/config.h b/third_party/opus/win32/config.h
new file mode 100644
index 0000000..3e54bcb
--- /dev/null
+++ b/third_party/opus/win32/config.h
@@ -0,0 +1,64 @@
+/***********************************************************************
+Copyright (c) 2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define USE_ALLOCA            1
+
+/* Comment out the next line for floating-point code */
+/*#define FIXED_POINT           1 */
+
+#define OPUS_BUILD            1
+
+#if defined(_M_IX86) || defined(_M_X64)
+/* Can always compile SSE intrinsics (no special compiler flags necessary) */
+#define OPUS_X86_MAY_HAVE_SSE
+#define OPUS_X86_MAY_HAVE_SSE2
+#define OPUS_X86_MAY_HAVE_SSE4_1
+
+/* Presume SSE functions, if compiled to use SSE/SSE2/AVX (note that AMD64 implies SSE2, and AVX
+   implies SSE4.1) */
+#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1)) || defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE 1
+#endif
+#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE2 1
+#endif
+#if defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE4_1 1
+#endif
+
+#if !defined(OPUS_X86_PRESUME_SSE4_1) || !defined(OPUS_X86_PRESUME_SSE2) || !defined(OPUS_X86_PRESUME_SSE)
+#define OPUS_HAVE_RTCD 1
+#endif
+
+#endif
+
+#include "version.h"
+
+#endif /* CONFIG_H */
diff --git a/third_party/opus/win32/version.h b/third_party/opus/win32/version.h
new file mode 100644
index 0000000..eb110f7
--- /dev/null
+++ b/third_party/opus/win32/version.h
@@ -0,0 +1 @@
+#define OPUS_VERSION "1.3-rc-2-gc1c247d-dirty"
diff --git a/third_party/sqlite/BUILD.gn b/third_party/sqlite/BUILD.gn
new file mode 100644
index 0000000..5876b64
--- /dev/null
+++ b/third_party/sqlite/BUILD.gn
@@ -0,0 +1,161 @@
+# Copyright (c) 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+config("sqlite_config") {
+  include_dirs = [ "." ]
+}
+
+source_set("sqlite") {
+  sources = [
+    "amalgamation/sqlite3.h",
+    "amalgamation/sqlite3.c",
+    # fts2.c currently has a lot of conflicts when added to
+    # the amalgamation.  It is probably not worth fixing that.
+    "src/ext/fts2/fts2.c",
+    "src/ext/fts2/fts2.h",
+    "src/ext/fts2/fts2_hash.c",
+    "src/ext/fts2/fts2_hash.h",
+    "src/ext/fts2/fts2_icu.c",
+    "src/ext/fts2/fts2_porter.c",
+    "src/ext/fts2/fts2_tokenizer.c",
+    "src/ext/fts2/fts2_tokenizer.h",
+    "src/ext/fts2/fts2_tokenizer1.c",
+  ]
+
+  cflags = []
+  defines = [
+    "SQLITE_CORE",
+    "SQLITE_ENABLE_BROKEN_FTS2",
+    "SQLITE_ENABLE_FTS2",
+    "SQLITE_ENABLE_FTS3",
+    "SQLITE_ENABLE_ICU",
+    "SQLITE_ENABLE_MEMORY_MANAGEMENT",
+    "SQLITE_SECURE_DELETE",
+    "SQLITE_SEPARATE_CACHE_POOLS",
+    "THREADSAFE",
+    "_HAS_EXCEPTIONS=0",
+  ]
+  if (is_chromeos) {
+    defines += [
+      # Despite obvious warnings about not using this flag in deployment, we
+      # are turning off sync in ChromeOS and relying on the underlying
+      # journaling filesystem to do error recovery properly. It's much faster.
+      "SQLITE_NO_SYNC",
+    ]
+  }
+
+  include_dirs = [
+    "amalgamation",
+    "src/src",  # Needed for fts2 to build.
+  ]
+
+  if (is_starboard) {
+    # Remove sources, defines, and include dirs related to full text search.
+    sources -= [
+      "src/ext/fts2/fts2.c",
+      "src/ext/fts2/fts2.h",
+      "src/ext/fts2/fts2_hash.c",
+      "src/ext/fts2/fts2_hash.h",
+      "src/ext/fts2/fts2_icu.c",
+      "src/ext/fts2/fts2_porter.c",
+      "src/ext/fts2/fts2_tokenizer.c",
+      "src/ext/fts2/fts2_tokenizer.h",
+      "src/ext/fts2/fts2_tokenizer1.c",
+    ]
+    defines -= [
+      "SQLITE_ENABLE_BROKEN_FTS2",
+      "SQLITE_ENABLE_FTS2",
+      "SQLITE_ENABLE_FTS3",
+      "SQLITE_ENABLE_ICU",
+    ]
+    include_dirs -= [ "src/src" ]
+
+    # Additional defines for Starboard.
+    defines += [
+      # "write-ahead log", requires shared memory primitives
+      # which we don't have on every platform.
+      "SQLITE_OMIT_WAL=1",
+      # Disable journaling, since we only use on-disk dbs as
+      # an intermediate stage to the savegame manager.
+      "SQLITE_NO_SYNC",
+      # Disable sqlite plugins
+      "SQLITE_OMIT_LOAD_EXTENSION",
+      # Localtime functions are not accurate on all platforms.
+      "SQLITE_OMIT_LOCALTIME",
+      "HAVE_USLEEP=1",
+    ]
+
+    configs -= [ "//starboard/build/config:size" ]
+  } else {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
+
+  if (is_win) {
+    cflags += [ "/wd4267" ]  # Conversion from size_t to "type".
+  } else if (is_linux) {
+    cflags += [
+      # SQLite doesn"t believe in compiler warnings,
+      # preferring testing.
+      #   http://www.sqlite.org/faq.html#q17
+      "-Wno-int-to-pointer-cast",
+      "-Wno-pointer-to-int-cast",
+    ]
+    libs = [ "dl" ]
+  } else if (is_mac || is_ios) {
+    libs = [ "CoreFoundation.framework" ]
+  } else if (is_android) {
+    defines += [
+      "HAVE_USLEEP=1",
+      "SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576",
+      "SQLITE_DEFAULT_AUTOVACUUM=1",
+      "SQLITE_TEMP_STORE=3",
+      "SQLITE_ENABLE_FTS3_BACKWARDS",
+      "DSQLITE_DEFAULT_FILE_FORMAT=4",
+    ]
+  }
+
+  if (is_clang) {
+    cflags += [
+      # sqlite does `if (*a++ && *b++);` in a non-buggy way.
+      "-Wno-empty-body",
+      # sqlite has some `unsigned < 0` checks.
+      "-Wno-tautological-compare",
+    ]
+    if (is_starboard) {
+      cflags += [
+        "-Wno-pointer-bool-conversion"
+      ]
+    }
+  }
+
+  public_configs = [ ":sqlite_config" ]
+
+  deps = [
+    "//third_party/icu",
+  ]
+}
+
+if (is_linux && !is_starboard) {
+  executable("sqlite_shell") {
+    sources = [
+      "src/src/shell.c",
+      "src/src/shell_icu_linux.c",
+      # Include a dummy c++ file to force linking of libstdc++.
+      "build_as_cpp.cc",
+    ]
+
+    deps = [
+      ":sqlite",
+      "//third_party/icu",
+    ]
+  }
+}
+
+if (is_ios && !is_starboard) {
+  source_set("sqlite_regexp") {
+    sources = [ "src/ext/icu/icu.c" ]
+    deps = [ "//third_party/icu" ]
+  }
+}
diff --git a/third_party/sqlite/METADATA b/third_party/sqlite/METADATA
index db56e9f..b101004 100644
--- a/third_party/sqlite/METADATA
+++ b/third_party/sqlite/METADATA
@@ -19,4 +19,8 @@
     day: 19
   }
   license_type: UNENCUMBERED
+  local_modifications:
+    '11/5/21 - Added BUILD.gn as part of GN migration.'
+    'Contents taken from https://chromium.googlesource.com/chromium/src/+/e5389527466d390b5653724a069008b9f1edcd5c/third_party/sqlite/BUILD.gn'
+    'and modified for Cobalt.'
 }
diff --git a/third_party/v8/__init__.py b/third_party/v8/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/v8/__init__.py
diff --git a/third_party/woff2/BUILD.gn b/third_party/woff2/BUILD.gn
new file mode 100644
index 0000000..0433da9
--- /dev/null
+++ b/third_party/woff2/BUILD.gn
@@ -0,0 +1,41 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# optimize_target_for_speed
+
+config("woff2_includes") {
+  include_dirs = [ "include" ]
+}
+
+static_library("woff2_dec") {
+  sources = [
+    "src/buffer.h",
+    "src/file.h",
+    "src/round.h",
+    "src/store_bytes.h",
+    "src/table_tags.cc",
+    "src/table_tags.h",
+    "src/variable_length.cc",
+    "src/variable_length.h",
+    "src/woff2_common.cc",
+    "src/woff2_common.h",
+    "src/woff2_dec.cc",
+    "src/woff2_out.cc",
+    "include/woff2/decode.h",
+    "include/woff2/encode.h",
+    "include/woff2/output.h",
+  ]
+  deps = [
+    "//starboard/common",
+    "//third_party/brotli:dec",
+  ]
+
+  public_configs = [ ":woff2_includes" ]
+
+  # TODO(ksakamoto): http://crbug.com/167187
+  if (is_win) {
+    cflags = [ "/wd4267" ]  # Conversion from size_t to 'type'.
+  }
+}
+
diff --git a/third_party/woff2/METADATA b/third_party/woff2/METADATA
index 98a685f..81208ba 100644
--- a/third_party/woff2/METADATA
+++ b/third_party/woff2/METADATA
@@ -18,4 +18,8 @@
     day: 13
   }
   license_type: NOTICE
+  local_modifications:
+    '11/3/21 - Added BUILD.gn as part of GN migration.'
+    'Contents taken without modifications from'
+    'https://chromium.googlesource.com/chromium/src/+/e15188b59eaacd43a66e2e3756539b5a4525478b/third_party/woff2/BUILD.gn'
 }