Merge "Fix breakages in SDK drop" into pi-androidx-dev
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
index 9ba3c38..9466f0c 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
@@ -47,6 +47,7 @@
     const val LOCALBROADCASTMANAGER = "androidx.localbroadcastmanager"
     const val MEDIA = "androidx.media"
     const val MEDIAROUTER = "androidx.mediarouter"
+    const val MEDIAWIDGET = "androidx.mediawidget"
     const val PALETTE = "androidx.palette"
     const val PERCENTLAYOUT = "androidx.percentlayout"
     const val PREFERENCE = "androidx.preference"
diff --git a/car/res/values/integers.xml b/car/res/values/integers.xml
index 1acb572..dcae680 100644
--- a/car/res/values/integers.xml
+++ b/car/res/values/integers.xml
@@ -31,10 +31,6 @@
     <!-- Slide Down Menu -->
     <integer name="car_slide_down_menu_column_number">4</integer>
 
-    <!-- The length limit of body text in a paged list item. String longer than this limit should be
-         truncated. -->
-    <integer name="car_list_item_text_length_limit">120</integer>
-
     <!-- The length limit of text in a borderless button. String longer than this limit should be
          truncated. -->
     <integer name="car_borderless_button_text_length_limit">20</integer>
diff --git a/car/src/main/java/androidx/car/utils/CarUxRestrictionsUtils.java b/car/src/main/java/androidx/car/utils/CarUxRestrictionsUtils.java
index e06ba80..7fec3c0 100644
--- a/car/src/main/java/androidx/car/utils/CarUxRestrictionsUtils.java
+++ b/car/src/main/java/androidx/car/utils/CarUxRestrictionsUtils.java
@@ -20,7 +20,6 @@
 
 import android.car.drivingstate.CarUxRestrictions;
 import android.content.Context;
-import androidx.annotation.RestrictTo;
 import android.text.InputFilter;
 import android.widget.TextView;
 
@@ -28,7 +27,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-import androidx.car.R;
+import androidx.annotation.RestrictTo;
 
 /**
  * Utility class that helps {@code View}s comply with {@link CarUxRestrictions}.
@@ -53,8 +52,7 @@
      */
     public static void comply(Context context, CarUxRestrictions carUxRestrictions, TextView tv) {
         if (sStringLengthFilter == null) {
-            int lengthLimit = context.getResources().getInteger(
-                    R.integer.car_list_item_text_length_limit);
+            int lengthLimit = carUxRestrictions.getMaxRestrictedStringLength();
             sStringLengthFilter = new InputFilter.LengthFilter(lengthLimit);
         }
 
diff --git a/compat/res/values/dimens.xml b/compat/res/values/dimens.xml
index 41abbe6..9ece458 100644
--- a/compat/res/values/dimens.xml
+++ b/compat/res/values/dimens.xml
@@ -72,8 +72,8 @@
     <dimen name="notification_right_side_padding_top">2dp</dimen>
 
     <!-- the maximum width of the large icon, above which it will be downscaled -->
-    <dimen name="notification_icon_max_width">320dp</dimen>
+    <dimen name="compat_notification_large_icon_max_width">320dp</dimen>
 
     <!-- the maximum height of the large icon, above which it will be downscaled -->
-    <dimen name="notification_icon_max_height">320dp</dimen>
+    <dimen name="compat_notification_large_icon_max_height">320dp</dimen>
 </resources>
diff --git a/compat/src/main/java/androidx/core/app/NotificationCompat.java b/compat/src/main/java/androidx/core/app/NotificationCompat.java
index aba40d1..9e60574 100644
--- a/compat/src/main/java/androidx/core/app/NotificationCompat.java
+++ b/compat/src/main/java/androidx/core/app/NotificationCompat.java
@@ -977,8 +977,10 @@
             }
 
             Resources res = mContext.getResources();
-            int maxWidth = res.getDimensionPixelSize(R.dimen.notification_icon_max_width);
-            int maxHeight = res.getDimensionPixelSize(R.dimen.notification_icon_max_height);
+            int maxWidth =
+                    res.getDimensionPixelSize(R.dimen.compat_notification_large_icon_max_width);
+            int maxHeight =
+                    res.getDimensionPixelSize(R.dimen.compat_notification_large_icon_max_height);
             if (icon.getWidth() <= maxWidth && icon.getHeight() <= maxHeight) {
                 return icon;
             }
diff --git a/media-widget/OWNERS b/media-widget/OWNERS
new file mode 100644
index 0000000..c740b62
--- /dev/null
+++ b/media-widget/OWNERS
@@ -0,0 +1,6 @@
+sungsoo@google.com
+insun@google.com
+jinpark@google.com
+hdmoon@google.com
+jaewan@google.com
+akersten@google.com
\ No newline at end of file
diff --git a/media-widget/build.gradle b/media-widget/build.gradle
new file mode 100644
index 0000000..de3f9d9
--- /dev/null
+++ b/media-widget/build.gradle
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import static androidx.build.dependencies.DependenciesKt.*
+import androidx.build.LibraryGroups
+import androidx.build.LibraryVersions
+
+plugins {
+    id("SupportAndroidLibraryPlugin")
+}
+
+dependencies {
+    api(project(":media"))
+    api(project(":mediarouter"))
+    api(project(":appcompat"))
+    api(project(":palette"))
+
+    androidTestImplementation(TEST_RUNNER_TMP, libs.exclude_for_espresso)
+    androidTestImplementation(ESPRESSO_CORE_TMP, libs.exclude_for_espresso)
+    androidTestImplementation(TEST_RULES_TMP, libs.exclude_for_espresso)
+    androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+    androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+    androidTestImplementation project(':internal-testutils')
+}
+
+supportLibrary {
+    name = "Android Media Support Library"
+    publish = true
+    mavenVersion = LibraryVersions.SUPPORT_LIBRARY
+    mavenGroup = LibraryGroups.MEDIA
+    inceptionYear = "2011"
+    description = "Android Media Support Library"
+}
diff --git a/media-widget/src/androidTest/AndroidManifest.xml b/media-widget/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..dd6e9e0
--- /dev/null
+++ b/media-widget/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2018 The Android Open Source Project
+  ~
+  ~ 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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="androidx.media.widget.test">
+    <uses-sdk android:targetSdkVersion="${target-sdk-version}"/>
+
+    <application>
+        <activity android:name="androidx.media.widget.VideoView2TestActivity"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:label="VideoView2TestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/media/src/androidTest/java/androidx/widget/MediaUtils2.java b/media-widget/src/androidTest/java/androidx/media/widget/MediaUtils2.java
similarity index 98%
rename from media/src/androidTest/java/androidx/widget/MediaUtils2.java
rename to media-widget/src/androidTest/java/androidx/media/widget/MediaUtils2.java
index 29eb9f6..59b2567 100644
--- a/media/src/androidTest/java/androidx/widget/MediaUtils2.java
+++ b/media-widget/src/androidTest/java/androidx/media/widget/MediaUtils2.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package androidx.widget;
+package androidx.media.widget;
 
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
diff --git a/media/src/androidTest/java/androidx/widget/VideoView2Test.java b/media-widget/src/androidTest/java/androidx/media/widget/VideoView2Test.java
similarity index 98%
rename from media/src/androidTest/java/androidx/widget/VideoView2Test.java
rename to media-widget/src/androidTest/java/androidx/media/widget/VideoView2Test.java
index 7f3dcfc..2876e47 100644
--- a/media/src/androidTest/java/androidx/widget/VideoView2Test.java
+++ b/media-widget/src/androidTest/java/androidx/media/widget/VideoView2Test.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.widget;
+package androidx.media.widget;
 
 import static android.content.Context.KEYGUARD_SERVICE;
 
@@ -44,7 +44,7 @@
 import android.view.WindowManager;
 
 import androidx.media.AudioAttributesCompat;
-import androidx.media.test.R;
+import androidx.media.widget.test.R;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/media/src/androidTest/java/androidx/widget/VideoView2TestActivity.java b/media-widget/src/androidTest/java/androidx/media/widget/VideoView2TestActivity.java
similarity index 93%
rename from media/src/androidTest/java/androidx/widget/VideoView2TestActivity.java
rename to media-widget/src/androidTest/java/androidx/media/widget/VideoView2TestActivity.java
index 26a9c92..d6a3ebc 100644
--- a/media/src/androidTest/java/androidx/widget/VideoView2TestActivity.java
+++ b/media-widget/src/androidTest/java/androidx/media/widget/VideoView2TestActivity.java
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package androidx.widget;
+package androidx.media.widget;
 
 import android.app.Activity;
 import android.os.Bundle;
 
