Import Cobalt 21.lts.4.302122
diff --git a/src/base/logging.cc b/src/base/logging.cc
index e75d72e..e2e29eb 100644
--- a/src/base/logging.cc
+++ b/src/base/logging.cc
@@ -138,7 +138,11 @@
   return "UNKNOWN";
 }
 
-int g_min_log_level = 0;
+#if defined(OFFICIAL_BUILD)
+int g_min_log_level = LOG_FATAL;
+#else
+int g_min_log_level = LOG_INFO;
+#endif
 
 LoggingDestination g_logging_destination = LOG_DEFAULT;
 
@@ -558,7 +562,7 @@
 #endif
 }
 
-#if defined(OFFICIAL_BUILD)
+#if defined(OFFICIAL_BUILD) && !SB_IS(EVERGREEN)
 int GetMinLogLevel() {
   return LOG_NUM_SEVERITIES;
 }
@@ -582,7 +586,7 @@
 
 void SetLogPrefix(const char* prefix) {}
 
-#else  // defined(OFFICIAL_BUILD)
+#else  // defined(OFFICIAL_BUILD) && !SB_IS(EVERGREEN)
 
 int GetMinLogLevel() {
   return g_min_log_level;
@@ -626,7 +630,7 @@
          base::ContainsOnlyChars(prefix, "abcdefghijklmnopqrstuvwxyz"));
   g_log_prefix = prefix;
 }
-#endif  // defined(OFFICIAL_BUILD)
+#endif  // defined(OFFICIAL_BUILD) && !SB_IS(EVERGREEN)
 
 void SetShowErrorDialogs(bool enable_dialogs) {
   show_error_dialogs = enable_dialogs;
diff --git a/src/base/logging.h b/src/base/logging.h
index 5363975..e2e94b5 100644
--- a/src/base/logging.h
+++ b/src/base/logging.h
@@ -412,12 +412,12 @@
 // LOG_IS_ON(DFATAL) always holds in debug mode. In particular, CHECK()s will
 // always fire if they fail.
 
-#if defined(OFFICIAL_BUILD)
+#if defined(OFFICIAL_BUILD) && !SB_IS(EVERGREEN)
 #define LOG_IS_ON(severity) false
-#else  // defined(OFFICIAL_BUILD)
+#else  // defined(OFFICIAL_BUILD) && !SB_IS(EVERGREEN)
 #define LOG_IS_ON(severity) \
   (::logging::ShouldCreateLogMessage(::logging::LOG_##severity))
-#endif  // defined(OFFICIAL_BUILD)
+#endif  // defined(OFFICIAL_BUILD) && !SB_IS(EVERGREEN)
 
 // We can't do any caching tricks with VLOG_IS_ON() like the
 // google-glog version since it requires GCC extensions.  This means
@@ -445,9 +445,9 @@
 #define LOG_IF(severity, condition) \
   LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity) && (condition))
 
-#if defined(OFFICIAL_BUILD)
+#if defined(OFFICIAL_BUILD) && !SB_IS(EVERGREEN)
 #define LOG_ONCE(severity) EAT_STREAM_PARAMETERS
-#else  // defined(OFFICIAL_BUILD)
+#else  // defined(OFFICIAL_BUILD) && !SB_IS(EVERGREEN)
 #define LOG_ONCE_MSG "[once] "
 
 constexpr uint32_t kFnvOffsetBasis32 = 0x811c9dc5U;
@@ -481,7 +481,7 @@
           ((::logging::LogOnceHelper<::logging::hash_32_fnv1a_const(__FILE__), \
                                     __LINE__>::logged_ = true) == true)))      \
       << LOG_ONCE_MSG
-#endif  // defined(OFFICIAL_BUILD)
+#endif  // defined(OFFICIAL_BUILD) && !SB_IS(EVERGREEN)
 
 // The VLOG macros log with negative verbosities.
 #define VLOG_STREAM(verbose_level) \
diff --git a/src/cobalt/CHANGELOG.md b/src/cobalt/CHANGELOG.md
index 9c41986..3799287 100644
--- a/src/cobalt/CHANGELOG.md
+++ b/src/cobalt/CHANGELOG.md
@@ -148,6 +148,12 @@
    Platforms can implement UrlFetcher observer for performance tracing by
    implementing CobaltExtensionUrlFetcherObserverApi.
 
+ - **Added support for Cobalt Updater Notification.**
+
+   Platforms can implement CobaltExtensionUpdaterNotificationApi to
+   receive notifications from the Cobalt Evergreen Updater.
+
+
 ## Version 20
 
  - **Support for QUIC and SPDY is now enabled.**
diff --git a/src/cobalt/browser/application.cc b/src/cobalt/browser/application.cc
index 3bd90e2..7d6a781 100644
--- a/src/cobalt/browser/application.cc
+++ b/src/cobalt/browser/application.cc
@@ -444,13 +444,15 @@
 }
 
 std::string GetMinLogLevelString() {
-#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kMinLogLevel)) {
     return command_line->GetSwitchValueASCII(switches::kMinLogLevel);
   }
-#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
+#if defined(OFFICIAL_BUILD)
+  return "fatal";
+#else
   return "info";
+#endif
 }
 
 int StringToLogLevel(const std::string& log_level) {
@@ -464,7 +466,11 @@
     return logging::LOG_FATAL;
   } else {
     NOTREACHED() << "Unrecognized logging level: " << log_level;
+#if defined(OFFICIAL_BUILD)
+    return logging::LOG_FATAL;
+#else
     return logging::LOG_INFO;
+#endif
   }
 }
 
@@ -846,7 +852,8 @@
 #endif
 
 #if SB_IS(EVERGREEN)
