Import Cobalt 21.master.0.283707
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc
index 6d14fbe..69c959b 100644
--- a/src/cobalt/browser/browser_module.cc
+++ b/src/cobalt/browser/browser_module.cc
@@ -1656,10 +1656,13 @@
     if (web_module_) {
       web_module_->SetCamera3D(input_device_manager_->camera_3d());
       web_module_->SetWebMediaPlayerFactory(media_module_.get());
-      web_module_->GetUiNavRoot()->SetContainerWindow(
-          system_window_->GetSbWindow());
     }
   }
+
+  if (web_module_) {
+    web_module_->GetUiNavRoot()->SetContainerWindow(
+        system_window_->GetSbWindow());
+  }
 }
 
 void BrowserModule::InstantiateRendererModule() {
@@ -1952,6 +1955,10 @@
 }
 
 void BrowserModule::SubmitCurrentRenderTreeToRenderer() {
+  if (web_module_) {
+    web_module_->GetUiNavRoot()->PerformQueuedUpdates();
+  }
+
   if (!renderer_module_) {
     return;
   }
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index a485246..ab60a96 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-282262
\ No newline at end of file
+283707
\ No newline at end of file
diff --git a/src/cobalt/build/gyp_utils.py b/src/cobalt/build/gyp_utils.py
index cabcbe1..986d81c 100644
--- a/src/cobalt/build/gyp_utils.py
+++ b/src/cobalt/build/gyp_utils.py
@@ -25,7 +25,7 @@
 import _env  # pylint: disable=unused-import
 from cobalt.tools import paths
 
-
+_REVINFO_KEY = 'cobalt_src'
 _VERSION_SERVER_URL = 'https://carbon-airlock-95823.appspot.com/build_version/generate'  # pylint:disable=line-too-long
 _XSSI_PREFIX = ")]}'\n"
 
@@ -34,32 +34,29 @@
 
 
 def GetRevinfo():
-  """Get absolute state of all git repos from gclient DEPS."""
+  """Get absolute state of all git repos."""
+
+  git_get_remote_args = ['config', '--get', 'remote.origin.url']
+  git_get_revision_args = ['rev-parse', 'HEAD']
 
   try:
-    revinfo_cmd = ['gclient', 'revinfo', '-a']
-
-    if sys.platform.startswith('linux') or sys.platform == 'darwin':
-      use_shell = False
-    else:
-      # Windows needs shell to find gclient in the PATH.
-      use_shell = True
-    output = subprocess.check_output(revinfo_cmd, shell=use_shell)
-    revinfo = {}
-    lines = output.splitlines()
-    for line in lines:
-      repo, url = line.split(':', 1)
-      repo = repo.strip().replace('\\', '/')
-      url = url.strip()
-      revinfo[repo] = url
-    return revinfo
-  except (subprocess.CalledProcessError, ValueError) as e:
-    logging.warning('Failed to get revision information: %s', e)
+    cobalt_remote = subprocess.check_output(['git'] +
+                                            git_get_remote_args).strip()
+    cobalt_rev = subprocess.check_output(['git'] +
+                                         git_get_revision_args).strip()
+    return {_REVINFO_KEY: '{}@{}'.format(cobalt_remote, cobalt_rev)}
+  except subprocess.CalledProcessError:
+    logging.info(
+        'Failed to get revision information. Trying again in src/ directory...')
     try:
-      logging.warning('Command output was: %s', line)
-    except NameError:
-      pass
-    return {}
+      cobalt_remote = subprocess.check_output(['git', '-C', 'src'] +
+                                              git_get_remote_args).strip()
+      cobalt_rev = subprocess.check_output(['git', '-C', 'src'] +
+                                           git_get_revision_args).strip()
+      return {_REVINFO_KEY: '{}@{}'.format(cobalt_remote, cobalt_rev)}
+    except subprocess.CalledProcessError as e:
+      logging.warning('Failed to get revision information: %s', e)
+      return {}
 
 
 def GetBuildNumber(version_server=_VERSION_SERVER_URL):
@@ -119,10 +116,10 @@
     match = search_re.search(f.read())
 
   if not match:
-    logging.critical('Could not query constant value.  The expression '
-                     'should only have numbers, operators, spaces, and '
-                     'parens.  Please check "%s" in %s.\n', constant_name,
-                     file_path)
+    logging.critical(
+        'Could not query constant value.  The expression '
+        'should only have numbers, operators, spaces, and '
+        'parens.  Please check "%s" in %s.\n', constant_name, file_path)
     sys.exit(1)
 
   expression = match.group(1)
diff --git a/src/cobalt/dom/document.cc b/src/cobalt/dom/document.cc
index bd077ba..3810d3d 100644
--- a/src/cobalt/dom/document.cc
+++ b/src/cobalt/dom/document.cc
@@ -997,6 +997,15 @@
 void Document::OnVisibilityStateChanged(VisibilityState visibility_state) {
   DispatchEvent(new Event(base::Tokens::visibilitychange(), Event::kBubbles,
                           Event::kNotCancelable));
+
+  // Refocus the previously-focused UI navigation item (if any).
+  if (visibility_state == kVisibilityStateVisible) {
+    HTMLElement* active_html_element = active_element() ?
+        active_element()->AsHTMLElement() : nullptr;
+    if (active_html_element) {
+      active_html_element->RefocusUiNavItem();
+    }
+  }
 }
 
 // Algorithm for 'change the frozenness of a document'
diff --git a/src/cobalt/dom/html_element.cc b/src/cobalt/dom/html_element.cc
index ea5606b..1db3c22 100644
--- a/src/cobalt/dom/html_element.cc
+++ b/src/cobalt/dom/html_element.cc
@@ -1441,6 +1441,34 @@
   ClearRuleMatchingState();
 }
 