-import androidx.media.test.R;
+import androidx.media.widget.test.R;
 
 /**
  * A minimal application for {@link VideoView2} test.
diff --git a/media-widget/src/androidTest/res/layout/videoview2_layout.xml b/media-widget/src/androidTest/res/layout/videoview2_layout.xml
new file mode 100644
index 0000000..40e07d5
--- /dev/null
+++ b/media-widget/src/androidTest/res/layout/videoview2_layout.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2018 The Android Open Source Project
+  ~
+  ~ 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.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.media.widget.VideoView2
+        android:id="@+id/videoview"
+        android:layout_width="160dp"
+        android:layout_height="120dp"/>
+</LinearLayout>
diff --git a/media-widget/src/androidTest/res/raw/testvideo.3gp b/media-widget/src/androidTest/res/raw/testvideo.3gp
new file mode 100644
index 0000000..8329311
--- /dev/null
+++ b/media-widget/src/androidTest/res/raw/testvideo.3gp
Binary files differ
diff --git a/media-widget/src/androidTest/res/values/themes.xml b/media-widget/src/androidTest/res/values/themes.xml
new file mode 100644
index 0000000..2843f5e
--- /dev/null
+++ b/media-widget/src/androidTest/res/values/themes.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2018 The Android Open Source Project
+  ~
+  ~ 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.
+  -->
+
+<resources>
+
+    <style name="HasWindowTitle">
+        <item name="windowNoTitle">false</item>
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/media-widget/src/main/AndroidManifest.xml b/media-widget/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..824903e
--- /dev/null
+++ b/media-widget/src/main/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2018 The Android Open Source Project
+  ~
+  ~ 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.
+  -->
+<manifest package="androidx.media.widget"/>
diff --git a/media/src/main/java/androidx/widget/BaseLayout.java b/media-widget/src/main/java/androidx/media/widget/BaseLayout.java
similarity index 93%
rename from media/src/main/java/androidx/widget/BaseLayout.java
rename to media-widget/src/main/java/androidx/media/widget/BaseLayout.java
index 127006e..0b6988a 100644
--- a/media/src/main/java/androidx/widget/BaseLayout.java
+++ b/media-widget/src/main/java/androidx/media/widget/BaseLayout.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.widget;
+package androidx.media.widget;
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
@@ -22,8 +22,6 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewGroup.MarginLayoutParams;
 
 import androidx.annotation.AttrRes;
 import androidx.annotation.NonNull;
@@ -83,8 +81,8 @@
         int count = getChildCount();
 
         final boolean measureMatchParentChildren =
-                View.MeasureSpec.getMode(widthMeasureSpec) != View.MeasureSpec.EXACTLY
-                        || View.MeasureSpec.getMode(heightMeasureSpec) != View.MeasureSpec.EXACTLY;
+                MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY
+                        || MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
         mMatchParentChildren.clear();
 
         int maxHeight = 0;
@@ -144,8 +142,8 @@
                     final int width = Math.max(0, getMeasuredWidth()
                             - getPaddingLeftWithForeground() - getPaddingRightWithForeground()
                             - lp.leftMargin - lp.rightMargin);
-                    childWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
-                            width, View.MeasureSpec.EXACTLY);
+                    childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                            width, MeasureSpec.EXACTLY);
                 } else {
                     childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
                             getPaddingLeftWithForeground() + getPaddingRightWithForeground()
@@ -157,8 +155,8 @@
                     final int height = Math.max(0, getMeasuredHeight()
                             - getPaddingTopWithForeground() - getPaddingBottomWithForeground()
                             - lp.topMargin - lp.bottomMargin);
-                    childHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
-                            height, View.MeasureSpec.EXACTLY);
+                    childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                            height, MeasureSpec.EXACTLY);
                 } else {
                     childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
                             getPaddingTopWithForeground() + getPaddingBottomWithForeground()
diff --git a/media/src/main/java/androidx/widget/MediaControlView2.java b/media-widget/src/main/java/androidx/media/widget/MediaControlView2.java
similarity index 97%
rename from media/src/main/java/androidx/widget/MediaControlView2.java
rename to media-widget/src/main/java/androidx/media/widget/MediaControlView2.java
index 51d427f..89fa946 100644
--- a/media/src/main/java/androidx/widget/MediaControlView2.java
+++ b/media-widget/src/main/java/androidx/media/widget/MediaControlView2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.widget;
+package androidx.media.widget;
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
@@ -50,11 +50,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
-import androidx.media.R;
 import androidx.media.SessionToken2;
-// import androidx.mediarouter.app.MediaRouteButton;
-// import androidx.mediarouter.media.MediaRouter;
-// import androidx.mediarouter.media.MediaRouteSelector;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -64,6 +60,10 @@
 import java.util.List;
 import java.util.Locale;
 
+// import androidx.mediarouter.app.MediaRouteButton;
+// import androidx.mediarouter.media.MediaRouter;
+// import androidx.mediarouter.media.MediaRouteSelector;
+
 /**
  * @hide
  * A View that contains the controls for MediaPlayer2.
@@ -96,7 +96,9 @@
 @RequiresApi(21) // TODO correct minSdk API use incompatibilities and remove before release.
 @RestrictTo(LIBRARY_GROUP)
 public class MediaControlView2 extends BaseLayout {
-    /** @hide */
+    /**
+     * @hide
+     */
     @RestrictTo(LIBRARY_GROUP)
     @IntDef({
             BUTTON_PLAY_PAUSE,
@@ -710,6 +712,7 @@
         return inflater.inflate(resId, null);
     }
 
+    @SuppressWarnings("deprecation")
     private void initControllerView(ViewGroup v) {
         // Relating to Title Bar View
         mTitleBar = v.findViewById(R.id.title_bar);
@@ -819,7 +822,7 @@
         mSettingsWindowMargin = (-1) * mResources.getDimensionPixelSize(
                 R.dimen.mcv2_settings_offset);
         mSettingsWindow = new PopupWindow(mSettingsListView, mEmbeddedSettingsItemWidth,
-                ViewGroup.LayoutParams.WRAP_CONTENT, true);
+                LayoutParams.WRAP_CONTENT, true);
     }
 
     /**
@@ -1033,14 +1036,14 @@
         }
     };
 
-    private final View.OnClickListener mPlayPauseListener = new View.OnClickListener() {
+    private final OnClickListener mPlayPauseListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             togglePausePlayState();
         }
     };
 
-    private final View.OnClickListener mRewListener = new View.OnClickListener() {
+    private final OnClickListener mRewListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             int pos = getCurrentPosition() - REWIND_TIME_MS;
@@ -1049,7 +1052,7 @@
         }
     };
 
-    private final View.OnClickListener mFfwdListener = new View.OnClickListener() {
+    private final OnClickListener mFfwdListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             int pos = getCurrentPosition() + FORWARD_TIME_MS;
@@ -1058,28 +1061,28 @@
         }
     };
 
-    private final View.OnClickListener mNextListener = new View.OnClickListener() {
+    private final OnClickListener mNextListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             mControls.skipToNext();
         }
     };
 
-    private final View.OnClickListener mPrevListener = new View.OnClickListener() {
+    private final OnClickListener mPrevListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             mControls.skipToPrevious();
         }
     };
 
-    private final View.OnClickListener mBackListener = new View.OnClickListener() {
+    private final OnClickListener mBackListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             // TODO: implement
         }
     };
 
-    private final View.OnClickListener mSubtitleListener = new View.OnClickListener() {
+    private final OnClickListener mSubtitleListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             mSettingsMode = SETTINGS_MODE_SUBTITLE_TRACK;
@@ -1089,7 +1092,7 @@
         }
     };
 
-    private final View.OnClickListener mVideoQualityListener = new View.OnClickListener() {
+    private final OnClickListener mVideoQualityListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             mSettingsMode = SETTINGS_MODE_VIDEO_QUALITY;
@@ -1099,7 +1102,7 @@
         }
     };
 
-    private final View.OnClickListener mFullScreenListener = new View.OnClickListener() {
+    private final OnClickListener mFullScreenListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             final boolean isEnteringFullScreen = !mIsFullScreen;
@@ -1119,7 +1122,7 @@
         }
     };
 
-    private final View.OnClickListener mOverflowRightListener = new View.OnClickListener() {
+    private final OnClickListener mOverflowRightListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             mBasicControls.setVisibility(View.GONE);
@@ -1127,7 +1130,7 @@
         }
     };
 
-    private final View.OnClickListener mOverflowLeftListener = new View.OnClickListener() {
+    private final OnClickListener mOverflowLeftListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             mBasicControls.setVisibility(View.VISIBLE);
@@ -1135,7 +1138,7 @@
         }
     };
 
-    private final View.OnClickListener mMuteButtonListener = new View.OnClickListener() {
+    private final OnClickListener mMuteButtonListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             if (!mIsMute) {
@@ -1156,7 +1159,7 @@
         }
     };
 
-    private final View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
+    private final OnClickListener mSettingsButtonListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
             mSettingsMode = SETTINGS_MODE_MAIN;
@@ -1389,6 +1392,7 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     private void updateLayoutForSizeChange(int sizeType) {
         mSizeType = sizeType;
         RelativeLayout.LayoutParams timeViewParams =
@@ -1671,7 +1675,7 @@
                     button.setImageResource(action.getIcon());
                     button.setTooltipText(action.getName());
                     final String actionString = action.getAction().toString();
-                    button.setOnClickListener(new View.OnClickListener() {
+                    button.setOnClickListener(new OnClickListener() {
                         @Override
                         public void onClick(View v) {
                             // TODO: Currently, we are just sending extras that came from session.
diff --git a/media/src/main/java/androidx/widget/VideoSurfaceView.java b/media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java
similarity index 98%
rename from media/src/main/java/androidx/widget/VideoSurfaceView.java
rename to media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java
index eafa6f3..d417bd2 100644
--- a/media/src/main/java/androidx/widget/VideoSurfaceView.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package androidx.widget;
+package androidx.media.widget;
 
-import static androidx.widget.VideoView2.VIEW_TYPE_SURFACEVIEW;
+import static androidx.media.widget.VideoView2.VIEW_TYPE_SURFACEVIEW;
 
 import android.content.Context;
 import android.graphics.Rect;
diff --git a/media/src/main/java/androidx/widget/VideoTextureView.java b/media-widget/src/main/java/androidx/media/widget/VideoTextureView.java
similarity index 98%
rename from media/src/main/java/androidx/widget/VideoTextureView.java
rename to media-widget/src/main/java/androidx/media/widget/VideoTextureView.java
index 836fdc3..cdc833b 100644
--- a/media/src/main/java/androidx/widget/VideoTextureView.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoTextureView.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package androidx.widget;
+package androidx.media.widget;
 
-import static androidx.widget.VideoView2.VIEW_TYPE_TEXTUREVIEW;
+import static androidx.media.widget.VideoView2.VIEW_TYPE_TEXTUREVIEW;
 
 import android.content.Context;
 import android.graphics.SurfaceTexture;
diff --git a/media/src/main/java/androidx/widget/VideoView2.java b/media-widget/src/main/java/androidx/media/widget/VideoView2.java
similarity index 98%
rename from media/src/main/java/androidx/widget/VideoView2.java
rename to media-widget/src/main/java/androidx/media/widget/VideoView2.java
index 3cb1717..a8ea450 100644
--- a/media/src/main/java/androidx/widget/VideoView2.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoView2.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.widget;
+package androidx.media.widget;
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
@@ -47,7 +47,6 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.ImageView;
@@ -63,7 +62,6 @@
 import androidx.media.DataSourceDesc;
 import androidx.media.MediaItem2;
 import androidx.media.MediaMetadata2;
-import androidx.media.R;
 import androidx.media.SessionToken2;
 import androidx.palette.graphics.Palette;
 
@@ -187,9 +185,9 @@
     private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain
     private boolean mAudioFocused = false;
 
-    private Pair<Executor, VideoView2.OnCustomActionListener> mCustomActionListenerRecord;
-    private VideoView2.OnViewTypeChangedListener mViewTypeChangedListener;
-    private VideoView2.OnFullScreenRequestListener mFullScreenRequestListener;
+    private Pair<Executor, OnCustomActionListener> mCustomActionListenerRecord;
+    private OnViewTypeChangedListener mViewTypeChangedListener;
+    private OnFullScreenRequestListener mFullScreenRequestListener;
 
     private VideoViewInterface mCurrentView;
     private VideoTextureView mTextureView;
@@ -472,7 +470,7 @@
      * Returns MediaController instance which is connected with MediaSession that VideoView2 is
      * using. This method should be called when VideoView2 is attached to window, or it throws
      * IllegalStateException, since internal MediaSession instance is not available until
-     * this view is attached to window. Please check {@link android.view.View#isAttachedToWindow}
+     * this view is attached to window. Please check {@link View#isAttachedToWindow}
      * before calling this method.
      *
      * @throws IllegalStateException if interal MediaSession is not created yet.
@@ -487,13 +485,14 @@
     }
 
     /**
-     * Returns {@link androidx.media.SessionToken2} so that developers create their own
+     * Returns {@link SessionToken2} so that developers create their own
      * {@link androidx.media.MediaController2} instance. This method should be called when
      * VideoView2 is attached to window, or it throws IllegalStateException.
      *
      * @throws IllegalStateException if interal MediaSession is not created yet.
      * @hide
      */