-  if (SbSystemGetExtension(kCobaltExtensionInstallationManagerName)) {
+  if (SbSystemGetExtension(kCobaltExtensionInstallationManagerName) &&
+      !command_line->HasSwitch(switches::kDisableUpdaterModule)) {
     updater_module_.reset(new updater::UpdaterModule(network_module_.get()));
   }
 #endif
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc
index 27fab77..189622c 100644
--- a/src/cobalt/browser/browser_module.cc
+++ b/src/cobalt/browser/browser_module.cc
@@ -715,7 +715,8 @@
   TRACE_EVENT0("cobalt::browser", "BrowserModule::RequestScreenshotToFile()");
   DCHECK(screen_shot_writer_);
 
-  scoped_refptr<render_tree::Node> render_tree = GetLastSubmissionAnimated();
+  scoped_refptr<render_tree::Node> render_tree =
+      web_module_->DoSynchronousLayoutAndGetRenderTree();
   if (!render_tree) {
     LOG(WARNING) << "Unable to get animated render tree";
     return;
@@ -732,7 +733,8 @@
   TRACE_EVENT0("cobalt::browser", "BrowserModule::RequestScreenshotToMemory()");
   DCHECK(screen_shot_writer_);
 
-  scoped_refptr<render_tree::Node> render_tree = GetLastSubmissionAnimated();
+  scoped_refptr<render_tree::Node> render_tree =
+      web_module_->DoSynchronousLayoutAndGetRenderTree();
   if (!render_tree) {
     LOG(WARNING) << "Unable to get animated render tree";
     return;
@@ -742,25 +744,6 @@
                                                  clip_rect, screenshot_ready);
 }
 
-scoped_refptr<render_tree::Node> BrowserModule::GetLastSubmissionAnimated() {
-  DCHECK(main_web_module_layer_);
-  base::Optional<renderer::Submission> last_submission =
-      main_web_module_layer_->GetCurrentSubmission();
-  if (!last_submission) {
-    LOG(WARNING) << "Unable to find last submission.";
-    return nullptr;
-  }
-  DCHECK(last_submission->render_tree);
-
-  render_tree::animations::AnimateNode* animate_node =
-      base::polymorphic_downcast<render_tree::animations::AnimateNode*>(
-          last_submission->render_tree.get());
-  render_tree::animations::AnimateNode::AnimateResults results =
-      animate_node->Apply(last_submission->time_offset);
-
-  return results.animated->source();
-}
-
 void BrowserModule::ProcessRenderTreeSubmissionQueue() {
   TRACE_EVENT0("cobalt::browser",
                "BrowserModule::ProcessRenderTreeSubmissionQueue()");
diff --git a/src/cobalt/browser/browser_module.h b/src/cobalt/browser/browser_module.h
index f5bce8f..0b4d122 100644
--- a/src/cobalt/browser/browser_module.h
+++ b/src/cobalt/browser/browser_module.h
@@ -434,10 +434,6 @@
   // Get the SbWindow via |system_window_| or potentially NULL.
   SbWindow GetSbWindow();
 
-  // This returns the render tree of the most recent submission, with animations
-  // applied according to the current time.
-  scoped_refptr<render_tree::Node> GetLastSubmissionAnimated();
-
   // Sets the fallback splash screen url to a topic-specific URL, if applicable.
   // Returns the topic used, or an empty Optional if a topic isn't found.
   base::Optional<std::string> SetSplashScreenTopicFallback(const GURL& url);
diff --git a/src/cobalt/browser/switches.cc b/src/cobalt/browser/switches.cc
index 64653d5..2021872 100644
--- a/src/cobalt/browser/switches.cc
+++ b/src/cobalt/browser/switches.cc
@@ -117,10 +117,6 @@
     "The minimum version of Cobalt that will be checked during compatibility "
     "validations.";
 
-const char kMinLogLevel[] = "min_log_level";
-const char kMinLogLevelHelp[] =
-    "Set the minimum logging level: info|warning|error|fatal.";
-
 const char kNullSavegame[] = "null_savegame";
 const char kNullSavegameHelp[] =
     "Setting NullSavegame will result in no data being read from previous "
@@ -208,6 +204,9 @@
 
 #endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
 
+const char kMinLogLevel[] = "min_log_level";
+const char kMinLogLevelHelp[] =
+    "Set the minimum logging level: info|warning|error|fatal.";
 const char kDisableJavaScriptJit[] = "disable_javascript_jit";
 const char kDisableJavaScriptJitHelp[] =
     "Specifies that javascript jit should be disabled.";
@@ -225,6 +224,12 @@
     "removed and the resolution will be 1us (or larger depending on the "
     "platform.";
 
+const char kDisableUpdaterModule[] = "disable_updater_module";
+const char kDisableUpdaterModuleHelp[] =
+    "Disables the Cobalt Evergreen UpdaterModule which is responsible for "
+    "downloading and installing new Cobalt updates. Passing the flag is "
+    "equivalent to opting out from further updates.";
+
 const char kEncodedImageCacheSizeInBytes[] =
     "encoded_image_cache_size_in_bytes";
 const char kEncodedImageCacheSizeInBytesHelp[] =
@@ -437,7 +442,7 @@
         {kIgnoreCertificateErrors, kIgnoreCertificateErrorsHelp},
         {kInputFuzzer, kInputFuzzerHelp}, {kMemoryTracker, kMemoryTrackerHelp},
         {kMinCompatibilityVersion, kMinCompatibilityVersionHelp},
-        {kMinLogLevel, kMinLogLevelHelp}, {kNullSavegame, kNullSavegameHelp},
+        {kNullSavegame, kNullSavegameHelp},
         {kDisablePartialLayout, kDisablePartialLayoutHelp}, {kProd, kProdHelp},
         {kRequireCSP, kRequireCSPHelp},
         {kRequireHTTPSLocation, kRequireHTTPSLocationHelp},
@@ -453,10 +458,10 @@
 #endif  // SB_API_VERSION >= 12 ||
         // SB_HAS(ON_SCREEN_KEYBOARD)
 #endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
-
         {kDisableJavaScriptJit, kDisableJavaScriptJitHelp},
         {kDisableMapToMesh, kDisableMapToMeshHelp},
         {kDisableTimerResolutionLimit, kDisableTimerResolutionLimitHelp},
+        {kDisableUpdaterModule, kDisableUpdaterModuleHelp},
         {kEncodedImageCacheSizeInBytes, kEncodedImageCacheSizeInBytesHelp},
         {kForceMigrationForStoragePartitioning,
          kForceMigrationForStoragePartitioningHelp},
@@ -468,6 +473,7 @@
         {kLocalStoragePartitionUrl, kLocalStoragePartitionUrlHelp},
         {kMaxCobaltCpuUsage, kMaxCobaltCpuUsageHelp},
         {kMaxCobaltGpuUsage, kMaxCobaltGpuUsageHelp},
+        {kMinLogLevel, kMinLogLevelHelp},
         {kOffscreenTargetCacheSizeInBytes,
          kOffscreenTargetCacheSizeInBytesHelp},
         {kOmitDeviceAuthenticationQueryParameters,
diff --git a/src/cobalt/browser/switches.h b/src/cobalt/browser/switches.h
index 67c03f7..94f052b 100644
--- a/src/cobalt/browser/switches.h
+++ b/src/cobalt/browser/switches.h
@@ -60,8 +60,6 @@
 extern const char kMemoryTrackerHelp[];
 extern const char kMinCompatibilityVersion[];
 extern const char kMinCompatibilityVersionHelp[];
-extern const char kMinLogLevel[];
-extern const char kMinLogLevelHelp[];
 extern const char kNullSavegame[];
 extern const char kNullSavegameHelp[];
 extern const char kDisablePartialLayout[];
@@ -102,6 +100,8 @@
 extern const char kDisableMapToMeshHelp[];
 extern const char kDisableTimerResolutionLimit[];
 extern const char kDisableTimerResolutionLimitHelp[];
+extern const char kDisableUpdaterModule[];
+extern const char kDisableUpdaterModuleHelp[];
 extern const char kEncodedImageCacheSizeInBytes[];
 extern const char kEncodedImageCacheSizeInBytesHelp[];
 extern const char kForceMigrationForStoragePartitioning[];
@@ -123,6 +123,8 @@
 extern const char kMaxCobaltCpuUsageHelp[];
 extern const char kMaxCobaltGpuUsage[];
 extern const char kMaxCobaltGpuUsageHelp[];
+extern const char kMinLogLevel[];
+extern const char kMinLogLevelHelp[];
 extern const char kOffscreenTargetCacheSizeInBytes[];
 extern const char kOffscreenTargetCacheSizeInBytesHelp[];
 extern const char kOmitDeviceAuthenticationQueryParameters[];
diff --git a/src/cobalt/browser/web_module.cc b/src/cobalt/browser/web_module.cc
index f570d3b..5036fd6 100644
--- a/src/cobalt/browser/web_module.cc
+++ b/src/cobalt/browser/web_module.cc
@@ -247,6 +247,9 @@
 
   void CancelSynchronousLoads();
 
+  void DoSynchronousLayoutAndGetRenderTree(
+      scoped_refptr<render_tree::Node>* render_tree);
+
  private:
   class DocumentLoadedObserver;
 
@@ -993,6 +996,16 @@
   synchronous_loader_interrupt_.Signal();
 }
 
+void WebModule::Impl::DoSynchronousLayoutAndGetRenderTree(
+    scoped_refptr<render_tree::Node>* render_tree) {
+  TRACE_EVENT0("cobalt::browser",
+               "WebModule::Impl::DoSynchronousLayoutAndGetRenderTree()");
+  DCHECK(render_tree);
+  scoped_refptr<render_tree::Node> tree =
+      window_->document()->DoSynchronousLayoutAndGetRenderTree();
+  *render_tree = tree;
+}
+
 void WebModule::Impl::OnCspPolicyChanged() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(is_running_);
@@ -1731,5 +1744,23 @@
                             base::Unretained(impl_.get()), callback));
 }
 