+void HTMLElement::RefocusUiNavItem() {
+  // Set the focus item for the UI navigation system. Search up the DOM tree to
+  // find the nearest ancestor that is a UI navigation item if needed. Do this
+  // step before dispatching events as the event handlers may make UI navigation
+  // changes.
+  for (Node* node = this; node; node = node->parent_node()) {
+    Element* element = node->AsElement();
+    if (!element) {
+      continue;
+    }
+    HTMLElement* html_element = element->AsHTMLElement();
+    if (!html_element) {
+      continue;
+    }
+    if (!html_element->ui_nav_item_ ||
+        html_element->ui_nav_item_->IsContainer()) {
+      continue;
+    }
+    // Updating the g_ui_nav_focus_ has the additional effect of suppressing
+    // the Blur call for the previously focused HTMLElement and the Focus call
+    // for this HTMLElement as a result of OnUiNavBlur / OnUiNavFocus callbacks
+    // that result from initiating the UI navigation focus change.
+    g_ui_nav_focus_ = html_element;
+    html_element->ui_nav_item_->Focus();
+    break;
+  }
+}
+
 void HTMLElement::SetDir(const std::string& value) {
   // https://html.spec.whatwg.org/commit-snapshots/ebcac971c2add28a911283899da84ec509876c44/#the-dir-attribute
   auto previous_dir = dir_;
@@ -2124,11 +2152,12 @@
 
 bool HTMLElement::UpdateUiNavigationAndReturnIfLayoutBoxesAreValid() {
   base::Optional<ui_navigation::NativeItemType> ui_nav_item_type;
-  if (computed_style()->overflow() == cssom::KeywordValue::GetAuto() ||
-      computed_style()->overflow() == cssom::KeywordValue::GetScroll()) {
-    ui_nav_item_type = ui_navigation::kNativeItemTypeContainer;
-  } else if (tabindex_ && *tabindex_ <= kUiNavFocusTabIndexThreshold) {
+  if (tabindex_ && *tabindex_ <= kUiNavFocusTabIndexThreshold &&
+      computed_style()->pointer_events() != cssom::KeywordValue::GetNone()) {
     ui_nav_item_type = ui_navigation::kNativeItemTypeFocus;
+  } else if (computed_style()->overflow() == cssom::KeywordValue::GetAuto() ||
+             computed_style()->overflow() == cssom::KeywordValue::GetScroll()) {
+    ui_nav_item_type = ui_navigation::kNativeItemTypeContainer;
   }
 
   if (ui_nav_item_type) {
diff --git a/src/cobalt/dom/html_element.h b/src/cobalt/dom/html_element.h
index 3994f6f..7bb152c 100644
--- a/src/cobalt/dom/html_element.h
+++ b/src/cobalt/dom/html_element.h
@@ -363,6 +363,11 @@
     return ui_nav_item_;
   }
 
+  // Reset focus on the associated UI navigation item (if any). This is used
+  // when resuming from the conealed state, in case the underlying UI navigation
+  // system was reset during the conceal.
+  void RefocusUiNavItem();
+
   // Returns true if the element is the root element as defined in
   // https://www.w3.org/TR/html50/semantics.html#the-root-element.
   bool IsRootElement();
diff --git a/src/cobalt/media_session/media_session_client.cc b/src/cobalt/media_session/media_session_client.cc
index 4b32aa9..4959580 100644
--- a/src/cobalt/media_session/media_session_client.cc
+++ b/src/cobalt/media_session/media_session_client.cc
@@ -193,7 +193,7 @@
 }
 
 void MediaSessionClient::InvokeActionInternal(
-    CobaltExtensionMediaSessionActionDetails* details) {
+    std::unique_ptr<CobaltExtensionMediaSessionActionDetails> details) {
   DCHECK(details->action >= 0 &&
          details->action < kCobaltExtensionMediaSessionActionNumActions);
 
@@ -222,7 +222,7 @@
   }
 
   std::unique_ptr<MediaSessionActionDetails> script_details =
-      ConvertActionDetails(details);
+      ConvertActionDetails(*details);
   it->second->value().Run(*script_details);
 
   // Queue a session update to reflect the effects of the action.
@@ -382,17 +382,17 @@
 
 std::unique_ptr<MediaSessionActionDetails>
 MediaSessionClient::ConvertActionDetails(
-    CobaltExtensionMediaSessionActionDetails* ext_details) {
+    const CobaltExtensionMediaSessionActionDetails& ext_details) {
   std::unique_ptr<MediaSessionActionDetails> details(
       new MediaSessionActionDetails());
-  details->set_action(ConvertMediaSessionAction(ext_details->action));
-  if (ext_details->seek_offset >= 0.0) {
-    details->set_seek_offset(ext_details->seek_offset);
+  details->set_action(ConvertMediaSessionAction(ext_details.action));
+  if (ext_details.seek_offset >= 0.0) {
+    details->set_seek_offset(ext_details.seek_offset);
   }
-  if (ext_details->seek_time >= 0.0) {
-    details->set_seek_time(ext_details->seek_time);
+  if (ext_details.seek_time >= 0.0) {
+    details->set_seek_time(ext_details.seek_time);
   }
-  details->set_fast_seek(ext_details->fast_seek);
+  details->set_fast_seek(ext_details.fast_seek);
   return details;
 }
 
diff --git a/src/cobalt/media_session/media_session_client.h b/src/cobalt/media_session/media_session_client.h
index d2d5221..76883d9 100644
--- a/src/cobalt/media_session/media_session_client.h
+++ b/src/cobalt/media_session/media_session_client.h
@@ -73,24 +73,28 @@
   // https://wicg.github.io/mediasession/#actions-model
   // Can be invoked from any thread.
   void InvokeAction(CobaltExtensionMediaSessionAction action) {
-    CobaltExtensionMediaSessionActionDetails details = {};
-    CobaltExtensionMediaSessionActionDetailsInit(&details, action);
-    InvokeActionInternal(std::move(&details));
+    std::unique_ptr<CobaltExtensionMediaSessionActionDetails> details(
+        new CobaltExtensionMediaSessionActionDetails());
+    CobaltExtensionMediaSessionActionDetailsInit(details.get(), action);
+    InvokeActionInternal(std::move(details));
   }
 
   // Invokes a given media session action that takes additional details.
   void InvokeCobaltExtensionAction(
       CobaltExtensionMediaSessionActionDetails details) {
-    InvokeActionInternal(&details);
+    std::unique_ptr<CobaltExtensionMediaSessionActionDetails> details_ptr(
+        new CobaltExtensionMediaSessionActionDetails(details));
+    InvokeActionInternal(std::move(details_ptr));
   }
 
   // Deprecated - use the alternative InvokeCobaltExtensionAction.
   // TODO: Delete once platform migrations to CobaltExtensionMediaSessionApi are
   // complete.
   void InvokeAction(std::unique_ptr<MediaSessionActionDetails> details) {
-    CobaltExtensionMediaSessionActionDetails* ext_details = {};
+    std::unique_ptr<CobaltExtensionMediaSessionActionDetails> ext_details(
+        new CobaltExtensionMediaSessionActionDetails());
     CobaltExtensionMediaSessionActionDetailsInit(
-        ext_details, ConvertMediaSessionAction(details->action()));
+        ext_details.get(), ConvertMediaSessionAction(details->action()));
     if (details->has_seek_offset()) {
       ext_details->seek_offset = details->seek_offset().value();
     }
@@ -102,6 +106,7 @@
     }
     InvokeActionInternal(std::move(ext_details));
   }
+
   // Invoked on the browser thread when any metadata, position state, playback
   // state, or supported session actions change.
   virtual void OnMediaSessionStateChanged(
@@ -129,13 +134,14 @@
   void UpdateMediaSessionState();
   MediaSessionPlaybackState ComputeActualPlaybackState() const;
   MediaSessionState::AvailableActionsSet ComputeAvailableActions() const;
-  void InvokeActionInternal(CobaltExtensionMediaSessionActionDetails* details);
+  void InvokeActionInternal(
+      std::unique_ptr<CobaltExtensionMediaSessionActionDetails> details);
 
   void ConvertMediaSessionActions(
       const MediaSessionState::AvailableActionsSet& actions,
       bool result[kCobaltExtensionMediaSessionActionNumActions]);
   std::unique_ptr<MediaSessionActionDetails> ConvertActionDetails(
-      CobaltExtensionMediaSessionActionDetails* ext_details);
+      const CobaltExtensionMediaSessionActionDetails& ext_details);
 
   // Static callback wrappers for MediaSessionAPI extension.
   static void UpdatePlatformPlaybackStateCallback(
diff --git a/src/cobalt/media_session/media_session_test.cc b/src/cobalt/media_session/media_session_test.cc
index 8b2f22e..36e6660 100644
--- a/src/cobalt/media_session/media_session_test.cc
+++ b/src/cobalt/media_session/media_session_test.cc
@@ -309,6 +309,25 @@
             state.available_actions().to_ulong());
 }
 
+TEST(MediaSessionTest, InvokeAction) {
+  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
+
+  MockMediaSessionClient client;
+  scoped_refptr<MediaSession> session = client.GetMediaSession();
+
+  MockCallbackFunction cf;
+  FakeScriptValue<MediaSession::MediaSessionActionHandler> holder(&cf);
+  std::unique_ptr<MediaSessionActionDetails> details(
+      new MediaSessionActionDetails());
+
+  session->SetActionHandler(kMediaSessionActionSeekto, holder);
+  EXPECT_CALL(cf, Run(SeekTime(1.2))).WillOnce(Return(CallbackResult<void>()));
+
+  details->set_action(kMediaSessionActionSeekto);
+  details->set_seek_time(1.2);
+  client.InvokeAction(std::move(details));
+}
+
 TEST(MediaSessionTest, SeekDetails) {
   base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
 
diff --git a/src/cobalt/ui_navigation/interface.cc b/src/cobalt/ui_navigation/interface.cc
index 7829188..86b0342 100644
--- a/src/cobalt/ui_navigation/interface.cc
+++ b/src/cobalt/ui_navigation/interface.cc
@@ -88,10 +88,36 @@
   *out_content_offset_y = stub_item->content_offset_y;
 }
 
+void DoBatchUpdate(void (*update_function)(void*), void* context) {
+  (*update_function)(context);
+}
+
 NativeInterface InitializeInterface() {
   NativeInterface interface = { 0 };
+
 #if SB_API_VERSION >= 12
-  if (SbUiNavGetInterface(&interface)) {
+  SbUiNavInterface sb_ui_interface = { 0 };
+  if (SbUiNavGetInterface(&sb_ui_interface)) {
+    interface.create_item = sb_ui_interface.create_item;
+    interface.destroy_item = sb_ui_interface.destroy_item;
+    interface.set_focus = sb_ui_interface.set_focus;
+    interface.set_item_enabled = sb_ui_interface.set_item_enabled;
+    interface.set_item_dir = sb_ui_interface.set_item_dir;
+    interface.set_item_size = sb_ui_interface.set_item_size;
+    interface.set_item_transform = sb_ui_interface.set_item_transform;
+    interface.get_item_focus_transform =
+        sb_ui_interface.get_item_focus_transform;
+    interface.get_item_focus_vector = sb_ui_interface.get_item_focus_vector;
+    interface.set_item_container_window =
+        sb_ui_interface.set_item_container_window;
+    interface.set_item_container_item = sb_ui_interface.set_item_container_item;
+    interface.set_item_content_offset = sb_ui_interface.set_item_content_offset;
+    interface.get_item_content_offset = sb_ui_interface.get_item_content_offset;
+#if SB_API_VERSION >= SB_UI_NAVIGATION2_VERSION
+    interface.do_batch_update = sb_ui_interface.do_batch_update;
+#else
+    interface.do_batch_update = &DoBatchUpdate;
+#endif
     return interface;
   }
 #endif
@@ -109,6 +135,7 @@
   interface.set_item_container_item = &SetItemContainerItem;
   interface.set_item_content_offset = &SetItemContentOffset;
   interface.get_item_content_offset = &GetItemContentOffset;
+  interface.do_batch_update = &DoBatchUpdate;
   return interface;
 }
 
diff --git a/src/cobalt/ui_navigation/interface.h b/src/cobalt/ui_navigation/interface.h
index b2011bc..9c81c59 100644
--- a/src/cobalt/ui_navigation/interface.h
+++ b/src/cobalt/ui_navigation/interface.h
@@ -32,7 +32,6 @@
 using NativeMatrix2x3 = SbUiNavMatrix2x3;
 using NativeMatrix4 = SbUiNavMatrix4;
 using NativeCallbacks = SbUiNavCallbacks;
-using NativeInterface = SbUiNavInterface;
 #define kNativeItemInvalid kSbUiNavItemInvalid
 
 #else
@@ -64,6 +63,10 @@
   void (*onscroll)(NativeItem item, void* callback_context);
 };
 
+#define kNativeItemInvalid nullptr
+
+#endif  // SB_API_VERSION >= 12
+
 struct NativeInterface {
   NativeItem (*create_item)(NativeItemType type,
                             const NativeCallbacks* callbacks,
@@ -85,12 +88,9 @@
   void (*get_item_content_offset)(NativeItem item,
                                   float* out_content_offset_x,
                                   float* out_content_offset_y);
+  void (*do_batch_update)(void (*update_function)(void*), void* context);
 };
 
-#define kNativeItemInvalid nullptr
-
-#endif  // SB_API_VERSION >= 11
-
 // Retrieve the interface to use for UI navigation.
 extern const NativeInterface& GetInterface();
 
diff --git a/src/cobalt/ui_navigation/nav_item.cc b/src/cobalt/ui_navigation/nav_item.cc
index 8eaf1f3..2cca3ec 100644
--- a/src/cobalt/ui_navigation/nav_item.cc
+++ b/src/cobalt/ui_navigation/nav_item.cc
@@ -14,9 +14,52 @@
 
 #include "cobalt/ui_navigation/nav_item.h"
 
+#include <vector>
+
+#include "base/bind.h"
+#include "starboard/atomic.h"
+#include "starboard/common/spin_lock.h"
+
 namespace cobalt {
 namespace ui_navigation {
 
+namespace {
+// These data structures support queuing of UI navigation changes so they can
+// be executed as a batch to atomically update the UI.
+SbAtomic32 g_pending_updates_lock(starboard::kSpinLockStateReleased);
+std::vector<base::Closure>* g_pending_updates = nullptr;
+
+// Pending focus change should always be done after all updates. This ensures
+// the focus target is up-to-date.
+volatile NativeItem g_pending_focus = kNativeItemInvalid;
+
+// This tracks the total number of NavItems. It is used to control allocation
+// and deletion of data for queued updates.
+int32_t g_nav_item_count = 0;
+
+// This helper function is necessary to preserve the |transform| by value.
+void SetTransformHelper(NativeItem native_item, NativeMatrix2x3 transform) {
+  GetInterface().set_item_transform(native_item, &transform);
+}
+
+// This processes all pending updates assuming the update spinlock is locked.
+void ProcessPendingChangesLocked(void* /* context */) {
+  for (size_t i = 0; i < g_pending_updates->size(); ++i) {
+    (*g_pending_updates)[i].Run();
+  }
+  g_pending_updates->clear();
+  if (g_pending_focus != kNativeItemInvalid) {
+    GetInterface().set_focus(g_pending_focus);
+    g_pending_focus = kNativeItemInvalid;
+  }
+}
+
+void ProcessPendingChanges(void* context) {
+  starboard::ScopedSpinLock lock(&g_pending_updates_lock);
+  ProcessPendingChangesLocked(context);
+}
+}  // namespace
+
 NativeCallbacks NavItem::s_callbacks_ = {
   &NavItem::OnBlur,
   &NavItem::OnFocus,
@@ -31,13 +74,117 @@
       onfocus_callback_(onfocus_callback),
       onscroll_callback_(onscroll_callback),
       nav_item_type_(type),
-      nav_item_(GetInterface().create_item(type, &s_callbacks_, this)) {
-  SbAtomicNoBarrier_Store8(&enabled_, 0);
+      nav_item_(GetInterface().create_item(type, &s_callbacks_, this)),
+      enabled_(false) {
+  starboard::ScopedSpinLock lock(&g_pending_updates_lock);
+  if (++g_nav_item_count == 1) {
+    g_pending_updates = new std::vector<base::Closure>();
+    g_pending_focus = kNativeItemInvalid;
+  }
 }
 
 NavItem::~NavItem() {
+  starboard::ScopedSpinLock lock(&g_pending_updates_lock);
   GetInterface().set_item_enabled(nav_item_, false);
-  GetInterface().destroy_item(nav_item_);
+  if (g_pending_focus == nav_item_) {
+    g_pending_focus = kNativeItemInvalid;
+  }
+  g_pending_updates->emplace_back(
+      base::Bind(GetInterface().destroy_item, nav_item_));
+  if (--g_nav_item_count == 0) {
+    ProcessPendingChangesLocked(nullptr);
+    delete g_pending_updates;
+    g_pending_updates = nullptr;
+  }
+}
+
+void NavItem::PerformQueuedUpdates() {
+  GetInterface().do_batch_update(&ProcessPendingChanges, nullptr);
+}
+
+void NavItem::Focus() {
+  starboard::ScopedSpinLock lock(&g_pending_updates_lock);
+  if (enabled_) {
+    g_pending_focus = nav_item_;
+  }
+}
+
+void NavItem::UnfocusAll() {
+  starboard::ScopedSpinLock lock(&g_pending_updates_lock);
+  g_pending_focus = kNativeItemInvalid;
+#if SB_API_VERSION >= SB_UI_NAVIGATION2_VERSION
+  g_pending_updates->emplace_back(
+      base::Bind(GetInterface().set_focus, kNativeItemInvalid));
+#endif
+}
+
+void NavItem::SetEnabled(bool enabled) {
+  starboard::ScopedSpinLock lock(&g_pending_updates_lock);
+  enabled_ = enabled;
+  if (enabled) {
+    g_pending_updates->emplace_back(
+        base::Bind(GetInterface().set_item_enabled, nav_item_, enabled));
+  } else {
+    // Disable immediately to avoid errant callbacks on this item.
+    GetInterface().set_item_enabled(nav_item_, enabled);
+    if (g_pending_focus == nav_item_) {
+      g_pending_focus = kNativeItemInvalid;
+    }
+  }
+}
+
+void NavItem::SetDir(NativeItemDir dir) {
+  // Do immediately in case it impacts content offset queries.
+  GetInterface().set_item_dir(nav_item_, dir);
+}
+
+void NavItem::SetSize(float width, float height) {
+  starboard::ScopedSpinLock lock(&g_pending_updates_lock);
+  g_pending_updates->emplace_back(
+      base::Bind(GetInterface().set_item_size, nav_item_, width, height));
+}
+
+void NavItem::SetTransform(const NativeMatrix2x3* transform) {
+  starboard::ScopedSpinLock lock(&g_pending_updates_lock);
+  g_pending_updates->emplace_back(
+      base::Bind(&SetTransformHelper, nav_item_, *transform));
+}
+
+bool NavItem::GetFocusTransform(NativeMatrix4* out_transform) {
+  return GetInterface().get_item_focus_transform(nav_item_, out_transform);
+}
+
+bool NavItem::GetFocusVector(float* out_x, float* out_y) {
+  return GetInterface().get_item_focus_vector(nav_item_, out_x, out_y);
+}
+
+void NavItem::SetContainerWindow(SbWindow window) {
+  // Do immediately since the lifetime of |window| is not guaranteed after this
+  // call.
+  GetInterface().set_item_container_window(nav_item_, window);
+}
+
+void NavItem::SetContainerItem(const scoped_refptr<NavItem>& container) {
+  // Set the container immediately so that subsequent calls to GetContainerItem
+  // are correct. However, the actual nav_item_ change should still be queued.
+  container_ = container;
+  starboard::ScopedSpinLock lock(&g_pending_updates_lock);
+  g_pending_updates->emplace_back(
+      base::Bind(GetInterface().set_item_container_item, nav_item_,
+                 container ? container->nav_item_ : kNativeItemInvalid));
+}
+
+const scoped_refptr<NavItem>& NavItem::GetContainerItem() const {
+  return container_;
+}
+
+void NavItem::SetContentOffset(float x, float y) {
+  // Do immediately since content offset may be queried immediately after.
+  GetInterface().set_item_content_offset(nav_item_, x, y);
+}
+
+void NavItem::GetContentOffset(float* out_x, float* out_y) {
+  GetInterface().get_item_content_offset(nav_item_, out_x, out_y);
 }
 
 // static
diff --git a/src/cobalt/ui_navigation/nav_item.h b/src/cobalt/ui_navigation/nav_item.h
index c43662f..a0579f7 100644
--- a/src/cobalt/ui_navigation/nav_item.h
+++ b/src/cobalt/ui_navigation/nav_item.h
@@ -18,7 +18,6 @@
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
 #include "cobalt/ui_navigation/interface.h"
-#include "starboard/atomic.h"
 
 namespace cobalt {
 namespace ui_navigation {
@@ -39,64 +38,24 @@
     return nav_item_type_ == kNativeItemTypeContainer;
   }
 
-  void Focus() {
-    if (SbAtomicNoBarrier_Load8(&enabled_)) {
-      GetInterface().set_focus(nav_item_);
-    }
-  }
+  // Some actions may be queued for later execution by this function. This is
+  // to ensure the UI is updated atomically. This function must be called
+  // periodically to ensure all UI updates are executed.
+  void PerformQueuedUpdates();
 
-  void UnfocusAll() {
-#if SB_API_VERSION >= SB_UI_NAVIGATION2_VERSION
-    GetInterface().set_focus(kNativeItemInvalid);
-#endif
-  }
-
-  void SetEnabled(bool enabled) {
-    SbAtomicNoBarrier_Store8(&enabled_, enabled ? 1 : 0);
-    GetInterface().set_item_enabled(nav_item_, enabled);
-  }
-
-  void SetDir(NativeItemDir dir) {
-    GetInterface().set_item_dir(nav_item_, dir);
-  }
-
-  void SetSize(float width, float height) {
-    GetInterface().set_item_size(nav_item_, width, height);
-  }
-
-  void SetTransform(const NativeMatrix2x3* transform) {
-    GetInterface().set_item_transform(nav_item_, transform);
-  }
-
-  bool GetFocusTransform(NativeMatrix4* out_transform) {
-    return GetInterface().get_item_focus_transform(nav_item_, out_transform);
-  }
-
-  bool GetFocusVector(float* out_x, float* out_y) {
-    return GetInterface().get_item_focus_vector(nav_item_, out_x, out_y);
-  }
-
-  void SetContainerWindow(SbWindow window) {
-    GetInterface().set_item_container_window(nav_item_, window);
-  }
-
-  void SetContainerItem(const scoped_refptr<NavItem>& container) {
-    container_ = container;
-    GetInterface().set_item_container_item(nav_item_,
-        container ? container->nav_item_ : kNativeItemInvalid);
-  }
-
-  const scoped_refptr<NavItem>& GetContainerItem() const {
-    return container_;
-  }
-
-  void SetContentOffset(float x, float y) {
-    GetInterface().set_item_content_offset(nav_item_, x, y);
-  }
-
-  void GetContentOffset(float* out_x, float* out_y) {
-    GetInterface().get_item_content_offset(nav_item_, out_x, out_y);
-  }
+  void Focus();
+  void UnfocusAll();
+  void SetEnabled(bool enabled);
+  void SetDir(NativeItemDir dir);
+  void SetSize(float width, float height);
+  void SetTransform(const NativeMatrix2x3* transform);
+  bool GetFocusTransform(NativeMatrix4* out_transform);
+  bool GetFocusVector(float* out_x, float* out_y);
+  void SetContainerWindow(SbWindow window);
+  void SetContainerItem(const scoped_refptr<NavItem>& container);
+  const scoped_refptr<NavItem>& GetContainerItem() const;
+  void SetContentOffset(float x, float y);
+  void GetContentOffset(float* out_x, float* out_y);
 
  private:
   friend class base::RefCountedThreadSafe<NavItem>;
@@ -114,7 +73,7 @@
 
   NativeItemType nav_item_type_;
   NativeItem nav_item_;
-  SbAtomic8 enabled_;
+  bool enabled_;
 
   static NativeCallbacks s_callbacks_;
 };
diff --git a/src/starboard/android/apk/build.id b/src/starboard/android/apk/build.id
deleted file mode 100644
index a485246..0000000
--- a/src/starboard/android/apk/build.id
+++ /dev/null
@@ -1 +0,0 @@
-282262
\ No newline at end of file
diff --git a/src/starboard/build/base_configuration.gypi b/src/starboard/build/base_configuration.gypi
index b8f6d94..a723315 100644
--- a/src/starboard/build/base_configuration.gypi
+++ b/src/starboard/build/base_configuration.gypi
@@ -81,6 +81,9 @@
     # Whether this is an evergreen build.
     'sb_evergreen': 0,
 
+    # Whether to use crashpad.
+    'sb_crashpad_enabled': 0,
+
     # Whether this is an evergreen compatible platform. A compatible platform
     # can run the elf_loader and launch the evergreen build.
     'sb_evergreen_compatible%': '<(sb_evergreen_compatible)',
diff --git a/src/starboard/client_porting/eztime/test_constants.h b/src/starboard/client_porting/eztime/test_constants.h
index 92e0e59..0561ea1 100644
--- a/src/starboard/client_porting/eztime/test_constants.h
+++ b/src/starboard/client_porting/eztime/test_constants.h
@@ -48,16 +48,16 @@
 // agree.
 static const EzTimeT kTestTimeWindowsNegative = SB_INT64_C(-12212553600);
 
-// 1443473373 in POSIX time is
-// Monday, 9/28/2015 20:49:33 UTC
-// NOTE: Update this value once every 5 or so years.
-static const EzTimeT kTestTimeWritten = SB_INT64_C(1443473373);
+// 1600970155 in POSIX time is
+// Thursday, 9/24/2020 17:55:55 UTC
+// NOTE: Update this value once every 25 or so years.
+static const EzTimeT kTestTimeWritten = SB_INT64_C(1600970155);
 
-// 5 years after the time this test was written.
+// 25 years after the time this test was written.
 static const EzTimeT kTestTimePastWritten =
-    (kTestTimeWritten + (5 * kTestEzTimeTYear));
+    (kTestTimeWritten + (25 * kTestEzTimeTYear));
 
-// 1443473373 in POSIX time is
+// 4133980800 in POSIX time is
 // Saturday, 01 Jan 2101 00:00:00 UTC
 // NOTE: Update this value once every 100 or so years.
 static const EzTimeT kTestTimeNextCentury = SB_INT64_C(4133980800);
diff --git a/src/starboard/elf_loader/elf_loader.gyp b/src/starboard/elf_loader/elf_loader.gyp
index 7b6a565..4970ae0 100644
--- a/src/starboard/elf_loader/elf_loader.gyp
+++ b/src/starboard/elf_loader/elf_loader.gyp
@@ -53,21 +53,17 @@
         'src/include',
         'src/src/',
       ],
+      'conditions': [
+        ['sb_evergreen_compatible == 1', {
+          'variables': {
+            'sb_crashpad_enabled': 1,
+          },
+        },],
+      ],
       'dependencies': [
         '<(DEPTH)/starboard/elf_loader/evergreen_config.gyp:evergreen_config',
         '<(DEPTH)/starboard/elf_loader/evergreen_info.gyp:evergreen_info',
-        '<(DEPTH)/starboard/starboard.gyp:starboard_base',
-      ],
-      'conditions': [
-        ['sb_evergreen_compatible == 1', {
-          'dependencies': [
-            '<(DEPTH)/third_party/crashpad/wrapper/wrapper.gyp:crashpad_wrapper',
-          ],
-        }, {
-          'dependencies': [
-            '<(DEPTH)/third_party/crashpad/wrapper/wrapper.gyp:crashpad_wrapper_stub',
-          ],
-        }],
+        '<(DEPTH)/starboard/starboard.gyp:starboard',
       ],
       'sources': [
         '<@(common_elf_loader_sources)',
@@ -113,7 +109,7 @@
       'dependencies': [
         'elf_loader',
         '<(DEPTH)/cobalt/content/fonts/fonts.gyp:copy_font_data',
-        '<(DEPTH)/starboard/starboard.gyp:starboard_full',
+        '<(DEPTH)/starboard/starboard.gyp:starboard',
         # TODO: Remove this dependency once MediaSession is migrated to use CobaltExtensions.
         '<@(cobalt_platform_dependencies)',
       ],
@@ -149,7 +145,7 @@
       ],
       'dependencies': [
         'elf_loader_sys',
-        '<(DEPTH)/starboard/starboard.gyp:starboard_full',
+        '<(DEPTH)/starboard/starboard.gyp:starboard',
       ],
       'sources': [
         'sandbox.cc',
@@ -166,7 +162,7 @@
         '<(DEPTH)/starboard/common/test_main.cc',
       ],
       'dependencies': [
-        '<(DEPTH)/starboard/starboard.gyp:starboard_full',
+        '<(DEPTH)/starboard/starboard.gyp:starboard',
         # TODO: Remove this dependency once MediaSession is migrated to use CobaltExtensions.
         '<@(cobalt_platform_dependencies)',
         '<(DEPTH)/testing/gmock.gyp:gmock',
diff --git a/src/starboard/evergreen/testing/linux/setup.sh b/src/starboard/evergreen/testing/linux/setup.sh
index 6701ea2..e28012d 100755
--- a/src/starboard/evergreen/testing/linux/setup.sh
+++ b/src/starboard/evergreen/testing/linux/setup.sh
@@ -21,6 +21,10 @@
 ID="id"
 TAIL="tail"
 
+if [[ -L "${STORAGE_DIR}" ]]; then
+  rm -f ${STORAGE_DIR} 1> /dev/null
+fi
+
 # Mounting a temporary filesystem cannot be done on buildbot since it requires
 # sudo. When run locally, check for the temporary filesystem and create and
 # mount it if it does not exist.
diff --git a/src/starboard/evergreen/testing/raspi/setup.sh b/src/starboard/evergreen/testing/raspi/setup.sh
index ab815ef..cec7179 100755
--- a/src/starboard/evergreen/testing/raspi/setup.sh
+++ b/src/starboard/evergreen/testing/raspi/setup.sh
@@ -44,6 +44,9 @@
 
 echo " Targeting the Raspberry Pi 2 at ${RASPI_ADDR}"
 
+# Attempt to unlink the path, ignoring errors.
+eval "${SSH}\"unlink \"${STORAGE_DIR}\"\"" 1> /dev/null
+
 # Mounting a temporary filesystem cannot be done on buildbot since it requires
 # sudo. When run locally, check for the temporary filesystem and create and
 # mount it if it does not exist.
diff --git a/src/starboard/evergreen/testing/setup.sh b/src/starboard/evergreen/testing/setup.sh
index 1546b28..a9a707a 100755
--- a/src/starboard/evergreen/testing/setup.sh
+++ b/src/starboard/evergreen/testing/setup.sh
@@ -63,6 +63,7 @@
   source $script "${DIR}/${1}"
 done
 
+# The /tmp/ directory is used for temporarily storing logs.
 if [[ ! -d "/tmp/" ]]; then
   error "The '/tmp/' directory is missing"
   exit 1
diff --git a/src/starboard/evergreen/testing/tests/abort_update_if_already_updating_test.sh b/src/starboard/evergreen/testing/tests/abort_update_if_already_updating_test.sh
index 90f8c1f..d83646e 100755
--- a/src/starboard/evergreen/testing/tests/abort_update_if_already_updating_test.sh
+++ b/src/starboard/evergreen/testing/tests/abort_update_if_already_updating_test.sh
@@ -25,7 +25,7 @@
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "Created drain file"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "Created drain file"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to create a drain file for the test package"
@@ -38,7 +38,7 @@
 
   create_file "${FILENAME}"
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "bailing out"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.1.log" "bailing out"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to find 'bailing out' in logs"
diff --git a/src/starboard/evergreen/testing/tests/alternative_content_test.sh b/src/starboard/evergreen/testing/tests/alternative_content_test.sh
index 00d6eca..51ac20b 100755
--- a/src/starboard/evergreen/testing/tests/alternative_content_test.sh
+++ b/src/starboard/evergreen/testing/tests/alternative_content_test.sh
@@ -25,14 +25,14 @@
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from test channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "update from test channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the test package"
     return 1
   fi
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "App is up to date" "--content=${CONTENT}"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.1.log" "App is up to date" "--content=${CONTENT}"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to find 'App is up to date' indicating failure"
diff --git a/src/starboard/evergreen/testing/tests/crashing_binary_test.sh b/src/starboard/evergreen/testing/tests/crashing_binary_test.sh
index 040538d..67a3f9a 100755
--- a/src/starboard/evergreen/testing/tests/crashing_binary_test.sh
+++ b/src/starboard/evergreen/testing/tests/crashing_binary_test.sh
@@ -20,12 +20,12 @@
 unset -f run_test
 
 TEST_NAME="CrashingBinary"
-TEST_FILE="tcrash.html"
+TEST_FILE="test.html"
 
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from tcrash channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=tcrash" "${TEST_NAME}.0.log" "update from tcrash channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the tcrash package"
@@ -33,7 +33,7 @@
   fi
 
   for i in {1..3}; do
-    start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.${i}.log" "Caught signal: SIG[A-Z]{4}"
+    start_cobalt "file:///tests/${TEST_FILE}?channel=tcrash" "${TEST_NAME}.${i}.log" "Caught signal: SIG[A-Z]{4}"
 
     if [[ $? -ne 0 ]]; then
       error "Binary did not crash on attempt #${i}"
@@ -41,7 +41,7 @@
     fi
   done
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.4.log" "App is up to date"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=tcrash" "${TEST_NAME}.4.log" "App is up to date"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to revert to working installation after crashing 3 times"
diff --git a/src/starboard/evergreen/testing/tests/disabled_updater_test.sh b/src/starboard/evergreen/testing/tests/disabled_updater_test.sh
index 985f110..93275c5 100755
--- a/src/starboard/evergreen/testing/tests/disabled_updater_test.sh
+++ b/src/starboard/evergreen/testing/tests/disabled_updater_test.sh
@@ -25,21 +25,21 @@
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from test channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "update from test channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the test package"
     return 1
   fi
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "App is up to date"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.1.log" "App is up to date"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to run downloaded installation"
     return 1
   fi
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.2.log" "disable_updates=1" "--disable_updates"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.2.log" "disable_updates=1" "--disable_updates"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to run system installation"
diff --git a/src/starboard/evergreen/testing/tests/load_slot_being_updated_test.sh b/src/starboard/evergreen/testing/tests/load_slot_being_updated_test.sh
index f61736e..14a8a9c 100755
--- a/src/starboard/evergreen/testing/tests/load_slot_being_updated_test.sh
+++ b/src/starboard/evergreen/testing/tests/load_slot_being_updated_test.sh
@@ -25,7 +25,7 @@
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from test channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "update from test channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the test package"
@@ -36,7 +36,7 @@
 
   create_file "${FILENAME}"
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "Active slot draining"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.1.log" "Active slot draining"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to abort loading a slot being drained"
diff --git a/src/starboard/evergreen/testing/tests/mismatched_architecture_test.sh b/src/starboard/evergreen/testing/tests/mismatched_architecture_test.sh
index 0f8a427..00cc6da 100755
--- a/src/starboard/evergreen/testing/tests/mismatched_architecture_test.sh
+++ b/src/starboard/evergreen/testing/tests/mismatched_architecture_test.sh
@@ -20,19 +20,19 @@
 unset -f run_test
 
 TEST_NAME="MismatchedArchitecture"
-TEST_FILE="tmsabi.html"
+TEST_FILE="test.html"
 
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from tmsabi channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=tmsabi" "${TEST_NAME}.0.log" "update from tmsabi channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the tmsabi package"
     return 1
   fi
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "Failed to load ELF header"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=tmsabi" "${TEST_NAME}.1.log" "Failed to load(ed)? ELF header"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to recognize architecture mismatch"
diff --git a/src/starboard/evergreen/testing/tests/noop_binary_test.sh b/src/starboard/evergreen/testing/tests/noop_binary_test.sh
index 30835a6..0eb7cae 100755
--- a/src/starboard/evergreen/testing/tests/noop_binary_test.sh
+++ b/src/starboard/evergreen/testing/tests/noop_binary_test.sh
@@ -20,12 +20,12 @@
 unset -f run_test
 
 TEST_NAME="NoOpBinary"
-TEST_FILE="tnoop.html"
+TEST_FILE="test.html"
 
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from tnoop channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=tnoop" "${TEST_NAME}.0.log" "update from tnoop channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the tnoop package"
@@ -33,7 +33,7 @@
   fi
 
   for i in {1..3}; do
-    start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.${i}.log" "Load start=0x[a-f0-9]{8,} base_memory_address=0x[a-f0-9]{8,}"
+    start_cobalt "file:///tests/${TEST_FILE}?channel=tnoop" "${TEST_NAME}.${i}.log" "Load start=0x[a-f0-9]{8,} base_memory_address=0x[a-f0-9]{8,}"
 
     if [[ $? -ne 0 ]]; then
       error "Failed to load binary"
@@ -46,7 +46,7 @@
     fi
   done
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.4.log" "App is up to date"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=tnoop" "${TEST_NAME}.4.log" "App is up to date"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to revert to working installation after no-oping 3 times"
diff --git a/src/starboard/evergreen/testing/tests/out_of_storage_test.sh b/src/starboard/evergreen/testing/tests/out_of_storage_test.sh
index a970be8..7a1a2b7 100755
--- a/src/starboard/evergreen/testing/tests/out_of_storage_test.sh
+++ b/src/starboard/evergreen/testing/tests/out_of_storage_test.sh
@@ -30,6 +30,13 @@
 
   clear_storage
 
+  # We do not delete the storage directory to avoid removing the existing icu
+  # tables. However, this means that we need to move it temporarily to create
+  # our symbolic link to the temporary filesystem.
+  if [[ -d "${STORAGE_DIR}" ]]; then
+    run_command "mv \"${STORAGE_DIR}\" \"${STORAGE_DIR}.tmp\"" 1> /dev/null
+  fi
+
   run_command "ln -s \"${STORAGE_DIR_TMPFS}\" \"${STORAGE_DIR}\"" 1> /dev/null
 
   # We need to explicitly clear the "storage", i.e. the temporary filesystem,
@@ -39,7 +46,15 @@
   OLD_TIMEOUT="${TIMEOUT}"
   TIMEOUT=300
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "Failed to update, error code is 12"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "Failed to update, error code is 12"
+
+  # Remove the symbolic link.
+  run_command "rm -f ${STORAGE_DIR}" 1> /dev/null
+
+  # Move the storage directory back to its original location.
+  if [[ -d "${STORAGE_DIR}.tmp" ]]; then
+    run_command "mv \"${STORAGE_DIR}.tmp\" \"${STORAGE_DIR}\"" 1> /dev/null
+  fi
 
   if [[ $? -ne 0 ]]; then
     error "Failed to run out of storage"
diff --git a/src/starboard/evergreen/testing/tests/quick_roll_forward_test.sh b/src/starboard/evergreen/testing/tests/quick_roll_forward_test.sh
index 4e15e72..7dc28fe 100755
--- a/src/starboard/evergreen/testing/tests/quick_roll_forward_test.sh
+++ b/src/starboard/evergreen/testing/tests/quick_roll_forward_test.sh
@@ -25,14 +25,14 @@
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from test channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "update from test channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the test package"
     return 1
   fi
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "App is up to date"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.1.log" "App is up to date"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to run downloaded installation"
diff --git a/src/starboard/evergreen/testing/tests/racing_updaters_test.sh b/src/starboard/evergreen/testing/tests/racing_updaters_test.sh
index 087b5cd..1b839af 100755
--- a/src/starboard/evergreen/testing/tests/racing_updaters_test.sh
+++ b/src/starboard/evergreen/testing/tests/racing_updaters_test.sh
@@ -44,7 +44,7 @@
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "Created drain file"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "Created drain file"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to create a drain file for the test package"
@@ -57,7 +57,7 @@
 
   wait_and_force_race_condition "Created drain file" "${LOG_PATH}/${TEST_NAME}.1.log" "${FILENAME}" &
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "failed to lock slot"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.1.log" "failed to lock slot"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to recognize another update is updating slot"
diff --git a/src/starboard/evergreen/testing/tests/tcrash.html b/src/starboard/evergreen/testing/tests/tcrash.html
deleted file mode 100644
index e05af63..0000000
--- a/src/starboard/evergreen/testing/tests/tcrash.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2020 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.
--->
-<html>
-<meta charset="utf-8">
-<title>tcrash</title>
-<script>
-  var changeChannel = setInterval(tryChangeChannel, 500);
-
-  function tryChangeChannel() {
-    const channel = window.h5vcc.updater.getUpdaterChannel();
-    const status = window.h5vcc.updater.getUpdateStatus();
-
-    if (channel == "") {
-      return;
-    }
-
-    if (channel == "qa") {
-      if ((status == "App is up to date") || (status == "Update installed, pending restart")) {
-        window.h5vcc.updater.setUpdaterChannel("tcrash");
-        console.log("channel was changed to tcrash");
-        return;
-      }
-    }
-
-    if ((channel == "tcrash") && (status == "Update installed, pending restart")) {
-      console.log("update from tcrash channel installed");
-      clearInterval(changeChannel);
-    }
-  }
-</script>
-</html>
diff --git a/src/starboard/evergreen/testing/tests/test.html b/src/starboard/evergreen/testing/tests/test.html
index f404546..81a943c 100644
--- a/src/starboard/evergreen/testing/tests/test.html
+++ b/src/starboard/evergreen/testing/tests/test.html
@@ -18,28 +18,47 @@
 <meta charset="utf-8">
 <title>test</title>
 <script>
-  var changeChannel = setInterval(tryChangeChannel, 500);
+  var changeChannel = null;
+  var targetChannel = null;
 
   function tryChangeChannel() {
-    const channel = window.h5vcc.updater.getUpdaterChannel();
+    const currentChannel = window.h5vcc.updater.getUpdaterChannel();
     const status = window.h5vcc.updater.getUpdateStatus();
 
-    if (channel == "") {
+    if ((currentChannel == "") ||
+        ((status != "App is up to date") &&
+         (status != "Update installed, pending restart"))) {
       return;
     }
 
-    if (channel == "qa") {
-      if ((status == "App is up to date") || (status == "Update installed, pending restart")) {
-        window.h5vcc.updater.setUpdaterChannel("test");
-        console.log("channel was changed to test");
-        return;
-      }
+    if (currentChannel == "qa") {
+      window.h5vcc.updater.setUpdaterChannel(targetChannel);
+      console.log("channel was changed to " + targetChannel);
+      return;
     }
 
-    if ((channel == "test") && (status == "Update installed, pending restart")) {
-      console.log("update from test channel installed");
-      clearInterval(changeChannel);
+    if (currentChannel == targetChannel) {
+      console.log("update from " + targetChannel + " channel installed");
     }
   }
+
+  var query = window.location.search;
+
+  if (query) {
+    // Splits each paramter of the query into an array after removing the
+    // prepended "?".
+    query = query.slice(1).split("&");
+  }
+
+  query.forEach(part => {
+    if (changeChannel) {
+      return;
+    }
+
+    if (part.startsWith("channel=")) {
+      targetChannel = part.split("=")[1];
+      changeChannel = setInterval(tryChangeChannel, 500);
+    }
+  });
 </script>
 </html>
diff --git a/src/starboard/evergreen/testing/tests/tfailv.html b/src/starboard/evergreen/testing/tests/tfailv.html
deleted file mode 100644
index c039830..0000000
--- a/src/starboard/evergreen/testing/tests/tfailv.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2020 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.
--->
-<html>
-<meta charset="utf-8">
-<title>tfailv</title>
-<script>
-  var changeChannel = setInterval(tryChangeChannel, 500);
-
-  function tryChangeChannel() {
-    const channel = window.h5vcc.updater.getUpdaterChannel();
-    const status = window.h5vcc.updater.getUpdateStatus();
-
-    if (channel == "") {
-      return;
-    }
-
-    if (channel == "qa") {
-      if ((status == "App is up to date") || (status == "Update installed, pending restart")) {
-        window.h5vcc.updater.setUpdaterChannel("tfailv");
-        console.log("channel was changed to tfailv");
-        return;
-      }
-    }
-
-    if ((channel == "tfailv") && (status == "Update installed, pending restart")) {
-      console.log("update from tfailv channel installed");
-      clearInterval(changeChannel);
-    }
-  }
-</script>
-</html>
diff --git a/src/starboard/evergreen/testing/tests/tmsabi.html b/src/starboard/evergreen/testing/tests/tmsabi.html
deleted file mode 100644
index ae70b57..0000000
--- a/src/starboard/evergreen/testing/tests/tmsabi.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2020 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.
--->
-<html>
-<meta charset="utf-8">
-<title>tmsabi</title>
-<script>
-  var changeChannel = setInterval(tryChangeChannel, 500);
-
-  function tryChangeChannel() {
-    const channel = window.h5vcc.updater.getUpdaterChannel();
-    const status = window.h5vcc.updater.getUpdateStatus();
-
-    if (channel == "") {
-      return;
-    }
-
-    if (channel == "qa") {
-      if ((status == "App is up to date") || (status == "Update installed, pending restart")) {
-        window.h5vcc.updater.setUpdaterChannel("tmsabi");
-        console.log("channel was changed to tmsabi");
-        return;
-      }
-    }
-
-    if ((channel == "tmsabi") && (status == "Update installed, pending restart")) {
-      console.log("update from tmsabi channel installed");
-      clearInterval(changeChannel);
-    }
-  }
-</script>
-</html>
diff --git a/src/starboard/evergreen/testing/tests/tnoop.html b/src/starboard/evergreen/testing/tests/tnoop.html
deleted file mode 100644
index ecfa328..0000000
--- a/src/starboard/evergreen/testing/tests/tnoop.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2020 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.
--->
-<html>
-<meta charset="utf-8">
-<title>tnoop</title>
-<script>
-  var changeChannel = setInterval(tryChangeChannel, 500);
-
-  function tryChangeChannel() {
-    const channel = window.h5vcc.updater.getUpdaterChannel();
-    const status = window.h5vcc.updater.getUpdateStatus();
-
-    if (channel == "") {
-      return;
-    }
-
-    if (channel == "qa") {
-      if ((status == "App is up to date") || (status == "Update installed, pending restart")) {
-        window.h5vcc.updater.setUpdaterChannel("tnoop");
-        console.log("channel was changed to tnoop");
-        return;
-      }
-    }
-
-    if ((channel == "tnoop") && (status == "Update installed, pending restart")) {
-      console.log("update from tnoop channel installed");
-      clearInterval(changeChannel);
-    }
-  }
-</script>
-</html>
diff --git a/src/starboard/evergreen/testing/tests/tseries.html b/src/starboard/evergreen/testing/tests/tseries.html
index 0d3aeff..09b5a52 100644
--- a/src/starboard/evergreen/testing/tests/tseries.html
+++ b/src/starboard/evergreen/testing/tests/tseries.html
@@ -16,7 +16,7 @@
 -->
 <html>
 <meta charset="utf-8">
-<title>ttseries</title>
+<title>tseries</title>
 <script>
   var alternatedCount = 0;
   var alternatingChannels = setInterval(alternateChannels, 500);
@@ -25,23 +25,28 @@
     const channel = window.h5vcc.updater.getUpdaterChannel();
     const status = window.h5vcc.updater.getUpdateStatus();
 
+    if (channel == "") {
+      return;
+    }
+
+    if ((status != "App is up to date") &&
+        (status != "Update installed, pending restart")) {
+      return;
+    }
+
     if (channel == "qa") {
-      console.log("channel changed from qa to tseries1");
       window.h5vcc.updater.setUpdaterChannel("tseries1");
+      console.log("channel changed from qa to tseries1");
       return;
     }
 
     if (alternatedCount < 5) {
-      if (status != "Update installed, pending restart") {
-        return;
-      }
-
       if (channel == "tseries1") {
-        console.log("channel changed from tseries1 to tseries2");
         window.h5vcc.updater.setUpdaterChannel("tseries2");
+        console.log("channel changed from tseries1 to tseries2");
       } else {
-        console.log("channel changed from " + channel + " to tseries1");
         window.h5vcc.updater.setUpdaterChannel("tseries1");
+        console.log("channel changed from tseries2 to tseries1");
       }
 
       alternatedCount++;
diff --git a/src/starboard/evergreen/testing/tests/update_fails_verification_test.sh b/src/starboard/evergreen/testing/tests/update_fails_verification_test.sh
index bfcbbc9..1c7f40b 100755
--- a/src/starboard/evergreen/testing/tests/update_fails_verification_test.sh
+++ b/src/starboard/evergreen/testing/tests/update_fails_verification_test.sh
@@ -20,19 +20,19 @@
 unset -f run_test
 
 TEST_NAME="UpdateFailsVerification"
-TEST_FILE="tfailv.html"
+TEST_FILE="test.html"
 
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "Verification failed. Verifier error = [0-9]+"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=tfailv" "${TEST_NAME}.0.log" "Verification failed. Verifier error = [0-9]+"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to fail verifying the downloaded installation"
     return 1
   fi
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "App is up to date"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=tfailv" "${TEST_NAME}.1.log" "App is up to date"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to revert back to the system image"
diff --git a/src/starboard/evergreen/testing/tests/update_works_for_only_one_app_test.sh b/src/starboard/evergreen/testing/tests/update_works_for_only_one_app_test.sh
index 2574654..b09bdb4 100755
--- a/src/starboard/evergreen/testing/tests/update_works_for_only_one_app_test.sh
+++ b/src/starboard/evergreen/testing/tests/update_works_for_only_one_app_test.sh
@@ -25,14 +25,14 @@
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from test channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "update from test channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the test package"
     return 1
   fi
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "App is up to date"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.1.log" "App is up to date"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to run the downloaded installation"
diff --git a/src/starboard/evergreen/testing/tests/valid_slot_overwritten_test.sh b/src/starboard/evergreen/testing/tests/valid_slot_overwritten_test.sh
index 6fc33b0..6c66c86 100755
--- a/src/starboard/evergreen/testing/tests/valid_slot_overwritten_test.sh
+++ b/src/starboard/evergreen/testing/tests/valid_slot_overwritten_test.sh
@@ -25,14 +25,14 @@
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from test channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "update from test channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the test package"
     return 1
   fi
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "App is up to date"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.1.log" "App is up to date"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to run the downloaded installation"
@@ -47,7 +47,7 @@
 
   create_file "${STORAGE_DIR}/installation_${SLOT}/app_key_TEST.good"
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.2.log" "AdoptInstallation: current_installation=${SLOT}"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.2.log" "AdoptInstallation: current_installation=${SLOT}"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to adopt installation"
diff --git a/src/starboard/evergreen/testing/tests/verify_qa_channel_update_test.sh b/src/starboard/evergreen/testing/tests/verify_qa_channel_update_test.sh
index 66c4632..1d7e1c9 100755
--- a/src/starboard/evergreen/testing/tests/verify_qa_channel_update_test.sh
+++ b/src/starboard/evergreen/testing/tests/verify_qa_channel_update_test.sh
@@ -25,14 +25,14 @@
 function run_test() {
   clear_storage
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.0.log" "update from test channel installed"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "update from test channel installed"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to download and install the test package"
     return 1
   fi
 
-  start_cobalt "file:///tests/${TEST_FILE}" "${TEST_NAME}.1.log" "App is up to date"
+  start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.1.log" "App is up to date"
 
   if [[ $? -ne 0 ]]; then
     error "Failed to run the downloaded installation"
diff --git a/src/starboard/linux/x64x11/clang/3.6/cobalt/configuration.py b/src/starboard/linux/x64x11/clang/3.6/cobalt/configuration.py
new file mode 100644
index 0000000..b8098ae
--- /dev/null
+++ b/src/starboard/linux/x64x11/clang/3.6/cobalt/configuration.py
@@ -0,0 +1,35 @@
+# Copyright 2020 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.
+"""Starboard Linux x64x11 Clang 3.6 Cobalt configuration."""
+
+import os
+
+from starboard.linux.shared.cobalt import configuration as shared_configuration
+from starboard.tools.testing import test_filter
+
+class CobaltLinuxX64X11Clang36Configuration(shared_configuration.CobaltLinuxConfiguration):
+  """Starboard Linux x64x11 Clang 3.6 Cobalt configuration."""
+
+  def GetTestFilters(self):
+    filters = super(CobaltLinuxX64X11Clang36Configuration, self).GetTestFilters()
+    for target, tests in self.__FILTERED_TESTS.iteritems():
+      filters.extend(test_filter.TestFilter(target, test) for test in tests)
+    return filters
+
+  # A map of failing or crashing tests per target.
+  __FILTERED_TESTS = {
+      'zip_unittests': [
+          'ZipReaderTest.ExtractToFileAsync_RegularFile',
+      ],
+  }
diff --git a/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc b/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc
index 3003a56..20eaa0c 100644
--- a/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc
+++ b/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc
@@ -228,6 +228,281 @@
   }
 }
 
+TEST(SbMediaCanPlayMimeAndKeySystem, PrintMaximumSupport) {
+  // AVC
+  std::string avc_resolution = "Unsupported";
+  // 1080p
+  SbMediaSupportType result = SbMediaCanPlayMimeAndKeySystem(
+      "video/mp4; codecs=\"avc1.4d402a\"; width=1920; height=1080; "
+      "framerate=30",
+      "");
+  if (result == kSbMediaSupportTypeProbably) {
+    avc_resolution = "1080p";
+    // 2K
+    result = SbMediaCanPlayMimeAndKeySystem(
+        "video/mp4; codecs=\"avc1.64402a\"; width=2560; height=1440; "
+        "framerate=30",
+        "");
+    if (result == kSbMediaSupportTypeProbably) {
+      avc_resolution = "2K";
+      // 4K
+      result = SbMediaCanPlayMimeAndKeySystem(
+          "video/mp4; codecs=\"avc1.64402a\"; width=3840; height=2160; "
+          "framerate=30",
+          "");
+      if (result == kSbMediaSupportTypeProbably) {
+        avc_resolution = "4K";
+      }
+    }
+  }
+
+  // AVC HFR
+  std::string avc_hfr_resolution = "Unsupported";
+  // 1080p
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "video/mp4; codecs=\"avc1.4d402a\"; width=1920; height=1080; "
+      "framerate=60",
+      "");
+  if (result == kSbMediaSupportTypeProbably) {
+    avc_hfr_resolution = "1080p";
+    // 2K
+    result = SbMediaCanPlayMimeAndKeySystem(
+        "video/mp4; codecs=\"avc1.64402a\"; width=2560; height=1440; "
+        "framerate=60",
+        "");
+    if (result == kSbMediaSupportTypeProbably) {
+      avc_hfr_resolution = "2K";
+      // 4K
+      result = SbMediaCanPlayMimeAndKeySystem(
+          "video/mp4; codecs=\"avc1.64402a\"; width=3840; height=2160; "
+          "framerate=60",
+          "");
+      if (result == kSbMediaSupportTypeProbably) {
+        avc_hfr_resolution = "4K";
+      }
+    }
+  }
+
+  // VP9
+  std::string vp9_resolution = "Unsupported";
+  // 1080p
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "video/webm; codecs=\"vp9\"; width=1920; height=1080; framerate=30", "");
+  if (result == kSbMediaSupportTypeProbably) {
+    vp9_resolution = "1080p";
+    // 2K
+    result = SbMediaCanPlayMimeAndKeySystem(
+        "video/webm; codecs=\"vp9\"; width=2560; height=1440; framerate=30",
+        "");
+    if (result == kSbMediaSupportTypeProbably) {
+      vp9_resolution = "2K";
+      // 4K
+      result = SbMediaCanPlayMimeAndKeySystem(
+          "video/webm; codecs=\"vp9\"; width=3840; height=2160; framerate=30",
+          "");
+      if (result == kSbMediaSupportTypeProbably) {
+        vp9_resolution = "4K";
+      }
+    }
+  }
+
+  // VP9 HFR
+  std::string vp9_hfr_resolution = "Unsupported";
+  // 1080p
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "video/webm; codecs=\"vp9\"; width=1920; height=1080; framerate=60", "");
+  if (result == kSbMediaSupportTypeProbably) {
+    vp9_hfr_resolution = "1080p";
+    // 2K
+    result = SbMediaCanPlayMimeAndKeySystem(
+        "video/webm; codecs=\"vp9\"; width=2560; height=1440; framerate=60",
+        "");
+    if (result == kSbMediaSupportTypeProbably) {
+      vp9_hfr_resolution = "2K";
+      // 4K
+      result = SbMediaCanPlayMimeAndKeySystem(
+          "video/webm; codecs=\"vp9\"; width=3840; height=2160; framerate=60",
+          "");
+      if (result == kSbMediaSupportTypeProbably) {
+        vp9_hfr_resolution = "4K";
+      }
+    }
+  }
+
+  // VP9 HDR
+  std::string vp9_hdr_resolution = "Unsupported";
+  // 1080p
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "video/webm; codecs=\"vp09.02.51.10.01.09.16.09.00\"; width=1920; "
+      "height=1080",
+      "");
+  if (result == kSbMediaSupportTypeProbably) {
+    vp9_hdr_resolution = "1080p";
+    // 2K
+    result = SbMediaCanPlayMimeAndKeySystem(
+        "video/webm; codecs=\"vp09.02.51.10.01.09.16.09.00\"; width=2560; "
+        "height=1440; framerate=30",
+        "");
+    if (result == kSbMediaSupportTypeProbably) {
+      vp9_hdr_resolution = "2K";
+      // 4K
+      result = SbMediaCanPlayMimeAndKeySystem(
+          "video/webm; codecs=\"vp09.02.51.10.01.09.16.09.00\"; width=3840; "
+          "height=2160; framerate=30",
+          "");
+      if (result == kSbMediaSupportTypeProbably) {
+        vp9_hdr_resolution = "4K";
+      }
+    }
+  }
+
+  // AV1
+  std::string av1_resolution = "Unsupported";
+  // 1080p
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "video/mp4; codecs=\"av01.0.08M.08\"; width=1920; "
+      "height=1080; framerate=30",
+      "");
+  if (result == kSbMediaSupportTypeProbably) {
+    av1_resolution = "1080p";
+    // 2K
+    result = SbMediaCanPlayMimeAndKeySystem(
+        "video/mp4; codecs=\"av01.0.08M.08\"; width=2560; "
+        "height=1440; framerate=30",
+        "");
+    if (result == kSbMediaSupportTypeProbably) {
+      av1_resolution = "2K";
+      // 4K
+      result = SbMediaCanPlayMimeAndKeySystem(
+          "video/mp4; codecs=\"av01.0.08M.08\"; width=3840; "
+          "height=2160; framerate=30",
+          "");
+      if (result == kSbMediaSupportTypeProbably) {
+        av1_resolution = "4K";
+      }
+    }
+  }
+  // AV1 HFR
+  std::string av1_hfr_resolution = "Unsupported";
+  // 1080p
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "video/mp4; codecs=\"av01.0.08M.08\"; width=1920; "
+      "height=1080; framerate=60",
+      "");
+  if (result == kSbMediaSupportTypeProbably) {
+    av1_hfr_resolution = "1080p";
+    // 2K
+    result = SbMediaCanPlayMimeAndKeySystem(
+        "video/mp4; codecs=\"av01.0.08M.08\"; width=2560; "
+        "height=1440; framerate=60",
+        "");
+    if (result == kSbMediaSupportTypeProbably) {
+      av1_hfr_resolution = "2K";
+      // 4K
+      result = SbMediaCanPlayMimeAndKeySystem(
+          "video/mp4; codecs=\"av01.0.08M.08\"; width=3840; "
+          "height=2160; framerate=60",
+          "");
+      if (result == kSbMediaSupportTypeProbably) {
+        av1_hfr_resolution = "4K";
+      }
+    }
+  }
+
+  // AV1 HDR
+  std::string av1_hdr_resolution = "Unsupported";
+  // 1080p
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "video/mp4; codecs=\"av01.0.09M.10.0.110.09.16.09.0\"; width=1920; "
+      "height=1080; framerate=30",
+      "");
+  if (result == kSbMediaSupportTypeProbably) {
+    av1_hdr_resolution = "1080p";
+    // 2K
+    result = SbMediaCanPlayMimeAndKeySystem(
+        "video/mp4; codecs=\"av01.0.12M.10.0.110.09.16.09.0\"; width=2560; "
+        "height=1440; framerate=30",
+        "");
+    if (result == kSbMediaSupportTypeProbably) {
+      av1_hdr_resolution = "2K";
+      // 4K
+      result = SbMediaCanPlayMimeAndKeySystem(
+          "video/mp4; codecs=\"av01.0.13M.10.0.110.09.16.09.0\"; width=3840; "
+          "height=2160; framerate=30",
+          "");
+      if (result == kSbMediaSupportTypeProbably) {
+        av1_hdr_resolution = "4K";
+      }
+    }
+  }
+
+  // AAC
+  std::string aac_support = "Unsupported";
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "audio/mp4; codecs=\"mp4a.40.2\"; channels=2", "");
+  if (result == kSbMediaSupportTypeProbably) {
+    aac_support = "Supported";
+  }
+
+  // AAC51
+  std::string aac51_support = "Unsupported";
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "audio/mp4; codecs=\"mp4a.40.2\"; channels=6", "");
+  if (result == kSbMediaSupportTypeProbably) {
+    aac51_support = "Supported";
+  }
+
+  // Opus
+  std::string opus_support = "Unsupported";
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "audio/webm; codecs=\"opus\"; "
+      "channels=2; bitrate=576;",
+      "");
+  if (result == kSbMediaSupportTypeProbably) {
+    opus_support = "Supported";
+  }
+
+  // Opus51
+  std::string opus51_support = "Unsupported";
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "audio/webm; codecs=\"opus\"; "
+      "channels=6; bitrate=576;",
+      "");
+  if (result == kSbMediaSupportTypeProbably) {
+    opus51_support = "Supported";
+  }
+
+  // AC-3
+  std::string ac3_support = "Unsupported";
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "audio/mp4; codecs=\"ac-3\"; channels=2", "");
+  if (result == kSbMediaSupportTypeProbably) {
+    ac3_support = "Supported";
+  }
+
+  // E-AC-3
+  std::string eac3_support = "Unsupported";
+  result = SbMediaCanPlayMimeAndKeySystem(
+      "audio/mp4; codecs=\"ec-3\"; channels=2", "");
+  if (result == kSbMediaSupportTypeProbably) {
+    eac3_support = "Supported";
+  }
+
+  SB_LOG(INFO) << "\nVideo Codec Capability:\n\tAVC: " << avc_resolution
+               << "\n\tAVC HFR: " << avc_hfr_resolution
+               << "\n\tVP9: " << vp9_resolution
+               << "\n\tVP9 HFR: " << vp9_hfr_resolution
+               << "\n\tVP9 HDR: " << vp9_hdr_resolution
+               << "\n\tAV1: " << av1_resolution
+               << "\n\tAV1 HFR:" << av1_hfr_resolution
+               << "\n\tAV1 HDR:" << av1_hdr_resolution
+               << "\n\nAudio Codec Capability:\n\tAAC: " << aac_support
+               << "\n\tAAC 51: " << aac51_support
+               << "\n\tOpus: " << opus_support
+               << "\n\tOpus 51: " << opus51_support
+               << "\n\tAC-3: " << ac3_support << "\n\tE-AC-3: " << eac3_support;
+}
+
 }  // namespace
 }  // namespace nplb
 }  // namespace starboard
