Import Cobalt 19.android.1.209838
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index bae6060..1aa0d38 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-203995
\ No newline at end of file
+209838
\ No newline at end of file
diff --git a/src/cobalt/version.h b/src/cobalt/version.h
index 9a3f6f8..ce25ff2 100644
--- a/src/cobalt/version.h
+++ b/src/cobalt/version.h
@@ -35,6 +35,6 @@
 //                  release is cut.
 //.
 
-#define COBALT_VERSION "19.android.1"
+#define COBALT_VERSION "19.android.2"
 
 #endif  // COBALT_VERSION_H_
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java
index ecc84c8..09ece25 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java
@@ -25,7 +25,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.view.ViewGroup.LayoutParams;
-import android.view.ViewTreeObserver;
+import android.view.ViewParent;
 import android.widget.FrameLayout;
 import dev.cobalt.media.VideoSurfaceView;
 import dev.cobalt.util.Log;
@@ -58,7 +58,7 @@
   private VideoSurfaceView videoSurfaceView;
   private KeyboardEditor keyboardEditor;
 
-  private ViewTreeObserver.OnGlobalLayoutListener videoSurfaceLayoutListener;
+  private boolean forceCreateNewVideoSurfaceView = false;
 
   @Override
   protected void onCreate(Bundle savedInstanceState) {
@@ -87,19 +87,11 @@
     addContentView(
         videoSurfaceView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
 
-    videoSurfaceLayoutListener =
-        new ViewTreeObserver.OnGlobalLayoutListener() {
-          @Override
-          public void onGlobalLayout() {
-            VideoSurfaceView.nativeOnGlobalLayout();
-          }
-        };
-    ViewTreeObserver observer = getWindow().getDecorView().getViewTreeObserver();
-    observer.addOnGlobalLayoutListener(videoSurfaceLayoutListener);
-
-    keyboardEditor = new KeyboardEditor(this);
-    addContentView(
-        keyboardEditor, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+    if (KeyboardInputConnection.nativeHasOnScreenKeyboard()) {
+      keyboardEditor = new KeyboardEditor(this);
+      addContentView(
+          keyboardEditor, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+    }
   }
 
   /**
@@ -115,6 +107,11 @@
 
   @Override
   protected void onStart() {
+    if (forceCreateNewVideoSurfaceView) {
+      Log.w(TAG, "Force to create a new video surface.");
+      createNewSurfaceView();
+    }
+
     getStarboardBridge().onActivityStart(this, keyboardEditor);
     super.onStart();
   }
@@ -123,13 +120,14 @@
   protected void onStop() {
     getStarboardBridge().onActivityStop(this);
     super.onStop();
+
+    if (VideoSurfaceView.getCurrentSurface() != null) {
+      forceCreateNewVideoSurfaceView = true;
+    }
   }
 
   @Override
   protected void onDestroy() {
-    ViewTreeObserver observer = getWindow().getDecorView().getViewTreeObserver();
-    observer.removeOnGlobalLayoutListener(videoSurfaceLayoutListener);
-
     super.onDestroy();
     getStarboardBridge().onActivityDestroy(this);
   }
@@ -231,16 +229,10 @@
   }
 
   public void setVideoSurfaceBounds(final int x, final int y, final int width, final int height) {
-    if (!videoSurfaceView.updateVideoBounds(x, y, width, height)) {
-      return;
-    }
-
-    VideoSurfaceView.nativeOnLayoutNeeded();
     runOnUiThread(
         new Runnable() {
           @Override
           public void run() {
-            VideoSurfaceView.nativeOnLayoutScheduled();
             LayoutParams layoutParams = videoSurfaceView.getLayoutParams();
             // Since videoSurfaceView is added directly to the Activity's content view, which is a
             // FrameLayout, we expect its layout params to become FrameLayout.LayoutParams.
@@ -263,4 +255,21 @@
           }
         });
   }
+
+  private void createNewSurfaceView() {
+    ViewParent parent = videoSurfaceView.getParent();
+    if (parent instanceof FrameLayout) {
+      FrameLayout frameLayout = (FrameLayout) parent;
+      int index = frameLayout.indexOfChild(videoSurfaceView);
+      frameLayout.removeView(videoSurfaceView);
+      videoSurfaceView = new VideoSurfaceView(this);
+      a11yHelper = new CobaltA11yHelper(videoSurfaceView);
+      frameLayout.addView(
+          videoSurfaceView,
+          index,
+          new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+    } else {
+      Log.w(TAG, "Unexpected surface view parent class " + parent.getClass().getName());
+    }
+  }
 }
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltService.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltService.java
index 591f63c..65e6dc8 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltService.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltService.java
@@ -57,6 +57,8 @@
   public abstract ResponseToClient receiveFromClient(byte[] data);
 
   /** Close the service. */
+  @SuppressWarnings("unused")
+  @UsedByNative
   public abstract void close();
 
   /** Send data from the service to the client. */
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/KeyboardInputConnection.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/KeyboardInputConnection.java
index 54a5a46..ce049b9 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/KeyboardInputConnection.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/KeyboardInputConnection.java
@@ -174,5 +174,7 @@
     return true;
   }
 
+  public static native boolean nativeHasOnScreenKeyboard();
+
   public static native void nativeSendText(CharSequence text, boolean isComposing);
 }
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java
index 5f59062..494f57b 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java
@@ -197,7 +197,7 @@
       // This conversion is safe, as only the lower bits will be set, since we
       // called |getTimestamp| without a timebase.
       // https://developer.android.com/reference/android/media/AudioTimestamp.html#framePosition
-      audioTimestamp.framePosition = (int) audioTimestamp.framePosition;
+      audioTimestamp.framePosition &= 0x7FFFFFFF;
     } else {
       // Time stamps haven't been updated yet, assume playback hasn't started.
       audioTimestamp.framePosition = 0;
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/VideoSurfaceView.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/VideoSurfaceView.java
index 2478b97..1367aa7 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/VideoSurfaceView.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/VideoSurfaceView.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.graphics.Color;
-import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.Surface;
 import android.view.SurfaceHolder;
@@ -31,13 +30,7 @@
  */
 public class VideoSurfaceView extends SurfaceView {
 
-  public static native void nativeOnLayoutNeeded();
-
-  public static native void nativeOnLayoutScheduled();
-
-  public static native void nativeOnGlobalLayout();
-
-  private Rect videoBounds;
+  private static Surface currentSurface = null;
 
   public VideoSurfaceView(Context context) {
     super(context);
@@ -60,7 +53,6 @@
   }
 
   private void initialize(Context context) {
-    videoBounds = new Rect();
     setBackgroundColor(Color.TRANSPARENT);
     getHolder().addCallback(new SurfaceHolderCallback());
 
@@ -69,17 +61,6 @@
     // punch-out video when the position / size is animated.
   }
 
-  public boolean updateVideoBounds(final int x, final int y, final int width, final int height) {
-    if (videoBounds.left != x
-        || videoBounds.top != y
-        || videoBounds.right != x + width
-        || videoBounds.bottom != y + height) {
-      videoBounds.set(x, y, x + width, y + height);
-      return true;
-    }
-    return false;
-  }
-
   private native void nativeOnVideoSurfaceChanged(Surface surface);
 
   private class SurfaceHolderCallback implements SurfaceHolder.Callback {
@@ -88,7 +69,8 @@
 
     @Override
     public void surfaceCreated(SurfaceHolder holder) {
-      nativeOnVideoSurfaceChanged(holder.getSurface());
+      currentSurface = holder.getSurface();
+      nativeOnVideoSurfaceChanged(currentSurface);
     }
 
     @Override
@@ -102,7 +84,12 @@
 
     @Override
     public void surfaceDestroyed(SurfaceHolder holder) {
-      nativeOnVideoSurfaceChanged(null);
+      currentSurface = null;
+      nativeOnVideoSurfaceChanged(currentSurface);
     }
   }
+
+  public static Surface getCurrentSurface() {
+    return currentSurface;
+  }
 }
diff --git a/src/starboard/android/shared/application_android.cc b/src/starboard/android/shared/application_android.cc
index a51dddd..1f013a8 100644
--- a/src/starboard/android/shared/application_android.cc
+++ b/src/starboard/android/shared/application_android.cc
@@ -395,6 +395,17 @@
   ApplicationAndroid::Get()->SendKeyboardInject(static_cast<SbKey>(key));
 }
 