+scoped_refptr<render_tree::Node>
+WebModule::DoSynchronousLayoutAndGetRenderTree() {
+  TRACE_EVENT0("cobalt::browser",
+               "WebModule::DoSynchronousLayoutAndGetRenderTree()");
+  DCHECK(message_loop());
+  DCHECK(impl_);
+  scoped_refptr<render_tree::Node> render_tree;
+  if (base::MessageLoop::current() != message_loop()) {
+    message_loop()->task_runner()->PostBlockingTask(
+        FROM_HERE,
+        base::Bind(&WebModule::Impl::DoSynchronousLayoutAndGetRenderTree,
+                   base::Unretained(impl_.get()), &render_tree));
+  } else {
+    impl_->DoSynchronousLayoutAndGetRenderTree(&render_tree);
+  }
+  return render_tree;
+}
+
 }  // namespace browser
 }  // namespace cobalt
diff --git a/src/cobalt/browser/web_module.h b/src/cobalt/browser/web_module.h
index be762ae..0f340cd 100644
--- a/src/cobalt/browser/web_module.h
+++ b/src/cobalt/browser/web_module.h
@@ -396,6 +396,8 @@
   void RequestJavaScriptHeapStatistics(
       const JavaScriptHeapStatisticsCallback& callback);
 
+  scoped_refptr<render_tree::Node> DoSynchronousLayoutAndGetRenderTree();
+
  private:
   // Data required to construct a WebModule, initialized in the constructor and
   // passed to |Initialize|.
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index ef7e632..22d7db0 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-301658
\ No newline at end of file
+302122
\ No newline at end of file
diff --git a/src/cobalt/extension/extension_test.cc b/src/cobalt/extension/extension_test.cc
index d57b5ed..246ef55 100644
--- a/src/cobalt/extension/extension_test.cc
+++ b/src/cobalt/extension/extension_test.cc
@@ -21,6 +21,7 @@
 #include "cobalt/extension/installation_manager.h"
 #include "cobalt/extension/javascript_cache.h"
 #include "cobalt/extension/platform_service.h"
+#include "cobalt/extension/updater_notification.h"
 #include "cobalt/extension/url_fetcher_observer.h"
 #include "starboard/system.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -266,6 +267,26 @@
       << "Extension struct should be a singleton";
 }
 