diff --git a/src/starboard/nplb/time_constants.h b/src/starboard/nplb/time_constants.h
index 2b87459..e816429 100644
--- a/src/starboard/nplb/time_constants.h
+++ b/src/starboard/nplb/time_constants.h
@@ -47,15 +47,15 @@
 static const SbTime kTestTimeWindowsNegative =
     SbTimeFromPosix(SB_INT64_C(-15065654400) * kSbTimeSecond);
 
-// 1443473373 in POSIX time is
-// Monday, 9/28/2015 20:49:33 UTC
-// NOTE: Update this value once every 5 or so years.
+// 1600970155 in POSIX time is
+// Thursday, 9/24/2020 17:55:55 UTC
+// NOTE: Update this value once every 25 or so years.
 static const SbTime kTestTimeWritten =
-    SbTimeFromPosix(SB_INT64_C(1443473373) * kSbTimeSecond);
+    SbTimeFromPosix(SB_INT64_C(1600970155) * kSbTimeSecond);
 
-// 5 years after the time this test was written.
+// 25 years after the time this test was written.
 static const SbTime kTestTimePastWritten =
-    SbTimeFromPosix(kTestTimeWritten + (5 * kTestSbTimeYear));
+    SbTimeFromPosix(kTestTimeWritten + (25 * kTestSbTimeYear));
 
 }  // namespace nplb
 }  // namespace starboard