+    @RestrictTo(LIBRARY_GROUP)
     public SessionToken2 getMediaSessionToken() {
         //return mProvider.getMediaSessionToken_impl();
         return null;
@@ -639,6 +638,7 @@
      * @see #setMediaItem
      * @hide
      */
+    @RestrictTo(LIBRARY_GROUP)
     public void setDataSource(@NonNull DataSourceDesc dataSource) {
         //mProvider.setDataSource_impl(dataSource);
     }
@@ -1004,6 +1004,7 @@
         }
     };
 
+    @SuppressWarnings("deprecation")
     private void requestAudioFocus(int focusType) {
         int result;
         if (android.os.Build.VERSION.SDK_INT >= 26) {
@@ -1091,6 +1092,7 @@
     /*
      * Reset the media player in any state
      */
+    @SuppressWarnings("deprecation")
     private void resetPlayer() {
         if (mMediaPlayer != null) {
             mMediaPlayer.reset();
@@ -1352,6 +1354,7 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     private void extractAudioMetadata() {
         if (!mIsMusicMediaType) {
             return;
@@ -1583,6 +1586,7 @@
 
     MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
         @Override
+        @SuppressWarnings("deprecation")
         public void onCompletion(MediaPlayer mp) {
             mCurrentState = STATE_PLAYBACK_COMPLETED;
             mTargetState = STATE_PLAYBACK_COMPLETED;
diff --git a/media/src/main/java/androidx/widget/VideoViewInterface.java b/media-widget/src/main/java/androidx/media/widget/VideoViewInterface.java
similarity index 98%
rename from media/src/main/java/androidx/widget/VideoViewInterface.java
rename to media-widget/src/main/java/androidx/media/widget/VideoViewInterface.java
index eca8c82..81b40a9 100644
--- a/media/src/main/java/androidx/widget/VideoViewInterface.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoViewInterface.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.widget;
+package androidx.media.widget;
 
 import android.media.MediaPlayer;
 import android.view.View;
diff --git a/media/src/main/res/drawable/custom_progress.xml b/media-widget/src/main/res/drawable/custom_progress.xml
similarity index 100%
rename from media/src/main/res/drawable/custom_progress.xml
rename to media-widget/src/main/res/drawable/custom_progress.xml
diff --git a/media/src/main/res/drawable/custom_progress_thumb.xml b/media-widget/src/main/res/drawable/custom_progress_thumb.xml
similarity index 100%
rename from media/src/main/res/drawable/custom_progress_thumb.xml
rename to media-widget/src/main/res/drawable/custom_progress_thumb.xml
diff --git a/media/src/main/res/drawable/ic_arrow_back.xml b/media-widget/src/main/res/drawable/ic_arrow_back.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_arrow_back.xml
rename to media-widget/src/main/res/drawable/ic_arrow_back.xml
diff --git a/media/src/main/res/drawable/ic_aspect_ratio.xml b/media-widget/src/main/res/drawable/ic_aspect_ratio.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_aspect_ratio.xml
rename to media-widget/src/main/res/drawable/ic_aspect_ratio.xml
diff --git a/media/src/main/res/drawable/ic_audiotrack.xml b/media-widget/src/main/res/drawable/ic_audiotrack.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_audiotrack.xml
rename to media-widget/src/main/res/drawable/ic_audiotrack.xml
diff --git a/media/src/main/res/drawable/ic_check.xml b/media-widget/src/main/res/drawable/ic_check.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_check.xml
rename to media-widget/src/main/res/drawable/ic_check.xml
diff --git a/media/src/main/res/drawable/ic_chevron_left.xml b/media-widget/src/main/res/drawable/ic_chevron_left.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_chevron_left.xml
rename to media-widget/src/main/res/drawable/ic_chevron_left.xml
diff --git a/media/src/main/res/drawable/ic_chevron_right.xml b/media-widget/src/main/res/drawable/ic_chevron_right.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_chevron_right.xml
rename to media-widget/src/main/res/drawable/ic_chevron_right.xml
diff --git a/media/src/main/res/drawable/ic_default_album_image.xml b/media-widget/src/main/res/drawable/ic_default_album_image.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_default_album_image.xml
rename to media-widget/src/main/res/drawable/ic_default_album_image.xml
diff --git a/media/src/main/res/drawable/ic_forward_30.xml b/media-widget/src/main/res/drawable/ic_forward_30.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_forward_30.xml
rename to media-widget/src/main/res/drawable/ic_forward_30.xml
diff --git a/media/src/main/res/drawable/ic_fullscreen.xml b/media-widget/src/main/res/drawable/ic_fullscreen.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_fullscreen.xml
rename to media-widget/src/main/res/drawable/ic_fullscreen.xml
diff --git a/media/src/main/res/drawable/ic_fullscreen_exit.xml b/media-widget/src/main/res/drawable/ic_fullscreen_exit.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_fullscreen_exit.xml
rename to media-widget/src/main/res/drawable/ic_fullscreen_exit.xml
diff --git a/media/src/main/res/drawable/ic_help.xml b/media-widget/src/main/res/drawable/ic_help.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_help.xml
rename to media-widget/src/main/res/drawable/ic_help.xml
diff --git a/media/src/main/res/drawable/ic_high_quality.xml b/media-widget/src/main/res/drawable/ic_high_quality.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_high_quality.xml
rename to media-widget/src/main/res/drawable/ic_high_quality.xml
diff --git a/media/src/main/res/drawable/ic_launch.xml b/media-widget/src/main/res/drawable/ic_launch.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_launch.xml
rename to media-widget/src/main/res/drawable/ic_launch.xml
diff --git a/media/src/main/res/drawable/ic_mute.xml b/media-widget/src/main/res/drawable/ic_mute.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_mute.xml
rename to media-widget/src/main/res/drawable/ic_mute.xml
diff --git a/media/src/main/res/drawable/ic_pause_circle_filled.xml b/media-widget/src/main/res/drawable/ic_pause_circle_filled.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_pause_circle_filled.xml
rename to media-widget/src/main/res/drawable/ic_pause_circle_filled.xml
diff --git a/media/src/main/res/drawable/ic_play_circle_filled.xml b/media-widget/src/main/res/drawable/ic_play_circle_filled.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_play_circle_filled.xml
rename to media-widget/src/main/res/drawable/ic_play_circle_filled.xml
diff --git a/media/src/main/res/drawable/ic_replay_circle_filled.xml b/media-widget/src/main/res/drawable/ic_replay_circle_filled.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_replay_circle_filled.xml
rename to media-widget/src/main/res/drawable/ic_replay_circle_filled.xml
diff --git a/media/src/main/res/drawable/ic_rewind_10.xml b/media-widget/src/main/res/drawable/ic_rewind_10.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_rewind_10.xml
rename to media-widget/src/main/res/drawable/ic_rewind_10.xml
diff --git a/media/src/main/res/drawable/ic_sd.xml b/media-widget/src/main/res/drawable/ic_sd.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_sd.xml
rename to media-widget/src/main/res/drawable/ic_sd.xml
diff --git a/media/src/main/res/drawable/ic_settings.xml b/media-widget/src/main/res/drawable/ic_settings.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_settings.xml
rename to media-widget/src/main/res/drawable/ic_settings.xml
diff --git a/media/src/main/res/drawable/ic_skip_next.xml b/media-widget/src/main/res/drawable/ic_skip_next.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_skip_next.xml
rename to media-widget/src/main/res/drawable/ic_skip_next.xml
diff --git a/media/src/main/res/drawable/ic_skip_previous.xml b/media-widget/src/main/res/drawable/ic_skip_previous.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_skip_previous.xml
rename to media-widget/src/main/res/drawable/ic_skip_previous.xml
diff --git a/media/src/main/res/drawable/ic_subtitle_off.xml b/media-widget/src/main/res/drawable/ic_subtitle_off.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_subtitle_off.xml
rename to media-widget/src/main/res/drawable/ic_subtitle_off.xml
diff --git a/media/src/main/res/drawable/ic_subtitle_on.xml b/media-widget/src/main/res/drawable/ic_subtitle_on.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_subtitle_on.xml
rename to media-widget/src/main/res/drawable/ic_subtitle_on.xml
diff --git a/media/src/main/res/drawable/ic_unmute.xml b/media-widget/src/main/res/drawable/ic_unmute.xml
similarity index 100%
rename from media/src/main/res/drawable/ic_unmute.xml
rename to media-widget/src/main/res/drawable/ic_unmute.xml
diff --git a/media/src/main/res/layout/embedded_music.xml b/media-widget/src/main/res/layout/embedded_music.xml
similarity index 100%
rename from media/src/main/res/layout/embedded_music.xml
rename to media-widget/src/main/res/layout/embedded_music.xml
diff --git a/media/src/main/res/layout/embedded_settings_list_item.xml b/media-widget/src/main/res/layout/embedded_settings_list_item.xml
similarity index 100%
rename from media/src/main/res/layout/embedded_settings_list_item.xml
rename to media-widget/src/main/res/layout/embedded_settings_list_item.xml
diff --git a/media/src/main/res/layout/embedded_sub_settings_list_item.xml b/media-widget/src/main/res/layout/embedded_sub_settings_list_item.xml
similarity index 100%
rename from media/src/main/res/layout/embedded_sub_settings_list_item.xml
rename to media-widget/src/main/res/layout/embedded_sub_settings_list_item.xml
diff --git a/media/src/main/res/layout/embedded_transport_controls.xml b/media-widget/src/main/res/layout/embedded_transport_controls.xml
similarity index 100%
rename from media/src/main/res/layout/embedded_transport_controls.xml
rename to media-widget/src/main/res/layout/embedded_transport_controls.xml
diff --git a/media/src/main/res/layout/full_landscape_music.xml b/media-widget/src/main/res/layout/full_landscape_music.xml
similarity index 100%
rename from media/src/main/res/layout/full_landscape_music.xml
rename to media-widget/src/main/res/layout/full_landscape_music.xml
diff --git a/media/src/main/res/layout/full_portrait_music.xml b/media-widget/src/main/res/layout/full_portrait_music.xml
similarity index 100%
rename from media/src/main/res/layout/full_portrait_music.xml
rename to media-widget/src/main/res/layout/full_portrait_music.xml
diff --git a/media/src/main/res/layout/full_settings_list_item.xml b/media-widget/src/main/res/layout/full_settings_list_item.xml
similarity index 100%
rename from media/src/main/res/layout/full_settings_list_item.xml
rename to media-widget/src/main/res/layout/full_settings_list_item.xml
diff --git a/media/src/main/res/layout/full_sub_settings_list_item.xml b/media-widget/src/main/res/layout/full_sub_settings_list_item.xml
similarity index 100%
rename from media/src/main/res/layout/full_sub_settings_list_item.xml
rename to media-widget/src/main/res/layout/full_sub_settings_list_item.xml
diff --git a/media/src/main/res/layout/full_transport_controls.xml b/media-widget/src/main/res/layout/full_transport_controls.xml
similarity index 100%
rename from media/src/main/res/layout/full_transport_controls.xml
rename to media-widget/src/main/res/layout/full_transport_controls.xml
diff --git a/media/src/main/res/layout/media_controller.xml b/media-widget/src/main/res/layout/media_controller.xml
similarity index 100%
rename from media/src/main/res/layout/media_controller.xml
rename to media-widget/src/main/res/layout/media_controller.xml
diff --git a/media/src/main/res/layout/minimal_transport_controls.xml b/media-widget/src/main/res/layout/minimal_transport_controls.xml
similarity index 100%
rename from media/src/main/res/layout/minimal_transport_controls.xml
rename to media-widget/src/main/res/layout/minimal_transport_controls.xml
diff --git a/media/src/main/res/layout/settings_list.xml b/media-widget/src/main/res/layout/settings_list.xml
similarity index 100%
rename from media/src/main/res/layout/settings_list.xml
rename to media-widget/src/main/res/layout/settings_list.xml
diff --git a/media/src/main/res/layout/title_bar_gradient.xml b/media-widget/src/main/res/layout/title_bar_gradient.xml
similarity index 100%
rename from media/src/main/res/layout/title_bar_gradient.xml
rename to media-widget/src/main/res/layout/title_bar_gradient.xml
diff --git a/media/src/main/res/values/arrays.xml b/media-widget/src/main/res/values/arrays.xml
similarity index 100%
rename from media/src/main/res/values/arrays.xml
rename to media-widget/src/main/res/values/arrays.xml
diff --git a/media-widget/src/main/res/values/colors.xml b/media-widget/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3aff9da
--- /dev/null
+++ b/media-widget/src/main/res/values/colors.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright 2018 The Android Open Source Project
+
+    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.
+  -->
+<resources>
+
+    <!-- The color of the material notification background for media notifications when no custom
+     color is specified -->
+    <color name="notification_material_background_media_default_color">#ff424242</color>
+
+    <color name="gray">#808080</color>
+    <color name="white">#ffffff</color>
+    <color name="white_opacity_70">#B3ffffff</color>
+    <color name="black_opacity_70">#B3000000</color>
+    <color name="title_bar_gradient_start">#50000000</color>
+    <color name="title_bar_gradient_end">#00000000</color>
+    <color name="bottom_bar_background">#40202020</color>
+</resources>
\ No newline at end of file
diff --git a/media-widget/src/main/res/values/dimens.xml b/media-widget/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..796f345
--- /dev/null
+++ b/media-widget/src/main/res/values/dimens.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright 2018 The Android Open Source Project
+
+    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.
+  -->
+
+<resources>
+    <dimen name="mcv2_embedded_settings_width">150dp</dimen>
+    <dimen name="mcv2_embedded_settings_height">36dp</dimen>
+    <dimen name="mcv2_embedded_settings_icon_size">20dp</dimen>
+    <dimen name="mcv2_embedded_settings_text_height">18dp</dimen>
+    <dimen name="mcv2_embedded_settings_main_text_size">12sp</dimen>
+    <dimen name="mcv2_embedded_settings_sub_text_size">10sp</dimen>
+    <dimen name="mcv2_full_settings_width">225dp</dimen>
+    <dimen name="mcv2_full_settings_height">54dp</dimen>
+    <dimen name="mcv2_full_settings_icon_size">30dp</dimen>
+    <dimen name="mcv2_full_settings_text_height">27dp</dimen>
+    <dimen name="mcv2_full_settings_main_text_size">16sp</dimen>
+    <dimen name="mcv2_full_settings_sub_text_size">13sp</dimen>
+    <dimen name="mcv2_settings_offset">8dp</dimen>
+
+    <dimen name="mcv2_transport_controls_padding">4dp</dimen>
+    <dimen name="mcv2_pause_icon_size">36dp</dimen>
+    <dimen name="mcv2_full_icon_size">28dp</dimen>
+    <dimen name="mcv2_embedded_icon_size">24dp</dimen>
+    <dimen name="mcv2_minimal_icon_size">24dp</dimen>
+    <dimen name="mcv2_icon_margin">10dp</dimen>
+
+    <dimen name="mcv2_full_album_image_portrait_size">232dp</dimen>
+    <dimen name="mcv2_full_album_image_landscape_size">176dp</dimen>
+
+    <dimen name="mcv2_custom_progress_max_size">2dp</dimen>
+    <dimen name="mcv2_custom_progress_thumb_size">12dp</dimen>
+    <dimen name="mcv2_buffer_view_height">5dp</dimen>
+</resources>
diff --git a/media/src/main/res/values/strings.xml b/media-widget/src/main/res/values/strings.xml
similarity index 92%
rename from media/src/main/res/values/strings.xml
rename to media-widget/src/main/res/values/strings.xml
index 4f46ccf..10889df 100644
--- a/media/src/main/res/values/strings.xml
+++ b/media-widget/src/main/res/values/strings.xml
@@ -1,22 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     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.
--->
+<!--
+  ~ Copyright 2018 The Android Open Source Project
+  ~
+  ~ 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.
+  -->
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
     <!-- Name for the default system route prior to Jellybean. [CHAR LIMIT=30] -->
     <string name="mr_system_route_name">System</string>
 
@@ -48,7 +48,7 @@
     <!-- Button to disconnect from a media route.  [CHAR LIMIT=30] -->
     <string name="mr_controller_disconnect">Disconnect</string>
 
-    <!-- Button to stop playback and disconnect from a media route. [CHAR LIMIT=30] -->
+    <!-- Button to stop playback and disconnect from a media route. [CHAR LIMIT=32] -->
     <string name="mr_controller_stop_casting">Stop casting</string>
 
     <!-- Content description for accessibility (not shown on the screen): dialog close button. [CHAR LIMIT=NONE] -->
diff --git a/media/src/main/res/values/style.xml b/media-widget/src/main/res/values/styles.xml
similarity index 100%
rename from media/src/main/res/values/style.xml
rename to media-widget/src/main/res/values/styles.xml
diff --git a/media/build.gradle b/media/build.gradle
index e55188a..af0928b 100644
--- a/media/build.gradle
+++ b/media/build.gradle
@@ -9,7 +9,6 @@
 dependencies {
     api(project(":annotation"))
     api(project(":core"))
-    api(project(":palette"))
 
     androidTestImplementation(TEST_RUNNER_TMP, libs.exclude_for_espresso)
     androidTestImplementation(ESPRESSO_CORE_TMP, libs.exclude_for_espresso)
diff --git a/media/src/androidTest/AndroidManifest.xml b/media/src/androidTest/AndroidManifest.xml
index 4fd25ca..32987a5 100644
--- a/media/src/androidTest/AndroidManifest.xml
+++ b/media/src/androidTest/AndroidManifest.xml
@@ -19,14 +19,6 @@
     <uses-sdk android:targetSdkVersion="${target-sdk-version}"/>
 
     <application>
-        <activity android:name="androidx.widget.VideoView2TestActivity"
-            android:configChanges="keyboardHidden|orientation|screenSize"
-            android:label="VideoVeiw2TestActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
         <activity android:name="androidx.media.MediaStubActivity"
                   android:label="MediaStubActivity"
                   android:screenOrientation="nosensor"
diff --git a/media/src/androidTest/res/layout/videoview2_layout.xml b/media/src/androidTest/res/layout/videoview2_layout.xml
deleted file mode 100644
index e3783c0..0000000
--- a/media/src/androidTest/res/layout/videoview2_layout.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright 2018 The Android Open Source Project
- *
- * 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.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <androidx.widget.VideoView2
-        android:id="@+id/videoview"
-        android:layout_width="160dp"
-        android:layout_height="120dp"/>
-</LinearLayout>
diff --git a/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java b/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
index 430913e..8f24837 100644
--- a/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
+++ b/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
@@ -1020,8 +1020,11 @@
      * Note that we cannot simply override {@link Service#attachBaseContext(Context)} and hide it
      * because lint checks considers the overriden method as the new public API that needs update
      * of current.txt.
+     *
+     * @hide
      */
-    void attachToBaseContext(Context base) {
+    @RestrictTo(LIBRARY)
+    public void attachToBaseContext(Context base) {
         attachBaseContext(base);
     }
 
diff --git a/media/src/main/java/androidx/media/MediaPlayer2.java b/media/src/main/java/androidx/media/MediaPlayer2.java
index 3802b9f..f1cd3b6 100644
--- a/media/src/main/java/androidx/media/MediaPlayer2.java
+++ b/media/src/main/java/androidx/media/MediaPlayer2.java
@@ -1524,16 +1524,6 @@
      */
     public static final int CALL_COMPLETED_PREPARE = 6;
 
-    /** The player just completed a call {@link #releaseDrm}.
-     * @see MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_RELEASE_DRM = 12;
-
-    /** The player just completed a call {@link #restoreDrmKeys}.
-     * @see MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_RESTORE_DRM_KEYS = 13;
-
     /** The player just completed a call {@link #seekTo}.
      * @see MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
      */
@@ -1621,8 +1611,6 @@
             CALL_COMPLETED_PAUSE,
             CALL_COMPLETED_PLAY,
             CALL_COMPLETED_PREPARE,
-            CALL_COMPLETED_RELEASE_DRM,
-            CALL_COMPLETED_RESTORE_DRM_KEYS,
             CALL_COMPLETED_SEEK_TO,
             CALL_COMPLETED_SELECT_TRACK,
             CALL_COMPLETED_SET_AUDIO_ATTRIBUTES,
@@ -1673,12 +1661,6 @@
      */
     public static final int CALL_STATUS_ERROR_IO = 4;
 
-    /** Status code represents that DRM operation is called before preparing a DRM scheme through
-     *  {@link #prepareDrm}.
-     * @see MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
-     */
-    public static final int CALL_STATUS_NO_DRM_SCHEME = 5;
-
     /**
      * @hide
      */
@@ -1688,8 +1670,7 @@
             CALL_STATUS_INVALID_OPERATION,
             CALL_STATUS_BAD_VALUE,
             CALL_STATUS_PERMISSION_DENIED,
-            CALL_STATUS_ERROR_IO,
-            CALL_STATUS_NO_DRM_SCHEME})
+            CALL_STATUS_ERROR_IO})
     @Retention(RetentionPolicy.SOURCE)
     @RestrictTo(LIBRARY_GROUP)
     public @interface CallStatus {}
diff --git a/media/src/main/java/androidx/media/MediaPlayer2Impl.java b/media/src/main/java/androidx/media/MediaPlayer2Impl.java
index 50c490f..6127473 100644
--- a/media/src/main/java/androidx/media/MediaPlayer2Impl.java
+++ b/media/src/main/java/androidx/media/MediaPlayer2Impl.java
@@ -1367,16 +1367,11 @@
      */
     @Override
     public void releaseDrm() throws NoDrmSchemeException {
-        addTask(new Task(CALL_COMPLETED_RELEASE_DRM, false) {
-            @Override
-            void process() throws NoDrmSchemeException {
-                try {
-                    mPlayer.releaseDrm();
-                } catch (MediaPlayer.NoDrmSchemeException e) {
-                    throw new NoDrmSchemeException(e.getMessage());
-                }
-            }
-        });
+        try {
+            mPlayer.releaseDrm();
+        } catch (MediaPlayer.NoDrmSchemeException e) {
+            throw new NoDrmSchemeException(e.getMessage());
+        }
     }
 
 
@@ -1470,16 +1465,11 @@
     @Override
     public void restoreDrmKeys(@NonNull final byte[] keySetId)
             throws NoDrmSchemeException {
-        addTask(new Task(CALL_COMPLETED_RESTORE_DRM_KEYS, false) {
-            @Override
-            void process() throws NoDrmSchemeException {
-                try {
-                    mPlayer.restoreKeys(keySetId);
-                } catch (MediaPlayer.NoDrmSchemeException e) {
-                    throw new NoDrmSchemeException(e.getMessage());
-                }
-            }
-        });
+        try {
+            mPlayer.restoreKeys(keySetId);
+        } catch (MediaPlayer.NoDrmSchemeException e) {
+            throw new NoDrmSchemeException(e.getMessage());
+        }
     }
 
 
@@ -2040,8 +2030,6 @@
                 status = CALL_STATUS_PERMISSION_DENIED;
             } catch (IOException e) {
                 status = CALL_STATUS_ERROR_IO;
-            } catch (NoDrmSchemeException e) {
-                status = CALL_STATUS_NO_DRM_SCHEME;
             } catch (Exception e) {
                 status = CALL_STATUS_ERROR_UNKNOWN;
             }
diff --git a/media/src/main/res/values/colors.xml b/media/src/main/res/values/colors.xml
index e44662a..d210220 100644
--- a/media/src/main/res/values/colors.xml
+++ b/media/src/main/res/values/colors.xml
@@ -19,12 +19,4 @@
     <!-- The color of the material notification background for media notifications when no custom
      color is specified -->
     <color name="notification_material_background_media_default_color">#ff424242</color>
-
-    <color name="gray">#808080</color>
-    <color name="white">#ffffff</color>
-    <color name="white_opacity_70">#B3ffffff</color>
-    <color name="black_opacity_70">#B3000000</color>
-    <color name="title_bar_gradient_start">#50000000</color>
-    <color name="title_bar_gradient_end">#00000000</color>
-    <color name="bottom_bar_background">#40202020</color>
 </resources>
\ No newline at end of file
diff --git a/media/src/main/res/values/dimens.xml b/media/src/main/res/values/dimens.xml
deleted file mode 100644
index 2d7b022..0000000
--- a/media/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     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.
--->
-
-<resources>
-    <!-- Dialog size -->
-    <eat-comment />
-    <!-- The platform's desired fixed width for a dialog along the major axis
-         (the screen is in landscape). This may be either a fraction or a dimension.-->
-    <dimen name="mr_dialog_fixed_width_major">320dp</dimen>
-    <!-- The platform's desired fixed width for a dialog along the minor axis
-         (the screen is in portrait). This may be either a fraction or a dimension.-->
-    <dimen name="mr_dialog_fixed_width_minor">320dp</dimen>
-
-    <!-- MediaRouteController's volume group list -->
-    <eat-comment />
-    <!-- Maximum height of volume group list. -->
-    <dimen name="mr_controller_volume_group_list_max_height">288dp</dimen>
-    <!-- Height of volume group item. -->
-    <dimen name="mr_controller_volume_group_list_item_height">68dp</dimen>
-    <!-- Size of an item's icon. -->
-    <dimen name="mr_controller_volume_group_list_item_icon_size">24dp</dimen>
-
-    <dimen name="mr_controller_volume_group_list_padding_top">16dp</dimen>
-    <!-- Group list expand/collapse animation duration. -->
-    <integer name="mr_controller_volume_group_list_animation_duration_ms">400</integer>
-    <!-- Group list fade in animation duration. -->
-    <integer name="mr_controller_volume_group_list_fade_in_duration_ms">400</integer>
-    <!-- Group list fade out animation duration. -->
-    <integer name="mr_controller_volume_group_list_fade_out_duration_ms">200</integer>
-
-    <dimen name="mcv2_embedded_settings_width">150dp</dimen>
-    <dimen name="mcv2_embedded_settings_height">36dp</dimen>
-    <dimen name="mcv2_embedded_settings_icon_size">20dp</dimen>
-    <dimen name="mcv2_embedded_settings_text_height">18dp</dimen>
-    <dimen name="mcv2_embedded_settings_main_text_size">12sp</dimen>
-    <dimen name="mcv2_embedded_settings_sub_text_size">10sp</dimen>
-    <dimen name="mcv2_full_settings_width">225dp</dimen>
-    <dimen name="mcv2_full_settings_height">54dp</dimen>
-    <dimen name="mcv2_full_settings_icon_size">30dp</dimen>
-    <dimen name="mcv2_full_settings_text_height">27dp</dimen>
-    <dimen name="mcv2_full_settings_main_text_size">16sp</dimen>
-    <dimen name="mcv2_full_settings_sub_text_size">13sp</dimen>
-    <dimen name="mcv2_settings_offset">8dp</dimen>
-
-    <dimen name="mcv2_transport_controls_padding">4dp</dimen>
-    <dimen name="mcv2_pause_icon_size">36dp</dimen>
-    <dimen name="mcv2_full_icon_size">28dp</dimen>
-    <dimen name="mcv2_embedded_icon_size">24dp</dimen>
-    <dimen name="mcv2_minimal_icon_size">24dp</dimen>
-    <dimen name="mcv2_icon_margin">10dp</dimen>
-
-    <dimen name="mcv2_full_album_image_portrait_size">232dp</dimen>
-    <dimen name="mcv2_full_album_image_landscape_size">176dp</dimen>
-
-    <dimen name="mcv2_custom_progress_max_size">2dp</dimen>
-    <dimen name="mcv2_custom_progress_thumb_size">12dp</dimen>
-    <dimen name="mcv2_buffer_view_height">5dp</dimen>
-    <!-- TODO: adjust bottom bar view -->
-</resources>
diff --git a/media/src/main/res/values/symbols.xml b/media/src/main/res/values/symbols.xml
deleted file mode 100644
index ee0e8c6..0000000
--- a/media/src/main/res/values/symbols.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* Copyright 2017, The Android Open Source Project
-**
-** 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.
-*/
--->
-<resources>
-    <!--java-symbol type="id" name="cc" />
-    <java-symbol type="id" name="ffwd" />
-    <java-symbol type="id" name="mediacontroller_progress" />
-    <java-symbol type="id" name="next" />
-    <java-symbol type="id" name="pause" />
-    <java-symbol type="id" name="prev" />
-    <java-symbol type="id" name="rew" />
-    <java-symbol type="id" name="time" />
-    <java-symbol type="id" name="time_current" /-->
-</resources>
\ No newline at end of file
diff --git a/samples/SupportMediaDemos/OWNERS b/samples/SupportMediaDemos/OWNERS
new file mode 100644
index 0000000..2f5d227
--- /dev/null
+++ b/samples/SupportMediaDemos/OWNERS
@@ -0,0 +1,6 @@
+insun@google.com
+jinpark@google.com
+sungsoo@google.com
+hdmoon@google.com
+jaewan@google.com
+akersten@google.com
\ No newline at end of file
diff --git a/samples/SupportMediaDemos/build.gradle b/samples/SupportMediaDemos/build.gradle
new file mode 100644
index 0000000..bf23177
--- /dev/null
+++ b/samples/SupportMediaDemos/build.gradle
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+plugins {
+    id("SupportAndroidTestAppPlugin")
+}
+
+dependencies {
+    implementation(project(":media"))
+    implementation(project(":media-widget"))
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 19
+        targetSdkVersion 26
+    }
+}
diff --git a/samples/SupportMediaDemos/src/main/AndroidManifest.xml b/samples/SupportMediaDemos/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..267eafd
--- /dev/null
+++ b/samples/SupportMediaDemos/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.androidx.media">
+    <application android:label="Video View Test">
+
+        <!-- Video Selection Activity -->
+        <activity android:name="VideoSelector"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            android:configChanges="orientation|screenSize"
+            >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <!-- Video playback activity -->
+        <activity android:name="VideoViewTest"
+            android:configChanges="orientation|screenSize"
+            >
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+            </intent-filter>
+        </activity>
+
+    </application>
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+</manifest>
diff --git a/samples/SupportMediaDemos/src/main/java/com/example/androidx/media/VideoSelector.java b/samples/SupportMediaDemos/src/main/java/com/example/androidx/media/VideoSelector.java
new file mode 100644
index 0000000..a77789f
--- /dev/null
+++ b/samples/SupportMediaDemos/src/main/java/com/example/androidx/media/VideoSelector.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.androidx.media;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ListView;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.TreeMap;
+
+/**
+ * Start activity for the VideoViewTest application.  This class manages the UI
+ * which allows a user to select a video to play back.
+ */
+public class VideoSelector extends Activity {
+    private ListView      mSelectList;
+    private VideoItemList mSelectItems;
+    private EditText      mUrlText;
+    private CheckBox      mTextureViewCheckbox;
+    private CheckBox      mLoopingCheckbox;
+    private CheckBox      mAdvertisementCheckBox;
+
+    private static final String TEST_VID_STASH = "/sdcard";
+    private static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 100;
+
+    private Intent createLaunchIntent(Context ctx, String url) {
+        Intent ret_val = new Intent(ctx, VideoViewTest.class);
+        ret_val.setData(Uri.parse(url));
+        ret_val.putExtra(
+                VideoViewTest.LOOPING_EXTRA_NAME, mLoopingCheckbox.isChecked());
+        ret_val.putExtra(
+                VideoViewTest.USE_TEXTURE_VIEW_EXTRA_NAME, mTextureViewCheckbox.isChecked());
+        ret_val.putExtra(
+                VideoViewTest.MEDIA_TYPE_ADVERTISEMENT, mAdvertisementCheckBox.isChecked());
+        return ret_val;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.video_selector);
+
+        mSelectList  = (ListView) findViewById(R.id.select_list);
+        final Button playButton = (Button) findViewById(R.id.play_button);
+        mUrlText = (EditText) findViewById(R.id.video_selection_input);
+        mSelectItems = null;
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
+                    == PackageManager.PERMISSION_GRANTED) {
+                setUpInitialItemList();
+            } else {
+                requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},
+                        EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
+            }
+        } else {
+            setUpInitialItemList();
+        }
+
+        playButton.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                Intent launch = createLaunchIntent(
+                        VideoSelector.this,
+                        mUrlText.getText().toString());
+                startActivity(launch);
+            }
+        });
+        mLoopingCheckbox = findViewById(R.id.looping_checkbox);
+        mLoopingCheckbox.setChecked(false);
+        mTextureViewCheckbox = findViewById(R.id.use_textureview_checkbox);
+        mTextureViewCheckbox.setChecked(false);
+        mAdvertisementCheckBox = findViewById(R.id.media_type_advertisement);
+        mAdvertisementCheckBox.setChecked(false);
+    }
+
+    @Override
+    public void onBackPressed() {
+        if ((null != mSelectItems) && (null != mSelectHandler) && !mSelectItems.getIsRoot()) {
+            mSelectHandler.onItemClick(null, null, 0, 0);
+        } else {
+            finish();
+        }
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] results) {
+        if (requestCode == EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE) {
+            if (results.length > 0 && results[0] == PackageManager.PERMISSION_GRANTED) {
+                setUpInitialItemList();
+            }
+        }
+    }
+
+    private void setUpInitialItemList() {
+        mSelectItems = createVil(TEST_VID_STASH);
+        mSelectList.setAdapter(mSelectItems);
+        mSelectList.setOnItemClickListener(mSelectHandler);
+    }
+
+    /**
+     * VideoItem is a class used to represent a selectable item on the listbox
+     * used to select videos to playback.
+     */
+    private static class VideoItem {
+        private final String mToStringName;
+        private final String mName;
+        private final String mUrl;
+        private final boolean mIsDir;
+
+        VideoItem(String name, String url, boolean isDir) {
+            mName = name;
+            mUrl  = url;
+            mIsDir = isDir;
+
+            if (isDir) {
+                mToStringName = String.format("[dir] %s", name);
+            } else {
+                int ndx = url.indexOf(':');
+                if (ndx > 0) {
+                    mToStringName = String.format("[%s] %s", url.substring(0, ndx), name);
+                } else {
+                    mToStringName = name;
+                }
+            }
+        }
+
+        public static VideoItem createFromLinkFile(File f) {
+            VideoItem retVal = null;
+
+            try {
+                BufferedReader rd = new BufferedReader(new FileReader(f));
+                String name = rd.readLine();
+                String url  = rd.readLine();
+                if ((null != name) && (null != url)) {
+                    retVal = new VideoItem(name, url, false);
+                }
+            } catch (FileNotFoundException e) {
+            } catch (IOException e) {
+            }
+
+            return retVal;
+        }
+
+        @Override
+        public String toString() {
+            return mToStringName;
+        }
+
+        public String getName() {
+            return mName;
+        }
+
+        public String getUrl() {
+            return mUrl;
+        }
+
+        public boolean getIsDir() {
+            return mIsDir;
+        }
+    }
+
+    private OnItemClickListener mSelectHandler = new OnItemClickListener() {
+        public void onItemClick(AdapterView parent,
+                                View v,
+                                int position,
+                                long id) {
+            if ((position >= 0) && (position < mSelectItems.getCount())) {
+                VideoItem item = mSelectItems.getItem(position);
+                if (item.getIsDir()) {
+                    VideoItemList new_list = createVil(item.getUrl());
+                    if (null != new_list) {
+                        mSelectItems = new_list;
+                        mSelectList.setAdapter(mSelectItems);
+                    }
+                } else {
+                    Intent launch = createLaunchIntent(
+                            VideoSelector.this,
+                            item.getUrl());
+                    startActivity(launch);
+                }
+            }
+        }
+    };
+
+    /**
+     * VideoItemList is an array adapter of video items used by the android
+     * framework to populate the list of videos to select.
+     */
+    private class VideoItemList extends ArrayAdapter<VideoItem> {
+        private final String mPath;
+        private final boolean mIsRoot;
+
+        private VideoItemList(String path, boolean isRoot) {
+            super(VideoSelector.this,
+                  R.layout.video_list_item,
+                  R.id.video_list_item);
+            mPath = path;
+            mIsRoot = isRoot;
+        }
+
+        public String getPath() {
+            return mPath;
+        }
+
+        public boolean getIsRoot() {
+            return mIsRoot;
+        }
+    };
+
+    private VideoItemList createVil(String p) {
+        boolean is_root = TEST_VID_STASH.equals(p);
+
+        File dir = new File(p);
+        if (!dir.isDirectory() || !dir.canRead()) {
+            return null;
+        }
+
+        VideoItemList retVal = new VideoItemList(p, is_root);
+
+        // If this is not the root directory, go ahead and add the back link to
+        // our parent.
+        if (!is_root) {
+            retVal.add(new VideoItem("..", dir.getParentFile().getAbsolutePath(), true));
+        }
+
+        // Make a sorted list of directories and files contained in this
+        // directory.
+        TreeMap<String, VideoItem> dirs  = new TreeMap<String, VideoItem>();
+        TreeMap<String, VideoItem> files = new TreeMap<String, VideoItem>();
+
+        File search_dir = new File(p);
+        File[] flist = search_dir.listFiles();
+        if (null == flist) {
+            return retVal;
+        }
+
+        for (File f : flist) {
+            if (f.canRead()) {
+                if (f.isFile()) {
+                    String fname = f.getName();
+                    VideoItem newItem = null;
+
+                    if (fname.endsWith(".url")) {
+                        newItem = VideoItem.createFromLinkFile(f);
+                    } else {
+                        String url = "file://" + f.getAbsolutePath();
+                        newItem = new VideoItem(fname, url, false);
+                    }
+
+                    if (null != newItem) {
+                        files.put(newItem.getName(), newItem);
+                    }
+                } else if (f.isDirectory()) {
+                    VideoItem newItem = new VideoItem(f.getName(), f.getAbsolutePath(), true);
+                    dirs.put(newItem.getName(), newItem);
+                }
+            }
+        }
+
+        // now add the the sorted directories to the result set.
+        for (VideoItem vi : dirs.values()) {
+            retVal.add(vi);
+        }
+
+        // finally add the the sorted files to the result set.
+        for (VideoItem vi : files.values()) {
+            retVal.add(vi);
+        }
+
+        return retVal;
+    }
+}
diff --git a/samples/SupportMediaDemos/src/main/java/com/example/androidx/media/VideoViewTest.java b/samples/SupportMediaDemos/src/main/java/com/example/androidx/media/VideoViewTest.java
new file mode 100644
index 0000000..d640303
--- /dev/null
+++ b/samples/SupportMediaDemos/src/main/java/com/example/androidx/media/VideoViewTest.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.androidx.media;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Toast;
+
+import androidx.media.widget.MediaControlView2;
+import androidx.media.widget.VideoView2;
+
+/**
+ * Test application for VideoView2/MediaControlView2
+ */
+@SuppressLint("NewApi")
+public class VideoViewTest extends Activity {
+    public static final String LOOPING_EXTRA_NAME =
+            "com.example.androidx.media.VideoViewTest.IsLooping";
+    public static final String USE_TEXTURE_VIEW_EXTRA_NAME =
+            "com.example.androidx.media.VideoViewTest.UseTextureView";
+    public static final String MEDIA_TYPE_ADVERTISEMENT =
+            "com.example.androidx.media.VideoViewTest.MediaTypeAdvertisement";
+    private static final String TAG = "VideoViewTest";
+
+    private MyVideoView mVideoView = null;
+    private float mSpeed = 1.0f;
+
+    private MediaControlView2 mMediaControlView = null;
+
+    private boolean mUseTextureView = false;
+    private int mPrevWidth;
+    private int mPrevHeight;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        //Remove title bar
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        setContentView(R.layout.video_activity);
+
+        mVideoView = findViewById(R.id.video_view);
+
+        String errorString = null;
+        Intent intent = getIntent();
+        Uri contentUri;
+        if (intent == null || (contentUri = intent.getData()) == null || !contentUri.isAbsolute()) {
+            errorString = "Invalid intent";
+        } else {
+            mUseTextureView = intent.getBooleanExtra(USE_TEXTURE_VIEW_EXTRA_NAME, false);
+            if (mUseTextureView) {
+                mVideoView.setViewType(VideoView2.VIEW_TYPE_TEXTUREVIEW);
+            }
+
+            mVideoView.setFullScreenRequestListener(new FullScreenRequestListener());
+            mVideoView.setVideoUri(contentUri);
+
+            mMediaControlView = new MediaControlView2(this);
+            mVideoView.setMediaControlView2(mMediaControlView, 2000);
+        }
+        if (errorString != null) {
+            showErrorDialog(errorString);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        if (mVideoView.isAttachedToWindow()) {
+            mVideoView.getMediaController().getTransportControls().play();
+            mVideoView.getMediaController().registerCallback(mMediaControllerCallback);
+        } else {
+            mVideoView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+                @Override
+                public void onViewAttachedToWindow(View v) {
+                    mVideoView.getMediaController().getTransportControls().play();
+                    mVideoView.getMediaController().registerCallback(mMediaControllerCallback);
+                }
+
+                @Override
+                public void onViewDetachedFromWindow(View v) {
+                    // No need to remove callback here since MediaSession has already been
+                    // destroyed.
+                }
+            });
+        }
+        setTitle(getViewTypeString(mVideoView));
+    }
+
+    @Override
+    protected void onPause() {
+        mVideoView.getMediaController().getTransportControls().pause();
+        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        super.onPause();
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.d(TAG, "onDestroy");
+        mVideoView.getMediaController().unregisterCallback(mMediaControllerCallback);
+        mVideoView.getMediaController().getTransportControls().stop();
+        super.onDestroy();
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            int screenWidth = getResources().getDisplayMetrics().widthPixels;
+            if (ev.getRawX() < (screenWidth / 2.0f)) {
+                // TODO: getSpeed() not needed?
+                mSpeed -= 0.1f;
+            } else {
+                mSpeed += 0.1f;
+            }
+            mVideoView.setSpeed(mSpeed);
+            Toast.makeText(this, "speed rate: " + String.format("%.2f", mSpeed), Toast.LENGTH_SHORT)
+                    .show();
+        }
+        return super.onTouchEvent(ev);
+    }
+
+    private void showErrorDialog(String errorMessage) {
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        builder.setTitle("Playback error")
+                .setMessage(errorMessage)
+                .setCancelable(false)
+                .setPositiveButton("OK",
+                        new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialogInterface, int i) {
+                                finish();
+                            }
+                        }).show();
+    }
+
+    MediaControllerCompat.Callback mMediaControllerCallback = new MediaControllerCompat.Callback() {
+        @Override
+        public void onPlaybackStateChanged(PlaybackStateCompat state) {
+            switch (state.getState()) {
+                case PlaybackStateCompat.STATE_STOPPED:
+                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+                    break;
+                case PlaybackStateCompat.STATE_ERROR:
+                    showErrorDialog("Error: (" + state.getErrorMessage() + ")");
+                    break;
+            }
+        }
+    };
+
+    private class FullScreenRequestListener implements VideoView2.OnFullScreenRequestListener {
+        @Override
+        public void onFullScreenRequest(View view, boolean fullScreen) {
+            // TODO: Remove bottom controls after adding back button functionality.
+            if (mPrevHeight == 0 && mPrevWidth == 0) {
+                ViewGroup.LayoutParams params = mVideoView.getLayoutParams();
+                mPrevWidth = params.width;
+                mPrevHeight = params.height;
+            }
+
+            if (fullScreen) {
+                // Remove notification bar
+                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                        WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+                ViewGroup.LayoutParams params = mVideoView.getLayoutParams();
+                params.width = ViewGroup.LayoutParams.MATCH_PARENT;
+                params.height = ViewGroup.LayoutParams.MATCH_PARENT;
+                mVideoView.setLayoutParams(params);
+            } else {
+                // Restore notification bar
+                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+                ViewGroup.LayoutParams params = mVideoView.getLayoutParams();
+                params.width = mPrevWidth;
+                params.height = mPrevHeight;
+                mVideoView.setLayoutParams(params);
+            }
+            mVideoView.requestLayout();
+            mVideoView.invalidate();
+        }
+    }
+
+    /**
+     * Extension of the stock android video view used to hook and override
+     * keypress behavior.  Mainly used to make sure that certain keystrokes
+     * don't automatically bring up the andriod MediaController widget (which
+     * then steals focus)
+     *
+     * @author johngro@google.com (John Grossman)
+     */
+    public static class MyVideoView extends VideoView2 {
+        private float mDX;
+        private float mDY;
+
+        public MyVideoView(Context context) {
+            super(context);
+        }
+
+        public MyVideoView(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public MyVideoView(Context context, AttributeSet attrs, int defStyle) {
+            super(context, attrs, defStyle);
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent ev) {
+            switch (ev.getAction()) {
+                case MotionEvent.ACTION_DOWN:
+                    mDX = ev.getRawX() - getX();
+                    mDY = ev.getRawY() - getY();
+                    super.onTouchEvent(ev);
+                    return true;
+                case MotionEvent.ACTION_MOVE:
+                    animate()
+                            .x(ev.getRawX() - mDX)
+                            .y(ev.getRawY() - mDY)
+                            .setDuration(0)
+                            .start();
+                    super.onTouchEvent(ev);
+                    return true;
+            }
+            return super.onTouchEvent(ev);
+        }
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        if (mVideoView.getViewType() == VideoView2.VIEW_TYPE_SURFACEVIEW) {
+            mVideoView.setViewType(VideoView2.VIEW_TYPE_TEXTUREVIEW);
+            Toast.makeText(this, "switch to TextureView", Toast.LENGTH_SHORT).show();
+            setTitle(getViewTypeString(mVideoView));
+        } else if (mVideoView.getViewType() == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
+            mVideoView.setViewType(VideoView2.VIEW_TYPE_SURFACEVIEW);
+            Toast.makeText(this, "switch to SurfaceView", Toast.LENGTH_SHORT).show();
+            setTitle(getViewTypeString(mVideoView));
+        }
+    }
+
+    private String getViewTypeString(VideoView2 videoView) {
+        if (videoView == null) {
+            return "Unknown";
+        }
+        int type = videoView.getViewType();
+        if (type == VideoView2.VIEW_TYPE_SURFACEVIEW) {
+            return "SurfaceView";
+        } else if (type == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
+            return "TextureView";
+        }
+        return "Unknown";
+    }
+}
diff --git a/samples/SupportMediaDemos/src/main/res/layout/video_activity.xml b/samples/SupportMediaDemos/src/main/res/layout/video_activity.xml
new file mode 100644
index 0000000..94784d4
--- /dev/null
+++ b/samples/SupportMediaDemos/src/main/res/layout/video_activity.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     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.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:widget="http://schemas.android.com/apk/com.android.media.update"
+    android:id="@+id/video_player_main"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#3F51B5">
+
+    <!-- MediaControlView will be created manually in code -->
+    <view
+        android:id="@+id/video_view"
+        class="com.example.androidx.media.VideoViewTest$MyVideoView"
+        android:layout_width="250dp"
+        android:layout_height="250dp"
+        android:layout_centerInParent="true"
+        widget:enableControlView="false" />
+
+    <!-- Video Status -->
+    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/vid_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:visibility="invisible">
+
+        <TableRow>
+
+            <TextView
+                style="@style/status_tag"
+                android:text="@string/vid_status_codec_tag" />
+
+            <TextView
+                android:id="@+id/vid_codec"
+                style="@style/status_value" />
+        </TableRow>
+
+        <TableRow>
+
+            <TextView
+                style="@style/status_tag"
+                android:text="@string/vid_status_bitrate_tag" />
+
+            <TextView
+                android:id="@+id/vid_bitrate"
+                style="@style/status_value" />
+        </TableRow>
+
+        <TableRow>
+
+            <TextView
+                style="@style/status_tag"
+                android:text="@string/vid_status_mode_tag" />
+
+            <TextView
+                android:id="@+id/vid_mode"
+                style="@style/status_value" />
+        </TableRow>
+
+        <TableRow>
+
+            <TextView
+                style="@style/status_tag"
+                android:text="@string/vid_status_outrect_tag" />
+
+            <TextView
+                android:id="@+id/vid_outrect"
+                style="@style/status_value" />
+        </TableRow>
+
+        <TableRow>
+
+            <TextView
+                style="@style/status_tag"
+                android:text="@string/vid_status_stereo_mode_tag" />
+
+            <TextView
+                android:id="@+id/vid_stereo_mode"
+                style="@style/status_value" />
+        </TableRow>
+    </TableLayout>
+
+    <!-- Audio Status -->
+    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/aud_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:visibility="invisible">
+
+        <TableRow>
+
+            <TextView
+                style="@style/status_tag"
+                android:text="@string/aud_status_codec_tag" />
+
+            <TextView
+                android:id="@+id/aud_codec"
+                style="@style/status_value" />
+        </TableRow>
+
+        <TableRow>
+
+            <TextView
+                style="@style/status_tag"
+                android:text="@string/aud_status_bitrate_tag" />
+
+            <TextView
+                android:id="@+id/aud_bitrate"
+                style="@style/status_value" />
+        </TableRow>
+
+        <TableRow>
+
+            <TextView
+                style="@style/status_tag"
+                android:text="@string/aud_status_mode_tag" />
+
+            <TextView
+                android:id="@+id/aud_mode"
+                style="@style/status_value" />
+        </TableRow>
+    </TableLayout>
+</RelativeLayout>
diff --git a/samples/SupportMediaDemos/src/main/res/layout/video_list_item.xml b/samples/SupportMediaDemos/src/main/res/layout/video_list_item.xml
new file mode 100644
index 0000000..c4e6045
--- /dev/null
+++ b/samples/SupportMediaDemos/src/main/res/layout/video_list_item.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     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.
+-->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/video_list_item"
+    style="@style/video_list_item_text"
+    android:padding="12sp"
+/>
diff --git a/samples/SupportMediaDemos/src/main/res/layout/video_selector.xml b/samples/SupportMediaDemos/src/main/res/layout/video_selector.xml
new file mode 100644
index 0000000..485090f
--- /dev/null
+++ b/samples/SupportMediaDemos/src/main/res/layout/video_selector.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/video_selector_main"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical"
+    android:padding="16sp">
+
+    <TextView
+        android:id="@+id/title_text"
+        style="@style/title_text"
+        android:layout_alignParentTop="true"
+        android:text="@string/select_video_prompt" />
+
+    <CheckBox
+        android:id="@+id/looping_checkbox"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_below="@id/title_text"
+        android:text="@string/looping_text" />
+
+    <CheckBox
+        android:id="@+id/use_textureview_checkbox"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/title_text"
+        android:layout_toLeftOf="@id/looping_checkbox"
+        android:text="@string/texture_view_text" />
+
+    <CheckBox
+        android:id="@+id/media_type_advertisement"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/title_text"
+        android:layout_toLeftOf="@id/use_textureview_checkbox"
+        android:text="@string/advertisement_text" />
+
+    <Button
+        android:id="@+id/play_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+        android:text="@string/play_button_text" />
+
+    <EditText
+        android:id="@+id/video_selection_input"
+        android:layout_width="400sp"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        android:layout_toLeftOf="@id/play_button"
+        android:editable="true" />
+
+    <ListView
+        android:id="@+id/select_list"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_above="@id/video_selection_input"
+        android:layout_below="@id/looping_checkbox" />
+</RelativeLayout>
diff --git a/samples/SupportMediaDemos/src/main/res/values/strings.xml b/samples/SupportMediaDemos/src/main/res/values/strings.xml
new file mode 100644
index 0000000..ba49f42
--- /dev/null
+++ b/samples/SupportMediaDemos/src/main/res/values/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="vid_status_codec_tag">Video Codec:</string>
+    <string name="vid_status_bitrate_tag">Avg. Bitrate:</string>
+    <string name="vid_status_mode_tag">Video Mode:</string>
+    <string name="vid_status_outrect_tag">Dest Rect:</string>
+    <string name="aud_status_codec_tag">Audio Codec:</string>
+    <string name="vid_status_stereo_mode_tag">Stereo Mode:</string>
+    <string name="aud_status_bitrate_tag">Bitrate:</string>
+    <string name="aud_status_mode_tag">Audio Mode:</string>
+    <string name="buf_status_fmt_string">Buffering: %d%%</string>
+    <string name="select_video_prompt">Select Video</string>
+    <string name="select_button_text">Select</string>
+    <string name="play_button_text">Play</string>
+    <string name="looping_text">Looping</string>
+    <string name="texture_view_text">Use TextureView</string>
+    <string name="advertisement_text">Advertisement</string>
+</resources>
diff --git a/samples/SupportMediaDemos/src/main/res/values/style.xml b/samples/SupportMediaDemos/src/main/res/values/style.xml
new file mode 100644
index 0000000..27ddd23
--- /dev/null
+++ b/samples/SupportMediaDemos/src/main/res/values/style.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     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.
+-->
+<resources>
+    <style name="basic_text">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+    </style>
+
+    <style name="title_text" parent="@style/basic_text">
+        <item name="android:textSize">24sp</item>
+    </style>
+
+    <style name="video_list_item_text" parent="@style/basic_text">
+        <item name="android:textSize">24sp</item>
+    </style>
+
+    <style name="status_text" parent="@style/basic_text">
+        <item name="android:textSize">24sp</item>
+    </style>
+    <style name="status_value" parent="@style/status_text">
+        <item name="android:gravity">left</item>
+    </style>
+    <style name="status_tag" parent="@style/status_text">
+        <item name="android:paddingRight">5dp</item>
+        <item name="android:gravity">right</item>
+    </style>
+</resources>
+
diff --git a/settings.gradle b/settings.gradle
index 16e5be7..d969d88 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -68,6 +68,7 @@
 includeProject(":loader", "loader")
 includeProject(":localbroadcastmanager", "localbroadcastmanager")
 includeProject(":media", "media")