+TEST(ExtensionTest, UpdaterNotification) {
+  typedef CobaltExtensionUpdaterNotificationApi ExtensionApi;
+  const char* kExtensionName = kCobaltExtensionUpdaterNotificationName;
+
+  const ExtensionApi* extension_api =
+      static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+  if (!extension_api) {
+    return;
+  }
+
+  EXPECT_STREQ(extension_api->name, kExtensionName);
+  EXPECT_EQ(extension_api->version, 1u);
+  EXPECT_NE(extension_api->UpdaterState, nullptr);
+
+  const ExtensionApi* second_extension_api =
+      static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+  EXPECT_EQ(second_extension_api, extension_api)
+      << "Extension struct should be a singleton";
+}
+
 }  // namespace extension
 }  // namespace cobalt
 #endif  // SB_API_VERSION >= 11
diff --git a/src/cobalt/extension/updater_notification.h b/src/cobalt/extension/updater_notification.h
new file mode 100644
index 0000000..151437f
--- /dev/null
+++ b/src/cobalt/extension/updater_notification.h
@@ -0,0 +1,61 @@
+// 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.
+
+#ifndef COBALT_EXTENSION_UPDATER_NOTIFICATION_H_
+#define COBALT_EXTENSION_UPDATER_NOTIFICATION_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define kCobaltExtensionUpdaterNotificationName \
+  "dev.cobalt.extension.UpdaterNotification"
+
+typedef enum CobaltExtensionUpdaterNotificationState {
+  kCobaltExtensionUpdaterNotificationStateNone = 0,
+  kCobaltExtensionUpdaterNotificationStateChecking = 1,
+  kCobaltExtensionUpdaterNotificationStateUpdateAvailable = 2,
+  kCobaltExtensionUpdaterNotificationStateDownloading = 3,
+  kCobaltExtensionUpdaterNotificationStateDownloaded = 4,
+  kCobaltExtensionUpdaterNotificationStateInstalling = 5,
+  kCobaltExtensionUpdaterNotificationStatekUpdated = 6,
+  kCobaltExtensionUpdaterNotificationStatekUpToDate = 7,
+  kCobaltExtensionUpdaterNotificationStatekUpdateFailed = 8,
+} CobaltExtensionUpdaterNotificationState;
+
+typedef struct CobaltExtensionUpdaterNotificationApi {
+  // Name should be the string |kCobaltExtensionUpdaterNotificationName|.
+  // This helps to validate that the extension API is correct.
+  const char* name;
+
+  // This specifies the version of the API that is implemented.
+  uint32_t version;
+
+  // The fields below this point were added in version 1 or later.
+
+  // Notify the Starboard implementation of the updater state.
+  // The Starboard platform can check if the device is low on storage
+  // and prompt the user to free some storage. The implementation
+  // should keep track of the frequency of showing the prompt to the
+  // user and try to minimize the number of user notifications.
+  void (*UpdaterState)(CobaltExtensionUpdaterNotificationState state);
+} CobaltExtensionUpdaterNotificationApi;
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // COBALT_EXTENSION_UPDATER_NOTIFICATION_H_
diff --git a/src/cobalt/extension/url_fetcher_observer.h b/src/cobalt/extension/url_fetcher_observer.h
index 7795689..d9a4a10 100644
--- a/src/cobalt/extension/url_fetcher_observer.h
+++ b/src/cobalt/extension/url_fetcher_observer.h
@@ -21,6 +21,9 @@
 extern "C" {
 #endif
 
+#define URL_FETCHER_OBSERVER_MAX_URL_SIZE 128
+#define URL_FETCHER_COMMAND_LINE_SWITCH "url_fetcher_observer"
+
 #define kCobaltExtensionUrlFetcherObserverName \
   "dev.cobalt.extension.UrlFetcherObserver"
 
diff --git a/src/cobalt/h5vcc/h5vcc_updater.cc b/src/cobalt/h5vcc/h5vcc_updater.cc
index 7db80e6..c4d7bbf 100644
--- a/src/cobalt/h5vcc/h5vcc_updater.cc
+++ b/src/cobalt/h5vcc/h5vcc_updater.cc
@@ -36,8 +36,7 @@
     return;
   }
 
-  if (updater_module_->GetUpdaterChannel().compare(channel) != 0 &&
-      updater_module_->IsChannelValid(channel)) {
+  if (updater_module_->GetUpdaterChannel().compare(channel) != 0) {
     updater_module_->SetUpdaterChannel(channel);
     updater_module_->CompareAndSwapChannelChanged(0, 1);
     updater_module_->RunUpdateCheck();
diff --git a/src/cobalt/layout/topmost_event_target.cc b/src/cobalt/layout/topmost_event_target.cc
index 8801fef..0ee7b82 100644
--- a/src/cobalt/layout/topmost_event_target.cc
+++ b/src/cobalt/layout/topmost_event_target.cc
@@ -239,13 +239,11 @@
         target_element->DispatchEvent(new dom::PointerEvent(
             base::Tokens::pointerover(), view, *event_init));
         for (scoped_refptr<dom::Element> element = target_element;
-             element != nearest_common_ancestor;
+             element && element != nearest_common_ancestor;
              element = element->parent_element()) {
-          if (element) {
-            element->DispatchEvent(new dom::PointerEvent(
-                base::Tokens::pointerenter(), dom::Event::kNotBubbles,
-                dom::Event::kNotCancelable, view, *event_init));
-          }
+          element->DispatchEvent(new dom::PointerEvent(
+              base::Tokens::pointerenter(), dom::Event::kNotBubbles,
+              dom::Event::kNotCancelable, view, *event_init));
         }
       }
 
@@ -254,13 +252,11 @@
       target_element->DispatchEvent(
           new dom::MouseEvent(base::Tokens::mouseover(), view, *event_init));
       for (scoped_refptr<dom::Element> element = target_element;
-           element != nearest_common_ancestor;
+           element && element != nearest_common_ancestor;
            element = element->parent_element()) {
-        if (element) {
-          element->DispatchEvent(new dom::MouseEvent(
-              base::Tokens::mouseenter(), dom::Event::kNotBubbles,
-              dom::Event::kNotCancelable, view, *event_init));
-        }
+        element->DispatchEvent(new dom::MouseEvent(
+            base::Tokens::mouseenter(), dom::Event::kNotBubbles,
+            dom::Event::kNotCancelable, view, *event_init));
       }
     }
   }