diff --git a/src/starboard/shared/signal/suspend_signals.cc b/src/starboard/shared/signal/suspend_signals.cc
index 83d48f5..6e89b38 100644
--- a/src/starboard/shared/signal/suspend_signals.cc
+++ b/src/starboard/shared/signal/suspend_signals.cc
@@ -61,27 +61,10 @@
 
 #if SB_API_VERSION >= SB_ADD_CONCEALED_STATE_SUPPORT_VERSION || \
     SB_HAS(CONCEALED_STATE)
-
-#if SB_IS(EVERGREEN_COMPATIBLE)
-void RequestConcealOrStop() {
-  if (loader_app::IsPendingRestart()) {
-    SbLogRawFormatF("\nPending update restart. Stopping.\n");
-    SbLogFlush();
-    SbSystemRequestStop(0);
-  } else {
-    SbSystemRequestConceal();
-  }
-}
-#endif
-
 void Conceal(int signal_id) {
   SignalMask(kAllSignals, SIG_BLOCK);
   LogSignalCaught(signal_id);
-#if SB_IS(EVERGREEN_COMPATIBLE)
-  RequestConcealOrStop();
-#else
   SbSystemRequestConceal();
-#endif
   SignalMask(kAllSignals, SIG_UNBLOCK);
 }
 