+includeProject(":media-widget", "media-widget")
 includeProject(":mediarouter", "mediarouter")
 includeProject(":palette", "palette")
 includeProject(":palette-ktx", "palette/ktx")
@@ -122,6 +123,7 @@
 includeProject(":support-emoji-demos", new File(samplesRoot, "SupportEmojiDemos"))
 includeProject(":support-leanback-demos", new File(samplesRoot, "SupportLeanbackDemos"))
 //includeProject(":support-leanback-jank", new File(samplesRoot, "SupportLeanbackJank"))
+includeProject(":support-media-demos", new File(samplesRoot, "SupportMediaDemos"))
 includeProject(":support-percent-demos", new File(samplesRoot, "SupportPercentDemos"))
 includeProject(":support-preference-demos", new File(samplesRoot, "SupportPreferenceDemos"))
 includeProject(":support-slices-demos", new File(samplesRoot, "SupportSliceDemos"))
diff --git a/webkit/api/current.txt b/webkit/api/current.txt
index dfb6bfa..b335efa 100644
--- a/webkit/api/current.txt
+++ b/webkit/api/current.txt
@@ -27,6 +27,10 @@
     method public abstract int getErrorCode();
   }
 
+  public class WebResourceRequestCompat {
+    method public static boolean isRedirect(android.webkit.WebResourceRequest);
+  }
+
   public class WebSettingsCompat {
     method public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
     method public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
@@ -73,6 +77,7 @@
     field public static final java.lang.String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
     field public static final java.lang.String START_SAFE_BROWSING = "START_SAFE_BROWSING";
     field public static final java.lang.String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
+    field public static final java.lang.String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
   }
 
 }