diff --git a/src/cobalt/updater/configurator.cc b/src/cobalt/updater/configurator.cc
index 925c06e..3657935 100644
--- a/src/cobalt/updater/configurator.cc
+++ b/src/cobalt/updater/configurator.cc
@@ -29,31 +29,6 @@
 // Default time constants.
 const int kDelayOneMinute = 60;
 const int kDelayOneHour = kDelayOneMinute * 60;
-const std::set<std::string> valid_channels = {
-    // Default channel for debug/devel builds.
-    "dev",
-    // Channel for dogfooders.
-    "dogfood",
-    // Default channel for gold builds.
-    "prod",
-    // Default channel for qa builds. A gold build can switch to this channel to
-    // get an official qa build.
-    "qa",
-    // Test an update with higher version than prod channel.
-    "test",
-    // Test an update with mismatched sabi.
-    "tmsabi",
-    // Test an update that does nothing.
-    "tnoop",
-    // Test an update that crashes.
-    "tcrash",
-    // Test an update that fails verification.
-    "tfailv",
-    // Test an update that works for one app only.
-    "t1app",
-    // Test a series of continuous updates with two channels.
-    "tseries1", "tseries2",
-};
 
 #if defined(COBALT_BUILD_TYPE_DEBUG) || defined(COBALT_BUILD_TYPE_DEVEL)
 const char kDefaultUpdaterChannel[] = "dev";
@@ -259,14 +234,6 @@
   updater_channel_ = updater_channel;
 }
 
-bool Configurator::IsChannelValid(const std::string& channel) {
-  if (!valid_channels.count(channel)) {
-    SetUpdaterStatus(std::string("Invalid channel requested"));
-    return false;
-  }
-  return true;
-}
-
 // The updater status is get by main web module thread and set by the updater
 // thread. The getter and set use a lock to prevent synchronization issue.
 std::string Configurator::GetUpdaterStatus() const {
diff --git a/src/cobalt/updater/configurator.h b/src/cobalt/updater/configurator.h
index c6fa12a..5314984 100644
--- a/src/cobalt/updater/configurator.h
+++ b/src/cobalt/updater/configurator.h
@@ -79,8 +79,6 @@
 
   void CompareAndSwapChannelChanged(int old_value, int new_value) override;
 
-  bool IsChannelValid(const std::string& channel);
-
   std::string GetUpdaterStatus() const override;
   void SetUpdaterStatus(const std::string& status) override;
 
diff --git a/src/cobalt/updater/updater_module.cc b/src/cobalt/updater/updater_module.cc
index 4cba4f3..db02d9a 100644
--- a/src/cobalt/updater/updater_module.cc
+++ b/src/cobalt/updater/updater_module.cc
@@ -51,6 +51,31 @@
 
 void QuitLoop(base::OnceClosure quit_closure) { std::move(quit_closure).Run(); }
 
+CobaltExtensionUpdaterNotificationState
+ComponentStateToCobaltExtensionUpdaterNotificationState(
+    ComponentState component_state) {
+  switch (component_state) {
+    case ComponentState::kChecking:
+      return kCobaltExtensionUpdaterNotificationStateChecking;
+    case ComponentState::kCanUpdate:
+      return kCobaltExtensionUpdaterNotificationStateUpdateAvailable;
+    case ComponentState::kDownloading:
+      return kCobaltExtensionUpdaterNotificationStateDownloading;
+    case ComponentState::kDownloaded:
+      return kCobaltExtensionUpdaterNotificationStateDownloaded;
+    case ComponentState::kUpdating:
+      return kCobaltExtensionUpdaterNotificationStateInstalling;
+    case ComponentState::kUpdated:
+      return kCobaltExtensionUpdaterNotificationStatekUpdated;
+    case ComponentState::kUpToDate:
+      return kCobaltExtensionUpdaterNotificationStatekUpdated;
+    case ComponentState::kUpdateError:
+      return kCobaltExtensionUpdaterNotificationStatekUpdateFailed;
+    default:
+      return kCobaltExtensionUpdaterNotificationStateNone;
+  }
+}
+
 }  // namespace
 
 namespace cobalt {
@@ -77,6 +102,11 @@
       status +=
           ", error code is " + std::to_string(crx_update_item_.error_code);
     }
+    if (updater_notification_ext_ != nullptr) {
+      updater_notification_ext_->UpdaterState(
+          ComponentStateToCobaltExtensionUpdaterNotificationState(
+              crx_update_item_.state));
+    }
   } else {
     status = "No status available";
   }
@@ -240,17 +270,30 @@
       base::TimeDelta::FromHours(kNextUpdateCheckHours));
 }
 
+// The following methods are called by other threads than the updater_thread_.
+
 void UpdaterModule::CompareAndSwapChannelChanged(int old_value, int new_value) {
-  updater_configurator_->CompareAndSwapChannelChanged(old_value, new_value);
+  auto config = updater_configurator_;
+  if (config) config->CompareAndSwapChannelChanged(old_value, new_value);
 }
 