@@ -107,27 +90,10 @@
   SignalMask(kAllSignals, SIG_UNBLOCK);
 }
 #else
-
-#if SB_IS(EVERGREEN_COMPATIBLE)
-void RequestSuspendOrStop() {
-  if (loader_app::IsPendingRestart()) {
-    SbLogRawFormatF("\nPending update restart . Stopping.\n");
-    SbLogFlush();
-    SbSystemRequestStop(0);
-  } else {
-    SbSystemRequestSuspend();
-  }
-}
-#endif
-
 void Suspend(int signal_id) {
   SignalMask(kAllSignals, SIG_BLOCK);
   LogSignalCaught(signal_id);
-#if SB_IS(EVERGREEN_COMPATIBLE)
-  RequestSuspendOrStop();
-#else
   SbSystemRequestSuspend();
-#endif
   SignalMask(kAllSignals, SIG_UNBLOCK);
 }
 
diff --git a/src/starboard/shared/signal/system_request_freeze.cc b/src/starboard/shared/signal/system_request_freeze.cc
index bfadf43..374261e 100644
--- a/src/starboard/shared/signal/system_request_freeze.cc
+++ b/src/starboard/shared/signal/system_request_freeze.cc
@@ -17,6 +17,10 @@
 #include "starboard/shared/signal/signal_internal.h"
 #include "starboard/shared/starboard/application.h"
 