+extern "C" SB_EXPORT_PLATFORM jboolean
+Java_dev_cobalt_coat_KeyboardInputConnection_nativeHasOnScreenKeyboard(
+    JniEnvExt* env,
+    jobject unused_this) {
+#if SB_HAS(ON_SCREEN_KEYBOARD)
+  return JNI_TRUE;
+#else   // SB_HAS(ON_SCREEN_KEYBOARD)
+  return JNI_FALSE;
+#endif  // SB_HAS(ON_SCREEN_KEYBOARD)
+}
+
 #if SB_HAS(ON_SCREEN_KEYBOARD)
 
 void ApplicationAndroid::SbWindowShowOnScreenKeyboard(SbWindow window,
diff --git a/src/starboard/android/shared/drm_create_system.cc b/src/starboard/android/shared/drm_create_system.cc
index e92d6a1..1e97b89 100644
--- a/src/starboard/android/shared/drm_create_system.cc
+++ b/src/starboard/android/shared/drm_create_system.cc
@@ -25,7 +25,7 @@
     SbDrmServerCertificateUpdatedFunc server_certificate_updated_callback,
     SbDrmSessionClosedFunc session_closed_callback) {
   using starboard::android::shared::DrmSystem;
-  using starboard::android::shared::IsWidevine;
+  using starboard::android::shared::IsWidevineL1;
 
   if (!update_request_callback || !session_updated_callback ||
       !key_statuses_changed_callback || !server_certificate_updated_callback ||
@@ -33,7 +33,7 @@
     return kSbDrmSystemInvalid;
   }
 
-  if (!IsWidevine(key_system)) {
+  if (!IsWidevineL1(key_system)) {
     return kSbDrmSystemInvalid;
   }
 
diff --git a/src/starboard/android/shared/drm_system.h b/src/starboard/android/shared/drm_system.h
index cec052b..b0a6cb7 100644
--- a/src/starboard/android/shared/drm_system.h
+++ b/src/starboard/android/shared/drm_system.h
@@ -49,7 +49,8 @@
                      int session_id_size);
   void CloseSession(const void* session_id, int session_id_size) override;
   DecryptStatus Decrypt(InputBuffer* buffer) override;
-#if SB_API_VERSION >= 10
+
+  bool IsServerCertificateUpdatable() override { return false; }
   void UpdateServerCertificate(int ticket,
                                const void* certificate,
                                int certificate_size) override {
@@ -57,7 +58,6 @@
     SB_UNREFERENCED_PARAMETER(certificate);
     SB_UNREFERENCED_PARAMETER(certificate_size);
   }
-#endif  // SB_API_VERSION >= 10
 
   jobject GetMediaCrypto() const { return j_media_crypto_; }
   void CallUpdateRequestCallback(int ticket,
diff --git a/src/starboard/android/shared/gyp_configuration.gypi b/src/starboard/android/shared/gyp_configuration.gypi
index 10f6c0c..5fc63d9 100644
--- a/src/starboard/android/shared/gyp_configuration.gypi
+++ b/src/starboard/android/shared/gyp_configuration.gypi
@@ -20,6 +20,7 @@
     'target_os': 'android',
     'final_executable_type': 'shared_library',
     'gtest_target_type': 'shared_library',
+    'sb_widevine_platform' : 'android',
 
     'gl_type': 'system_gles2',
     'enable_remote_debugging': 0,
diff --git a/src/starboard/android/shared/media_codec_bridge.cc b/src/starboard/android/shared/media_codec_bridge.cc
index 51c3586..2a3bcc2 100644
--- a/src/starboard/android/shared/media_codec_bridge.cc
+++ b/src/starboard/android/shared/media_codec_bridge.cc
@@ -230,11 +230,13 @@
 }
 
 MediaCodecBridge::~MediaCodecBridge() {
+  if (!j_media_codec_bridge_) {
+    return;
+  }
+
   JniEnvExt* env = JniEnvExt::Get();
 
   env->CallVoidMethodOrAbort(j_media_codec_bridge_, "stop", "()V");
-
-  SB_DCHECK(j_media_codec_bridge_);
   env->CallVoidMethodOrAbort(j_media_codec_bridge_, "release", "()V");
   env->DeleteGlobalRef(j_media_codec_bridge_);
   j_media_codec_bridge_ = NULL;
diff --git a/src/starboard/android/shared/media_common.h b/src/starboard/android/shared/media_common.h
index cbc2668..d899307 100644
--- a/src/starboard/android/shared/media_common.h
+++ b/src/starboard/android/shared/media_common.h
@@ -32,11 +32,15 @@
 
 const int64_t kSecondInMicroseconds = 1000 * 1000;
 
-inline bool IsWidevine(const char* key_system) {
+inline bool IsWidevineL1(const char* key_system) {
   return SbStringCompareAll(key_system, "com.widevine") == 0 ||
          SbStringCompareAll(key_system, "com.widevine.alpha") == 0;
 }
 
+inline bool IsWidevineL3(const char* key_system) {
+  return SbStringCompareAll(key_system, "com.youtube.widevine.l3") == 0;
+}
+
 // Map a supported |SbMediaAudioCodec| into its corresponding mime type
 // string.  Returns |NULL| if |audio_codec| is not supported.
 inline const char* SupportedAudioCodecToMimeType(
diff --git a/src/starboard/android/shared/media_decoder.cc b/src/starboard/android/shared/media_decoder.cc
index 1bee654..3c7ae4f 100644
--- a/src/starboard/android/shared/media_decoder.cc
+++ b/src/starboard/android/shared/media_decoder.cc
@@ -301,12 +301,15 @@
     decoder_thread_ = kSbThreadInvalid;
   }
 
-  host_->OnFlushing();
-  jint status = media_codec_bridge_->Flush();
-  if (status != MEDIA_CODEC_OK) {
-    SB_LOG(ERROR) << "Failed to flush media codec.";
+  if (is_valid()) {
+    host_->OnFlushing();
+
+    jint status = media_codec_bridge_->Flush();
+    if (status != MEDIA_CODEC_OK) {
+      SB_LOG(ERROR) << "Failed to flush media codec.";
+    }
+    host_ = NULL;
   }
-  host_ = NULL;
 }
 
 void MediaDecoder::CollectPendingData_Locked(
diff --git a/src/starboard/android/shared/media_is_supported.cc b/src/starboard/android/shared/media_is_supported.cc
index 4750d03..4dd0d82 100644
--- a/src/starboard/android/shared/media_is_supported.cc
+++ b/src/starboard/android/shared/media_is_supported.cc
@@ -20,7 +20,7 @@
 SB_EXPORT bool SbMediaIsSupported(SbMediaVideoCodec video_codec,
                                   SbMediaAudioCodec audio_codec,
                                   const char* key_system) {
-  using starboard::android::shared::IsWidevine;
+  using starboard::android::shared::IsWidevineL1;
   using starboard::android::shared::JniEnvExt;
   // Filter anything other then aac as we only support paid content on aac.
   // TODO: Add support of Opus if we are going to support software based drm
@@ -29,7 +29,7 @@
       audio_codec != kSbMediaAudioCodecAac) {
     return false;
   }
-  if (!IsWidevine(key_system)) {
+  if (!IsWidevineL1(key_system)) {
     return false;
   }
   return JniEnvExt::Get()->CallStaticBooleanMethodOrAbort(
diff --git a/src/starboard/android/shared/sdk_utils.py b/src/starboard/android/shared/sdk_utils.py
index 025e8df..bed171b 100644
--- a/src/starboard/android/shared/sdk_utils.py
+++ b/src/starboard/android/shared/sdk_utils.py
@@ -39,6 +39,7 @@
 _ANDROID_NDK_API_LEVEL = '21'
 
 # Packages to install in the Android SDK.
+# We download ndk-bundle separately, so it's not in this list.
 # Get available packages from "sdkmanager --list --verbose"
 _ANDROID_SDK_PACKAGES = [
     'build-tools;28.0.3',
@@ -47,7 +48,6 @@
     'extras;android;m2repository',
     'extras;google;m2repository',
     'lldb;3.1',
-    'ndk-bundle',
     'patcher;v4',
     'platforms;android-28',
     'platform-tools',
@@ -61,6 +61,12 @@
 # see https://developer.android.com/studio/index.html#command-tools
 _SDK_URL = 'https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip'
 
+# Location from which to download the Android NDK.
+# see https://developer.android.com/ndk/downloads (perhaps in "NDK archives")
+_NDK_ZIP_REVISION = 'android-ndk-r19c'
+_NDK_ZIP_FILE = _NDK_ZIP_REVISION + '-linux-x86_64.zip'
+_NDK_URL = 'https://dl.google.com/android/repository/' + _NDK_ZIP_FILE
+
 _STARBOARD_TOOLCHAINS_DIR = build.GetToolchainsDir()
 
 # The path to the Android SDK, if placed inside of starboard-toolchains.
@@ -198,18 +204,33 @@
       logging.warning('Checking Android SDK.')
       _DownloadInstallOrUpdateSdk()
 
+    ndk_path = GetNdkPath()
     if _ANDROID_NDK_HOME:
-      logging.warning('Warning: Using Android NDK in ANDROID_NDK_HOME,'
-                      ' which is not automatically updated')
-    ndk_revision = _GetInstalledNdkRevision()
-    logging.warning('Using Android NDK version %s', ndk_revision)
+      logging.warning('Warning: ANDROID_NDK_HOME references NDK %s in %s,'
+                      ' which is not automatically updated.',
+                      _GetInstalledNdkRevision(), ndk_path)
 
     if _ANDROID_HOME or _ANDROID_NDK_HOME:
       reply = raw_input(
-          'Do you want to continue using your custom Android tools? [yN]')
+          'Do you want to continue using your custom Android tools? [y/N]')
       if reply.upper() != 'Y':
         sys.exit(1)
+    elif not _CheckStamp(ndk_path):
+      logging.warning('Downloading NDK from %s to %s', _NDK_URL, ndk_path)
+      if os.path.exists(ndk_path):
+        shutil.rmtree(ndk_path)
+      # Download the NDK into _STARBOARD_TOOLCHAINS_DIR and move the top
+      # _NDK_ZIP_REVISION directory that is in the zip to 'ndk-bundle'.
+      ndk_unzip_path = os.path.join(_STARBOARD_TOOLCHAINS_DIR,
+                                    _NDK_ZIP_REVISION)
+      if os.path.exists(ndk_unzip_path):
+        shutil.rmtree(ndk_unzip_path)
+      _DownloadAndUnzipFile(_NDK_URL, _STARBOARD_TOOLCHAINS_DIR)
+      # Move NDK into its proper final place.
+      os.rename(ndk_unzip_path, ndk_path)
+      _UpdateStamp(ndk_path)
 
+    logging.warning('Using Android NDK version %s', _GetInstalledNdkRevision())
   finally:
     fcntl.flock(toolchains_dir_fd, fcntl.LOCK_UN)
     os.close(toolchains_dir_fd)
diff --git a/src/starboard/android/shared/starboard_platform.gypi b/src/starboard/android/shared/starboard_platform.gypi
index 7e2d83b..1609871 100644
--- a/src/starboard/android/shared/starboard_platform.gypi
+++ b/src/starboard/android/shared/starboard_platform.gypi
@@ -14,6 +14,7 @@
 {
   'variables': {
     'has_input_events_filter' : '<!(python ../../../build/file_exists.py <(DEPTH)/starboard/android/shared/input_events_filter.cc)',
+    'has_drm_system_extension%': '<!(test -e <(DEPTH)/starboard/android/shared/drm_system_extension/drm_system_extension.gyp && echo 1 || echo 0)',
   },
   'includes': [
     '<(DEPTH)/starboard/shared/starboard/player/filter/player_filter.gypi',
@@ -84,7 +85,6 @@
         'directory_get_next.cc',
         'directory_internal.h',
         'directory_open.cc',
-        'drm_create_system.cc',
         'drm_system.cc',
         'drm_system.h',
         'egl_swap_buffers.cc',
@@ -126,11 +126,9 @@
         'media_get_max_buffer_capacity.cc',
         'media_is_audio_supported.cc',
         'media_is_output_protected.cc',
-        'media_is_supported.cc',
         'media_is_video_supported.cc',
         'media_set_output_protection.cc',
         'microphone_impl.cc',
-        'player_components_impl.cc',
         'player_create.cc',
         'player_destroy.cc',
         'player_set_bounds.cc',
@@ -346,7 +344,9 @@
         '<(DEPTH)/starboard/shared/starboard/drm/drm_close_session.cc',
         '<(DEPTH)/starboard/shared/starboard/drm/drm_destroy_system.cc',
         '<(DEPTH)/starboard/shared/starboard/drm/drm_generate_session_update_request.cc',
+        '<(DEPTH)/starboard/shared/starboard/drm/drm_is_server_certificate_updatable.cc',
         '<(DEPTH)/starboard/shared/starboard/drm/drm_system_internal.h',
+        '<(DEPTH)/starboard/shared/starboard/drm/drm_update_server_certificate.cc',
         '<(DEPTH)/starboard/shared/starboard/drm/drm_update_session.cc',
         '<(DEPTH)/starboard/shared/starboard/event_cancel.cc',
         '<(DEPTH)/starboard/shared/starboard/event_schedule.cc',
@@ -429,8 +429,6 @@
         '<(DEPTH)/starboard/shared/stub/cryptography_set_authenticated_data.cc',
         '<(DEPTH)/starboard/shared/stub/cryptography_set_initialization_vector.cc',
         '<(DEPTH)/starboard/shared/stub/cryptography_transform.cc',
-        '<(DEPTH)/starboard/shared/stub/drm_is_server_certificate_updatable.cc',
-        '<(DEPTH)/starboard/shared/stub/drm_update_server_certificate.cc',
         '<(DEPTH)/starboard/shared/stub/image_decode.cc',
         '<(DEPTH)/starboard/shared/stub/image_is_decode_supported.cc',
         '<(DEPTH)/starboard/shared/stub/system_get_total_gpu_memory.cc',
@@ -446,17 +444,6 @@
         '<(DEPTH)/starboard/shared/stub/thread_sampler_thaw.cc',
         '<(DEPTH)/starboard/shared/stub/window_get_diagonal_size_in_inches.cc',
       ],
-      'conditions': [
-        ['has_input_events_filter=="True"', {
-          'sources': [
-            'input_events_filter.cc',
-            'input_events_filter.h',
-          ],
-          'defines': [
-            'STARBOARD_INPUT_EVENTS_FILTER',
-          ],
-        }],
-      ],
       'defines': [
         # This must be defined when building Starboard, and must not when
         # building Starboard client code.
@@ -468,6 +455,28 @@
         '<(DEPTH)/third_party/opus/opus.gyp:opus',
         'starboard_base_symbolize',
       ],
+      'conditions': [
+        ['has_input_events_filter=="True"', {
+          'sources': [
+            'input_events_filter.cc',
+            'input_events_filter.h',
+          ],
+          'defines': [
+            'STARBOARD_INPUT_EVENTS_FILTER',
+          ],
+        }],
+        ['has_drm_system_extension==1', {
+          'dependencies': [
+            '<(DEPTH)/starboard/android/shared/drm_system_extension/drm_system_extension.gyp:drm_system_extension',
+          ],
+        }, {
+          'sources': [
+            'drm_create_system.cc',
+            'media_is_supported.cc',
+            'player_components_impl.cc',
+          ],
+        }],
+      ],
     },
   ],
 }
diff --git a/src/starboard/android/shared/video_decoder.cc b/src/starboard/android/shared/video_decoder.cc
index 9baffbd..e1808bf 100644
--- a/src/starboard/android/shared/video_decoder.cc
+++ b/src/starboard/android/shared/video_decoder.cc
@@ -25,7 +25,6 @@
 #include "starboard/android/shared/jni_env_ext.h"
 #include "starboard/android/shared/jni_utils.h"
 #include "starboard/android/shared/media_common.h"
-#include "starboard/android/shared/video_window.h"
 #include "starboard/android/shared/window_internal.h"
 #include "starboard/configuration.h"
 #include "starboard/decode_target.h"
@@ -170,7 +169,8 @@
       decode_target_(kSbDecodeTargetInvalid),
       frame_width_(0),
       frame_height_(0),
-      first_buffer_received_(false) {
+      first_buffer_received_(false),
+      surface_condition_variable_(surface_destroy_mutex_) {
   if (!InitializeCodec()) {
     SB_LOG(ERROR) << "Failed to initialize video decoder.";
     TeardownCodec();
@@ -241,12 +241,16 @@
     // because we need to change the color metadata.
     if (media_decoder_ == NULL) {
       if (!InitializeCodec()) {
-        // TODO: Communicate this failure to our clients somehow.
         SB_LOG(ERROR) << "Failed to reinitialize codec.";
+        TeardownCodec();
+        error_cb_(kSbPlayerErrorDecode, "Cannot initialize codec.");
       }
     }
   }
 
+  if (!is_valid()) {
+    return;
+  }
   media_decoder_->WriteInputBuffer(input_buffer);
   if (number_of_frames_being_decoded_.increment() < kMaxPendingWorkSize) {
     decoder_status_cb_(kNeedMoreInput, NULL);
@@ -261,6 +265,9 @@
     first_buffer_timestamp_ = 0;
   }
 
+  if (!is_valid()) {
+    return;
+  }
   media_decoder_->WriteEndOfStream();
 }
 
@@ -271,6 +278,7 @@
 }
 
 bool VideoDecoder::InitializeCodec() {
+  SB_DCHECK(BelongsToCurrentThread());
   // Setup the output surface object.  If we are in punch-out mode, target
   // the passed in Android video surface.  If we are in decode-to-texture
   // mode, create a surface from a new texture target and use that as the
@@ -278,7 +286,10 @@
   jobject j_output_surface = NULL;
   switch (output_mode_) {
     case kSbPlayerOutputModePunchOut: {
-      j_output_surface = GetVideoSurface();
+      j_output_surface = AcquireVideoSurface();
+      if (j_output_surface) {
+        owns_video_surface_ = true;
+      }
     } break;
     case kSbPlayerOutputModeDecodeToTexture: {
       // A width and height of (0, 0) is provided here because Android doesn't
@@ -306,14 +317,12 @@
     return false;
   }
 
-  ANativeWindow* video_window = GetVideoWindow();
-  if (!video_window) {
+  int width, height;
+  if (!GetVideoWindowSize(&width, &height)) {
     SB_LOG(ERROR)
         << "Can't initialize the codec since we don't have a video window.";
     return false;
   }
-  int width = ANativeWindow_getWidth(video_window);
-  int height = ANativeWindow_getHeight(video_window);
 
   jobject j_media_crypto = drm_system_ ? drm_system_->GetMediaCrypto() : NULL;
   SB_DCHECK(!drm_system_ || j_media_crypto);
@@ -331,6 +340,11 @@
 }
 
 void VideoDecoder::TeardownCodec() {
+  SB_DCHECK(BelongsToCurrentThread());
+  if (owns_video_surface_) {
+    ReleaseVideoSurface();
+    owns_video_surface_ = false;
+  }
   media_decoder_.reset();
   color_metadata_ = starboard::nullopt;
 
@@ -494,6 +508,21 @@
   }
 }
 
+void VideoDecoder::OnSurfaceDestroyed() {
+  if (!BelongsToCurrentThread()) {
+    // Wait until codec is stoped.
+    ScopedLock lock(surface_destroy_mutex_);
+    Schedule(std::bind(&VideoDecoder::OnSurfaceDestroyed, this));
+    surface_condition_variable_.WaitTimed(kSbTimeSecond);
+    return;
+  }
+  // When this function is called, the decoder no longer owns the surface.
+  owns_video_surface_ = false;
+  TeardownCodec();
+  ScopedLock lock(surface_destroy_mutex_);
+  surface_condition_variable_.Signal();
+}
+
 }  // namespace shared
 }  // namespace android
 }  // namespace starboard
diff --git a/src/starboard/android/shared/video_decoder.h b/src/starboard/android/shared/video_decoder.h
index 0a4bd13..99aba66 100644
--- a/src/starboard/android/shared/video_decoder.h
+++ b/src/starboard/android/shared/video_decoder.h
@@ -20,9 +20,11 @@
 #include "starboard/android/shared/drm_system.h"
 #include "starboard/android/shared/media_codec_bridge.h"
 #include "starboard/android/shared/media_decoder.h"
+#include "starboard/android/shared/video_window.h"
 #include "starboard/atomic.h"
 #include "starboard/common/optional.h"
 #include "starboard/common/ref_counted.h"
+#include "starboard/condition_variable.h"
 #include "starboard/decode_target.h"
 #include "starboard/media.h"
 #include "starboard/player.h"
@@ -30,6 +32,7 @@
 #include "starboard/shared/starboard/player/filter/video_decoder_internal.h"
 #include "starboard/shared/starboard/player/filter/video_renderer_sink.h"
 #include "starboard/shared/starboard/player/input_buffer_internal.h"
+#include "starboard/shared/starboard/player/job_queue.h"
 
 namespace starboard {
 namespace android {
@@ -37,7 +40,9 @@
 
 class VideoDecoder
     : public ::starboard::shared::starboard::player::filter::VideoDecoder,
-      private MediaDecoder::Host {
+      private MediaDecoder::Host,
+      private ::starboard::shared::starboard::player::JobQueue::JobOwner,
+      private VideoSurfaceHolder {
  public:
   typedef ::starboard::shared::starboard::player::filter::VideoRendererSink
       VideoRendererSink;
@@ -79,6 +84,8 @@
   bool Tick(MediaCodecBridge* media_codec_bridge) override;
   void OnFlushing() override;
 
+  void OnSurfaceDestroyed() override;
+
   // These variables will be initialized inside ctor or Initialize() and will
   // not be changed during the life time of this class.
   const SbMediaVideoCodec video_codec_;
@@ -115,6 +122,13 @@
 
   bool first_buffer_received_;
   volatile SbTime first_buffer_timestamp_;
+
+  // Use |owns_video_surface_| only on decoder thread, to avoid unnecessary
+  // invocation of ReleaseVideoSurface(), though ReleaseVideoSurface() would
+  // do nothing if not own the surface.
+  bool owns_video_surface_ = false;
+  starboard::Mutex surface_destroy_mutex_;
+  starboard::ConditionVariable surface_condition_variable_;
 };
 
 }  // namespace shared
diff --git a/src/starboard/android/shared/video_window.cc b/src/starboard/android/shared/video_window.cc
index da4bbf0..518674d 100644
--- a/src/starboard/android/shared/video_window.cc
+++ b/src/starboard/android/shared/video_window.cc
@@ -21,9 +21,10 @@
 #include <jni.h>
 
 #include "starboard/android/shared/jni_env_ext.h"
-#include "starboard/condition_variable.h"
 #include "starboard/configuration.h"
 #include "starboard/log.h"
+#include "starboard/mutex.h"
+#include "starboard/once.h"
 #include "starboard/shared/gles/gl_call.h"
 
 namespace starboard {
@@ -32,17 +33,14 @@
 
 namespace {
 
+// Global video surface pointer mutex.
+SB_ONCE_INITIALIZE_FUNCTION(Mutex, GetViewSurfaceMutex);
 // Global pointer to the single video surface.
 jobject g_j_video_surface = NULL;
 // Global pointer to the single video window.
 ANativeWindow* g_native_video_window = NULL;
-
-// Facilitate synchronization of punch-out videos.
-SbMutex g_bounds_updates_mutex = SB_MUTEX_INITIALIZER;
-SbConditionVariable g_bounds_updates_condition =
-    SB_CONDITION_VARIABLE_INITIALIZER;
-int g_bounds_updates_needed = 0;
-int g_bounds_updates_scheduled = 0;
+// Global video surface pointer holder.
+VideoSurfaceHolder* g_video_surface_holder = NULL;
 
 }  // namespace
 
@@ -51,58 +49,61 @@
     JNIEnv* env,
     jobject unused_this,
     jobject surface) {
+  ScopedLock lock(*GetViewSurfaceMutex());
+  if (g_video_surface_holder) {
+    g_video_surface_holder->OnSurfaceDestroyed();
+    g_video_surface_holder = NULL;
+  }
   if (g_j_video_surface) {
-    // TODO: Ensure that the decoder isn't still using the surface.
     env->DeleteGlobalRef(g_j_video_surface);
+    g_j_video_surface = NULL;
   }
   if (g_native_video_window) {
-    // TODO: Ensure that the decoder isn't still using the window.
     ANativeWindow_release(g_native_video_window);
+    g_native_video_window = NULL;
   }
   if (surface) {
     g_j_video_surface = env->NewGlobalRef(surface);
     g_native_video_window = ANativeWindow_fromSurface(env, surface);
-  } else {
-    g_j_video_surface = NULL;
-    g_native_video_window = NULL;
   }
 }
 
-extern "C" SB_EXPORT_PLATFORM void
-Java_dev_cobalt_media_VideoSurfaceView_nativeOnLayoutNeeded() {
-  SbMutexAcquire(&g_bounds_updates_mutex);
-  ++g_bounds_updates_needed;
-  SbMutexRelease(&g_bounds_updates_mutex);
-}
-
-extern "C" SB_EXPORT_PLATFORM void
-Java_dev_cobalt_media_VideoSurfaceView_nativeOnLayoutScheduled() {
-  SbMutexAcquire(&g_bounds_updates_mutex);
-  ++g_bounds_updates_scheduled;
-  SbMutexRelease(&g_bounds_updates_mutex);
-}
-
-extern "C" SB_EXPORT_PLATFORM void
-Java_dev_cobalt_media_VideoSurfaceView_nativeOnGlobalLayout() {
-  SbMutexAcquire(&g_bounds_updates_mutex);
-  g_bounds_updates_needed -= g_bounds_updates_scheduled;
-  g_bounds_updates_scheduled = 0;
-  if (g_bounds_updates_needed <= 0) {
-    g_bounds_updates_needed = 0;
-    SbConditionVariableSignal(&g_bounds_updates_condition);
+jobject VideoSurfaceHolder::AcquireVideoSurface() {
+  ScopedLock lock(*GetViewSurfaceMutex());
+  SB_DCHECK(g_video_surface_holder == NULL);
+  if (g_video_surface_holder != NULL) {
+    return NULL;
   }
-  SbMutexRelease(&g_bounds_updates_mutex);
-}
-
-jobject GetVideoSurface() {
+  if (!g_j_video_surface) {
+    return NULL;
+  }
+  g_video_surface_holder = this;
   return g_j_video_surface;
 }
 
-ANativeWindow* GetVideoWindow() {
-  return g_native_video_window;
+void VideoSurfaceHolder::ReleaseVideoSurface() {
+  ScopedLock lock(*GetViewSurfaceMutex());
+  if (g_video_surface_holder == this) {
+    g_video_surface_holder = NULL;
+  }
 }
 
-void ClearVideoWindow() {
+bool VideoSurfaceHolder::GetVideoWindowSize(int* width, int* height) {
+  ScopedLock lock(*GetViewSurfaceMutex());
+  if (g_native_video_window == NULL) {
+    return false;
+  } else {
+    *width = ANativeWindow_getWidth(g_native_video_window);
+    *height = ANativeWindow_getHeight(g_native_video_window);
+    return true;
+  }
+}
+
+void VideoSurfaceHolder::ClearVideoWindow() {
+  // Lock *GetViewSurfaceMutex() here, to avoid releasing g_native_video_window
+  // during painting.
+  ScopedLock lock(*GetViewSurfaceMutex());
+
   if (!g_native_video_window) {
     SB_LOG(INFO) << "Tried to clear video window when it was null.";
     return;
@@ -188,20 +189,6 @@
   EGL_CALL(eglTerminate(display));
 }
 
-void WaitForVideoBoundsUpdate() {
-  SbMutexAcquire(&g_bounds_updates_mutex);
-  if (g_bounds_updates_needed > 0) {
-    // Use a timed wait to deal with possible race conditions in which
-    // suspend occurs in the middle of a bounds update.
-    SbConditionVariableWaitTimed(&g_bounds_updates_condition,
-                                 &g_bounds_updates_mutex,
-                                 100 * kSbTimeMillisecond);
-    g_bounds_updates_needed = 0;
-    g_bounds_updates_scheduled = 0;
-  }
-  SbMutexRelease(&g_bounds_updates_mutex);
-}
-
 }  // namespace shared
 }  // namespace android
 }  // namespace starboard
diff --git a/src/starboard/android/shared/video_window.h b/src/starboard/android/shared/video_window.h
index 39cb33f..908b567 100644
--- a/src/starboard/android/shared/video_window.h
+++ b/src/starboard/android/shared/video_window.h
@@ -22,19 +22,31 @@
 namespace android {
 namespace shared {
 
-// Returns the surface which video should be rendered.  This is the surface
-// that owns the native window returned by |GetVideoWindow|.
-jobject GetVideoSurface();
+class VideoSurfaceHolder {
+ public:
+  // OnSurfaceDestroyed() will be invoked when surface is destroyed. When this
+  // function is called, the decoder no longer owns the surface. Calling
+  // AcquireVideoSurface(), ReleaseVideoSurface(), GetVideoWindowSize() or
+  // ClearVideoWindow() in this function may cause dead lock.
+  virtual void OnSurfaceDestroyed() = 0;
 
-// Returns the native window into which video should be rendered.
-ANativeWindow* GetVideoWindow();
+ protected:
+  ~VideoSurfaceHolder() {}
 
-// Clear the video window by painting it Black.  This function is safe to call
-// regardless of whether the video window has been initialized or not.
-void ClearVideoWindow();
+  // Returns the surface which video should be rendered. Surface cannot be
+  // acquired before last holder release the surface.
+  jobject AcquireVideoSurface();
 
-// Wait for all outstanding adjustments of video bounds before returning.
-void WaitForVideoBoundsUpdate();
+  // Release the surface to make the surface available for other holder.
+  void ReleaseVideoSurface();
+
+  // Get the native window size. Return false if don't have available native
+  // window.
+  bool GetVideoWindowSize(int* width, int* height);
+
+  // Clear the video window by painting it Black.
+  void ClearVideoWindow();
+};
 
 }  // namespace shared
 }  // namespace android
diff --git a/src/starboard/linux/shared/starboard_platform.gypi b/src/starboard/linux/shared/starboard_platform.gypi
index 5eed6f1..0a2cedb 100644
--- a/src/starboard/linux/shared/starboard_platform.gypi
+++ b/src/starboard/linux/shared/starboard_platform.gypi
@@ -368,13 +368,13 @@
           '<(DEPTH)/starboard/shared/starboard/drm/drm_close_session.cc',
           '<(DEPTH)/starboard/shared/starboard/drm/drm_destroy_system.cc',
           '<(DEPTH)/starboard/shared/starboard/drm/drm_generate_session_update_request.cc',
+          '<(DEPTH)/starboard/shared/starboard/drm/drm_is_server_certificate_updatable.cc',
           '<(DEPTH)/starboard/shared/starboard/drm/drm_system_internal.h',
+          '<(DEPTH)/starboard/shared/starboard/drm/drm_update_server_certificate.cc',
           '<(DEPTH)/starboard/shared/starboard/drm/drm_update_session.cc',
 
-          '<(DEPTH)/starboard/shared/widevine/drm_is_server_certificate_updatable.cc',
           '<(DEPTH)/starboard/shared/widevine/drm_system_widevine.cc',
           '<(DEPTH)/starboard/shared/widevine/drm_system_widevine.h',
-          '<(DEPTH)/starboard/shared/widevine/drm_update_server_certificate.cc',
           '<(DEPTH)/starboard/shared/widevine/media_is_supported.cc',
           '<(DEPTH)/starboard/shared/widevine/widevine_storage.cc',
           '<(DEPTH)/starboard/shared/widevine/widevine_storage.h',
diff --git a/src/starboard/shared/widevine/drm_is_server_certificate_updatable.cc b/src/starboard/shared/starboard/drm/drm_is_server_certificate_updatable.cc
similarity index 69%
rename from src/starboard/shared/widevine/drm_is_server_certificate_updatable.cc
rename to src/starboard/shared/starboard/drm/drm_is_server_certificate_updatable.cc
index 91d17dd..57afcd5 100644
--- a/src/starboard/shared/widevine/drm_is_server_certificate_updatable.cc
+++ b/src/starboard/shared/starboard/drm/drm_is_server_certificate_updatable.cc
@@ -1,4 +1,4 @@
-// Copyright 2018 The Cobalt Authors. All Rights Reserved.
+// Copyright 2019 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.
@@ -14,12 +14,18 @@
 
 #include "starboard/drm.h"
 
+#include "starboard/log.h"
+#include "starboard/shared/starboard/drm/drm_system_internal.h"
+
 #if SB_API_VERSION >= 10
 
 bool SbDrmIsServerCertificateUpdatable(SbDrmSystem drm_system) {
-  SB_UNREFERENCED_PARAMETER(drm_system);
+  if (!SbDrmSystemIsValid(drm_system)) {
+    SB_DLOG(ERROR) << "Invalid DRM system.";
+    return false;
+  }
 
-  return true;
+  return drm_system->IsServerCertificateUpdatable();
 }
 
 #endif  // SB_API_VERSION >= 10
diff --git a/src/starboard/shared/starboard/drm/drm_system_internal.h b/src/starboard/shared/starboard/drm/drm_system_internal.h
index 696855b..5cf70e5 100644
--- a/src/starboard/shared/starboard/drm/drm_system_internal.h
+++ b/src/starboard/shared/starboard/drm/drm_system_internal.h
@@ -42,6 +42,8 @@
   virtual DecryptStatus Decrypt(InputBuffer* buffer) = 0;
 
 #if SB_API_VERSION >= 10
+  virtual bool IsServerCertificateUpdatable() = 0;
+
   virtual void UpdateServerCertificate(int ticket,
                                        const void* certificate,
                                        int certificate_size) = 0;
diff --git a/src/starboard/shared/widevine/drm_update_server_certificate.cc b/src/starboard/shared/starboard/drm/drm_update_server_certificate.cc
similarity index 95%
rename from src/starboard/shared/widevine/drm_update_server_certificate.cc
rename to src/starboard/shared/starboard/drm/drm_update_server_certificate.cc
index b9f29d4..c39cd11 100644
--- a/src/starboard/shared/widevine/drm_update_server_certificate.cc
+++ b/src/starboard/shared/starboard/drm/drm_update_server_certificate.cc
@@ -1,4 +1,4 @@
-// Copyright 2018 The Cobalt Authors. All Rights Reserved.
+// Copyright 2019 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.
diff --git a/src/starboard/shared/widevine/drm_system_widevine.cc b/src/starboard/shared/widevine/drm_system_widevine.cc
index 471b163..3a0f961 100644
--- a/src/starboard/shared/widevine/drm_system_widevine.cc
+++ b/src/starboard/shared/widevine/drm_system_widevine.cc
@@ -14,6 +14,7 @@
 
 #include "starboard/shared/widevine/drm_system_widevine.h"
 
+#include <algorithm>
 #include <vector>
 
 #include "starboard/character.h"
@@ -47,6 +48,38 @@
   }
 };
 
+class Registry {
+ public:
+  void Register(SbDrmSystem drm_system) {
+    SB_DCHECK(SbDrmSystemIsValid(drm_system));
+    ScopedLock scoped_lock(mutex_);
+    auto iter = std::find(drm_systems_.begin(), drm_systems_.end(), drm_system);
+    SB_DCHECK(iter == drm_systems_.end());
+    drm_systems_.push_back(drm_system);
+  }
+
+  void Unregister(SbDrmSystem drm_system) {
+    ScopedLock scoped_lock(mutex_);
+    auto iter = std::find(drm_systems_.begin(), drm_systems_.end(), drm_system);
+    SB_DCHECK(iter != drm_systems_.end());
+    drm_systems_.erase(iter);
+  }
+
+  bool Contains(SbDrmSystem drm_system) const {
+    ScopedLock scoped_lock(mutex_);
+    auto iter = std::find(drm_systems_.begin(), drm_systems_.end(), drm_system);
+    return iter != drm_systems_.end();
+  }
+
+ private:
+  Mutex mutex_;
+  // Use std::vector<> as usually there is only one active instance of widevine
+  // drm system.
+  std::vector<SbDrmSystem> drm_systems_;
+};
+
+SB_ONCE_INITIALIZE_FUNCTION(Registry, GetRegistry);
+
 std::string GetWidevineStoragePath() {
   char path[SB_FILE_MAX_PATH + 1] = {0};
   auto path_size = SB_ARRAY_SIZE_INT(path);
@@ -212,9 +245,13 @@
 #endif  // SB_API_VERSION >= 10
   cdm_.reset(wv3cdm::create(this, NULL, kEnablePrivacyMode));
   SB_DCHECK(cdm_);
+
+  GetRegistry()->Register(this);
 }
 
-DrmSystemWidevine::~DrmSystemWidevine() {}
+DrmSystemWidevine::~DrmSystemWidevine() {
+  GetRegistry()->Unregister(this);
+}
 
 // static
 bool DrmSystemWidevine::IsKeySystemSupported(const char* key_system) {
@@ -226,6 +263,11 @@
   return false;
 }
 
+// static
+bool DrmSystemWidevine::IsDrmSystemWidevine(SbDrmSystem drm_system) {
+  return GetRegistry()->Contains(drm_system);
+}
+
 void DrmSystemWidevine::GenerateSessionUpdateRequest(
     int ticket,
     const char* type,
diff --git a/src/starboard/shared/widevine/drm_system_widevine.h b/src/starboard/shared/widevine/drm_system_widevine.h
index d9873a4..ddc8ab2 100644
--- a/src/starboard/shared/widevine/drm_system_widevine.h
+++ b/src/starboard/shared/widevine/drm_system_widevine.h
@@ -61,6 +61,7 @@
   ~DrmSystemWidevine() override;
 
   static bool IsKeySystemSupported(const char* key_system);
+  static bool IsDrmSystemWidevine(SbDrmSystem drm_system);
 
   // From |SbDrmSystemPrivate|.
   void GenerateSessionUpdateRequest(int ticket,
@@ -80,6 +81,8 @@
   DecryptStatus Decrypt(InputBuffer* buffer) override;
 
 #if SB_API_VERSION >= 10
+  bool IsServerCertificateUpdatable() override { return true; }
+
   // This function is called by the app to explicitly set the server
   // certificate.  For an app that supports this feature, it should call this
   // function before calling any other functions like
diff --git a/src/third_party/boringssl/boringssl.gyp b/src/third_party/boringssl/boringssl.gyp
index 81abcd8..ac3d496 100644
--- a/src/third_party/boringssl/boringssl.gyp
+++ b/src/third_party/boringssl/boringssl.gyp
@@ -211,7 +211,7 @@
       '.',
       '<@(openssl_config_path)',
     ],
-    'direct_dependent_settings': {
+    'all_dependent_settings': {
       'include_dirs': [
         '<@(openssl_config_path)',
       ],
@@ -231,7 +231,7 @@
       'include_dirs': [
         '<(boringssl_root)/include',
       ],
-      'direct_dependent_settings': {
+      'all_dependent_settings': {
         'include_dirs': [
           '<(boringssl_root)/include',
         ],
@@ -242,7 +242,6 @@
         # of assembly language files for the current OS and CPU architecture, or
         # it will turn off assembly language files entirely if the
         # |asm_target_arch| has been set to "none".
-
         ['target_os not in ["linux", "android", "tvos"] or asm_target_arch not in ["x86", "x64", "arm", "arm64"]', {
           # please read comments for |target_os=="win"| condition below
           'defines': [