-// The following three methods all called by the main web module thread.
 std::string UpdaterModule::GetUpdaterChannel() const {
-  return updater_configurator_->GetChannel();
+  auto config = updater_configurator_;
+  if (!config) return "";
+
+  return config->GetChannel();
 }
 
 void UpdaterModule::SetUpdaterChannel(const std::string& updater_channel) {
-  updater_configurator_->SetChannel(updater_channel);
+  auto config = updater_configurator_;
+  if (config) config->SetChannel(updater_channel);
+}
+
+std::string UpdaterModule::GetUpdaterStatus() const {
+  auto config = updater_configurator_;
+  if (!config) return "";
+
+  return config->GetUpdaterStatus();
 }
 
 void UpdaterModule::RunUpdateCheck() {
diff --git a/src/cobalt/updater/updater_module.h b/src/cobalt/updater/updater_module.h
index f2c1d02..49b8715 100644
--- a/src/cobalt/updater/updater_module.h
+++ b/src/cobalt/updater/updater_module.h
@@ -22,6 +22,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread.h"
+#include "cobalt/extension/updater_notification.h"
 #include "cobalt/network/network_module.h"
 #include "cobalt/updater/configurator.h"
 #include "components/prefs/pref_service.h"
@@ -52,22 +53,22 @@
 };
 
 // Mapping a component state to an updater status.
-const std::map<ComponentState, UpdaterStatus>
-  component_to_updater_status_map = {
-      {ComponentState::kNew, UpdaterStatus::kNewUpdate},
-      {ComponentState::kChecking, UpdaterStatus::kChecking},
-      {ComponentState::kCanUpdate, UpdaterStatus::kUpdateAvailable},
-      {ComponentState::kDownloadingDiff, UpdaterStatus::kDownloadingDiff},
-      {ComponentState::kDownloading, UpdaterStatus::kDownloading},
-      {ComponentState::kDownloaded, UpdaterStatus::kDownloaded},
-      {ComponentState::kUpdatingDiff, UpdaterStatus::kUpdatingDiff},
-      {ComponentState::kUpdating, UpdaterStatus::kUpdating},
-      {ComponentState::kUpdated, UpdaterStatus::kUpdated},
-      {ComponentState::kUpToDate, UpdaterStatus::kUpToDate},
-      {ComponentState::kUpdateError, UpdaterStatus::kUpdateError},
-      {ComponentState::kUninstalled, UpdaterStatus::kUninstalled},
-      {ComponentState::kRun, UpdaterStatus::kRun},
-  };
+const std::map<ComponentState, UpdaterStatus> component_to_updater_status_map =
+    {
+        {ComponentState::kNew, UpdaterStatus::kNewUpdate},
+        {ComponentState::kChecking, UpdaterStatus::kChecking},
+        {ComponentState::kCanUpdate, UpdaterStatus::kUpdateAvailable},
+        {ComponentState::kDownloadingDiff, UpdaterStatus::kDownloadingDiff},
+        {ComponentState::kDownloading, UpdaterStatus::kDownloading},
+        {ComponentState::kDownloaded, UpdaterStatus::kDownloaded},
+        {ComponentState::kUpdatingDiff, UpdaterStatus::kUpdatingDiff},
+        {ComponentState::kUpdating, UpdaterStatus::kUpdating},
+        {ComponentState::kUpdated, UpdaterStatus::kUpdated},
+        {ComponentState::kUpToDate, UpdaterStatus::kUpToDate},
+        {ComponentState::kUpdateError, UpdaterStatus::kUpdateError},
+        {ComponentState::kUninstalled, UpdaterStatus::kUninstalled},
+        {ComponentState::kRun, UpdaterStatus::kRun},
+};
 
 // Translating an updater status to a status string.
 const std::map<UpdaterStatus, const char*> updater_status_string_map = {
@@ -94,7 +95,20 @@
   Observer(scoped_refptr<update_client::UpdateClient> update_client,
            scoped_refptr<Configurator> updater_configurator)
       : update_client_(update_client),
-        updater_configurator_(updater_configurator) {}
+        updater_configurator_(updater_configurator) {
+    const CobaltExtensionUpdaterNotificationApi* updater_notification_ext =
+        static_cast<const CobaltExtensionUpdaterNotificationApi*>(
+            SbSystemGetExtension(kCobaltExtensionUpdaterNotificationName));
+    if (updater_notification_ext &&
+        SbStringCompareAll(updater_notification_ext->name,
+                           kCobaltExtensionUpdaterNotificationName) == 0 &&
+        updater_notification_ext->version >= 1) {
+      updater_notification_ext_ = updater_notification_ext;
+    } else {
+      updater_notification_ext_ = nullptr;
+    }
+  }
+
 
   // Overrides for update_client::UpdateClient::Observer.
   void OnEvent(Events event, const std::string& id) override;
@@ -103,6 +117,7 @@
   scoped_refptr<update_client::UpdateClient> update_client_;
   scoped_refptr<Configurator> updater_configurator_;
   update_client::CrxUpdateItem crx_update_item_;
+  const CobaltExtensionUpdaterNotificationApi* updater_notification_ext_;
   DISALLOW_COPY_AND_ASSIGN(Observer);
 };
 
@@ -122,15 +137,10 @@
   void SetUpdaterChannel(const std::string& updater_channel);
 
   void CompareAndSwapChannelChanged(int old_value, int new_value);
-  bool IsChannelValid(const std::string& channel) {
-    return updater_configurator_->IsChannelValid(channel);
-  }
 
   void RunUpdateCheck();
 
-  std::string GetUpdaterStatus() const {
-    return updater_configurator_->GetUpdaterStatus();
-  }
+  std::string GetUpdaterStatus() const;
 
   void ResetInstallations();
 
diff --git a/src/components/update_client/url_fetcher_downloader.cc b/src/components/update_client/url_fetcher_downloader.cc
index 9703910..f94b010 100644
--- a/src/components/update_client/url_fetcher_downloader.cc
+++ b/src/components/update_client/url_fetcher_downloader.cc
@@ -6,6 +6,7 @@
 
 #include <stdint.h>
 #include <stack>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -76,8 +77,7 @@
     std::unique_ptr<CrxDownloader> successor,
     scoped_refptr<NetworkFetcherFactory> network_fetcher_factory)
     : CrxDownloader(std::move(successor)),