+#if SB_IS(EVERGREEN_COMPATIBLE)
+#include "starboard/loader_app/pending_restart.h"
+#endif
+
 #if SB_API_VERSION >= SB_ADD_CONCEALED_STATE_SUPPORT_VERSION || \
     SB_HAS(CONCEALED_STATE)
 void FreezeDone(void* /*context*/) {
@@ -25,8 +29,19 @@
 }
 
 void SbSystemRequestFreeze() {
+#if SB_IS(EVERGREEN_COMPATIBLE)
+  if (starboard::loader_app::IsPendingRestart()) {
+    SbLogRawFormatF("\nPending update restart . Stopping.\n");
+    SbLogFlush();
+    starboard::shared::starboard::Application::Get()->Stop(0);
+  } else {
+    // Let the platform decide if directly transit into Frozen.
+    starboard::shared::starboard::Application::Get()->Freeze(NULL, &FreezeDone);
+  }
+#else
   // Let the platform decide if directly transit into Frozen.
   starboard::shared::starboard::Application::Get()->Freeze(NULL, &FreezeDone);
+#endif
 }
 #endif  // SB_API_VERSION >= SB_ADD_CONCEALED_STATE_SUPPORT_VERSION ||
         // SB_HAS(CONCEALED_STATE)
diff --git a/src/starboard/shared/signal/system_request_suspend.cc b/src/starboard/shared/signal/system_request_suspend.cc
index e3977d9..950d487 100644
--- a/src/starboard/shared/signal/system_request_suspend.cc
+++ b/src/starboard/shared/signal/system_request_suspend.cc
@@ -17,6 +17,10 @@
 #include "starboard/shared/signal/signal_internal.h"
 #include "starboard/shared/starboard/application.h"
 