diff --git a/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java b/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java
new file mode 100644
index 0000000..783efca
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package androidx.webkit;
+
+import android.annotation.SuppressLint;
+import android.webkit.WebResourceRequest;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresFeature;
+import androidx.webkit.internal.WebResourceRequestAdapter;
+import androidx.webkit.internal.WebViewFeatureInternal;
+import androidx.webkit.internal.WebViewGlueCommunicator;
+
+// TODO(gsennton) add a test for this class
+
+/**
+ * Compatibility version of {@link WebResourceRequest}.
+ */
+public class WebResourceRequestCompat {
+
+    // Developers should not be able to instantiate this class.
+    private WebResourceRequestCompat() {}
+
+    /**
+     * Gets whether the request was a result of a server-side redirect.
+     *
+     * @return whether the request was a result of a server-side redirect.
+     */
+    @SuppressLint("NewApi")
+    @RequiresFeature(name = WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
+    public static boolean isRedirect(@NonNull WebResourceRequest request) {
+        WebViewFeatureInternal feature = WebViewFeatureInternal.WEB_RESOURCE_REQUEST_IS_REDIRECT;
+        if (feature.isSupportedByFramework()) {
+            return request.isRedirect();
+        } else if (feature.isSupportedByWebView()) {
+            return getAdapter(request).isRedirect();
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+
+    private static WebResourceRequestAdapter getAdapter(WebResourceRequest request) {
+        return WebViewGlueCommunicator.getCompatConverter().convertWebResourceRequest(request);
+    }
+}
diff --git a/webkit/src/main/java/androidx/webkit/WebViewFeature.java b/webkit/src/main/java/androidx/webkit/WebViewFeature.java
index 4286880..76f876c 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewFeature.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewFeature.java
@@ -62,7 +62,8 @@
             RECEIVE_WEB_RESOURCE_ERROR,
             RECEIVE_HTTP_ERROR,
             SHOULD_OVERRIDE_WITH_REDIRECTS,
-            SAFE_BROWSING_HIT
+            SAFE_BROWSING_HIT,
+            WEB_RESOURCE_REQUEST_IS_REDIRECT
     })
     @Retention(RetentionPolicy.SOURCE)
     @Target({ElementType.PARAMETER, ElementType.METHOD})
@@ -211,6 +212,14 @@
     public static final String SAFE_BROWSING_HIT = Features.SAFE_BROWSING_HIT;
 
     /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link WebResourceRequestCompat#isRedirect(WebResourceRequest)}.
+     */
+    public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT =
+            Features.WEB_RESOURCE_REQUEST_IS_REDIRECT;
+
+    /**
      * Return whether a feature is supported at run-time. This depends on the Android version of the
      * device and the WebView APK on the device.
      */
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebResourceRequestAdapter.java b/webkit/src/main/java/androidx/webkit/internal/WebResourceRequestAdapter.java
new file mode 100644
index 0000000..0d6a05d
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/WebResourceRequestAdapter.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package androidx.webkit.internal;
+
+import android.webkit.WebResourceRequest;
+
+import org.chromium.support_lib_boundary.WebResourceRequestBoundaryInterface;
+
+/**
+ * Adapter between {@link androidx.webkit.WebResourceRequestCompat} and
+ * {@link org.chromium.support_lib_boundary.WebResourceRequestBoundaryInterface}.
+ */
+public class WebResourceRequestAdapter {
+    private final WebResourceRequestBoundaryInterface mBoundaryInterface;
+
+    public WebResourceRequestAdapter(WebResourceRequestBoundaryInterface boundaryInterface) {
+        mBoundaryInterface = boundaryInterface;
+    }
+
+    /**
+     * Adapter method for
+     * {@link androidx.webkit.WebResourceRequestCompat#isRedirect(WebResourceRequest)}.
+     */
+    public boolean isRedirect() {
+        return mBoundaryInterface.isRedirect();
+    }
+}
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java b/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
index d804ee9..b648dc7 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
@@ -23,6 +23,7 @@
 import android.webkit.WebSettings;
 
 import androidx.webkit.ServiceWorkerClientCompat;
+import androidx.webkit.WebResourceRequestCompat;
 import androidx.webkit.WebViewClientCompat;
 import androidx.webkit.WebViewCompat;
 import androidx.webkit.WebViewFeature;
@@ -157,7 +158,14 @@
      * TODO(ntfschr): turn this into a javadoc link once the method is implemented in
      * http://ag/3858246.
      */
-    SAFE_BROWSING_HIT(WebViewFeature.SAFE_BROWSING_HIT, Build.VERSION_CODES.O_MR1);
+    SAFE_BROWSING_HIT(WebViewFeature.SAFE_BROWSING_HIT, Build.VERSION_CODES.O_MR1),
+
+    /**
+     * This feature covers
+     * {@link WebResourceRequestCompat#isRedirect(WebResourceRequest)}.
+     */
+    WEB_RESOURCE_REQUEST_IS_REDIRECT(WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
+            Build.VERSION_CODES.N);
 
     private final String mFeatureValue;
     private final int mOsVersion;
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java b/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java
index 4d264a3..e333480 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java
@@ -17,9 +17,11 @@
 package androidx.webkit.internal;
 
 import android.webkit.ServiceWorkerWebSettings;
+import android.webkit.WebResourceRequest;
 import android.webkit.WebSettings;
 
 import org.chromium.support_lib_boundary.ServiceWorkerWebSettingsBoundaryInterface;
+import org.chromium.support_lib_boundary.WebResourceRequestBoundaryInterface;
 import org.chromium.support_lib_boundary.WebSettingsBoundaryInterface;
 import org.chromium.support_lib_boundary.WebkitToCompatConverterBoundaryInterface;
 import org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil;
@@ -56,4 +58,14 @@
                 ServiceWorkerWebSettingsBoundaryInterface.class,
                 mImpl.convertServiceWorkerSettings(settings));
     }
+
+    /**
+     * Return a {@link WebResourceRequestAdapter} linked to the given {@link WebResourceRequest} so
+     * that calls on either of those objects affect the other object.
+     */
+    public WebResourceRequestAdapter convertWebResourceRequest(WebResourceRequest request) {
+        return new WebResourceRequestAdapter(BoundaryInterfaceReflectionUtil.castToSuppLibClass(
+                WebResourceRequestBoundaryInterface.class,
+                mImpl.convertWebResourceRequest(request)));
+    }
 }