-      network_fetcher_factory_(network_fetcher_factory) {
-}
+      network_fetcher_factory_(network_fetcher_factory) {}
 #endif
 
 UrlFetcherDownloader::~UrlFetcherDownloader() {
@@ -230,7 +230,11 @@
   // the request and avoid overloading the server in this case.
   // is not accepting requests for the moment.
   int error = -1;
+#if defined(STARBOARD)
+  if (!file_path.empty() && response_code_ == 200 && net_error == 0) {
+#else
   if (!file_path.empty() && response_code_ == 200) {
+#endif
     DCHECK_EQ(0, net_error);
     error = 0;
   } else if (response_code_ != -1) {
diff --git a/src/net/url_request/url_fetcher_core.cc b/src/net/url_request/url_fetcher_core.cc
index 2979a78..1281828 100644
--- a/src/net/url_request/url_fetcher_core.cc
+++ b/src/net/url_request/url_fetcher_core.cc
@@ -139,15 +139,21 @@
   CHECK(original_url_.is_valid());
 
 #if SB_API_VERSION >= 11
+  const base::CommandLine& command_line =
+      *base::CommandLine::ForCurrentProcess();
   const CobaltExtensionUrlFetcherObserverApi* observer_extension =
       static_cast<const CobaltExtensionUrlFetcherObserverApi*>(
           SbSystemGetExtension(kCobaltExtensionUrlFetcherObserverName));
-  if (observer_extension &&
+  if (command_line.HasSwitch(URL_FETCHER_COMMAND_LINE_SWITCH) &&
+      observer_extension &&
       SbStringCompareAll(observer_extension->name,
                          kCobaltExtensionUrlFetcherObserverName) == 0 &&
       observer_extension->version >= 1) {
     observer_extension_ = observer_extension;
-    observer_extension_->FetcherCreated(original_url_.spec().c_str());
+    observer_extension_->FetcherCreated(
+        original_url_.spec()
+            .substr(0, URL_FETCHER_OBSERVER_MAX_URL_SIZE)
+            .c_str());
   } else {
     observer_extension_ = nullptr;
   }
@@ -616,7 +622,10 @@
 
 URLFetcherCore::~URLFetcherCore() {
   if (observer_extension_ != nullptr) {
-    observer_extension_->FetcherDestroyed(original_url_.spec().c_str());
+    observer_extension_->FetcherDestroyed(
+        original_url_.spec()
+            .substr(0, URL_FETCHER_OBSERVER_MAX_URL_SIZE)
+            .c_str());
   }
   // |request_| should be NULL. If not, it's unsafe to delete it here since we
   // may not be on the IO thread.
@@ -647,7 +656,10 @@
   DCHECK(network_task_runner_->BelongsToCurrentThread());
 
   if (observer_extension_ != nullptr) {
-    observer_extension_->StartURLRequest(original_url_.spec().c_str());
+    observer_extension_->StartURLRequest(
+        original_url_.spec()
+            .substr(0, URL_FETCHER_OBSERVER_MAX_URL_SIZE)
+            .c_str());
   }
   if (was_cancelled_) {
     // Since StartURLRequest() is posted as a *delayed* task, it may
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/CobaltMediaSession.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/CobaltMediaSession.java
index 8df3ca9..c340a6b 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/CobaltMediaSession.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/CobaltMediaSession.java
@@ -107,7 +107,7 @@
 
   public void setLifecycleCallback(LifecycleCallback lifecycleCallback) {
     this.lifecycleCallback = lifecycleCallback;
-    if (lifecycleCallback != null) {
+    if (lifecycleCallback != null && this.mediaSession != null) {
       lifecycleCallback.onMediaSessionLifecycle(
           this.mediaSession.isActive(), this.mediaSession.getSessionToken());
     }
diff --git a/src/starboard/android/apk/build.id b/src/starboard/android/apk/build.id
new file mode 100644
index 0000000..ef01811
--- /dev/null
+++ b/src/starboard/android/apk/build.id
@@ -0,0 +1 @@
+301999
\ No newline at end of file
diff --git a/src/starboard/android/apk/cobalt-gradle.sh b/src/starboard/android/apk/cobalt-gradle.sh
index 156c8f2..a5b430f 100755
--- a/src/starboard/android/apk/cobalt-gradle.sh
+++ b/src/starboard/android/apk/cobalt-gradle.sh
@@ -54,7 +54,7 @@
 # Allow parallel gradle builds, as defined by a COBALT_GRADLE_BUILD_COUNT envvar
 # or default to 1 if that's not set (so buildbot only runs 1 gradle at a time).
 BUCKETS=${COBALT_GRADLE_BUILD_COUNT:-1}
-if [ "$BUCKETS"==1 ]; then
+if [ "$BUCKETS" -eq 1 ]; then
   echo "Gradle daemon and parallel gradle disabled for Cobalt build"
   GRADLE_ARGS+=(
     "-Dorg.gradle.parallel=false"
diff --git a/src/starboard/android/shared/model_year_test.cc b/src/starboard/android/shared/model_year_test.cc
new file mode 100644
index 0000000..1197242
--- /dev/null
+++ b/src/starboard/android/shared/model_year_test.cc
@@ -0,0 +1,43 @@
+// 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.
+
+#include <string>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace starboard {
+namespace android {
+namespace shared {
+namespace {
+
+TEST(ModelYearTest, YearIsFourDigitsOrUnknown) {
+  const size_t kValueSize = 1024;
+  char value[kValueSize] = {0};
+  SbMemorySet(value, 0xCD, kValueSize);
+  bool result =
+      SbSystemGetProperty(kSbSystemPropertyModelYear, value, kValueSize);
+  SB_DCHECK(result);
+  std::string year = value;
+  if (year == "unknown") {
+    return;
+  }
+  EXPECT_EQ(4, year.length());
+  EXPECT_EQ(std::string::npos, year.find_first_not_of("0123456789"));
+  EXPECT_EQ("20", year.substr(0, 2));
+}
+
+}  // namespace
+}  // namespace shared
+}  // namespace android
+}  // namespace starboard
diff --git a/src/starboard/android/shared/starboard_platform_tests.gypi b/src/starboard/android/shared/starboard_platform_tests.gypi
index 5b8fe50..0c34f23 100644
--- a/src/starboard/android/shared/starboard_platform_tests.gypi
+++ b/src/starboard/android/shared/starboard_platform_tests.gypi
@@ -23,6 +23,7 @@
         '<(DEPTH)/starboard/common/test_main.cc',
         '<@(media_tests_sources)',
         'jni_env_ext_test.cc',
+        'model_year_test.cc',
         'video_frame_tracker_test.cc',
       ],
       'defines': [
diff --git a/src/starboard/android/shared/system_get_property.cc b/src/starboard/android/shared/system_get_property.cc
index 192dabc..b77d103 100644
--- a/src/starboard/android/shared/system_get_property.cc
+++ b/src/starboard/android/shared/system_get_property.cc
@@ -104,8 +104,24 @@
     case kSbSystemPropertyChipsetModelNumber:
       return GetAndroidSystemProperty("ro.board.platform", out_value,
                                       value_length, kUnknownValue);
-    case kSbSystemPropertyModelYear:
-       return false;
+    case kSbSystemPropertyModelYear: {
+      char key1[PROP_VALUE_MAX] = "";
+      SB_DCHECK(GetAndroidSystemProperty("ro.oem.key1", key1, PROP_VALUE_MAX,
+                                         kUnknownValue));
+      if (SbStringCompareAll(key1, kUnknownValue) == 0 ||
+          SbStringGetLength(key1) < 10) {
+        return CopyStringAndTestIfSuccess(out_value, value_length,
+                                          kUnknownValue);
+      }
+      // See
+      // https://support.google.com/androidpartners_androidtv/answer/9351639?hl=en
+      // for the format of key1.
+      std::string year = "20";
+      year += key1[9];
+      year += key1[10];
+      return CopyStringAndTestIfSuccess(out_value, value_length, year.c_str());
+    }
+
 #if SB_API_VERSION >= 12
     case kSbSystemPropertySystemIntegratorName:
 #else
@@ -125,8 +141,8 @@
     case kSbSystemPropertyUserAgentAuxField: {
       JniEnvExt* env = JniEnvExt::Get();
       ScopedLocalJavaRef<jstring> aux_string(
-          env->CallStarboardObjectMethodOrAbort(
-              "getUserAgentAuxField", "()Ljava/lang/String;"));
+          env->CallStarboardObjectMethodOrAbort("getUserAgentAuxField",
+                                                "()Ljava/lang/String;"));
 
       std::string utf_str = env->GetStringStandardUTFOrAbort(aux_string.Get());
       bool success =
diff --git a/src/starboard/common/log.cc b/src/starboard/common/log.cc
index b7a6ab0..08994c2 100644
--- a/src/starboard/common/log.cc
+++ b/src/starboard/common/log.cc
@@ -35,7 +35,11 @@
 namespace starboard {
 namespace logging {
 namespace {
+#if SB_LOGGING_IS_OFFICIAL_BUILD
+SbLogPriority g_min_log_level = kSbLogPriorityFatal;
+#else
 SbLogPriority g_min_log_level = kSbLogPriorityUnknown;
+#endif
 
 #if SB_API_VERSION < 11
 SB_ONCE_INITIALIZE_FUNCTION(RecursiveMutex, g_log_mutex);
@@ -61,11 +65,7 @@
 }
 
 SbLogPriority GetMinLogLevel() {
-#if SB_LOGGING_IS_OFFICIAL_BUILD
-  return SB_LOG_FATAL;
-#else
   return g_min_log_level;
-#endif
 }
 
 SbLogPriority StringToLogLevel(const std::string& log_level) {
diff --git a/src/starboard/common/log.h b/src/starboard/common/log.h
index df38642..f1ec6b9 100644
--- a/src/starboard/common/log.h
+++ b/src/starboard/common/log.h
@@ -123,7 +123,8 @@
 #define SB_LAZY_STREAM(stream, condition) \
   !(condition) ? (void)0 : ::starboard::logging::LogMessageVoidify() & (stream)
 
-#if SB_LOGGING_IS_OFFICIAL_BUILD
+#if SB_LOGGING_IS_OFFICIAL_BUILD && !SB_IS(EVERGREEN) && \
+    !SB_IS(EVERGREEN_COMPATIBLE)
 #define SB_LOG_IS_ON(severity)                         \
   ((::starboard::logging::SB_LOG_##severity >=         \
     ::starboard::logging::SB_LOG_FATAL)                \
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 5f69e22..3e13e55 100755
--- a/src/starboard/evergreen/testing/tests/out_of_storage_test.sh
+++ b/src/starboard/evergreen/testing/tests/out_of_storage_test.sh
@@ -46,7 +46,7 @@
   OLD_TIMEOUT="${TIMEOUT}"
   TIMEOUT=300
 
-  cycle_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "Failed to update, log "error" code is 12"
+  cycle_cobalt "file:///tests/${TEST_FILE}?channel=test" "${TEST_NAME}.0.log" "Failed to update, log \"error\" code is 12"
 
   # Remove the symbolic link.
   run_command "rm -f ${STORAGE_DIR}" 1> /dev/null
diff --git a/src/starboard/shared/starboard/application.cc b/src/starboard/shared/starboard/application.cc
index fcf8612..f9addee 100644
--- a/src/starboard/shared/starboard/application.cc
+++ b/src/starboard/shared/starboard/application.cc
@@ -114,7 +114,11 @@
     ::starboard::logging::SetMinLogLevel(::starboard::logging::StringToLogLevel(
         command_line_->GetSwitchValue(kMinLogLevel)));
   } else {
+#if SB_LOGGING_IS_OFFICIAL_BUILD
+    ::starboard::logging::SetMinLogLevel(::starboard::logging::SB_LOG_FATAL);
+#else
     ::starboard::logging::SetMinLogLevel(::starboard::logging::SB_LOG_INFO);
+#endif
   }
 #endif  // SB_API_VERSION >= 11