+#if SB_IS(EVERGREEN_COMPATIBLE)
+#include "starboard/loader_app/pending_restart.h"
+#endif
+
 #if SB_API_VERSION < SB_ADD_CONCEALED_STATE_SUPPORT_VERSION && \
     !SB_HAS(CONCEALED_STATE)
 void SuspendDone(void* /*context*/) {
@@ -25,7 +29,18 @@
 }
 
 void SbSystemRequestSuspend() {
+#if SB_IS(EVERGREEN_COMPATIBLE)
+  if (starboard::loader_app::IsPendingRestart()) {
+    SbLogRawFormatF("\nPending update restart . Stopping.\n");
+    SbLogFlush();
+    starboard::shared::starboard::Application::Get()->Stop(0);
+  } else {
+    starboard::shared::starboard::Application::Get()->Suspend(NULL,
+                                                              &SuspendDone);
+  }
+#else
   starboard::shared::starboard::Application::Get()->Suspend(NULL, &SuspendDone);
+#endif
 }
 #endif  // SB_API_VERSION < SB_ADD_CONCEALED_STATE_SUPPORT_VERSION &&
         // !SB_HAS(CONCEALED_STATE)
diff --git a/src/starboard/starboard.gyp b/src/starboard/starboard.gyp
index 0808490..9c74ba2 100644
--- a/src/starboard/starboard.gyp
+++ b/src/starboard/starboard.gyp
@@ -19,7 +19,7 @@
 {
   'targets': [
     {
-      'target_name': 'starboard_base',
+      'target_name': 'starboard',
       'type': 'none',
       'conditions': [
         ['sb_evergreen == 1', {
@@ -37,14 +37,6 @@
             'starboard_full',
           ],
         }],
-       ],
-    },
-    {
-      'target_name': 'starboard',
-      'type': 'none',
-      'dependencies': [
-        '<(DEPTH)/third_party/crashpad/wrapper/wrapper.gyp:crashpad_wrapper_stub',
-        'starboard_base',
       ],
     },
     {
@@ -60,6 +52,15 @@
         '<(DEPTH)/<(starboard_path)/starboard_platform.gyp:starboard_platform',
       ],
       'conditions': [
+        ['sb_crashpad_enabled == 1', {
+          'dependencies': [
+            '<(DEPTH)/third_party/crashpad/wrapper/wrapper.gyp:crashpad_wrapper',
+          ],
+        }, {
+          'dependencies': [
+            '<(DEPTH)/third_party/crashpad/wrapper/wrapper.gyp:crashpad_wrapper_stub',
+          ],
+        }],
         ['final_executable_type=="shared_library"', {
           'all_dependent_settings': {
             'target_conditions': [
diff --git a/src/starboard/ui_navigation.h b/src/starboard/ui_navigation.h
index 6ff4137..e110c43 100644
--- a/src/starboard/ui_navigation.h
+++ b/src/starboard/ui_navigation.h
@@ -162,6 +162,10 @@
   // This specifies directionality for container items. Containers within
   // containers do not inherit directionality. Directionality must be specified
   // for each container explicitly.
+#if SB_API_VERSION >= SB_UI_NAVIGATION2_VERSION
+  //
+  // This should work even if |item| is disabled.
+#endif
   void (*set_item_dir)(SbUiNavItem item, SbUiNavItemDir dir);
 
   // Set the interactable size of the specified navigation item. By default,
@@ -246,6 +250,11 @@
   //   [container position] + [content position] - [container content offset]
   // If |item| is not a container, then this does nothing.
   // By default, the content offset is (0,0).
+#if SB_API_VERSION >= SB_UI_NAVIGATION2_VERSION
+  //
+  // This should update the values returned by get_item_content_offset() even
+  // if the |item| is disabled.
+#endif
   void (*set_item_content_offset)(SbUiNavItem item,
                                   float content_offset_x,
                                   float content_offset_y);
@@ -262,6 +271,12 @@
   void (*get_item_content_offset)(SbUiNavItem item,
                                   float* out_content_offset_x,
                                   float* out_content_offset_y);
+
+#if SB_API_VERSION >= SB_UI_NAVIGATION2_VERSION
+  // Call |update_function| with |context| to perform a series of UI navigation
+  // changes atomically before returning.
+  void (*do_batch_update)(void (*update_function)(void*), void* context);
+#endif
 } SbUiNavInterface;
 
 // --- Constants -------------------------------------------------------------
diff --git a/src/third_party/crashpad/util/file/file_io.h b/src/third_party/crashpad/util/file/file_io.h
index 6fa0f96..46b1ee6 100644
--- a/src/third_party/crashpad/util/file/file_io.h
+++ b/src/third_party/crashpad/util/file/file_io.h
@@ -19,6 +19,7 @@
 
 #include <string>
 
+#include "base/base_wrapper.h"
 #include "build/build_config.h"
 
 #if defined(OS_POSIX)
diff --git a/src/third_party/crashpad/util/net/http_transport_socket.cc b/src/third_party/crashpad/util/net/http_transport_socket.cc
index 5a88ccd..278a8b8 100644
--- a/src/third_party/crashpad/util/net/http_transport_socket.cc
+++ b/src/third_party/crashpad/util/net/http_transport_socket.cc
@@ -144,7 +144,12 @@
                            kSbFileSepString + "cobalt" + kSbFileSepString +
                            "content" + kSbFileSepString + "ssl" +
                            kSbFileSepString + "certs");
-
+      // If this is not Cobalt Evergreen setup use the regular content path.
+      if (!SbFileExists(cert_location.c_str())) {
+        cert_location = buffer.data();
+        cert_location.append(std::string(kSbFileSepString) + "ssl" +
+                             kSbFileSepString + "certs");
+      }
       if (SSL_CTX_load_verify_locations(
               ctx_.get(), nullptr, cert_location.c_str()) <= 0) {
         LOG(ERROR) << "SSL_CTX_load_verify_locations";
diff --git a/src/third_party/crashpad/wrapper/wrapper.cc b/src/third_party/crashpad/wrapper/wrapper.cc
index 0ab09e5..ef36040 100644
--- a/src/third_party/crashpad/wrapper/wrapper.cc
+++ b/src/third_party/crashpad/wrapper/wrapper.cc
@@ -25,6 +25,7 @@
 #include "client/settings.h"
 #include "starboard/configuration_constants.h"
 #include "starboard/directory.h"
+#include "starboard/file.h"
 #include "starboard/system.h"
 
 namespace third_party {
@@ -179,6 +180,12 @@
   ::crashpad::CrashpadClient* client = GetCrashpadClient();
 
   const base::FilePath handler_path = GetPathToCrashpadHandlerBinary();
+  if (!SbFileExists(handler_path.value().c_str())) {
+    LOG(WARNING) << "crashpad_handler not at expected location of "
+                 << handler_path.value();
+    return;
+  }
+
   const base::FilePath database_directory_path = GetDatabasePath();
   const base::FilePath default_metrics_dir;
   const std::string product_name = GetProductName();
diff --git a/src/third_party/crashpad/wrapper/wrapper.gyp b/src/third_party/crashpad/wrapper/wrapper.gyp
index a9a4382..b7196e1 100644
--- a/src/third_party/crashpad/wrapper/wrapper.gyp
+++ b/src/third_party/crashpad/wrapper/wrapper.gyp
@@ -22,22 +22,16 @@
         'wrapper.h',
       ],
     },
-  ],
-  'conditions': [
-    ['sb_evergreen_compatible == 1', {
-      'targets': [
-        {
-          'target_name': 'crashpad_wrapper',
-          'type': 'static_library',
-          'sources': [
-            'wrapper.cc',
-            'wrapper.h',
-          ],
-          'dependencies': [
-            '<(DEPTH)/third_party/crashpad/client/client.gyp:crashpad_client',
-          ],
-        },
+    {
+      'target_name': 'crashpad_wrapper',
+      'type': 'static_library',
+      'sources': [
+        'wrapper.cc',
+        'wrapper.h',
       ],
-    }],
+      'dependencies': [
+        '<(DEPTH)/third_party/crashpad/client/client.gyp:crashpad_client',
+      ],
+    },
   ],
 }
diff --git a/src/third_party/mini_chromium/base/base.gyp b/src/third_party/mini_chromium/base/base.gyp
index 7d1dbee..71dd510 100644
--- a/src/third_party/mini_chromium/base/base.gyp
+++ b/src/third_party/mini_chromium/base/base.gyp
@@ -43,6 +43,7 @@
         'atomicops_internals_atomicword_compat.h',
         'atomicops_internals_portable.h',
         'auto_reset.h',
+        'base_wrapper.h',
         'bit_cast.h',
         'compiler_specific.h',
         'debug/alias.cc',
diff --git a/src/third_party/mini_chromium/base/base_wrapper.h b/src/third_party/mini_chromium/base/base_wrapper.h
new file mode 100644
index 0000000..ae57c30
--- /dev/null
+++ b/src/third_party/mini_chromium/base/base_wrapper.h
@@ -0,0 +1,29 @@
+// Copyright 2020 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef MINI_CHROMIUM_BASE_BASE_WRAPPER_H_
+#define MINI_CHROMIUM_BASE_BASE_WRAPPER_H_
+
+// Change the symbol name to avoid collisions with //base
+#define FilePath MFilePath
+#define GetLogMessageHandler MGetLogMessageHandler
+#define LogMessage MLogMessage
+#define ReadUnicodeCharacter MReadUnicodeCharacter
+#define SetLogMessageHandler MSetLogMessageHandler
+#define UTF16ToUTF8 MUTF16ToUTF8
+#define UmaHistogramSparse MUmaHistogramSparse
+#define WriteUnicodeCharacter MWriteUnicodeCharacter
+#define c16len mc16len
+
+#endif  // MINI_CHROMIUM_BASE_BASE_WRAPPER_H_
diff --git a/src/third_party/mini_chromium/base/files/file_path.h b/src/third_party/mini_chromium/base/files/file_path.h
index 0ac91bf..ca20380 100644
--- a/src/third_party/mini_chromium/base/files/file_path.h
+++ b/src/third_party/mini_chromium/base/files/file_path.h
@@ -107,6 +107,7 @@
 #include <iosfwd>
 #include <string>
 
+#include "base/base_wrapper.h"
 #include "base/compiler_specific.h"
 #include "build/build_config.h"
 
diff --git a/src/third_party/mini_chromium/base/logging.h b/src/third_party/mini_chromium/base/logging.h
index 37bf23b..0270090 100644
--- a/src/third_party/mini_chromium/base/logging.h
+++ b/src/third_party/mini_chromium/base/logging.h
@@ -12,6 +12,7 @@
 #include <sstream>
 #include <string>
 
+#include "base/base_wrapper.h"
 #include "base/macros.h"
 #include "build/build_config.h"
 
diff --git a/src/third_party/mini_chromium/base/metrics/histogram_functions.h b/src/third_party/mini_chromium/base/metrics/histogram_functions.h
index a96cb9d..5f2af8f 100644
--- a/src/third_party/mini_chromium/base/metrics/histogram_functions.h
+++ b/src/third_party/mini_chromium/base/metrics/histogram_functions.h
@@ -7,6 +7,8 @@
 
 #include <string>
 
+#include "base/base_wrapper.h"
+
 // These are no-op stub versions of a subset of the functions from Chromium's
 // base/metrics/histogram_functions.h. This allows us to instrument the Crashpad
 // code as necessary, while not affecting out-of-Chromium builds.
diff --git a/src/third_party/mini_chromium/base/strings/string16.h b/src/third_party/mini_chromium/base/strings/string16.h
index 04605e4..bb311c2 100644
--- a/src/third_party/mini_chromium/base/strings/string16.h
+++ b/src/third_party/mini_chromium/base/strings/string16.h
@@ -10,6 +10,7 @@
 
 #include <string>
 
+#include "base/base_wrapper.h"
 #include "build/build_config.h"
 
 namespace base {
diff --git a/src/third_party/mini_chromium/base/strings/utf_string_conversion_utils.h b/src/third_party/mini_chromium/base/strings/utf_string_conversion_utils.h
index 72f86ae..4d5353d 100644
--- a/src/third_party/mini_chromium/base/strings/utf_string_conversion_utils.h
+++ b/src/third_party/mini_chromium/base/strings/utf_string_conversion_utils.h
@@ -5,6 +5,7 @@
 #ifndef MINI_CHROMIUM_BASE_STRINGS_UTF_STRING_CONVERSION_UTILS_H_
 #define MINI_CHROMIUM_BASE_STRINGS_UTF_STRING_CONVERSION_UTILS_H_
 
+#include "base/base_wrapper.h"
 #include "base/strings/string16.h"
 
 namespace base {
diff --git a/src/third_party/mini_chromium/base/strings/utf_string_conversions.h b/src/third_party/mini_chromium/base/strings/utf_string_conversions.h
index c2ca674..8e97fcd 100644
--- a/src/third_party/mini_chromium/base/strings/utf_string_conversions.h
+++ b/src/third_party/mini_chromium/base/strings/utf_string_conversions.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "base/base_wrapper.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 
diff --git a/src/third_party/zlib/zlib.gyp b/src/third_party/zlib/zlib.gyp
index a122c83..e6df9b9 100644
--- a/src/third_party/zlib/zlib.gyp
+++ b/src/third_party/zlib/zlib.gyp
@@ -520,7 +520,6 @@
         'minizip',
         'zip',
         'zlib',
-        '<(DEPTH)/base/base.gyp:base',
         '<(DEPTH)/base/base.gyp:test_support_base',
         '<(DEPTH)/starboard/common/common.gyp:common',
         '<(DEPTH)/testing/gmock.gyp:gmock',
diff --git a/src/v8/src/base/platform/platform-starboard.cc b/src/v8/src/base/platform/platform-starboard.cc
index a9a0118..0caa0d2 100644
--- a/src/v8/src/base/platform/platform-starboard.cc
+++ b/src/v8/src/base/platform/platform-starboard.cc
@@ -4,7 +4,7 @@
 
 // Platform-specific code for Starboard goes here. Starboard is the platform
 // abstraction layer for Cobalt, an HTML5 container used mainly by YouTube
-// LivingRoom products.
+// apps in the living room.
 
 #include "src/base/lazy-instance.h"
 #include "src/base/macros.h"