Merge "Add baseline and line height attributes" into pi-preview1-androidx-dev am: 374f3212da
am: 4175d378ab

Change-Id: If53c2c653219e363a6464cecbcdb668436feebd4
diff --git a/app-toolkit/common/src/main/java/androidx/arch/core/internal/SafeIterableMap.java b/app-toolkit/common/src/main/java/androidx/arch/core/internal/SafeIterableMap.java
index ef09098..f57efb0 100644
--- a/app-toolkit/common/src/main/java/androidx/arch/core/internal/SafeIterableMap.java
+++ b/app-toolkit/common/src/main/java/androidx/arch/core/internal/SafeIterableMap.java
@@ -230,6 +230,7 @@
             return mNext != null;
         }
 
+        @SuppressWarnings("ReferenceEquality")
         @Override
         public void supportRemove(@NonNull Entry<K, V> entry) {
             if (mExpectedEnd == entry && entry == mNext) {
@@ -246,6 +247,7 @@
             }
         }
 
+        @SuppressWarnings("ReferenceEquality")
         private Entry<K, V> nextNode() {
             if (mNext == mExpectedEnd || mExpectedEnd == null) {
                 return null;
@@ -302,6 +304,7 @@
         private Entry<K, V> mCurrent;
         private boolean mBeforeStart = true;
 
+        @SuppressWarnings("ReferenceEquality")
         @Override
         public void supportRemove(@NonNull Entry<K, V> entry) {
             if (entry == mCurrent) {
@@ -369,6 +372,7 @@
             return mKey + "=" + mValue;
         }
 
+        @SuppressWarnings("ReferenceEquality")
         @Override
         public boolean equals(Object obj) {
             if (obj == this) {
diff --git a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
index 9ee229a..861dc72 100644
--- a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
@@ -44,6 +44,8 @@
             "-Xep:JavaLangClash:ERROR",
             "-Xep:PrivateConstructorForUtilityClass:ERROR",
             "-Xep:TypeParameterUnusedInFormals:ERROR",
+            "-Xep:StringSplitter:ERROR",
+            "-Xep:ReferenceEquality:ERROR",
 
             // Nullaway
             "-XepIgnoreUnknownCheckNames", // https://github.com/uber/NullAway/issues/25
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
index 9466f0c..9ba3c38 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
@@ -47,7 +47,6 @@
     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/buildSrc/src/main/kotlin/androidx/build/SupportAndroidLibraryPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/SupportAndroidLibraryPlugin.kt
index a278051..6f0b3e0 100644
--- a/buildSrc/src/main/kotlin/androidx/build/SupportAndroidLibraryPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/SupportAndroidLibraryPlugin.kt
@@ -65,6 +65,20 @@
 
             VersionFileWriterTask.setUpAndroidLibrary(project, library)
             DiffAndDocs.registerAndroidProject(project, library, supportLibraryExtension)
+
+            library.libraryVariants.all { libraryVariant ->
+                if (libraryVariant.getBuildType().getName().equals("debug")) {
+                    @Suppress("DEPRECATION")
+                    val javaCompile = libraryVariant.javaCompile
+                    if (supportLibraryExtension.failOnUncheckedWarnings) {
+                        javaCompile.options.compilerArgs.add("-Xlint:unchecked")
+                    }
+                    if (supportLibraryExtension.failOnDeprecationWarnings) {
+                        javaCompile.options.compilerArgs.add("-Xlint:deprecation")
+                    }
+                    javaCompile.options.compilerArgs.add("-Werror")
+                }
+            }
         }
 
         project.apply(mapOf("plugin" to "com.android.library"))
diff --git a/buildSrc/src/main/kotlin/androidx/build/SupportJavaLibraryPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/SupportJavaLibraryPlugin.kt
index e8bd816..cee2955 100644
--- a/buildSrc/src/main/kotlin/androidx/build/SupportJavaLibraryPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/SupportJavaLibraryPlugin.kt
@@ -23,6 +23,7 @@
 import org.gradle.api.Plugin
 import org.gradle.api.Project
 import org.gradle.api.plugins.JavaPluginConvention
+import org.gradle.api.tasks.bundling.Jar
 import org.gradle.api.tasks.compile.JavaCompile
 
 /**
@@ -47,6 +48,11 @@
                 convention.targetCompatibility = JavaVersion.VERSION_1_7
             }
             DiffAndDocs.registerJavaProject(project, supportLibraryExtension)
+
+            project.tasks.withType(Jar::class.java) { jarTask ->
+                jarTask.setReproducibleFileOrder(true)
+                jarTask.setPreserveFileTimestamps(false)
+            }
         }
 
         project.apply(mapOf("plugin" to ErrorProneBasePlugin::class.java))
diff --git a/buildSrc/src/main/kotlin/androidx/build/SupportKotlinLibraryPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/SupportKotlinLibraryPlugin.kt
index d2a6ddb..9558f76 100644
--- a/buildSrc/src/main/kotlin/androidx/build/SupportKotlinLibraryPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/SupportKotlinLibraryPlugin.kt
@@ -20,6 +20,7 @@
 import org.gradle.api.Plugin
 import org.gradle.api.Project
 import org.gradle.api.plugins.JavaPluginConvention
+import org.gradle.api.tasks.bundling.Jar
 
 class SupportKotlinLibraryPlugin : Plugin<Project> {
     override fun apply(project: Project) {
@@ -38,6 +39,12 @@
                 convention.sourceCompatibility = JavaVersion.VERSION_1_7
                 convention.targetCompatibility = JavaVersion.VERSION_1_7
             }
+
+            project.tasks.withType(Jar::class.java) { jarTask ->
+                jarTask.setReproducibleFileOrder(true)
+                jarTask.setPreserveFileTimestamps(false)
+            }
+
         }
 
         CheckExternalDependencyLicensesTask.configure(project)
diff --git a/buildSrc/src/main/kotlin/androidx/build/SupportLibraryExtension.kt b/buildSrc/src/main/kotlin/androidx/build/SupportLibraryExtension.kt
index 4f69460..98528bb 100644
--- a/buildSrc/src/main/kotlin/androidx/build/SupportLibraryExtension.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/SupportLibraryExtension.kt
@@ -34,6 +34,9 @@
     private var licenses: MutableCollection<License> = ArrayList()
     var java8Library = false
     var publish = false
+    var failOnUncheckedWarnings = true
+    var failOnDeprecationWarnings = true
+
     /**
      * This flag works only if publish flag is "true".
      * It is useful for modules that are used for tooling. For example room annotation
diff --git a/car/build.gradle b/car/build.gradle
index 52d2a40..d2e9be6 100644
--- a/car/build.gradle
+++ b/car/build.gradle
@@ -9,7 +9,8 @@
 dependencies {
     api project(':appcompat')
     api project(':cardview')
-    api "com.android.temp.support:design-widget:28.0.0-alpha1", {
+    api "com.android.temp.support:design-widget:28.0.0-alpha1@aar", {
+        transitive = true
         exclude group: 'androidx.annotation'
         exclude group: 'androidx.core'
         exclude group: 'androidx.legacy'
@@ -54,4 +55,5 @@
     description = "Android Car Support UI"
     java8Library = true
     minSdkVersion = 24
+    failOnUncheckedWarnings = false
 }
diff --git a/cardview/build.gradle b/cardview/build.gradle
index d583284..c950dac 100644
--- a/cardview/build.gradle
+++ b/cardview/build.gradle
@@ -22,4 +22,5 @@
     mavenGroup = LibraryGroups.CARDVIEW
     inceptionYear = "2011"
     description = "Android Support CardView v7"
+    failOnDeprecationWarnings = false
 }
diff --git a/compat/api/current.txt b/compat/api/current.txt
index 0a19457..88eac66 100644
--- a/compat/api/current.txt
+++ b/compat/api/current.txt
@@ -809,6 +809,11 @@
     method public static long getLongVersionCode(android.content.pm.PackageInfo);
   }
 
+  public final class PermissionInfoCompat {
+    method public static int getProtection(android.content.pm.PermissionInfo);
+    method public static int getProtectionFlags(android.content.pm.PermissionInfo);
+  }
+
   public class ShortcutInfoCompat {
     method public android.content.ComponentName getActivity();
     method public java.lang.CharSequence getDisabledMessage();
diff --git a/compat/build.gradle b/compat/build.gradle
index 940819b..e4a719a 100644
--- a/compat/build.gradle
+++ b/compat/build.gradle
@@ -37,4 +37,6 @@
     mavenGroup = LibraryGroups.CORE
     inceptionYear = "2015"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/compat/src/androidTest/java/androidx/core/content/pm/PermissionInfoCompatTest.java b/compat/src/androidTest/java/androidx/core/content/pm/PermissionInfoCompatTest.java
new file mode 100644
index 0000000..79613be
--- /dev/null
+++ b/compat/src/androidTest/java/androidx/core/content/pm/PermissionInfoCompatTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.core.content.pm;
+
+import android.content.pm.PermissionInfo;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PermissionInfoCompatTest {
+    @Test
+    public void testGetProtectionAndFlags() {
+        PermissionInfo pi = new PermissionInfo();
+
+        pi.protectionLevel = PermissionInfo.PROTECTION_DANGEROUS
+                | PermissionInfo.PROTECTION_FLAG_PRIVILEGED;
+
+        Assert.assertEquals(PermissionInfo.PROTECTION_DANGEROUS,
+                PermissionInfoCompat.getProtection(pi));
+
+        Assert.assertEquals(PermissionInfo.PROTECTION_FLAG_PRIVILEGED,
+                PermissionInfoCompat.getProtectionFlags(pi));
+
+        pi.protectionLevel = 0xf | 0xfff0;
+        Assert.assertEquals(0xf, PermissionInfoCompat.getProtection(pi));
+        Assert.assertEquals(0xfff0, PermissionInfoCompat.getProtectionFlags(pi));
+    }
+}
diff --git a/compat/src/main/java/androidx/core/app/NotificationManagerCompat.java b/compat/src/main/java/androidx/core/app/NotificationManagerCompat.java
index 3660de3..e8b6188 100644
--- a/compat/src/main/java/androidx/core/app/NotificationManagerCompat.java
+++ b/compat/src/main/java/androidx/core/app/NotificationManagerCompat.java
@@ -267,7 +267,7 @@
             // Parse the string again if it is different from the last time this method was called.
             if (enabledNotificationListeners != null
                     && !enabledNotificationListeners.equals(sEnabledNotificationListeners)) {
-                final String[] components = enabledNotificationListeners.split(":");
+                final String[] components = enabledNotificationListeners.split(":", -1);
                 Set<String> packageNames = new HashSet<String>(components.length);
                 for (String component : components) {
                     ComponentName componentName = ComponentName.unflattenFromString(component);
diff --git a/compat/src/main/java/androidx/core/content/pm/PermissionInfoCompat.java b/compat/src/main/java/androidx/core/content/pm/PermissionInfoCompat.java
new file mode 100644
index 0000000..df095a6
--- /dev/null
+++ b/compat/src/main/java/androidx/core/content/pm/PermissionInfoCompat.java
@@ -0,0 +1,92 @@
+/*
+ * 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.core.content.pm;
+
+import android.annotation.SuppressLint;
+import android.content.pm.PermissionInfo;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.core.os.BuildCompat;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Helper for accessing features in {@link PermissionInfo}.
+ */
+public final class PermissionInfoCompat {
+    private PermissionInfoCompat() {
+    }
+
+    /** @hide */
+    @IntDef(flag = false, value = {
+            PermissionInfo.PROTECTION_NORMAL,
+            PermissionInfo.PROTECTION_DANGEROUS,
+            PermissionInfo.PROTECTION_SIGNATURE,
+            PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM,
+    })
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Protection {}
+
+    /** @hide */
+    @SuppressLint("UniqueConstants") // because _SYSTEM and _PRIVILEGED are aliases.
+    @IntDef(flag = true, value = {
+            PermissionInfo.PROTECTION_FLAG_PRIVILEGED,
+            PermissionInfo.PROTECTION_FLAG_SYSTEM,
+            PermissionInfo.PROTECTION_FLAG_DEVELOPMENT,
+            PermissionInfo.PROTECTION_FLAG_APPOP,
+            PermissionInfo.PROTECTION_FLAG_PRE23,
+            PermissionInfo.PROTECTION_FLAG_INSTALLER,
+            PermissionInfo.PROTECTION_FLAG_VERIFIER,
+            PermissionInfo.PROTECTION_FLAG_PREINSTALLED,
+            PermissionInfo.PROTECTION_FLAG_SETUP,
+            PermissionInfo.PROTECTION_FLAG_INSTANT,
+            PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY,
+    })
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ProtectionFlags {}
+
+    /**
+     * Return the base permission type of a {@link PermissionInfo}.
+     */
+    @SuppressLint("WrongConstant") // for "PermissionInfo.PROTECTION_MASK_BASE"
+    @Protection
+    public static int getProtection(@NonNull PermissionInfo permissionInfo) {
+        if (BuildCompat.isAtLeastP()) {
+            return permissionInfo.getProtection();
+        } else {
+            return permissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+        }
+    }
+
+    /**
+     * Return the additional protection flags of a {@link PermissionInfo}.
+     */
+    @SuppressLint("WrongConstant") // for "~PermissionInfo.PROTECTION_MASK_BASE"
+    @ProtectionFlags
+    public static int getProtectionFlags(@NonNull PermissionInfo permissionInfo) {
+        if (BuildCompat.isAtLeastP()) {
+            return permissionInfo.getProtectionFlags();
+        } else {
+            return permissionInfo.protectionLevel & ~PermissionInfo.PROTECTION_MASK_BASE;
+        }
+    }
+}
diff --git a/compat/src/main/java/androidx/core/graphics/drawable/IconCompat.java b/compat/src/main/java/androidx/core/graphics/drawable/IconCompat.java
index 366ddf3..4c296ea 100644
--- a/compat/src/main/java/androidx/core/graphics/drawable/IconCompat.java
+++ b/compat/src/main/java/androidx/core/graphics/drawable/IconCompat.java
@@ -569,6 +569,58 @@
         return bundle;
     }
 
+    @Override
+    public String toString() {
+        if (mType == TYPE_UNKOWN) {
+            return String.valueOf(mObj1);
+        }
+        final StringBuilder sb = new StringBuilder("Icon(typ=").append(typeToString(mType));
+        switch (mType) {
+            case TYPE_BITMAP:
+            case TYPE_ADAPTIVE_BITMAP:
+                sb.append(" size=")
+                        .append(((Bitmap) mObj1).getWidth())
+                        .append("x")
+                        .append(((Bitmap) mObj1).getHeight());
+                break;
+            case TYPE_RESOURCE:
+                sb.append(" pkg=")
+                        .append(getResPackage())
+                        .append(" id=")
+                        .append(String.format("0x%08x", getResId()));
+                break;
+            case TYPE_DATA:
+                sb.append(" len=").append(mInt1);
+                if (mInt2 != 0) {
+                    sb.append(" off=").append(mInt2);
+                }
+                break;
+            case TYPE_URI:
+                sb.append(" uri=").append(mObj1);
+                break;
+        }
+        if (mTintList != null) {
+            sb.append(" tint=");
+            sb.append(mTintList);
+        }
+        if (mTintMode != DEFAULT_TINT_MODE) {
+            sb.append(" mode=").append(mTintMode);
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+
+    private static String typeToString(int x) {
+        switch (x) {
+            case TYPE_BITMAP: return "BITMAP";
+            case TYPE_ADAPTIVE_BITMAP: return "BITMAP_MASKABLE";
+            case TYPE_DATA: return "DATA";
+            case TYPE_RESOURCE: return "RESOURCE";
+            case TYPE_URI: return "URI";
+            default: return "UNKNOWN";
+        }
+    }
+
     /**
      * Extracts an icon from a bundle that was added using {@link #toBundle()}.
      */
diff --git a/compat/src/main/java/androidx/core/os/LocaleHelper.java b/compat/src/main/java/androidx/core/os/LocaleHelper.java
index 001d657..5ce4c82 100644
--- a/compat/src/main/java/androidx/core/os/LocaleHelper.java
+++ b/compat/src/main/java/androidx/core/os/LocaleHelper.java
@@ -33,7 +33,7 @@
     // Simpleton implementation for Locale.forLanguageTag(...)
     static Locale forLanguageTag(String str) {
         if (str.contains("-")) {
-            String[] args = str.split("-");
+            String[] args = str.split("-", -1);
             if (args.length > 2) {
                 return new Locale(args[0], args[1], args[2]);
             } else if (args.length > 1) {
@@ -42,7 +42,7 @@
                 return new Locale(args[0]);
             }
         } else if (str.contains("_")) {
-            String[] args = str.split("_");
+            String[] args = str.split("_", -1);
             if (args.length > 2) {
                 return new Locale(args[0], args[1], args[2]);
             } else if (args.length > 1) {
diff --git a/compat/src/main/java/androidx/core/os/LocaleListCompat.java b/compat/src/main/java/androidx/core/os/LocaleListCompat.java
index a933877..0be1ff3 100644
--- a/compat/src/main/java/androidx/core/os/LocaleListCompat.java
+++ b/compat/src/main/java/androidx/core/os/LocaleListCompat.java
@@ -289,7 +289,7 @@
         if (list == null || list.isEmpty()) {
             return getEmptyLocaleList();
         } else {
-            final String[] tags = list.split(",");
+            final String[] tags = list.split(",", -1);
             final Locale[] localeArray = new Locale[tags.length];
             for (int i = 0; i < localeArray.length; i++) {
                 localeArray[i] = Build.VERSION.SDK_INT >= 21
diff --git a/compat/src/main/java/androidx/core/os/LocaleListHelper.java b/compat/src/main/java/androidx/core/os/LocaleListHelper.java
index 0a656bc..137d9cd 100644
--- a/compat/src/main/java/androidx/core/os/LocaleListHelper.java
+++ b/compat/src/main/java/androidx/core/os/LocaleListHelper.java
@@ -273,7 +273,7 @@
         if (list == null || list.isEmpty()) {
             return getEmptyLocaleList();
         } else {
-            final String[] tags = list.split(",");
+            final String[] tags = list.split(",", -1);
             final Locale[] localeArray = new Locale[tags.length];
             for (int i = 0; i < localeArray.length; i++) {
                 localeArray[i] = LocaleHelper.forLanguageTag(tags[i]);
diff --git a/content/build.gradle b/content/build.gradle
index 25b01e5..d5f8b80 100644
--- a/content/build.gradle
+++ b/content/build.gradle
@@ -38,4 +38,5 @@
     mavenGroup = LibraryGroups.CONTENTPAGING
     inceptionYear = "2017"
     description = "Library providing support for paging across content exposed via a ContentProvider. Use of this library allows a client to avoid expensive interprocess \"cursor window swaps\" on the UI thread."
+    failOnDeprecationWarnings = false
 }
diff --git a/coordinatorlayout/build.gradle b/coordinatorlayout/build.gradle
index 8e72580..4775f67 100644
--- a/coordinatorlayout/build.gradle
+++ b/coordinatorlayout/build.gradle
@@ -39,4 +39,6 @@
     mavenGroup = LibraryGroups.COORDINATORLAYOUT
     inceptionYear = "2011"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/cursoradapter/build.gradle b/cursoradapter/build.gradle
index ce80655..2493a2b 100644
--- a/cursoradapter/build.gradle
+++ b/cursoradapter/build.gradle
@@ -16,4 +16,5 @@
     mavenGroup = LibraryGroups.CURSORADAPTER
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnDeprecationWarnings = false
 }
diff --git a/customview/build.gradle b/customview/build.gradle
index 37cfc2f..f2ebd43 100644
--- a/customview/build.gradle
+++ b/customview/build.gradle
@@ -22,4 +22,5 @@
     mavenGroup = LibraryGroups.CUSTOMVIEW
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnDeprecationWarnings = false
 }
diff --git a/dynamic-animation/build.gradle b/dynamic-animation/build.gradle
index 637abb4..6da13e0 100644
--- a/dynamic-animation/build.gradle
+++ b/dynamic-animation/build.gradle
@@ -24,4 +24,5 @@
     mavenGroup = LibraryGroups.DYNAMICANIMATION
     inceptionYear = "2017"
     description = "Physics-based animation in support library, where the animations are driven by physics force. You can use this Animation library to create smooth and realistic animations."
+    failOnUncheckedWarnings = false
 }
\ No newline at end of file
diff --git a/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java b/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java
index f697f24..d685bf1 100644
--- a/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java
+++ b/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java
@@ -3920,7 +3920,7 @@
                         break;
                     }
                     case IFD_FORMAT_USHORT: {
-                        final String[] values = value.split(",");
+                        final String[] values = value.split(",", -1);
                         final int[] intArray = new int[values.length];
                         for (int j = 0; j < values.length; ++j) {
                             intArray[j] = Integer.parseInt(values[j]);
@@ -3930,7 +3930,7 @@
                         break;
                     }
                     case IFD_FORMAT_SLONG: {
-                        final String[] values = value.split(",");
+                        final String[] values = value.split(",", -1);
                         final int[] intArray = new int[values.length];
                         for (int j = 0; j < values.length; ++j) {
                             intArray[j] = Integer.parseInt(values[j]);
@@ -3940,7 +3940,7 @@
                         break;
                     }
                     case IFD_FORMAT_ULONG: {
-                        final String[] values = value.split(",");
+                        final String[] values = value.split(",", -1);
                         final long[] longArray = new long[values.length];
                         for (int j = 0; j < values.length; ++j) {
                             longArray[j] = Long.parseLong(values[j]);
@@ -3950,10 +3950,10 @@
                         break;
                     }
                     case IFD_FORMAT_URATIONAL: {
-                        final String[] values = value.split(",");
+                        final String[] values = value.split(",", -1);
                         final Rational[] rationalArray = new Rational[values.length];
                         for (int j = 0; j < values.length; ++j) {
-                            final String[] numbers = values[j].split("/");
+                            final String[] numbers = values[j].split("/", -1);
                             rationalArray[j] = new Rational((long) Double.parseDouble(numbers[0]),
                                     (long) Double.parseDouble(numbers[1]));
                         }
@@ -3962,10 +3962,10 @@
                         break;
                     }
                     case IFD_FORMAT_SRATIONAL: {
-                        final String[] values = value.split(",");
+                        final String[] values = value.split(",", -1);
                         final Rational[] rationalArray = new Rational[values.length];
                         for (int j = 0; j < values.length; ++j) {
-                            final String[] numbers = values[j].split("/");
+                            final String[] numbers = values[j].split("/", -1);
                             rationalArray[j] = new Rational((long) Double.parseDouble(numbers[0]),
                                     (long) Double.parseDouble(numbers[1]));
                         }
@@ -3974,7 +3974,7 @@
                         break;
                     }
                     case IFD_FORMAT_DOUBLE: {
-                        final String[] values = value.split(",");
+                        final String[] values = value.split(",", -1);
                         final double[] doubleArray = new double[values.length];
                         for (int j = 0; j < values.length; ++j) {
                             doubleArray[j] = Double.parseDouble(values[j]);
@@ -4510,7 +4510,7 @@
         setAttribute(TAG_GPS_SPEED_REF, "K");
         setAttribute(TAG_GPS_SPEED, new Rational(location.getSpeed()
                 * TimeUnit.HOURS.toSeconds(1) / 1000).toString());
-        String[] dateTime = sFormatter.format(new Date(location.getTime())).split("\\s+");
+        String[] dateTime = sFormatter.format(new Date(location.getTime())).split("\\s+", -1);
         setAttribute(ExifInterface.TAG_GPS_DATESTAMP, dateTime[0]);
         setAttribute(ExifInterface.TAG_GPS_TIMESTAMP, dateTime[1]);
     }
@@ -4643,18 +4643,18 @@
 
     private static double convertRationalLatLonToDouble(String rationalString, String ref) {
         try {
-            String [] parts = rationalString.split(",");
+            String [] parts = rationalString.split(",", -1);
 
             String [] pair;
-            pair = parts[0].split("/");
+            pair = parts[0].split("/", -1);
             double degrees = Double.parseDouble(pair[0].trim())
                     / Double.parseDouble(pair[1].trim());
 
-            pair = parts[1].split("/");
+            pair = parts[1].split("/", -1);
             double minutes = Double.parseDouble(pair[0].trim())
                     / Double.parseDouble(pair[1].trim());
 
-            pair = parts[2].split("/");
+            pair = parts[2].split("/", -1);
             double seconds = Double.parseDouble(pair[0].trim())
                     / Double.parseDouble(pair[1].trim());
 
@@ -6017,7 +6017,7 @@
         // See TIFF 6.0 Section 2, "Image File Directory".
         // Take the first component if there are more than one component.
         if (entryValue.contains(",")) {
-            String[] entryValues = entryValue.split(",");
+            String[] entryValues = entryValue.split(",", -1);
             Pair<Integer, Integer> dataFormat = guessDataFormat(entryValues[0]);
             if (dataFormat.first == IFD_FORMAT_STRING) {
                 return dataFormat;
@@ -6049,7 +6049,7 @@
         }
 
         if (entryValue.contains("/")) {
-            String[] rationalNumber = entryValue.split("/");
+            String[] rationalNumber = entryValue.split("/", -1);
             if (rationalNumber.length == 2) {
                 try {
                     long numerator = (long) Double.parseDouble(rationalNumber[0]);
diff --git a/fragment/build.gradle b/fragment/build.gradle
index 5f8954f..7faa903 100644
--- a/fragment/build.gradle
+++ b/fragment/build.gradle
@@ -30,4 +30,6 @@
     mavenGroup = LibraryGroups.FRAGMENT
     inceptionYear = "2011"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/graphics/drawable/static/build.gradle b/graphics/drawable/static/build.gradle
index 19a0366..423cb22 100644
--- a/graphics/drawable/static/build.gradle
+++ b/graphics/drawable/static/build.gradle
@@ -31,4 +31,5 @@
     mavenGroup = LibraryGroups.VECTORDRAWABLE
     inceptionYear = "2015"
     description = "Android Support VectorDrawable"
+    failOnDeprecationWarnings = false
 }
\ No newline at end of file
diff --git a/gridlayout/build.gradle b/gridlayout/build.gradle
index fb4dd10..930e191 100644
--- a/gridlayout/build.gradle
+++ b/gridlayout/build.gradle
@@ -21,4 +21,5 @@
     mavenGroup = LibraryGroups.GRIDLAYOUT
     inceptionYear = "2013"
     description = "Android Support Grid Layout"
+    failOnDeprecationWarnings = false
 }
diff --git a/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java b/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java
index 9b5df45..35d34d4 100644
--- a/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java
+++ b/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java
@@ -25,6 +25,8 @@
 import android.util.Log;
 import android.view.Surface;
 
+import java.util.Objects;
+
 /**
  * Holds state associated with a Surface used for MediaCodec encoder input.
  * <p>
@@ -63,7 +65,7 @@
      */
     private void eglSetup() {
         mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
-        if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) {
+        if (Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) {
             throw new RuntimeException("unable to get EGL14 display");
         }
         int[] version = new int[2];
@@ -130,7 +132,7 @@
     }
 
     private void releaseEGLSurface() {
-        if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) {
+        if (!Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) {
             EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);
             mEGLSurface = EGL14.EGL_NO_SURFACE;
         }
@@ -141,7 +143,7 @@
      * Surface that was passed to our constructor.
      */
     public void release() {
-        if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) {
+        if (!Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) {
             EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);
             EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);
             EGL14.eglReleaseThread();
diff --git a/jetifier/jetifier/core/src/main/resources/default.config b/jetifier/jetifier/core/src/main/resources/default.config
index bec56c3..a4aeadf 100644
--- a/jetifier/jetifier/core/src/main/resources/default.config
+++ b/jetifier/jetifier/core/src/main/resources/default.config
@@ -1112,6 +1112,10 @@
             "from": { "groupId": "com.android.support.test.uiautomator", "artifactId": "uiautomator-v18", "version": "28.0.0" },
             "to": [{ "groupId": "androidx.test.uiautomator", "artifactId": "uiautomator", "version": "1.0.0" }]
         },
+        {
+            "from": { "groupId": "com.android.support", "artifactId": "car", "version": "28.0.0" },
+            "to": [{ "groupId": "androidx.car", "artifactId": "car", "version": "1.0.0" }]
+        },
         # Keep it same
         {
             "from": { "groupId": "com.android.support", "artifactId": "slices-core", "version": "28.0.0" },
diff --git a/jetifier/jetifier/core/src/main/resources/default.generated.config b/jetifier/jetifier/core/src/main/resources/default.generated.config
index 33ddfb7..3acc5fc 100644
--- a/jetifier/jetifier/core/src/main/resources/default.generated.config
+++ b/jetifier/jetifier/core/src/main/resources/default.generated.config
@@ -2104,6 +2104,20 @@
     {
       "from": {
         "groupId": "com.android.support",
+        "artifactId": "car",
+        "version": "28.0.0"
+      },
+      "to": [
+        {
+          "groupId": "androidx.car",
+          "artifactId": "car",
+          "version": "1.0.0"
+        }
+      ]
+    },
+    {
+      "from": {
+        "groupId": "com.android.support",
         "artifactId": "slices-core",
         "version": "28.0.0"
       },
@@ -2244,59 +2258,23 @@
   ],
   "map": {
     "types": {
+      "android/support/v4/widget/SlidingPaneLayout": "androidx/slidingpanelayout/widget/SlidingPaneLayout",
+      "android/support/v4/view/AccessibilityDelegateCompat": "androidx/core/view/AccessibilityDelegateCompat",
+      "android/support/v4/view/accessibility/AccessibilityNodeInfoCompat": "androidx/core/view/accessibility/AccessibilityNodeInfoCompat",
+      "android/support/v4/view/ViewCompat": "androidx/core/view/ViewCompat",
+      "android/support/v4/widget/ViewDragHelper": "androidx/customview/widget/ViewDragHelper",
       "android/support/annotation/NonNull": "androidx/annotation/NonNull",
-      "android/support/annotation/RestrictTo": "androidx/annotation/RestrictTo",
-      "android/support/v4/os/BuildCompat": "androidx/core/os/BuildCompat",
       "android/support/annotation/Nullable": "androidx/annotation/Nullable",
+      "android/support/v4/view/AbsSavedState": "androidx/customview/view/AbsSavedState",
       "android/support/annotation/RequiresApi": "androidx/annotation/RequiresApi",
+      "android/support/annotation/Px": "androidx/annotation/Px",
       "android/support/annotation/ColorInt": "androidx/annotation/ColorInt",
-      "android/support/v7/widget/RecyclerView": "androidx/recyclerview/widget/RecyclerView",
-      "android/support/v7/widget/LinearLayoutManager": "androidx/recyclerview/widget/LinearLayoutManager",
-      "android/arch/lifecycle/LiveData": "androidx/lifecycle/LiveData",
-      "android/arch/lifecycle/Observer": "androidx/lifecycle/Observer",
-      "android/support/annotation/AttrRes": "androidx/annotation/AttrRes",
-      "android/databinding/BindingAdapter": "androidx/databinding/BindingAdapter",
-      "android/databinding/BindingMethod": "androidx/databinding/BindingMethod",
-      "android/databinding/ObservableMap": "androidx/databinding/ObservableMap",
-      "android/databinding/BindingBuildInfo": "androidx/databinding/BindingBuildInfo",
-      "android/databinding/Observable": "androidx/databinding/Observable",
-      "android/databinding/Untaggable": "androidx/databinding/Untaggable",
-      "android/databinding/InverseBindingMethod": "androidx/databinding/InverseBindingMethod",
-      "android/databinding/CallbackRegistry": "androidx/databinding/CallbackRegistry",
-      "android/databinding/BindingMethods": "androidx/databinding/BindingMethods",
-      "android/databinding/InverseBindingListener": "androidx/databinding/InverseBindingListener",
-      "android/databinding/BindingConversion": "androidx/databinding/BindingConversion",
-      "android/databinding/ObservableList": "androidx/databinding/ObservableList",
-      "android/databinding/InverseBindingMethods": "androidx/databinding/InverseBindingMethods",
-      "android/databinding/InverseMethod": "androidx/databinding/InverseMethod",
-      "android/databinding/Bindable": "androidx/databinding/Bindable",
-      "android/databinding/InverseBindingAdapter": "androidx/databinding/InverseBindingAdapter",
-      "android/support/design/drawable/DrawableUtils": "android/support/design/drawable/DrawableUtils",
-      "android/support/app/recommendation/ContentRecommendation": "androidx/recommendation/app/ContentRecommendation",
       "android/support/annotation/DrawableRes": "androidx/annotation/DrawableRes",
-      "android/support/app/recommendation/RecommendationExtender": "androidx/recommendation/app/RecommendationExtender",
-      "android/arch/lifecycle/ErrorMessages": "androidx/lifecycle/ErrorMessages",
-      "android/arch/lifecycle/model/EventMethod": "androidx/lifecycle/model/EventMethod",
-      "android/arch/lifecycle/Elements_extKt": "androidx/lifecycle/Elements_extKt",
-      "android/arch/lifecycle/WriterKt": "androidx/lifecycle/WriterKt",
-      "android/arch/lifecycle/ObserversCollector": "androidx/lifecycle/ObserversCollector",
-      "android/arch/lifecycle/Validator": "androidx/lifecycle/Validator",
-      "android/arch/lifecycle/model/LifecycleObserverInfo": "androidx/lifecycle/model/LifecycleObserverInfo",
-      "android/arch/lifecycle/model/AdapterClassKt": "androidx/lifecycle/model/AdapterClassKt",
-      "android/arch/lifecycle/OnLifecycleEvent": "androidx/lifecycle/OnLifecycleEvent",
-      "android/arch/lifecycle/Lifecycle": "androidx/lifecycle/Lifecycle",
-      "android/arch/lifecycle/LifecycleObserver": "androidx/lifecycle/LifecycleObserver",
-      "android/arch/lifecycle/model/EventMethodCall": "androidx/lifecycle/model/EventMethodCall",
-      "android/arch/lifecycle/model/AdapterClass": "androidx/lifecycle/model/AdapterClass",
-      "android/arch/lifecycle/model/InputModel": "androidx/lifecycle/model/InputModel",
-      "android/arch/lifecycle/Lifecycling": "androidx/lifecycle/Lifecycling",
-      "android/arch/lifecycle/LifecycleProcessor": "androidx/lifecycle/LifecycleProcessor",
-      "android/arch/lifecycle/Input_collectorKt": "androidx/lifecycle/Input_collectorKt",
-      "android/arch/lifecycle/TransformationKt": "androidx/lifecycle/TransformationKt",
-      "android/arch/lifecycle/GeneratedAdapter": "androidx/lifecycle/GeneratedAdapter",
-      "android/arch/lifecycle/LifecycleOwner": "androidx/lifecycle/LifecycleOwner",
-      "android/arch/lifecycle/MethodCallsLogger": "androidx/lifecycle/MethodCallsLogger",
+      "android/support/v4/content/ContextCompat": "androidx/core/content/ContextCompat",
+      "android/support/v4/content/LocalBroadcastManager": "androidx/localbroadcastmanager/content/LocalBroadcastManager",
+      "android/support/v4/content/WakefulBroadcastReceiver": "androidx/legacy/content/WakefulBroadcastReceiver",
       "android/support/v4/media/AudioAttributesCompat": "androidx/media/AudioAttributesCompat",
+      "android/support/annotation/RestrictTo": "androidx/annotation/RestrictTo",
       "android/support/v4/media/AudioAttributesCompatApi21": "androidx/media/AudioAttributesCompatApi21",
       "android/support/v4/media/MediaBrowserCompat": "android/support/v4/media/MediaBrowserCompat",
       "android/support/v4/media/session/MediaSessionCompat": "android/support/v4/media/session/MediaSessionCompat",
@@ -2342,529 +2320,77 @@
       "android/support/v4/media/session/MediaSessionCompatApi22": "android/support/v4/media/session/MediaSessionCompatApi22",
       "android/support/v4/media/session/PlaybackStateCompatApi21": "android/support/v4/media/session/PlaybackStateCompatApi21",
       "android/support/v4/media/session/PlaybackStateCompatApi22": "android/support/v4/media/session/PlaybackStateCompatApi22",
-      "android/support/annotation/AnimRes": "androidx/annotation/AnimRes",
-      "android/support/annotation/AnimatorRes": "androidx/annotation/AnimatorRes",
-      "android/support/annotation/AnyRes": "androidx/annotation/AnyRes",
-      "android/support/annotation/AnyThread": "androidx/annotation/AnyThread",
-      "android/support/annotation/ArrayRes": "androidx/annotation/ArrayRes",
-      "android/support/annotation/BinderThread": "androidx/annotation/BinderThread",
-      "android/support/annotation/BoolRes": "androidx/annotation/BoolRes",
-      "android/support/annotation/CallSuper": "androidx/annotation/CallSuper",
-      "android/support/annotation/CheckResult": "androidx/annotation/CheckResult",
-      "android/support/annotation/ColorLong": "androidx/annotation/ColorLong",
-      "android/support/annotation/ColorRes": "androidx/annotation/ColorRes",
-      "android/support/annotation/DimenRes": "androidx/annotation/DimenRes",
-      "android/support/annotation/Dimension": "androidx/annotation/Dimension",
-      "android/support/annotation/FloatRange": "androidx/annotation/FloatRange",
-      "android/support/annotation/FontRes": "androidx/annotation/FontRes",
-      "android/support/annotation/FractionRes": "androidx/annotation/FractionRes",
-      "android/support/annotation/GuardedBy": "androidx/annotation/GuardedBy",
-      "android/support/annotation/HalfFloat": "androidx/annotation/HalfFloat",
-      "android/support/annotation/IdRes": "androidx/annotation/IdRes",
-      "android/support/annotation/IntDef": "androidx/annotation/IntDef",
-      "android/support/annotation/IntRange": "androidx/annotation/IntRange",
-      "android/support/annotation/IntegerRes": "androidx/annotation/IntegerRes",
-      "android/support/annotation/InterpolatorRes": "androidx/annotation/InterpolatorRes",
-      "android/support/annotation/Keep": "androidx/annotation/Keep",
-      "android/support/annotation/LayoutRes": "androidx/annotation/LayoutRes",
-      "android/support/annotation/LongDef": "androidx/annotation/LongDef",
-      "android/support/annotation/MainThread": "androidx/annotation/MainThread",
-      "android/support/annotation/MenuRes": "androidx/annotation/MenuRes",
-      "android/support/annotation/NavigationRes": "androidx/annotation/NavigationRes",
-      "android/support/annotation/PluralsRes": "androidx/annotation/PluralsRes",
-      "android/support/annotation/Px": "androidx/annotation/Px",
-      "android/support/annotation/RawRes": "androidx/annotation/RawRes",
-      "android/support/annotation/RequiresPermission": "androidx/annotation/RequiresPermission",
-      "android/support/annotation/Size": "androidx/annotation/Size",
-      "android/support/annotation/StringDef": "androidx/annotation/StringDef",
-      "android/support/annotation/StringRes": "androidx/annotation/StringRes",
-      "android/support/annotation/StyleRes": "androidx/annotation/StyleRes",
-      "android/support/annotation/StyleableRes": "androidx/annotation/StyleableRes",
-      "android/support/annotation/TransitionRes": "androidx/annotation/TransitionRes",
-      "android/support/annotation/UiThread": "androidx/annotation/UiThread",
-      "android/support/annotation/VisibleForTesting": "androidx/annotation/VisibleForTesting",
-      "android/support/annotation/WorkerThread": "androidx/annotation/WorkerThread",
-      "android/support/annotation/XmlRes": "androidx/annotation/XmlRes",
-      "android/support/design/stateful/ExtendableSavedState": "android/support/design/stateful/ExtendableSavedState",
-      "android/support/v4/view/AbsSavedState": "androidx/customview/view/AbsSavedState",
-      "android/support/v4/util/SimpleArrayMap": "androidx/collection/SimpleArrayMap",
-      "android/support/design/shape/CornerTreatment": "android/support/design/shape/CornerTreatment",
-      "android/support/design/shape/ShapePath": "android/support/design/shape/ShapePath",
-      "android/support/design/shape/CutCornerTreatment": "android/support/design/shape/CutCornerTreatment",
-      "android/support/design/shape/EdgeTreatment": "android/support/design/shape/EdgeTreatment",
-      "android/support/design/shape/InterpolateOnScrollPositionChangeHelper": "android/support/design/shape/InterpolateOnScrollPositionChangeHelper",
-      "android/support/design/shape/MaterialShapeDrawable": "android/support/design/shape/MaterialShapeDrawable",
-      "android/support/v4/graphics/drawable/TintAwareDrawable": "androidx/core/graphics/drawable/TintAwareDrawable",
-      "android/support/design/shape/ShapePathModel": "android/support/design/shape/ShapePathModel",
-      "android/support/design/shape/RoundedCornerTreatment": "android/support/design/shape/RoundedCornerTreatment",
-      "android/support/design/shape/TriangleEdgeTreatment": "android/support/design/shape/TriangleEdgeTreatment",
-      "android/support/v4/widget/DrawerLayout": "androidx/drawerlayout/widget/DrawerLayout",
-      "android/support/v4/view/AccessibilityDelegateCompat": "androidx/core/view/AccessibilityDelegateCompat",
-      "android/support/v4/view/accessibility/AccessibilityNodeInfoCompat": "androidx/core/view/accessibility/AccessibilityNodeInfoCompat",
-      "android/support/v4/view/ViewCompat": "androidx/core/view/ViewCompat",
-      "android/support/v4/widget/ViewDragHelper": "androidx/customview/widget/ViewDragHelper",
-      "android/support/v4/content/ContextCompat": "androidx/core/content/ContextCompat",
-      "android/support/v4/view/GravityCompat": "androidx/core/view/GravityCompat",
-      "android/support/v4/graphics/drawable/DrawableCompat": "androidx/core/graphics/drawable/DrawableCompat",
-      "android/support/design/ripple/RippleUtils": "android/support/design/ripple/RippleUtils",
-      "android/support/v4/graphics/ColorUtils": "androidx/core/graphics/ColorUtils",
-      "android/support/design/resources/MaterialResources": "android/support/design/resources/MaterialResources",
-      "android/support/v7/content/res/AppCompatResources": "androidx/appcompat/content/res/AppCompatResources",
-      "android/support/design/resources/TextAppearance": "android/support/design/resources/TextAppearance",
-      "android/support/design/resources/R": "android/support/design/resources/R",
-      "android/support/v4/content/res/ResourcesCompat": "androidx/core/content/res/ResourcesCompat",
-      "android/arch/lifecycle/DefaultLifecycleObserver": "androidx/lifecycle/DefaultLifecycleObserver",
-      "android/arch/lifecycle/FullLifecycleObserver": "androidx/lifecycle/FullLifecycleObserver",
-      "android/support/multidex/ZipUtil": "androidx/multidex/ZipUtil",
-      "android/support/multidex/MultiDexExtractor": "androidx/multidex/MultiDexExtractor",
-      "android/support/multidex/MultiDex": "androidx/multidex/MultiDex",
-      "android/support/multidex/MultiDexApplication": "androidx/multidex/MultiDexApplication",
-      "android/support/v7/widget/CardView": "androidx/cardview/widget/CardView",
-      "android/support/v7/widget/CardViewDelegate": "androidx/cardview/widget/CardViewDelegate",
-      "android/support/v7/cardview/R": "androidx/cardview/R",
-      "android/support/v7/widget/CardViewImpl": "androidx/cardview/widget/CardViewImpl",
-      "android/support/v7/widget/CardViewApi21Impl": "androidx/cardview/widget/CardViewApi21Impl",
-      "android/support/v7/widget/CardViewApi17Impl": "androidx/cardview/widget/CardViewApi17Impl",
-      "android/support/v7/widget/CardViewBaseImpl": "androidx/cardview/widget/CardViewBaseImpl",
-      "android/support/v7/widget/RoundRectDrawableWithShadow": "androidx/cardview/widget/RoundRectDrawableWithShadow",
-      "android/support/v7/widget/RoundRectDrawable": "androidx/cardview/widget/RoundRectDrawable",
-      "android/arch/persistence/room/DatabaseConfiguration": "androidx/room/DatabaseConfiguration",
-      "android/arch/persistence/db/SupportSQLiteOpenHelper": "androidx/sqlite/db/SupportSQLiteOpenHelper",
-      "android/arch/persistence/room/RoomDatabase": "androidx/room/RoomDatabase",
-      "android/arch/persistence/room/EntityDeletionOrUpdateAdapter": "androidx/room/EntityDeletionOrUpdateAdapter",
-      "android/arch/persistence/room/SharedSQLiteStatement": "androidx/room/SharedSQLiteStatement",
-      "android/arch/persistence/db/SupportSQLiteStatement": "androidx/sqlite/db/SupportSQLiteStatement",
-      "android/arch/persistence/room/EntityInsertionAdapter": "androidx/room/EntityInsertionAdapter",
-      "android/arch/persistence/room/InvalidationTracker": "androidx/room/InvalidationTracker",
-      "android/arch/persistence/db/SupportSQLiteDatabase": "androidx/sqlite/db/SupportSQLiteDatabase",
-      "android/arch/core/internal/SafeIterableMap": "androidx/arch/core/internal/SafeIterableMap",
-      "android/support/v4/util/ArraySet": "androidx/collection/ArraySet",
-      "android/arch/core/executor/ArchTaskExecutor": "androidx/arch/core/executor/ArchTaskExecutor",
-      "android/arch/persistence/room/Room": "androidx/room/Room",
-      "android/arch/persistence/room/migration/Migration": "androidx/room/migration/Migration",
-      "android/arch/persistence/db/framework/FrameworkSQLiteOpenHelperFactory": "androidx/sqlite/db/framework/FrameworkSQLiteOpenHelperFactory",
-      "android/support/v4/app/ActivityManagerCompat": "androidx/core/app/ActivityManagerCompat",
-      "android/support/v4/util/SparseArrayCompat": "androidx/collection/SparseArrayCompat",
-      "android/arch/persistence/db/SimpleSQLiteQuery": "androidx/sqlite/db/SimpleSQLiteQuery",
-      "android/arch/persistence/db/SupportSQLiteQuery": "androidx/sqlite/db/SupportSQLiteQuery",
-      "android/arch/persistence/room/RoomOpenHelper": "androidx/room/RoomOpenHelper",
-      "android/arch/persistence/room/RoomMasterTable": "androidx/room/RoomMasterTable",
-      "android/arch/persistence/room/RoomSQLiteQuery": "androidx/room/RoomSQLiteQuery",
-      "android/arch/persistence/db/SupportSQLiteProgram": "androidx/sqlite/db/SupportSQLiteProgram",
-      "android/arch/persistence/room/paging/LimitOffsetDataSource": "androidx/room/paging/LimitOffsetDataSource",
-      "android/arch/paging/PositionalDataSource": "androidx/paging/PositionalDataSource",
-      "android/arch/persistence/room/util/StringUtil": "androidx/room/util/StringUtil",
-      "android/arch/persistence/room/util/TableInfo": "androidx/room/util/TableInfo",
-      "android/arch/persistence/room/ColumnInfo": "androidx/room/ColumnInfo",
-      "android/support/text/emoji/bundled/BundledEmojiCompatConfig": "androidx/emoji/bundled/BundledEmojiCompatConfig",
-      "android/support/text/emoji/EmojiCompat": "androidx/emoji/text/EmojiCompat",
-      "android/support/v4/util/Preconditions": "androidx/core/util/Preconditions",
-      "android/support/text/emoji/MetadataRepo": "androidx/emoji/text/MetadataRepo",
-      "android/support/v7/graphics/ColorCutQuantizer": "androidx/palette/graphics/ColorCutQuantizer",
-      "android/support/v7/graphics/Palette": "androidx/palette/graphics/Palette",
-      "android/support/v7/graphics/Target": "androidx/palette/graphics/Target",
-      "android/arch/persistence/room/EmptyResultSetException": "androidx/room/EmptyResultSetException",
-      "android/arch/persistence/room/RxRoom": "androidx/room/RxRoom",
-      "android/support/v4/app/ActionBarDrawerToggle": "androidx/legacy/app/ActionBarDrawerToggle",
-      "android/support/v4/widget/Space": "androidx/legacy/widget/Space",
-      "android/support/animation/AnimationHandler": "androidx/dynamicanimation/animation/AnimationHandler",
-      "android/support/animation/DynamicAnimation": "androidx/dynamicanimation/animation/DynamicAnimation",
-      "android/support/animation/FloatPropertyCompat": "androidx/dynamicanimation/animation/FloatPropertyCompat",
-      "android/support/animation/FloatValueHolder": "androidx/dynamicanimation/animation/FloatValueHolder",
-      "android/support/animation/FlingAnimation": "androidx/dynamicanimation/animation/FlingAnimation",
-      "android/support/animation/Force": "androidx/dynamicanimation/animation/Force",
-      "android/support/animation/SpringAnimation": "androidx/dynamicanimation/animation/SpringAnimation",
-      "android/support/animation/SpringForce": "androidx/dynamicanimation/animation/SpringForce",
-      "android/arch/persistence/db/framework/FrameworkSQLiteDatabase": "androidx/sqlite/db/framework/FrameworkSQLiteDatabase",
-      "android/arch/persistence/db/framework/FrameworkSQLiteProgram": "androidx/sqlite/db/framework/FrameworkSQLiteProgram",
-      "android/arch/persistence/db/framework/FrameworkSQLiteStatement": "androidx/sqlite/db/framework/FrameworkSQLiteStatement",
-      "android/arch/persistence/db/framework/FrameworkSQLiteOpenHelper": "androidx/sqlite/db/framework/FrameworkSQLiteOpenHelper",
-      "android/arch/persistence/room/guava/GuavaRoom": "androidx/room/guava/GuavaRoom",
-      "android/arch/lifecycle/LiveDataReactiveStreams": "androidx/lifecycle/LiveDataReactiveStreams",
-      "android/support/v4/widget/CircleImageView": "androidx/swiperefreshlayout/widget/CircleImageView",
-      "android/support/v4/widget/CircularProgressDrawable": "androidx/swiperefreshlayout/widget/CircularProgressDrawable",
-      "android/support/v4/view/animation/FastOutSlowInInterpolator": "androidx/interpolator/view/animation/FastOutSlowInInterpolator",
-      "android/support/v4/widget/SwipeRefreshLayout": "androidx/swiperefreshlayout/widget/SwipeRefreshLayout",
-      "android/support/v4/view/NestedScrollingParent": "androidx/core/view/NestedScrollingParent",
-      "android/support/v4/view/NestedScrollingChild": "androidx/core/view/NestedScrollingChild",
-      "android/support/v4/view/NestedScrollingParentHelper": "androidx/core/view/NestedScrollingParentHelper",
-      "android/support/v4/view/NestedScrollingChildHelper": "androidx/core/view/NestedScrollingChildHelper",
-      "android/support/v4/widget/ListViewCompat": "androidx/core/widget/ListViewCompat",
-      "android/support/design/bottomappbar/BottomAppBar": "android/support/design/bottomappbar/BottomAppBar",
-      "android/support/design/bottomappbar/BottomAppBarTopEdgeTreatment": "android/support/design/bottomappbar/BottomAppBarTopEdgeTreatment",
-      "android/support/v7/widget/ActionMenuView": "androidx/appcompat/widget/ActionMenuView",
-      "android/support/design/widget/CoordinatorLayout": "androidx/coordinatorlayout/widget/CoordinatorLayout",
-      "android/support/design/widget/FloatingActionButton": "android/support/design/widget/FloatingActionButton",
-      "android/support/v7/widget/Toolbar": "androidx/appcompat/widget/Toolbar",
-      "android/support/design/bottomappbar/R": "android/support/design/bottomappbar/R",
-      "android/arch/paging/AsyncPagedListDiffer": "androidx/paging/AsyncPagedListDiffer",
-      "android/arch/paging/PagedList": "androidx/paging/PagedList",
-      "android/support/v7/util/ListUpdateCallback": "androidx/recyclerview/widget/ListUpdateCallback",
-      "android/support/v7/util/DiffUtil": "androidx/recyclerview/widget/DiffUtil",
-      "android/arch/paging/PagedStorage": "androidx/paging/PagedStorage",
       "android/support/v7/recyclerview/extensions/AsyncDifferConfig": "androidx/recyclerview/widget/AsyncDifferConfig",
-      "android/arch/paging/PagedStorageDiffHelper": "androidx/paging/PagedStorageDiffHelper",
+      "android/support/v7/util/DiffUtil": "androidx/recyclerview/widget/DiffUtil",
+      "android/support/v7/recyclerview/extensions/AsyncListDiffer": "androidx/recyclerview/widget/AsyncListDiffer",
+      "android/support/v7/widget/RecyclerView": "androidx/recyclerview/widget/RecyclerView",
+      "android/support/v7/util/ListUpdateCallback": "androidx/recyclerview/widget/ListUpdateCallback",
       "android/support/v7/util/AdapterListUpdateCallback": "androidx/recyclerview/widget/AdapterListUpdateCallback",
-      "android/arch/paging/LivePagedListBuilder": "androidx/paging/LivePagedListBuilder",
-      "android/arch/paging/DataSource": "androidx/paging/DataSource",
-      "android/arch/lifecycle/ComputableLiveData": "androidx/lifecycle/ComputableLiveData",
-      "android/arch/paging/LivePagedListProvider": "androidx/paging/LivePagedListProvider",
-      "android/arch/paging/PagedListAdapter": "androidx/paging/PagedListAdapter",
-      "android/support/design/chip/Chip": "android/support/design/chip/Chip",
-      "android/support/design/chip/ChipDrawable": "android/support/design/chip/ChipDrawable",
-      "android/support/v4/widget/ExploreByTouchHelper": "androidx/customview/widget/ExploreByTouchHelper",
-      "android/support/design/chip/R": "android/support/design/chip/R",
-      "android/support/v7/widget/AppCompatCheckBox": "androidx/appcompat/widget/AppCompatCheckBox",
-      "android/support/design/animation/MotionSpec": "android/support/design/animation/MotionSpec",
-      "android/support/design/canvas/CanvasCompat": "android/support/design/canvas/CanvasCompat",
-      "android/support/v4/text/BidiFormatter": "androidx/core/text/BidiFormatter",
-      "android/support/design/chip/ChipGroup": "android/support/design/chip/ChipGroup",
-      "android/support/v4/app/LoaderManager": "androidx/loader/app/LoaderManager",
-      "android/support/v4/content/Loader": "androidx/loader/content/Loader",
-      "android/arch/lifecycle/ViewModelStoreOwner": "androidx/lifecycle/ViewModelStoreOwner",
-      "android/support/v4/app/LoaderManagerImpl": "androidx/loader/app/LoaderManagerImpl",
-      "android/arch/lifecycle/ViewModelStore": "androidx/lifecycle/ViewModelStore",
-      "android/arch/lifecycle/MutableLiveData": "androidx/lifecycle/MutableLiveData",
-      "android/support/v4/util/DebugUtils": "androidx/core/util/DebugUtils",
-      "android/arch/lifecycle/ViewModelProvider": "androidx/lifecycle/ViewModelProvider",
-      "android/arch/lifecycle/ViewModel": "androidx/lifecycle/ViewModel",
-      "android/support/v4/content/AsyncTaskLoader": "androidx/loader/content/AsyncTaskLoader",
-      "android/support/v4/content/ModernAsyncTask": "androidx/loader/content/ModernAsyncTask",
-      "android/support/v4/os/OperationCanceledException": "androidx/core/os/OperationCanceledException",
-      "android/support/v4/util/TimeUtils": "androidx/core/util/TimeUtils",
-      "android/support/v4/content/CursorLoader": "androidx/loader/content/CursorLoader",
-      "android/support/v4/os/CancellationSignal": "androidx/core/os/CancellationSignal",
-      "android/support/v4/content/ContentResolverCompat": "androidx/core/content/ContentResolverCompat",
-      "android/arch/persistence/room/migration/bundle/DatabaseBundle": "androidx/room/migration/bundle/DatabaseBundle",
-      "android/arch/persistence/room/migration/bundle/SchemaEquality": "androidx/room/migration/bundle/SchemaEquality",
-      "android/arch/persistence/room/migration/bundle/EntityBundle": "androidx/room/migration/bundle/EntityBundle",
-      "android/arch/persistence/room/migration/bundle/SchemaEqualityUtil": "androidx/room/migration/bundle/SchemaEqualityUtil",
-      "android/arch/persistence/room/migration/bundle/FieldBundle": "androidx/room/migration/bundle/FieldBundle",
-      "android/arch/persistence/room/migration/bundle/IndexBundle": "androidx/room/migration/bundle/IndexBundle",
-      "android/arch/persistence/room/migration/bundle/BundleUtil": "androidx/room/migration/bundle/BundleUtil",
-      "android/arch/persistence/room/migration/bundle/PrimaryKeyBundle": "androidx/room/migration/bundle/PrimaryKeyBundle",
-      "android/arch/persistence/room/migration/bundle/ForeignKeyBundle": "androidx/room/migration/bundle/ForeignKeyBundle",
-      "android/arch/persistence/room/migration/bundle/SchemaBundle": "androidx/room/migration/bundle/SchemaBundle",
-      "android/support/design/widget/AppBarLayout": "android/support/design/widget/AppBarLayout",
-      "android/support/v4/view/OnApplyWindowInsetsListener": "androidx/core/view/OnApplyWindowInsetsListener",
-      "android/support/v4/view/WindowInsetsCompat": "androidx/core/view/WindowInsetsCompat",
-      "android/support/design/widget/HeaderBehavior": "android/support/design/widget/HeaderBehavior",
-      "android/support/design/animation/AnimationUtils": "android/support/design/animation/AnimationUtils",
-      "android/support/design/widget/MathUtils": "android/support/design/widget/MathUtils",
-      "android/support/design/widget/R": "android/support/design/widget/R",
-      "android/support/design/widget/HeaderScrollingViewBehavior": "android/support/design/widget/HeaderScrollingViewBehavior",
-      "android/support/design/widget/ViewUtilsLollipop": "android/support/design/widget/ViewUtilsLollipop",
-      "android/support/v4/util/ObjectsCompat": "androidx/core/util/ObjectsCompat",
-      "android/support/design/widget/BaseTransientBottomBar": "android/support/design/widget/BaseTransientBottomBar",
-      "android/support/design/snackbar/ContentViewCallback": "android/support/design/snackbar/ContentViewCallback",
-      "android/support/design/widget/SnackbarManager": "android/support/design/widget/SnackbarManager",
-      "android/support/design/widget/SwipeDismissBehavior": "android/support/design/widget/SwipeDismissBehavior",
-      "android/support/design/widget/BottomNavigationView": "android/support/design/widget/BottomNavigationView",
-      "android/support/v7/view/menu/MenuBuilder": "androidx/appcompat/view/menu/MenuBuilder",
-      "android/support/v7/view/menu/MenuPresenter": "androidx/appcompat/view/menu/MenuPresenter",
-      "android/support/v7/widget/TintTypedArray": "androidx/appcompat/widget/TintTypedArray",
-      "android/support/v7/view/SupportMenuInflater": "androidx/appcompat/view/SupportMenuInflater",
-      "android/support/design/widget/BottomSheetBehavior": "android/support/design/widget/BottomSheetBehavior",
-      "android/support/design/widget/BottomSheetDialog": "android/support/design/widget/BottomSheetDialog",
-      "android/support/v7/app/AppCompatDialog": "androidx/appcompat/app/AppCompatDialog",
-      "android/support/design/widget/BottomSheetDialogFragment": "android/support/design/widget/BottomSheetDialogFragment",
-      "android/support/v7/app/AppCompatDialogFragment": "androidx/appcompat/app/AppCompatDialogFragment",
-      "android/support/design/widget/CheckableImageButton": "android/support/design/widget/CheckableImageButton",
-      "android/support/v7/widget/AppCompatImageButton": "androidx/appcompat/widget/AppCompatImageButton",
-      "android/support/v7/appcompat/R": "androidx/appcompat/R",
-      "android/support/design/widget/CircularBorderDrawable": "android/support/design/widget/CircularBorderDrawable",
-      "android/support/design/widget/CircularBorderDrawableLollipop": "android/support/design/widget/CircularBorderDrawableLollipop",
-      "android/support/design/widget/CollapsingTextHelper": "android/support/design/widget/CollapsingTextHelper",
-      "android/support/v4/text/TextDirectionHeuristicsCompat": "androidx/core/text/TextDirectionHeuristicsCompat",
-      "android/support/v4/text/TextDirectionHeuristicCompat": "androidx/core/text/TextDirectionHeuristicCompat",
-      "android/support/design/widget/CollapsingToolbarLayout": "android/support/design/widget/CollapsingToolbarLayout",
-      "android/support/design/widget/ViewOffsetHelper": "android/support/design/widget/ViewOffsetHelper",
-      "android/support/design/widget/DescendantOffsetUtils": "android/support/design/widget/DescendantOffsetUtils",
-      "android/support/design/widget/CutoutDrawable": "android/support/design/widget/CutoutDrawable",
-      "android/support/design/widget/DrawableUtils": "android/support/design/widget/DrawableUtils",
-      "android/support/design/widget/FloatingActionButtonImpl": "android/support/design/widget/FloatingActionButtonImpl",
-      "android/support/design/widget/ShadowViewDelegate": "android/support/design/widget/ShadowViewDelegate",
-      "android/support/design/widget/VisibilityAwareImageButton": "android/support/design/widget/VisibilityAwareImageButton",
-      "android/support/v4/view/TintableBackgroundView": "androidx/core/view/TintableBackgroundView",
-      "android/support/v4/widget/TintableImageSourceView": "androidx/core/widget/TintableImageSourceView",
-      "android/support/design/expandable/ExpandableTransformationWidget": "android/support/design/expandable/ExpandableTransformationWidget",
-      "android/support/v7/widget/AppCompatImageHelper": "androidx/appcompat/widget/AppCompatImageHelper",
-      "android/support/design/expandable/ExpandableWidgetHelper": "android/support/design/expandable/ExpandableWidgetHelper",
-      "android/support/design/expandable/ExpandableWidget": "android/support/design/expandable/ExpandableWidget",
-      "android/support/v7/widget/AppCompatDrawableManager": "androidx/appcompat/widget/AppCompatDrawableManager",
-      "android/support/design/widget/FloatingActionButtonImplLollipop": "android/support/design/widget/FloatingActionButtonImplLollipop",
-      "android/support/design/widget/ShadowDrawableWrapper": "android/support/design/widget/ShadowDrawableWrapper",
-      "android/support/design/widget/StateListAnimator": "android/support/design/widget/StateListAnimator",
-      "android/support/design/animation/MotionTiming": "android/support/design/animation/MotionTiming",
-      "android/support/design/animation/ImageMatrixProperty": "android/support/design/animation/ImageMatrixProperty",
-      "android/support/design/animation/MatrixEvaluator": "android/support/design/animation/MatrixEvaluator",
-      "android/support/design/animation/AnimatorSetCompat": "android/support/design/animation/AnimatorSetCompat",
-      "android/support/design/widget/ViewOffsetBehavior": "android/support/design/widget/ViewOffsetBehavior",
-      "android/support/design/widget/HideBottomViewOnScrollBehavior": "android/support/design/widget/HideBottomViewOnScrollBehavior",
-      "android/support/design/widget/IndicatorViewController": "android/support/design/widget/IndicatorViewController",
-      "android/support/design/widget/TextInputLayout": "android/support/design/widget/TextInputLayout",
-      "android/support/v7/widget/AppCompatTextView": "androidx/appcompat/widget/AppCompatTextView",
-      "android/support/v4/widget/TextViewCompat": "androidx/core/widget/TextViewCompat",
-      "android/support/design/widget/NavigationView": "android/support/design/widget/NavigationView",
-      "android/support/v7/view/menu/MenuView": "androidx/appcompat/view/menu/MenuView",
-      "android/support/v7/view/menu/MenuItemImpl": "androidx/appcompat/view/menu/MenuItemImpl",
-      "android/support/v7/graphics/drawable/DrawableWrapper": "androidx/appcompat/graphics/drawable/DrawableWrapper",
-      "android/support/design/widget/Snackbar": "android/support/design/widget/Snackbar",
-      "android/support/design/widget/TabItem": "android/support/design/widget/TabItem",
-      "android/support/design/widget/TabLayout": "android/support/design/widget/TabLayout",
-      "android/support/v4/view/ViewPager": "androidx/viewpager/widget/ViewPager",
-      "android/support/v4/view/PagerAdapter": "androidx/viewpager/widget/PagerAdapter",
-      "android/support/v7/app/ActionBar": "androidx/appcompat/app/ActionBar",
-      "android/support/v4/view/PointerIconCompat": "androidx/core/view/PointerIconCompat",
-      "android/support/v4/view/MarginLayoutParamsCompat": "androidx/core/view/MarginLayoutParamsCompat",
-      "android/support/v7/widget/TooltipCompat": "androidx/appcompat/widget/TooltipCompat",
+      "android/support/v7/recyclerview/extensions/ListAdapter": "androidx/recyclerview/widget/ListAdapter",
+      "android/support/v7/util/AsyncListUtil": "androidx/recyclerview/widget/AsyncListUtil",
+      "android/support/v7/util/ThreadUtil": "androidx/recyclerview/widget/ThreadUtil",
+      "android/support/v7/util/TileList": "androidx/recyclerview/widget/TileList",
+      "android/support/annotation/WorkerThread": "androidx/annotation/WorkerThread",
+      "android/support/annotation/UiThread": "androidx/annotation/UiThread",
+      "android/support/v7/util/MessageThreadUtil": "androidx/recyclerview/widget/MessageThreadUtil",
+      "android/support/v7/util/BatchingListUpdateCallback": "androidx/recyclerview/widget/BatchingListUpdateCallback",
+      "android/support/annotation/VisibleForTesting": "androidx/annotation/VisibleForTesting",
+      "android/support/v7/util/SortedList": "androidx/recyclerview/widget/SortedList",
+      "android/support/v7/widget/AdapterHelper": "androidx/recyclerview/widget/AdapterHelper",
+      "android/support/v7/widget/OpReorderer": "androidx/recyclerview/widget/OpReorderer",
       "android/support/v4/util/Pools": "androidx/core/util/Pools",
-      "android/support/design/widget/TextInputEditText": "android/support/design/widget/TextInputEditText",
-      "android/support/v7/widget/AppCompatEditText": "androidx/appcompat/widget/AppCompatEditText",
-      "android/support/v7/widget/DrawableUtils": "androidx/appcompat/widget/DrawableUtils",
-      "android/support/design/bottomnavigation/LabelVisibilityMode": "android/support/design/bottomnavigation/LabelVisibilityMode",
-      "android/support/design/button/MaterialButton": "android/support/design/button/MaterialButton",
-      "android/support/v7/widget/AppCompatButton": "androidx/appcompat/widget/AppCompatButton",
-      "android/support/design/button/R": "android/support/design/button/R",
-      "android/support/design/button/MaterialButtonHelper": "android/support/design/button/MaterialButtonHelper",
-      "android/support/design/button/MaterialButtonBackgroundDrawable": "android/support/design/button/MaterialButtonBackgroundDrawable",
-      "android/support/v4/view/animation/FastOutLinearInInterpolator": "androidx/interpolator/view/animation/FastOutLinearInInterpolator",
-      "android/support/v4/view/animation/LookupTableInterpolator": "androidx/interpolator/view/animation/LookupTableInterpolator",
-      "android/support/v4/view/animation/LinearOutSlowInInterpolator": "androidx/interpolator/view/animation/LinearOutSlowInInterpolator",
-      "android/arch/lifecycle/MediatorLiveData": "androidx/lifecycle/MediatorLiveData",
-      "android/arch/lifecycle/Transformations": "androidx/lifecycle/Transformations",
-      "android/arch/core/util/Function": "androidx/arch/core/util/Function",
-      "android/databinding/adapters/AbsListViewBindingAdapter": "androidx/databinding/adapters/AbsListViewBindingAdapter",
-      "android/databinding/adapters/AbsSeekBarBindingAdapter": "androidx/databinding/adapters/AbsSeekBarBindingAdapter",
-      "android/databinding/adapters/AbsSpinnerBindingAdapter": "androidx/databinding/adapters/AbsSpinnerBindingAdapter",
-      "android/databinding/adapters/ObservableListAdapter": "androidx/databinding/adapters/ObservableListAdapter",
-      "android/databinding/adapters/ActionMenuViewBindingAdapter": "androidx/databinding/adapters/ActionMenuViewBindingAdapter",
-      "android/databinding/adapters/AdapterViewBindingAdapter": "androidx/databinding/adapters/AdapterViewBindingAdapter",
-      "android/databinding/adapters/AutoCompleteTextViewBindingAdapter": "androidx/databinding/adapters/AutoCompleteTextViewBindingAdapter",
-      "android/databinding/adapters/CalendarViewBindingAdapter": "androidx/databinding/adapters/CalendarViewBindingAdapter",
-      "android/databinding/adapters/CardViewBindingAdapter": "androidx/databinding/adapters/CardViewBindingAdapter",
-      "android/databinding/adapters/CheckedTextViewBindingAdapter": "androidx/databinding/adapters/CheckedTextViewBindingAdapter",
-      "android/databinding/adapters/ChronometerBindingAdapter": "androidx/databinding/adapters/ChronometerBindingAdapter",
-      "android/databinding/adapters/CompoundButtonBindingAdapter": "androidx/databinding/adapters/CompoundButtonBindingAdapter",
-      "android/databinding/adapters/Converters": "androidx/databinding/adapters/Converters",
-      "android/databinding/adapters/DatePickerBindingAdapter": "androidx/databinding/adapters/DatePickerBindingAdapter",
-      "android/databinding/adapters/ListenerUtil": "androidx/databinding/adapters/ListenerUtil",
-      "android/databinding/adapters/ExpandableListViewBindingAdapter": "androidx/databinding/adapters/ExpandableListViewBindingAdapter",
-      "android/databinding/adapters/FrameLayoutBindingAdapter": "androidx/databinding/adapters/FrameLayoutBindingAdapter",
-      "android/databinding/adapters/ImageViewBindingAdapter": "androidx/databinding/adapters/ImageViewBindingAdapter",
-      "android/databinding/adapters/LinearLayoutBindingAdapter": "androidx/databinding/adapters/LinearLayoutBindingAdapter",
-      "android/databinding/adapters/NumberPickerBindingAdapter": "androidx/databinding/adapters/NumberPickerBindingAdapter",
-      "android/databinding/adapters/ProgressBarBindingAdapter": "androidx/databinding/adapters/ProgressBarBindingAdapter",
-      "android/databinding/adapters/RadioGroupBindingAdapter": "androidx/databinding/adapters/RadioGroupBindingAdapter",
-      "android/databinding/adapters/RatingBarBindingAdapter": "androidx/databinding/adapters/RatingBarBindingAdapter",
-      "android/databinding/adapters/SearchViewBindingAdapter": "androidx/databinding/adapters/SearchViewBindingAdapter",
-      "android/databinding/adapters/SeekBarBindingAdapter": "androidx/databinding/adapters/SeekBarBindingAdapter",
-      "android/databinding/adapters/SpinnerBindingAdapter": "androidx/databinding/adapters/SpinnerBindingAdapter",
-      "android/databinding/adapters/SwitchBindingAdapter": "androidx/databinding/adapters/SwitchBindingAdapter",
-      "android/databinding/adapters/SwitchCompatBindingAdapter": "androidx/databinding/adapters/SwitchCompatBindingAdapter",
-      "android/support/v7/widget/SwitchCompat": "androidx/appcompat/widget/SwitchCompat",
-      "android/databinding/adapters/TabHostBindingAdapter": "androidx/databinding/adapters/TabHostBindingAdapter",
-      "android/databinding/adapters/TabWidgetBindingAdapter": "androidx/databinding/adapters/TabWidgetBindingAdapter",
-      "android/databinding/adapters/TableLayoutBindingAdapter": "androidx/databinding/adapters/TableLayoutBindingAdapter",
-      "android/databinding/adapters/TextViewBindingAdapter": "androidx/databinding/adapters/TextViewBindingAdapter",
-      "android/databinding/adapters/TimePickerBindingAdapter": "androidx/databinding/adapters/TimePickerBindingAdapter",
-      "android/databinding/adapters/ToolbarBindingAdapter": "androidx/databinding/adapters/ToolbarBindingAdapter",
-      "android/databinding/adapters/VideoViewBindingAdapter": "androidx/databinding/adapters/VideoViewBindingAdapter",
-      "android/databinding/adapters/ViewBindingAdapter": "androidx/databinding/adapters/ViewBindingAdapter",
-      "android/databinding/adapters/ViewGroupBindingAdapter": "androidx/databinding/adapters/ViewGroupBindingAdapter",
-      "android/databinding/adapters/ViewStubBindingAdapter": "androidx/databinding/adapters/ViewStubBindingAdapter",
-      "android/databinding/ViewStubProxy": "androidx/databinding/ViewStubProxy",
-      "android/databinding/adapters/ZoomControlsBindingAdapter": "androidx/databinding/adapters/ZoomControlsBindingAdapter",
+      "android/support/v7/widget/ChildHelper": "androidx/recyclerview/widget/ChildHelper",
+      "android/support/v7/widget/DefaultItemAnimator": "androidx/recyclerview/widget/DefaultItemAnimator",
+      "android/support/v7/widget/SimpleItemAnimator": "androidx/recyclerview/widget/SimpleItemAnimator",
+      "android/support/v7/widget/DividerItemDecoration": "androidx/recyclerview/widget/DividerItemDecoration",
+      "android/support/v7/widget/FastScroller": "androidx/recyclerview/widget/FastScroller",
+      "android/support/v7/widget/GapWorker": "androidx/recyclerview/widget/GapWorker",
+      "android/support/v4/os/TraceCompat": "androidx/core/os/TraceCompat",
+      "android/support/v7/widget/GridLayoutManager": "androidx/recyclerview/widget/GridLayoutManager",
+      "android/support/v7/widget/LinearLayoutManager": "androidx/recyclerview/widget/LinearLayoutManager",
+      "android/support/v7/widget/OrientationHelper": "androidx/recyclerview/widget/OrientationHelper",
+      "android/support/v7/widget/LayoutState": "androidx/recyclerview/widget/LayoutState",
+      "android/support/v7/widget/helper/ItemTouchHelper": "androidx/recyclerview/widget/ItemTouchHelper",
+      "android/support/v7/widget/LinearSmoothScroller": "androidx/recyclerview/widget/LinearSmoothScroller",
+      "android/support/v7/widget/ScrollbarHelper": "androidx/recyclerview/widget/ScrollbarHelper",
+      "android/support/v7/widget/ViewBoundsCheck": "androidx/recyclerview/widget/ViewBoundsCheck",
+      "android/support/v7/widget/LinearSnapHelper": "androidx/recyclerview/widget/LinearSnapHelper",
+      "android/support/v7/widget/SnapHelper": "androidx/recyclerview/widget/SnapHelper",
+      "android/support/v7/widget/PagerSnapHelper": "androidx/recyclerview/widget/PagerSnapHelper",
+      "android/support/v7/widget/PositionMap": "androidx/recyclerview/widget/PositionMap",
+      "android/support/v7/widget/ViewInfoStore": "androidx/recyclerview/widget/ViewInfoStore",
+      "android/support/v7/recyclerview/R": "androidx/recyclerview/R",
+      "android/support/annotation/CallSuper": "androidx/annotation/CallSuper",
+      "android/support/v7/widget/RecyclerViewAccessibilityDelegate": "androidx/recyclerview/widget/RecyclerViewAccessibilityDelegate",
+      "android/support/v4/view/ScrollingView": "androidx/core/view/ScrollingView",
+      "android/support/v4/view/NestedScrollingChild2": "androidx/core/view/NestedScrollingChild2",
+      "android/support/v4/view/NestedScrollingChildHelper": "androidx/core/view/NestedScrollingChildHelper",
+      "android/support/v4/view/ViewConfigurationCompat": "androidx/core/view/ViewConfigurationCompat",
+      "android/support/v4/view/MotionEventCompat": "androidx/core/view/MotionEventCompat",
+      "android/support/v4/widget/EdgeEffectCompat": "androidx/core/widget/EdgeEffectCompat",
+      "android/support/v4/util/Preconditions": "androidx/core/util/Preconditions",
+      "android/support/v4/view/accessibility/AccessibilityEventCompat": "androidx/core/view/accessibility/AccessibilityEventCompat",
+      "android/support/v7/widget/StaggeredGridLayoutManager": "androidx/recyclerview/widget/StaggeredGridLayoutManager",
+      "android/support/v4/util/LongSparseArray": "androidx/collection/LongSparseArray",
+      "android/support/v4/view/GestureDetectorCompat": "androidx/core/view/GestureDetectorCompat",
+      "android/support/v7/widget/helper/ItemTouchUIUtilImpl": "androidx/recyclerview/widget/ItemTouchUIUtilImpl",
+      "android/support/v7/widget/helper/ItemTouchUIUtil": "androidx/recyclerview/widget/ItemTouchUIUtil",
+      "android/support/v7/widget/util/SortedListAdapterCallback": "androidx/recyclerview/widget/SortedListAdapterCallback",
+      "android/support/v4/print/PrintHelper": "androidx/print/PrintHelper",
+      "android/databinding/BaseObservable": "androidx/databinding/BaseObservable",
+      "android/databinding/Observable": "androidx/databinding/Observable",
+      "android/databinding/PropertyChangeRegistry": "androidx/databinding/PropertyChangeRegistry",
+      "android/databinding/BaseObservableField": "androidx/databinding/BaseObservableField",
       "android/databinding/DataBinderMapper": "androidx/databinding/DataBinderMapper",
       "android/databinding/DataBindingComponent": "androidx/databinding/DataBindingComponent",
       "android/databinding/ViewDataBinding": "androidx/databinding/ViewDataBinding",
-      "android/support/text/emoji/EmojiProcessor": "androidx/emoji/text/EmojiProcessor",
-      "android/support/text/emoji/EmojiMetadata": "androidx/emoji/text/EmojiMetadata",
-      "android/support/text/emoji/EmojiSpan": "androidx/emoji/text/EmojiSpan",
-      "android/support/text/emoji/TypefaceEmojiSpan": "androidx/emoji/text/TypefaceEmojiSpan",
-      "android/support/v4/graphics/PaintCompat": "androidx/core/graphics/PaintCompat",
-      "android/support/text/emoji/widget/SpannableBuilder": "androidx/emoji/widget/SpannableBuilder",
-      "android/support/text/emoji/FontRequestEmojiCompatConfig": "androidx/emoji/text/FontRequestEmojiCompatConfig",
-      "android/support/v4/provider/FontsContractCompat": "androidx/core/provider/FontsContractCompat",
-      "android/support/v4/provider/FontRequest": "androidx/core/provider/FontRequest",
-      "android/support/v4/graphics/TypefaceCompatUtil": "androidx/core/graphics/TypefaceCompatUtil",
-      "android/support/text/emoji/MetadataListReader": "androidx/emoji/text/MetadataListReader",
-      "android/support/text/emoji/widget/EditTextAttributeHelper": "androidx/emoji/widget/EditTextAttributeHelper",
-      "android/support/text/emoji/R": "androidx/emoji/R",
-      "android/support/text/emoji/widget/EmojiButton": "androidx/emoji/widget/EmojiButton",
-      "android/support/text/emoji/widget/EmojiTextViewHelper": "androidx/emoji/widget/EmojiTextViewHelper",
-      "android/support/text/emoji/widget/EmojiEditText": "androidx/emoji/widget/EmojiEditText",
-      "android/support/text/emoji/widget/EmojiEditTextHelper": "androidx/emoji/widget/EmojiEditTextHelper",
-      "android/support/text/emoji/widget/EmojiTextWatcher": "androidx/emoji/widget/EmojiTextWatcher",
-      "android/support/text/emoji/widget/EmojiEditableFactory": "androidx/emoji/widget/EmojiEditableFactory",
-      "android/support/text/emoji/widget/EmojiKeyListener": "androidx/emoji/widget/EmojiKeyListener",
-      "android/support/text/emoji/widget/EmojiInputConnection": "androidx/emoji/widget/EmojiInputConnection",
-      "android/support/text/emoji/widget/EmojiExtractEditText": "androidx/emoji/widget/EmojiExtractEditText",
-      "android/support/text/emoji/widget/EmojiExtractTextLayout": "androidx/emoji/widget/EmojiExtractTextLayout",
-      "android/support/text/emoji/widget/ExtractButtonCompat": "androidx/emoji/widget/ExtractButtonCompat",
-      "android/support/text/emoji/widget/EmojiInputFilter": "androidx/emoji/widget/EmojiInputFilter",
-      "android/support/text/emoji/widget/EmojiTextView": "androidx/emoji/widget/EmojiTextView",
-      "android/support/text/emoji/widget/EmojiTransformationMethod": "androidx/emoji/widget/EmojiTransformationMethod",
-      "android/arch/lifecycle/GenericLifecycleObserver": "androidx/lifecycle/GenericLifecycleObserver",
-      "android/support/v13/view/DragAndDropPermissionsCompat": "androidx/core/view/DragAndDropPermissionsCompat",
-      "android/support/v13/view/DragStartHelper": "androidx/core/view/DragStartHelper",
-      "android/support/v4/view/MotionEventCompat": "androidx/core/view/MotionEventCompat",
-      "android/support/v13/view/inputmethod/EditorInfoCompat": "androidx/core/view/inputmethod/EditorInfoCompat",
-      "android/support/v13/view/inputmethod/InputConnectionCompat": "androidx/core/view/inputmethod/InputConnectionCompat",
-      "android/support/v13/view/inputmethod/InputContentInfoCompat": "androidx/core/view/inputmethod/InputContentInfoCompat",
-      "android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat": "androidx/core/accessibilityservice/AccessibilityServiceInfoCompat",
-      "android/support/v4/app/ActivityCompat": "androidx/core/app/ActivityCompat",
-      "android/support/v4/app/SharedElementCallback": "androidx/core/app/SharedElementCallback",
-      "android/support/v4/app/ActivityOptionsCompat": "androidx/core/app/ActivityOptionsCompat",
-      "android/support/v4/app/AlarmManagerCompat": "androidx/core/app/AlarmManagerCompat",
-      "android/support/v4/app/AppLaunchChecker": "androidx/core/app/AppLaunchChecker",
-      "android/support/v4/app/AppOpsManagerCompat": "androidx/core/app/AppOpsManagerCompat",
-      "android/support/v4/app/FrameMetricsAggregator": "androidx/core/app/FrameMetricsAggregator",
-      "android/support/v4/app/INotificationSideChannel": "androidx/core/app/INotificationSideChannel",
-      "android/support/v4/app/JobIntentService": "androidx/core/app/JobIntentService",
-      "android/support/v4/app/NavUtils": "androidx/core/app/NavUtils",
-      "android/support/v4/app/RemoteInput": "androidx/core/app/RemoteInput",
-      "android/support/v4/app/NotificationCompatBuilder": "androidx/core/app/NotificationCompatBuilder",
-      "android/support/compat/R": "androidx/core/R",
-      "android/support/v4/app/NotificationCompatJellybean": "androidx/core/app/NotificationCompatJellybean",
-      "android/support/v4/app/NotificationCompatExtras": "androidx/core/app/NotificationCompatExtras",
-      "android/support/v4/app/NotificationCompatSideChannelService": "androidx/core/app/NotificationCompatSideChannelService",
-      "android/support/v4/app/NotificationManagerCompat": "androidx/core/app/NotificationManagerCompat",
-      "android/support/v4/app/ServiceCompat": "androidx/core/app/ServiceCompat",
-      "android/support/v4/app/ShareCompat": "androidx/core/app/ShareCompat",
-      "android/arch/lifecycle/LifecycleRegistry": "androidx/lifecycle/LifecycleRegistry",
-      "android/arch/lifecycle/ReportFragment": "androidx/lifecycle/ReportFragment",
-      "android/support/v4/app/TaskStackBuilder": "androidx/core/app/TaskStackBuilder",
-      "android/support/v4/content/FileProvider": "androidx/core/content/FileProvider",
-      "android/support/v4/content/IntentCompat": "androidx/core/content/IntentCompat",
-      "android/support/v4/content/MimeTypeFilter": "androidx/core/content/MimeTypeFilter",
-      "android/support/v4/content/PermissionChecker": "androidx/core/content/PermissionChecker",
-      "android/support/v4/content/SharedPreferencesCompat": "androidx/core/content/SharedPreferencesCompat",
-      "android/support/v4/content/pm/ActivityInfoCompat": "androidx/core/content/pm/ActivityInfoCompat",
-      "android/support/v4/content/pm/ShortcutInfoCompat": "androidx/core/content/pm/ShortcutInfoCompat",
-      "android/support/v4/graphics/drawable/IconCompat": "androidx/core/graphics/drawable/IconCompat",
-      "android/support/v4/content/pm/ShortcutManagerCompat": "androidx/core/content/pm/ShortcutManagerCompat",
-      "android/support/v4/content/res/ConfigurationHelper": "androidx/core/content/res/ConfigurationHelper",
-      "android/support/v4/content/res/FontResourcesParserCompat": "androidx/core/content/res/FontResourcesParserCompat",
-      "android/support/v4/graphics/TypefaceCompat": "androidx/core/graphics/TypefaceCompat",
-      "android/support/v4/content/res/TypedArrayUtils": "androidx/core/content/res/TypedArrayUtils",
-      "android/support/v4/database/DatabaseUtilsCompat": "androidx/core/database/DatabaseUtilsCompat",
-      "android/support/v4/graphics/BitmapCompat": "androidx/core/graphics/BitmapCompat",
-      "android/support/v4/graphics/PathParser": "androidx/core/graphics/PathParser",
-      "android/support/v4/util/LruCache": "androidx/collection/LruCache",
-      "android/support/v4/graphics/TypefaceCompatApi28Impl": "androidx/core/graphics/TypefaceCompatApi28Impl",
-      "android/support/v4/graphics/TypefaceCompatApi26Impl": "androidx/core/graphics/TypefaceCompatApi26Impl",
-      "android/support/v4/graphics/TypefaceCompatApi24Impl": "androidx/core/graphics/TypefaceCompatApi24Impl",
-      "android/support/v4/graphics/TypefaceCompatApi21Impl": "androidx/core/graphics/TypefaceCompatApi21Impl",
-      "android/support/v4/graphics/TypefaceCompatBaseImpl": "androidx/core/graphics/TypefaceCompatBaseImpl",
-      "android/support/v4/graphics/drawable/WrappedDrawable": "androidx/core/graphics/drawable/WrappedDrawable",
-      "android/support/v4/graphics/drawable/WrappedDrawableApi21": "androidx/core/graphics/drawable/WrappedDrawableApi21",
-      "android/support/v4/graphics/drawable/WrappedDrawableApi19": "androidx/core/graphics/drawable/WrappedDrawableApi19",
-      "android/support/v4/graphics/drawable/WrappedDrawableApi14": "androidx/core/graphics/drawable/WrappedDrawableApi14",
-      "android/support/v4/graphics/drawable/RoundedBitmapDrawable": "androidx/core/graphics/drawable/RoundedBitmapDrawable",
-      "android/support/v4/graphics/drawable/RoundedBitmapDrawable21": "androidx/core/graphics/drawable/RoundedBitmapDrawable21",
-      "android/support/v4/graphics/drawable/RoundedBitmapDrawableFactory": "androidx/core/graphics/drawable/RoundedBitmapDrawableFactory",
-      "android/support/v4/hardware/display/DisplayManagerCompat": "androidx/core/hardware/display/DisplayManagerCompat",
-      "android/support/v4/hardware/fingerprint/FingerprintManagerCompat": "androidx/core/hardware/fingerprint/FingerprintManagerCompat",
-      "android/support/v4/internal/view/SupportMenu": "androidx/core/internal/view/SupportMenu",
-      "android/support/v4/internal/view/SupportMenuItem": "androidx/core/internal/view/SupportMenuItem",
-      "android/support/v4/view/ActionProvider": "androidx/core/view/ActionProvider",
-      "android/support/v4/internal/view/SupportSubMenu": "androidx/core/internal/view/SupportSubMenu",
-      "android/support/v4/math/MathUtils": "androidx/core/math/MathUtils",
-      "android/support/v4/net/ConnectivityManagerCompat": "androidx/core/net/ConnectivityManagerCompat",
-      "android/support/v4/net/DatagramSocketWrapper": "androidx/core/net/DatagramSocketWrapper",
-      "android/support/v4/net/TrafficStatsCompat": "androidx/core/net/TrafficStatsCompat",
-      "android/support/v4/os/ConfigurationCompat": "androidx/core/os/ConfigurationCompat",
-      "android/support/v4/os/LocaleListCompat": "androidx/core/os/LocaleListCompat",
-      "android/support/v4/os/EnvironmentCompat": "androidx/core/os/EnvironmentCompat",
-      "android/support/v4/os/IResultReceiver": "androidx/core/os/IResultReceiver",
-      "android/support/v4/os/LocaleHelper": "androidx/core/os/LocaleHelper",
-      "android/support/v4/os/LocaleListInterface": "androidx/core/os/LocaleListInterface",
-      "android/support/v4/os/LocaleListHelper": "androidx/core/os/LocaleListHelper",
-      "android/support/v4/os/ParcelableCompat": "androidx/core/os/ParcelableCompat",
-      "android/support/v4/os/ParcelableCompatCreatorCallbacks": "androidx/core/os/ParcelableCompatCreatorCallbacks",
-      "android/support/v4/os/TraceCompat": "androidx/core/os/TraceCompat",
-      "android/support/v4/os/UserManagerCompat": "androidx/core/os/UserManagerCompat",
-      "android/support/v4/provider/SelfDestructiveThread": "androidx/core/provider/SelfDestructiveThread",
-      "android/support/v4/text/TextUtilsCompat": "androidx/core/text/TextUtilsCompat",
-      "android/support/v4/text/ICUCompat": "androidx/core/text/ICUCompat",
-      "android/support/v4/text/util/FindAddress": "androidx/core/text/util/FindAddress",
-      "android/support/v4/text/util/LinkifyCompat": "androidx/core/text/util/LinkifyCompat",
-      "android/support/v4/util/PatternsCompat": "androidx/core/util/PatternsCompat",
-      "android/support/v4/util/AtomicFile": "androidx/core/util/AtomicFile",
-      "android/support/v4/util/LogWriter": "androidx/core/util/LogWriter",
-      "android/support/v4/view/accessibility/AccessibilityNodeProviderCompat": "androidx/core/view/accessibility/AccessibilityNodeProviderCompat",
-      "android/support/v4/view/GestureDetectorCompat": "androidx/core/view/GestureDetectorCompat",
-      "android/support/v4/view/InputDeviceCompat": "androidx/core/view/InputDeviceCompat",
-      "android/support/v4/view/LayoutInflaterCompat": "androidx/core/view/LayoutInflaterCompat",
-      "android/support/v4/view/LayoutInflaterFactory": "androidx/core/view/LayoutInflaterFactory",
-      "android/support/v4/view/MenuCompat": "androidx/core/view/MenuCompat",
-      "android/support/v4/view/MenuItemCompat": "androidx/core/view/MenuItemCompat",
-      "android/support/v4/view/NestedScrollingChild2": "androidx/core/view/NestedScrollingChild2",
-      "android/support/v4/view/ViewParentCompat": "androidx/core/view/ViewParentCompat",
-      "android/support/v4/view/NestedScrollingParent2": "androidx/core/view/NestedScrollingParent2",
-      "android/support/v4/view/ScaleGestureDetectorCompat": "androidx/core/view/ScaleGestureDetectorCompat",
-      "android/support/v4/view/ScrollingView": "androidx/core/view/ScrollingView",
-      "android/support/v4/view/VelocityTrackerCompat": "androidx/core/view/VelocityTrackerCompat",
-      "android/support/v4/view/ViewPropertyAnimatorCompat": "androidx/core/view/ViewPropertyAnimatorCompat",
-      "android/support/v4/view/ViewConfigurationCompat": "androidx/core/view/ViewConfigurationCompat",
-      "android/support/v4/view/ViewGroupCompat": "androidx/core/view/ViewGroupCompat",
-      "android/support/v4/view/ViewPropertyAnimatorListener": "androidx/core/view/ViewPropertyAnimatorListener",
-      "android/support/v4/view/ViewPropertyAnimatorUpdateListener": "androidx/core/view/ViewPropertyAnimatorUpdateListener",
-      "android/support/v4/view/ViewPropertyAnimatorListenerAdapter": "androidx/core/view/ViewPropertyAnimatorListenerAdapter",
-      "android/support/v4/view/WindowCompat": "androidx/core/view/WindowCompat",
-      "android/support/v4/view/accessibility/AccessibilityEventCompat": "androidx/core/view/accessibility/AccessibilityEventCompat",
-      "android/support/v4/view/accessibility/AccessibilityRecordCompat": "androidx/core/view/accessibility/AccessibilityRecordCompat",
-      "android/support/v4/view/accessibility/AccessibilityManagerCompat": "androidx/core/view/accessibility/AccessibilityManagerCompat",
-      "android/support/v4/view/accessibility/AccessibilityWindowInfoCompat": "androidx/core/view/accessibility/AccessibilityWindowInfoCompat",
-      "android/support/v4/view/animation/PathInterpolatorApi14": "androidx/core/view/animation/PathInterpolatorApi14",
-      "android/support/v4/view/animation/PathInterpolatorCompat": "androidx/core/view/animation/PathInterpolatorCompat",
-      "android/support/v4/widget/AutoScrollHelper": "androidx/core/widget/AutoScrollHelper",
-      "android/support/v4/widget/AutoSizeableTextView": "androidx/core/widget/AutoSizeableTextView",
-      "android/support/v4/widget/CompoundButtonCompat": "androidx/core/widget/CompoundButtonCompat",
-      "android/support/v4/widget/TintableCompoundButton": "androidx/core/widget/TintableCompoundButton",
-      "android/support/v4/widget/ContentLoadingProgressBar": "androidx/core/widget/ContentLoadingProgressBar",
-      "android/support/v4/widget/EdgeEffectCompat": "androidx/core/widget/EdgeEffectCompat",
-      "android/support/v4/widget/ImageViewCompat": "androidx/core/widget/ImageViewCompat",
-      "android/support/v4/widget/ListPopupWindowCompat": "androidx/core/widget/ListPopupWindowCompat",
-      "android/support/v4/widget/ListViewAutoScrollHelper": "androidx/core/widget/ListViewAutoScrollHelper",
-      "android/support/v4/widget/NestedScrollView": "androidx/core/widget/NestedScrollView",
-      "android/support/v4/widget/PopupMenuCompat": "androidx/core/widget/PopupMenuCompat",
-      "android/support/v4/widget/PopupWindowCompat": "androidx/core/widget/PopupWindowCompat",
-      "android/support/v4/widget/ScrollerCompat": "androidx/core/widget/ScrollerCompat",
-      "android/arch/core/internal/FastSafeIterableMap": "androidx/arch/core/internal/FastSafeIterableMap",
-      "android/arch/lifecycle/LifecycleRegistryOwner": "androidx/lifecycle/LifecycleRegistryOwner",
-      "android/support/design/transformation/ExpandableBehavior": "android/support/design/transformation/ExpandableBehavior",
-      "android/support/design/transformation/ExpandableTransformationBehavior": "android/support/design/transformation/ExpandableTransformationBehavior",
-      "android/support/design/transformation/FabTransformationBehavior": "android/support/design/transformation/FabTransformationBehavior",
-      "android/support/design/circularreveal/CircularRevealWidget": "android/support/design/circularreveal/CircularRevealWidget",
-      "android/support/design/animation/Positioning": "android/support/design/animation/Positioning",
-      "android/support/design/transformation/R": "android/support/design/transformation/R",
-      "android/support/design/animation/DrawableAlphaProperty": "android/support/design/animation/DrawableAlphaProperty",
-      "android/support/design/math/MathUtils": "android/support/design/math/MathUtils",
-      "android/support/design/circularreveal/CircularRevealCompat": "android/support/design/circularreveal/CircularRevealCompat",
-      "android/support/design/animation/ArgbEvaluatorCompat": "android/support/design/animation/ArgbEvaluatorCompat",
-      "android/support/design/circularreveal/CircularRevealHelper": "android/support/design/circularreveal/CircularRevealHelper",
-      "android/support/design/animation/ChildrenAlphaProperty": "android/support/design/animation/ChildrenAlphaProperty",
-      "android/support/design/transformation/TransformationChildLayout": "android/support/design/transformation/TransformationChildLayout",
-      "android/support/design/transformation/TransformationChildCard": "android/support/design/transformation/TransformationChildCard",
-      "android/support/design/transformation/FabTransformationScrimBehavior": "android/support/design/transformation/FabTransformationScrimBehavior",
-      "android/support/design/transformation/FabTransformationSheetBehavior": "android/support/design/transformation/FabTransformationSheetBehavior",
-      "android/support/design/circularreveal/cardview/CircularRevealCardView": "android/support/design/circularreveal/cardview/CircularRevealCardView",
-      "android/support/design/circularreveal/CircularRevealFrameLayout": "android/support/design/circularreveal/CircularRevealFrameLayout",
-      "android/support/v4/widget/CursorAdapter": "androidx/cursoradapter/widget/CursorAdapter",
-      "android/support/v4/widget/CursorFilter": "androidx/cursoradapter/widget/CursorFilter",
-      "android/support/v4/widget/ResourceCursorAdapter": "androidx/cursoradapter/widget/ResourceCursorAdapter",
-      "android/support/v4/widget/SimpleCursorAdapter": "androidx/cursoradapter/widget/SimpleCursorAdapter",
-      "android/support/design/theme/MaterialComponentsViewInflater": "android/support/design/theme/MaterialComponentsViewInflater",
-      "android/support/v7/app/AppCompatViewInflater": "androidx/appcompat/app/AppCompatViewInflater",
-      "android/databinding/BaseObservable": "androidx/databinding/BaseObservable",
-      "android/databinding/PropertyChangeRegistry": "androidx/databinding/PropertyChangeRegistry",
-      "android/databinding/BaseObservableField": "androidx/databinding/BaseObservableField",
       "android/databinding/DataBindingUtil": "androidx/databinding/DataBindingUtil",
       "android/databinding/DataBinderMapperImpl": "androidx/databinding/DataBinderMapperImpl",
       "android/databinding/ListChangeRegistry": "androidx/databinding/ListChangeRegistry",
+      "android/databinding/CallbackRegistry": "androidx/databinding/CallbackRegistry",
+      "android/databinding/ObservableList": "androidx/databinding/ObservableList",
       "android/databinding/MapChangeRegistry": "androidx/databinding/MapChangeRegistry",
+      "android/databinding/ObservableMap": "androidx/databinding/ObservableMap",
       "android/databinding/MergedDataBinderMapper": "androidx/databinding/MergedDataBinderMapper",
       "android/databinding/ObservableArrayList": "androidx/databinding/ObservableArrayList",
       "android/databinding/ObservableArrayMap": "androidx/databinding/ObservableArrayMap",
@@ -2879,33 +2405,248 @@
       "android/databinding/ObservableParcelable": "androidx/databinding/ObservableParcelable",
       "android/databinding/ObservableShort": "androidx/databinding/ObservableShort",
       "android/databinding/OnRebindCallback": "androidx/databinding/OnRebindCallback",
-      "android/support/v4/util/LongSparseArray": "androidx/collection/LongSparseArray",
-      "android/support/v4/app/BackStackRecord": "androidx/fragment/app/BackStackRecord",
-      "android/support/v4/app/Fragment": "androidx/fragment/app/Fragment",
-      "android/support/v4/app/FragmentTransaction": "androidx/fragment/app/FragmentTransaction",
+      "android/arch/lifecycle/Observer": "androidx/lifecycle/Observer",
+      "android/arch/lifecycle/LiveData": "androidx/lifecycle/LiveData",
+      "android/arch/lifecycle/LifecycleOwner": "androidx/lifecycle/LifecycleOwner",
+      "android/arch/lifecycle/LifecycleObserver": "androidx/lifecycle/LifecycleObserver",
+      "android/arch/lifecycle/Lifecycle": "androidx/lifecycle/Lifecycle",
+      "android/arch/lifecycle/OnLifecycleEvent": "androidx/lifecycle/OnLifecycleEvent",
+      "android/databinding/InverseBindingListener": "androidx/databinding/InverseBindingListener",
+      "android/support/annotation/MainThread": "androidx/annotation/MainThread",
+      "android/databinding/ViewStubProxy": "androidx/databinding/ViewStubProxy",
+      "android/support/v7/widget/CardView": "androidx/cardview/widget/CardView",
+      "android/support/v7/widget/CardViewDelegate": "androidx/cardview/widget/CardViewDelegate",
+      "android/support/v7/cardview/R": "androidx/cardview/R",
+      "android/support/v7/widget/CardViewImpl": "androidx/cardview/widget/CardViewImpl",
+      "android/support/v7/widget/CardViewApi21Impl": "androidx/cardview/widget/CardViewApi21Impl",
+      "android/support/v7/widget/CardViewApi17Impl": "androidx/cardview/widget/CardViewApi17Impl",
+      "android/support/v7/widget/CardViewBaseImpl": "androidx/cardview/widget/CardViewBaseImpl",
+      "android/support/v7/widget/RoundRectDrawableWithShadow": "androidx/cardview/widget/RoundRectDrawableWithShadow",
+      "android/support/v7/widget/RoundRectDrawable": "androidx/cardview/widget/RoundRectDrawable",
+      "android/databinding/BindingAdapter": "androidx/databinding/BindingAdapter",
+      "android/databinding/BindingMethod": "androidx/databinding/BindingMethod",
+      "android/databinding/BindingBuildInfo": "androidx/databinding/BindingBuildInfo",
+      "android/databinding/Untaggable": "androidx/databinding/Untaggable",
+      "android/databinding/InverseBindingMethod": "androidx/databinding/InverseBindingMethod",
+      "android/databinding/BindingMethods": "androidx/databinding/BindingMethods",
+      "android/databinding/BindingConversion": "androidx/databinding/BindingConversion",
+      "android/databinding/InverseBindingMethods": "androidx/databinding/InverseBindingMethods",
+      "android/databinding/InverseMethod": "androidx/databinding/InverseMethod",
+      "android/databinding/Bindable": "androidx/databinding/Bindable",
+      "android/databinding/InverseBindingAdapter": "androidx/databinding/InverseBindingAdapter",
+      "android/support/v7/view/menu/MenuView": "androidx/appcompat/view/menu/MenuView",
+      "android/support/v7/view/menu/MenuItemImpl": "androidx/appcompat/view/menu/MenuItemImpl",
+      "android/support/v7/widget/TooltipCompat": "androidx/appcompat/widget/TooltipCompat",
+      "android/support/v4/view/PointerIconCompat": "androidx/core/view/PointerIconCompat",
+      "android/support/v4/graphics/drawable/DrawableCompat": "androidx/core/graphics/drawable/DrawableCompat",
+      "android/support/annotation/StyleRes": "androidx/annotation/StyleRes",
+      "android/support/v4/widget/TextViewCompat": "androidx/core/widget/TextViewCompat",
+      "android/support/v7/view/menu/MenuBuilder": "androidx/appcompat/view/menu/MenuBuilder",
+      "android/support/v7/view/menu/MenuPresenter": "androidx/appcompat/view/menu/MenuPresenter",
+      "android/support/v7/appcompat/R": "androidx/appcompat/R",
+      "android/support/transition/TransitionSet": "androidx/transition/TransitionSet",
+      "android/support/annotation/Dimension": "androidx/annotation/Dimension",
+      "android/support/transition/AutoTransition": "androidx/transition/AutoTransition",
+      "android/support/v4/view/animation/FastOutSlowInInterpolator": "androidx/interpolator/view/animation/FastOutSlowInInterpolator",
+      "android/support/transition/Transition": "androidx/transition/Transition",
+      "android/support/v7/content/res/AppCompatResources": "androidx/appcompat/content/res/AppCompatResources",
+      "android/support/transition/TransitionManager": "androidx/transition/TransitionManager",
+      "android/support/v7/view/menu/SubMenuBuilder": "androidx/appcompat/view/menu/SubMenuBuilder",
+      "android/support/v7/widget/LinearLayoutCompat": "androidx/appcompat/widget/LinearLayoutCompat",
+      "android/support/v4/content/res/ResourcesCompat": "androidx/core/content/res/ResourcesCompat",
+      "android/support/annotation/LayoutRes": "androidx/annotation/LayoutRes",
+      "android/support/v4/view/WindowInsetsCompat": "androidx/core/view/WindowInsetsCompat",
+      "android/support/v4/view/OnApplyWindowInsetsListener": "androidx/core/view/OnApplyWindowInsetsListener",
+      "android/support/design/snackbar/ContentViewCallback": "android/support/design/snackbar/ContentViewCallback",
+      "android/support/transition/TransitionValues": "androidx/transition/TransitionValues",
+      "android/support/annotation/StyleableRes": "androidx/annotation/StyleableRes",
+      "android/support/annotation/AttrRes": "androidx/annotation/AttrRes",
+      "android/support/v7/widget/TintTypedArray": "androidx/appcompat/widget/TintTypedArray",
+      "android/support/v4/widget/ExploreByTouchHelper": "androidx/customview/widget/ExploreByTouchHelper",
+      "android/support/v4/widget/FocusStrategy": "androidx/customview/widget/FocusStrategy",
+      "android/support/v4/util/SparseArrayCompat": "androidx/collection/SparseArrayCompat",
+      "android/support/v4/view/accessibility/AccessibilityNodeProviderCompat": "androidx/core/view/accessibility/AccessibilityNodeProviderCompat",
+      "android/support/v4/view/ViewParentCompat": "androidx/core/view/ViewParentCompat",
+      "android/support/v4/view/accessibility/AccessibilityRecordCompat": "androidx/core/view/accessibility/AccessibilityRecordCompat",
+      "android/arch/persistence/room/migration/bundle/DatabaseBundle": "androidx/room/migration/bundle/DatabaseBundle",
+      "android/arch/persistence/room/migration/bundle/SchemaEquality": "androidx/room/migration/bundle/SchemaEquality",
+      "android/arch/persistence/room/migration/bundle/EntityBundle": "androidx/room/migration/bundle/EntityBundle",
+      "android/arch/persistence/room/migration/bundle/SchemaEqualityUtil": "androidx/room/migration/bundle/SchemaEqualityUtil",
+      "android/arch/persistence/room/migration/bundle/FieldBundle": "androidx/room/migration/bundle/FieldBundle",
+      "android/arch/persistence/room/migration/bundle/IndexBundle": "androidx/room/migration/bundle/IndexBundle",
+      "android/arch/persistence/room/migration/bundle/BundleUtil": "androidx/room/migration/bundle/BundleUtil",
+      "android/arch/persistence/room/migration/bundle/PrimaryKeyBundle": "androidx/room/migration/bundle/PrimaryKeyBundle",
+      "android/arch/persistence/room/migration/bundle/ForeignKeyBundle": "androidx/room/migration/bundle/ForeignKeyBundle",
+      "android/arch/persistence/room/migration/bundle/SchemaBundle": "androidx/room/migration/bundle/SchemaBundle",
+      "android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout": "androidx/leanback/preference/internal/OutlineOnlyWithChildrenFrameLayout",
+      "android/support/v17/preference/BaseLeanbackPreferenceFragment": "androidx/leanback/preference/BaseLeanbackPreferenceFragment",
+      "android/support/v14/preference/PreferenceFragment": "androidx/preference/PreferenceFragment",
+      "android/support/v17/preference/R": "androidx/leanback/preference/R",
+      "android/support/v17/leanback/widget/VerticalGridView": "androidx/leanback/widget/VerticalGridView",
+      "android/support/v7/preference/PreferenceRecyclerViewAccessibilityDelegate": "androidx/preference/PreferenceRecyclerViewAccessibilityDelegate",
+      "android/support/v17/preference/LeanbackListPreferenceDialogFragment": "androidx/leanback/preference/LeanbackListPreferenceDialogFragment",
+      "android/support/v7/preference/DialogPreference": "androidx/preference/DialogPreference",
+      "android/support/v14/preference/MultiSelectListPreference": "androidx/preference/MultiSelectListPreference",
+      "android/support/v7/preference/ListPreference": "androidx/preference/ListPreference",
+      "android/support/v17/preference/LeanbackPreferenceDialogFragment": "androidx/leanback/preference/LeanbackPreferenceDialogFragment",
+      "android/support/v4/util/ArraySet": "androidx/collection/ArraySet",
+      "android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21": "androidx/leanback/preference/LeanbackPreferenceFragmentTransitionHelperApi21",
+      "android/support/v7/preference/Preference": "androidx/preference/Preference",
+      "android/support/v17/preference/LeanbackPreferenceFragment": "androidx/leanback/preference/LeanbackPreferenceFragment",
+      "android/support/v7/preference/PreferenceScreen": "androidx/preference/PreferenceScreen",
+      "android/support/v17/leanback/transition/FadeAndShortSlide": "androidx/leanback/transition/FadeAndShortSlide",
+      "android/support/v17/preference/LeanbackSettingsFragment": "androidx/leanback/preference/LeanbackSettingsFragment",
+      "android/support/v17/preference/LeanbackSettingsRootView": "androidx/leanback/preference/LeanbackSettingsRootView",
+      "android/support/v4/view/animation/FastOutLinearInInterpolator": "androidx/interpolator/view/animation/FastOutLinearInInterpolator",
+      "android/support/v4/view/animation/LookupTableInterpolator": "androidx/interpolator/view/animation/LookupTableInterpolator",
+      "android/support/v4/view/animation/LinearOutSlowInInterpolator": "androidx/interpolator/view/animation/LinearOutSlowInInterpolator",
+      "android/support/v7/app/MediaRouteActionProvider": "androidx/mediarouter/app/MediaRouteActionProvider",
+      "android/support/v7/media/MediaRouter": "androidx/mediarouter/media/MediaRouter",
+      "android/support/v4/view/ActionProvider": "androidx/core/view/ActionProvider",
+      "android/support/v7/media/MediaRouteSelector": "androidx/mediarouter/media/MediaRouteSelector",
+      "android/support/v7/app/MediaRouteDialogFactory": "androidx/mediarouter/app/MediaRouteDialogFactory",
+      "android/support/v7/app/MediaRouteButton": "androidx/mediarouter/app/MediaRouteButton",
+      "android/support/v7/mediarouter/R": "androidx/mediarouter/R",
+      "android/support/v7/app/MediaRouterThemeHelper": "androidx/mediarouter/app/MediaRouterThemeHelper",
       "android/support/v4/app/FragmentManager": "androidx/fragment/app/FragmentManager",
-      "android/support/v4/app/FragmentManagerImpl": "androidx/fragment/app/FragmentManagerImpl",
-      "android/support/v4/app/FragmentHostCallback": "androidx/fragment/app/FragmentHostCallback",
-      "android/support/v4/app/FragmentTransition": "androidx/fragment/app/FragmentTransition",
-      "android/support/v4/app/BackStackState": "androidx/fragment/app/BackStackState",
-      "android/support/v4/app/BaseFragmentActivityApi14": "androidx/fragment/app/BaseFragmentActivityApi14",
-      "android/support/v4/app/BaseFragmentActivityApi16": "androidx/fragment/app/BaseFragmentActivityApi16",
-      "android/support/v4/app/DialogFragment": "androidx/fragment/app/DialogFragment",
+      "android/support/v4/app/Fragment": "androidx/fragment/app/Fragment",
+      "android/support/v7/app/MediaRouteChooserDialogFragment": "androidx/mediarouter/app/MediaRouteChooserDialogFragment",
+      "android/support/v7/app/MediaRouteControllerDialogFragment": "androidx/mediarouter/app/MediaRouteControllerDialogFragment",
       "android/support/v4/app/FragmentActivity": "androidx/fragment/app/FragmentActivity",
-      "android/support/v4/app/FragmentContainer": "androidx/fragment/app/FragmentContainer",
-      "android/support/v4/app/FragmentManagerNonConfig": "androidx/fragment/app/FragmentManagerNonConfig",
-      "android/support/v4/app/SuperNotCalledException": "androidx/fragment/app/SuperNotCalledException",
-      "android/support/v4/app/FragmentController": "androidx/fragment/app/FragmentController",
-      "android/support/v4/app/FragmentState": "androidx/fragment/app/FragmentState",
-      "android/support/v4/app/FragmentManagerState": "androidx/fragment/app/FragmentManagerState",
-      "android/support/v4/app/FragmentPagerAdapter": "androidx/fragment/app/FragmentPagerAdapter",
-      "android/support/v4/app/FragmentStatePagerAdapter": "androidx/fragment/app/FragmentStatePagerAdapter",
-      "android/support/v4/app/FragmentTabHost": "androidx/fragment/app/FragmentTabHost",
-      "android/support/v4/app/FragmentTransitionImpl": "androidx/fragment/app/FragmentTransitionImpl",
-      "android/support/v4/app/OneShotPreDrawListener": "androidx/fragment/app/OneShotPreDrawListener",
-      "android/support/v4/app/FragmentTransitionCompat21": "androidx/fragment/app/FragmentTransitionCompat21",
-      "android/support/v4/app/ListFragment": "androidx/fragment/app/ListFragment",
-      "android/support/v4/widget/SlidingPaneLayout": "androidx/slidingpanelayout/widget/SlidingPaneLayout",
+      "android/support/v7/app/MediaRouteChooserDialog": "androidx/mediarouter/app/MediaRouteChooserDialog",
+      "android/support/v7/app/AppCompatDialog": "androidx/appcompat/app/AppCompatDialog",
+      "android/support/v7/app/MediaRouteDialogHelper": "androidx/mediarouter/app/MediaRouteDialogHelper",
+      "android/support/v4/app/DialogFragment": "androidx/fragment/app/DialogFragment",
+      "android/support/v7/app/MediaRouteControllerDialog": "androidx/mediarouter/app/MediaRouteControllerDialog",
+      "android/support/v7/app/OverlayListView": "androidx/mediarouter/app/OverlayListView",
+      "android/support/v7/graphics/Palette": "androidx/palette/graphics/Palette",
+      "android/support/v4/util/ObjectsCompat": "androidx/core/util/ObjectsCompat",
+      "android/support/v7/app/MediaRouteVolumeSlider": "androidx/mediarouter/app/MediaRouteVolumeSlider",
+      "android/support/v7/app/AlertDialog": "androidx/appcompat/app/AlertDialog",
+      "android/support/v7/app/MediaRouteExpandCollapseButton": "androidx/mediarouter/app/MediaRouteExpandCollapseButton",
+      "android/support/v7/app/MediaRouteDiscoveryFragment": "androidx/mediarouter/app/MediaRouteDiscoveryFragment",
+      "android/support/v7/widget/AppCompatSeekBar": "androidx/appcompat/widget/AppCompatSeekBar",
+      "android/support/v4/graphics/ColorUtils": "androidx/core/graphics/ColorUtils",
+      "android/support/v7/media/MediaControlIntent": "androidx/mediarouter/media/MediaControlIntent",
+      "android/support/v7/media/MediaItemMetadata": "androidx/mediarouter/media/MediaItemMetadata",
+      "android/support/v7/media/MediaItemStatus": "androidx/mediarouter/media/MediaItemStatus",
+      "android/support/v4/util/TimeUtils": "androidx/core/util/TimeUtils",
+      "android/support/v7/media/MediaRouteDescriptor": "androidx/mediarouter/media/MediaRouteDescriptor",
+      "android/support/v7/media/MediaRouteDiscoveryRequest": "androidx/mediarouter/media/MediaRouteDiscoveryRequest",
+      "android/support/v7/media/MediaRouteProvider": "androidx/mediarouter/media/MediaRouteProvider",
+      "android/support/v7/media/MediaRouteProviderDescriptor": "androidx/mediarouter/media/MediaRouteProviderDescriptor",
+      "android/support/v7/media/MediaRouteProviderProtocol": "androidx/mediarouter/media/MediaRouteProviderProtocol",
+      "android/support/v7/media/MediaRouteProviderService": "androidx/mediarouter/media/MediaRouteProviderService",
+      "android/support/v7/media/SystemMediaRouteProvider": "androidx/mediarouter/media/SystemMediaRouteProvider",
+      "android/support/v7/media/RemoteControlClientCompat": "androidx/mediarouter/media/RemoteControlClientCompat",
+      "android/support/v7/media/RegisteredMediaRouteProviderWatcher": "androidx/mediarouter/media/RegisteredMediaRouteProviderWatcher",
+      "android/support/v4/hardware/display/DisplayManagerCompat": "androidx/core/hardware/display/DisplayManagerCompat",
+      "android/support/v4/app/ActivityManagerCompat": "androidx/core/app/ActivityManagerCompat",
+      "android/support/v7/media/MediaRouterApi24": "androidx/mediarouter/media/MediaRouterApi24",
+      "android/support/v7/media/MediaRouterJellybean": "androidx/mediarouter/media/MediaRouterJellybean",
+      "android/support/v7/media/MediaRouterJellybeanMr1": "androidx/mediarouter/media/MediaRouterJellybeanMr1",
+      "android/support/v7/media/MediaRouterJellybeanMr2": "androidx/mediarouter/media/MediaRouterJellybeanMr2",
+      "android/support/v7/media/MediaSessionStatus": "androidx/mediarouter/media/MediaSessionStatus",
+      "android/support/v7/media/RegisteredMediaRouteProvider": "androidx/mediarouter/media/RegisteredMediaRouteProvider",
+      "android/support/v7/media/RemotePlaybackClient": "androidx/mediarouter/media/RemotePlaybackClient",
+      "android/support/text/emoji/bundled/BundledEmojiCompatConfig": "androidx/emoji/bundled/BundledEmojiCompatConfig",
+      "android/support/text/emoji/EmojiCompat": "androidx/emoji/text/EmojiCompat",
+      "android/support/text/emoji/MetadataRepo": "androidx/emoji/text/MetadataRepo",
+      "android/support/v4/provider/DocumentFile": "androidx/documentfile/provider/DocumentFile",
+      "android/support/v4/provider/RawDocumentFile": "androidx/documentfile/provider/RawDocumentFile",
+      "android/support/v4/provider/SingleDocumentFile": "androidx/documentfile/provider/SingleDocumentFile",
+      "android/support/v4/provider/TreeDocumentFile": "androidx/documentfile/provider/TreeDocumentFile",
+      "android/support/v4/provider/DocumentsContractApi19": "androidx/documentfile/provider/DocumentsContractApi19",
+      "android/support/graphics/drawable/AndroidResources": "androidx/vectordrawable/graphics/drawable/AndroidResources",
+      "android/support/graphics/drawable/VectorDrawableCommon": "androidx/vectordrawable/graphics/drawable/VectorDrawableCommon",
+      "android/support/v4/graphics/drawable/TintAwareDrawable": "androidx/core/graphics/drawable/TintAwareDrawable",
+      "android/support/graphics/drawable/VectorDrawableCompat": "androidx/vectordrawable/graphics/drawable/VectorDrawableCompat",
+      "android/support/v4/graphics/PathParser": "androidx/core/graphics/PathParser",
+      "android/support/v4/content/res/TypedArrayUtils": "androidx/core/content/res/TypedArrayUtils",
+      "android/support/design/card/MaterialCardView": "android/support/design/card/MaterialCardView",
+      "android/support/design/card/R": "android/support/design/card/R",
+      "android/support/design/card/MaterialCardViewHelper": "android/support/design/card/MaterialCardViewHelper",
+      "android/support/v4/os/BuildCompat": "androidx/core/os/BuildCompat",
+      "android/support/design/widget/AppBarLayout": "android/support/design/widget/AppBarLayout",
+      "android/support/design/widget/CoordinatorLayout": "androidx/coordinatorlayout/widget/CoordinatorLayout",
+      "android/support/design/widget/HeaderBehavior": "android/support/design/widget/HeaderBehavior",
+      "android/support/design/animation/AnimationUtils": "android/support/design/animation/AnimationUtils",
+      "android/support/design/widget/MathUtils": "android/support/design/widget/MathUtils",
+      "android/support/design/widget/R": "android/support/design/widget/R",
+      "android/support/design/widget/HeaderScrollingViewBehavior": "android/support/design/widget/HeaderScrollingViewBehavior",
+      "android/support/design/widget/ViewUtilsLollipop": "android/support/design/widget/ViewUtilsLollipop",
+      "android/support/design/widget/BaseTransientBottomBar": "android/support/design/widget/BaseTransientBottomBar",
+      "android/support/design/widget/SnackbarManager": "android/support/design/widget/SnackbarManager",
+      "android/support/design/widget/SwipeDismissBehavior": "android/support/design/widget/SwipeDismissBehavior",
+      "android/support/annotation/IntRange": "androidx/annotation/IntRange",
+      "android/support/design/widget/BottomNavigationView": "android/support/design/widget/BottomNavigationView",
+      "android/support/annotation/DimenRes": "androidx/annotation/DimenRes",
+      "android/support/annotation/IdRes": "androidx/annotation/IdRes",
+      "android/support/annotation/IntegerRes": "androidx/annotation/IntegerRes",
+      "android/support/annotation/BoolRes": "androidx/annotation/BoolRes",
+      "android/support/v7/view/SupportMenuInflater": "androidx/appcompat/view/SupportMenuInflater",
+      "android/support/design/widget/BottomSheetBehavior": "android/support/design/widget/BottomSheetBehavior",
+      "android/support/design/widget/BottomSheetDialog": "android/support/design/widget/BottomSheetDialog",
+      "android/support/design/widget/BottomSheetDialogFragment": "android/support/design/widget/BottomSheetDialogFragment",
+      "android/support/v7/app/AppCompatDialogFragment": "androidx/appcompat/app/AppCompatDialogFragment",
+      "android/support/design/widget/CheckableImageButton": "android/support/design/widget/CheckableImageButton",
+      "android/support/v7/widget/AppCompatImageButton": "androidx/appcompat/widget/AppCompatImageButton",
+      "android/support/design/widget/CircularBorderDrawable": "android/support/design/widget/CircularBorderDrawable",
+      "android/support/design/widget/CircularBorderDrawableLollipop": "android/support/design/widget/CircularBorderDrawableLollipop",
+      "android/support/design/widget/CollapsingTextHelper": "android/support/design/widget/CollapsingTextHelper",
+      "android/support/v4/view/GravityCompat": "androidx/core/view/GravityCompat",
+      "android/support/v4/text/TextDirectionHeuristicsCompat": "androidx/core/text/TextDirectionHeuristicsCompat",
+      "android/support/v4/text/TextDirectionHeuristicCompat": "androidx/core/text/TextDirectionHeuristicCompat",
+      "android/support/design/widget/CollapsingToolbarLayout": "android/support/design/widget/CollapsingToolbarLayout",
+      "android/support/design/widget/ViewOffsetHelper": "android/support/design/widget/ViewOffsetHelper",
+      "android/support/v7/widget/Toolbar": "androidx/appcompat/widget/Toolbar",
+      "android/support/design/widget/DescendantOffsetUtils": "android/support/design/widget/DescendantOffsetUtils",
+      "android/support/design/widget/CutoutDrawable": "android/support/design/widget/CutoutDrawable",
+      "android/support/design/widget/DrawableUtils": "android/support/design/widget/DrawableUtils",
+      "android/support/design/widget/FloatingActionButton": "android/support/design/widget/FloatingActionButton",
+      "android/support/design/widget/FloatingActionButtonImpl": "android/support/design/widget/FloatingActionButtonImpl",
+      "android/support/design/widget/ShadowViewDelegate": "android/support/design/widget/ShadowViewDelegate",
+      "android/support/design/widget/VisibilityAwareImageButton": "android/support/design/widget/VisibilityAwareImageButton",
+      "android/support/v4/view/TintableBackgroundView": "androidx/core/view/TintableBackgroundView",
+      "android/support/v4/widget/TintableImageSourceView": "androidx/core/widget/TintableImageSourceView",
+      "android/support/design/expandable/ExpandableTransformationWidget": "android/support/design/expandable/ExpandableTransformationWidget",
+      "android/support/v7/widget/AppCompatImageHelper": "androidx/appcompat/widget/AppCompatImageHelper",
+      "android/support/design/expandable/ExpandableWidgetHelper": "android/support/design/expandable/ExpandableWidgetHelper",
+      "android/support/design/resources/MaterialResources": "android/support/design/resources/MaterialResources",
+      "android/support/design/animation/MotionSpec": "android/support/design/animation/MotionSpec",
+      "android/support/design/expandable/ExpandableWidget": "android/support/design/expandable/ExpandableWidget",
+      "android/support/v7/widget/AppCompatDrawableManager": "androidx/appcompat/widget/AppCompatDrawableManager",
+      "android/support/design/stateful/ExtendableSavedState": "android/support/design/stateful/ExtendableSavedState",
+      "android/support/v4/util/SimpleArrayMap": "androidx/collection/SimpleArrayMap",
+      "android/support/annotation/AnimatorRes": "androidx/annotation/AnimatorRes",
+      "android/support/design/widget/FloatingActionButtonImplLollipop": "android/support/design/widget/FloatingActionButtonImplLollipop",
+      "android/support/design/widget/ShadowDrawableWrapper": "android/support/design/widget/ShadowDrawableWrapper",
+      "android/support/design/widget/StateListAnimator": "android/support/design/widget/StateListAnimator",
+      "android/support/design/ripple/RippleUtils": "android/support/design/ripple/RippleUtils",
+      "android/support/design/animation/MotionTiming": "android/support/design/animation/MotionTiming",
+      "android/support/design/animation/ImageMatrixProperty": "android/support/design/animation/ImageMatrixProperty",
+      "android/support/design/animation/MatrixEvaluator": "android/support/design/animation/MatrixEvaluator",
+      "android/support/design/animation/AnimatorSetCompat": "android/support/design/animation/AnimatorSetCompat",
+      "android/support/design/widget/ViewOffsetBehavior": "android/support/design/widget/ViewOffsetBehavior",
+      "android/support/design/widget/HideBottomViewOnScrollBehavior": "android/support/design/widget/HideBottomViewOnScrollBehavior",
+      "android/support/design/widget/IndicatorViewController": "android/support/design/widget/IndicatorViewController",
+      "android/support/design/widget/TextInputLayout": "android/support/design/widget/TextInputLayout",
+      "android/support/v4/widget/Space": "androidx/legacy/widget/Space",
+      "android/support/v7/widget/AppCompatTextView": "androidx/appcompat/widget/AppCompatTextView",
+      "android/support/design/widget/NavigationView": "android/support/design/widget/NavigationView",
+      "android/support/v7/graphics/drawable/DrawableWrapper": "androidx/appcompat/graphics/drawable/DrawableWrapper",
+      "android/support/design/widget/Snackbar": "android/support/design/widget/Snackbar",
+      "android/support/annotation/StringRes": "androidx/annotation/StringRes",
+      "android/support/design/widget/TabItem": "android/support/design/widget/TabItem",
+      "android/support/design/widget/TabLayout": "android/support/design/widget/TabLayout",
+      "android/support/v4/view/ViewPager": "androidx/viewpager/widget/ViewPager",
+      "android/support/v4/view/PagerAdapter": "androidx/viewpager/widget/PagerAdapter",
+      "android/support/v7/app/ActionBar": "androidx/appcompat/app/ActionBar",
+      "android/support/v4/view/MarginLayoutParamsCompat": "androidx/core/view/MarginLayoutParamsCompat",
+      "android/support/annotation/ColorRes": "androidx/annotation/ColorRes",
+      "android/support/design/widget/TextInputEditText": "android/support/design/widget/TextInputEditText",
+      "android/support/v7/widget/AppCompatEditText": "androidx/appcompat/widget/AppCompatEditText",
+      "android/support/v7/widget/DrawableUtils": "androidx/appcompat/widget/DrawableUtils",
       "android/support/v17/leanback/animation/LogAccelerateInterpolator": "androidx/leanback/animation/LogAccelerateInterpolator",
       "android/support/v17/leanback/animation/LogDecelerateInterpolator": "androidx/leanback/animation/LogDecelerateInterpolator",
       "android/support/v17/leanback/app/BackgroundFragment": "androidx/leanback/app/BackgroundFragment",
@@ -2922,7 +2663,6 @@
       "android/support/v17/leanback/app/BaseRowFragment": "androidx/leanback/app/BaseRowFragment",
       "android/support/v17/leanback/widget/OnChildViewHolderSelectedListener": "androidx/leanback/widget/OnChildViewHolderSelectedListener",
       "android/support/v17/leanback/widget/ItemBridgeAdapter": "androidx/leanback/widget/ItemBridgeAdapter",
-      "android/support/v17/leanback/widget/VerticalGridView": "androidx/leanback/widget/VerticalGridView",
       "android/support/v17/leanback/widget/ObjectAdapter": "androidx/leanback/widget/ObjectAdapter",
       "android/support/v17/leanback/widget/PresenterSelector": "androidx/leanback/widget/PresenterSelector",
       "android/support/v17/leanback/widget/Row": "androidx/leanback/widget/Row",
@@ -2948,6 +2688,7 @@
       "android/support/v17/leanback/widget/InvisibleRowPresenter": "androidx/leanback/widget/InvisibleRowPresenter",
       "android/support/v17/leanback/app/BrowseSupportFragment": "androidx/leanback/app/BrowseSupportFragment",
       "android/support/v17/leanback/app/HeadersSupportFragment": "androidx/leanback/app/HeadersSupportFragment",
+      "android/support/v4/app/FragmentTransaction": "androidx/fragment/app/FragmentTransaction",
       "android/support/v17/leanback/app/RowsSupportFragment": "androidx/leanback/app/RowsSupportFragment",
       "android/support/v17/leanback/app/DetailsBackgroundVideoHelper": "androidx/leanback/app/DetailsBackgroundVideoHelper",
       "android/support/v17/leanback/widget/ParallaxTarget": "androidx/leanback/widget/ParallaxTarget",
@@ -2981,6 +2722,7 @@
       "android/support/v17/leanback/widget/DiffCallback": "androidx/leanback/widget/DiffCallback",
       "android/support/v17/leanback/app/GuidedStepRootLayout": "androidx/leanback/app/GuidedStepRootLayout",
       "android/support/v17/leanback/widget/NonOverlappingLinearLayout": "androidx/leanback/widget/NonOverlappingLinearLayout",
+      "android/support/v4/app/ActivityCompat": "androidx/core/app/ActivityCompat",
       "android/support/v17/leanback/widget/Util": "androidx/leanback/widget/Util",
       "android/support/v17/leanback/app/GuidedStepSupportFragment": "androidx/leanback/app/GuidedStepSupportFragment",
       "android/support/v17/leanback/widget/FocusHighlightHelper": "androidx/leanback/widget/FocusHighlightHelper",
@@ -3038,7 +2780,6 @@
       "android/support/v17/leanback/widget/PlaybackTransportRowPresenter": "androidx/leanback/widget/PlaybackTransportRowPresenter",
       "android/support/v17/leanback/system/Settings": "androidx/leanback/system/Settings",
       "android/support/v17/leanback/widget/ShadowOverlayContainer": "androidx/leanback/widget/ShadowOverlayContainer",
-      "android/support/v17/leanback/transition/FadeAndShortSlide": "androidx/leanback/transition/FadeAndShortSlide",
       "android/support/v17/leanback/transition/TranslationAnimationCreator": "androidx/leanback/transition/TranslationAnimationCreator",
       "android/support/v17/leanback/transition/LeanbackTransitionHelper": "androidx/leanback/transition/LeanbackTransitionHelper",
       "android/support/v17/leanback/transition/LeanbackTransitionHelperKitKat": "androidx/leanback/transition/LeanbackTransitionHelperKitKat",
@@ -3058,7 +2799,6 @@
       "android/support/v17/leanback/widget/BaseCardView": "androidx/leanback/widget/BaseCardView",
       "android/support/v17/leanback/widget/GridLayoutManager": "androidx/leanback/widget/GridLayoutManager",
       "android/support/v17/leanback/widget/WindowAlignment": "androidx/leanback/widget/WindowAlignment",
-      "android/support/v7/widget/SimpleItemAnimator": "androidx/recyclerview/widget/SimpleItemAnimator",
       "android/support/v17/leanback/widget/OnChildSelectedListener": "androidx/leanback/widget/OnChildSelectedListener",
       "android/support/v17/leanback/widget/ViewsStateBundle": "androidx/leanback/widget/ViewsStateBundle",
       "android/support/v17/leanback/widget/BrowseRowsFrameLayout": "androidx/leanback/widget/BrowseRowsFrameLayout",
@@ -3072,6 +2812,7 @@
       "android/support/v17/leanback/widget/DetailsOverviewRowPresenter": "androidx/leanback/widget/DetailsOverviewRowPresenter",
       "android/support/v17/leanback/widget/DetailsOverviewSharedElementHelper": "androidx/leanback/widget/DetailsOverviewSharedElementHelper",
       "android/support/v17/leanback/widget/RoundedRectHelper": "androidx/leanback/widget/RoundedRectHelper",
+      "android/support/v4/app/SharedElementCallback": "androidx/core/app/SharedElementCallback",
       "android/support/v17/leanback/widget/RecyclerViewParallax": "androidx/leanback/widget/RecyclerViewParallax",
       "android/support/v17/leanback/widget/FacetProvider": "androidx/leanback/widget/FacetProvider",
       "android/support/v17/leanback/widget/FacetProviderAdapter": "androidx/leanback/widget/FacetProviderAdapter",
@@ -3085,10 +2826,8 @@
       "android/support/v4/util/CircularIntArray": "androidx/collection/CircularIntArray",
       "android/support/v17/leanback/widget/SingleRow": "androidx/leanback/widget/SingleRow",
       "android/support/v17/leanback/widget/StaggeredGridDefault": "androidx/leanback/widget/StaggeredGridDefault",
-      "android/support/v7/widget/LinearSmoothScroller": "androidx/recyclerview/widget/LinearSmoothScroller",
       "android/support/v17/leanback/widget/ItemAlignmentFacetHelper": "androidx/leanback/widget/ItemAlignmentFacetHelper",
       "android/support/v17/leanback/widget/ItemAlignment": "androidx/leanback/widget/ItemAlignment",
-      "android/support/v7/widget/OrientationHelper": "androidx/recyclerview/widget/OrientationHelper",
       "android/support/v17/leanback/widget/GuidanceStylingRelativeLayout": "androidx/leanback/widget/GuidanceStylingRelativeLayout",
       "android/support/v17/leanback/widget/ImeKeyMonitor": "androidx/leanback/widget/ImeKeyMonitor",
       "android/support/v17/leanback/widget/GuidedActionDiffCallback": "androidx/leanback/widget/GuidedActionDiffCallback",
@@ -3131,131 +2870,29 @@
       "android/support/v4/util/CircularArray": "androidx/collection/CircularArray",
       "android/support/v17/leanback/widget/TitleView": "androidx/leanback/widget/TitleView",
       "android/support/v17/leanback/widget/VideoSurfaceView": "androidx/leanback/widget/VideoSurfaceView",
+      "android/support/v4/util/LruCache": "androidx/collection/LruCache",
       "android/support/v17/leanback/widget/Visibility": "androidx/leanback/widget/Visibility",
       "android/support/v17/leanback/widget/picker/Picker": "androidx/leanback/widget/picker/Picker",
       "android/support/v17/leanback/widget/picker/PickerUtility": "androidx/leanback/widget/picker/PickerUtility",
       "android/support/v17/leanback/widget/picker/PickerColumn": "androidx/leanback/widget/picker/PickerColumn",
       "android/support/v17/leanback/widget/picker/TimePicker": "androidx/leanback/widget/picker/TimePicker",
-      "android/support/v4/provider/DocumentFile": "androidx/documentfile/provider/DocumentFile",
-      "android/support/v4/provider/RawDocumentFile": "androidx/documentfile/provider/RawDocumentFile",
-      "android/support/v4/provider/SingleDocumentFile": "androidx/documentfile/provider/SingleDocumentFile",
-      "android/support/v4/provider/TreeDocumentFile": "androidx/documentfile/provider/TreeDocumentFile",
-      "android/support/v4/provider/DocumentsContractApi19": "androidx/documentfile/provider/DocumentsContractApi19",
-      "android/arch/lifecycle/EmptyActivityLifecycleCallbacks": "androidx/lifecycle/EmptyActivityLifecycleCallbacks",
-      "android/arch/lifecycle/HolderFragment": "androidx/lifecycle/HolderFragment",
-      "android/arch/lifecycle/LifecycleDispatcher": "androidx/lifecycle/LifecycleDispatcher",
-      "android/arch/lifecycle/LifecycleService": "androidx/lifecycle/LifecycleService",
-      "android/arch/lifecycle/ServiceLifecycleDispatcher": "androidx/lifecycle/ServiceLifecycleDispatcher",
-      "android/arch/lifecycle/ProcessLifecycleOwner": "androidx/lifecycle/ProcessLifecycleOwner",
-      "android/arch/lifecycle/ProcessLifecycleOwnerInitializer": "androidx/lifecycle/ProcessLifecycleOwnerInitializer",
-      "android/arch/lifecycle/ViewModelProviders": "androidx/lifecycle/ViewModelProviders",
-      "android/arch/lifecycle/ViewModelStores": "androidx/lifecycle/ViewModelStores",
-      "android/arch/persistence/room/testing/MigrationTestHelper": "androidx/room/testing/MigrationTestHelper",
-      "android/support/wear/ambient/AmbientDelegate": "androidx/wear/ambient/AmbientDelegate",
-      "android/support/wear/ambient/WearableControllerProvider": "androidx/wear/ambient/WearableControllerProvider",
-      "android/support/wear/ambient/AmbientMode": "androidx/wear/ambient/AmbientMode",
-      "android/support/wear/ambient/AmbientModeSupport": "androidx/wear/ambient/AmbientModeSupport",
-      "android/support/wear/ambient/SharedLibraryVersion": "androidx/wear/ambient/SharedLibraryVersion",
-      "android/support/wear/internal/widget/ResourcesUtil": "androidx/wear/internal/widget/ResourcesUtil",
-      "android/support/wear/internal/widget/drawer/MultiPagePresenter": "androidx/wear/internal/widget/drawer/MultiPagePresenter",
-      "android/support/wear/widget/drawer/WearableNavigationDrawerView": "androidx/wear/widget/drawer/WearableNavigationDrawerView",
-      "android/support/wear/internal/widget/drawer/WearableNavigationDrawerPresenter": "androidx/wear/internal/widget/drawer/WearableNavigationDrawerPresenter",
-      "android/support/wear/widget/drawer/WearableDrawerController": "androidx/wear/widget/drawer/WearableDrawerController",
-      "android/support/wear/internal/widget/drawer/MultiPageUi": "androidx/wear/internal/widget/drawer/MultiPageUi",
-      "android/support/wear/R": "androidx/wear/R",
-      "android/support/wear/widget/drawer/PageIndicatorView": "androidx/wear/widget/drawer/PageIndicatorView",
-      "android/support/wear/internal/widget/drawer/SinglePagePresenter": "androidx/wear/internal/widget/drawer/SinglePagePresenter",
-      "android/support/wear/internal/widget/drawer/SinglePageUi": "androidx/wear/internal/widget/drawer/SinglePageUi",
-      "android/support/wear/widget/CircledImageView": "androidx/wear/widget/CircledImageView",
-      "android/support/wear/utils/MetadataConstants": "androidx/wear/utils/MetadataConstants",
-      "android/support/wear/widget/BezierSCurveInterpolator": "androidx/wear/widget/BezierSCurveInterpolator",
-      "android/support/wear/widget/BoxInsetLayout": "androidx/wear/widget/BoxInsetLayout",
-      "android/support/wear/widget/ProgressDrawable": "androidx/wear/widget/ProgressDrawable",
-      "android/support/wear/widget/CircularProgressLayout": "androidx/wear/widget/CircularProgressLayout",
-      "android/support/wear/widget/CircularProgressLayoutController": "androidx/wear/widget/CircularProgressLayoutController",
-      "android/support/wear/widget/CurvingLayoutCallback": "androidx/wear/widget/CurvingLayoutCallback",
-      "android/support/wear/widget/WearableLinearLayoutManager": "androidx/wear/widget/WearableLinearLayoutManager",
-      "android/support/wear/widget/RoundedDrawable": "androidx/wear/widget/RoundedDrawable",
-      "android/support/wear/widget/ScrollManager": "androidx/wear/widget/ScrollManager",
-      "android/support/wear/widget/SimpleAnimatorListener": "androidx/wear/widget/SimpleAnimatorListener",
-      "android/support/wear/widget/SwipeDismissFrameLayout": "androidx/wear/widget/SwipeDismissFrameLayout",
-      "android/support/wear/widget/SwipeDismissLayout": "androidx/wear/widget/SwipeDismissLayout",
-      "android/support/wear/widget/WearableRecyclerView": "androidx/wear/widget/WearableRecyclerView",
-      "android/support/wear/widget/drawer/AbsListViewFlingWatcher": "androidx/wear/widget/drawer/AbsListViewFlingWatcher",
-      "android/support/wear/widget/drawer/FlingWatcherFactory": "androidx/wear/widget/drawer/FlingWatcherFactory",
-      "android/support/wear/widget/drawer/RecyclerViewFlingWatcher": "androidx/wear/widget/drawer/RecyclerViewFlingWatcher",
-      "android/support/wear/widget/drawer/ScrollViewFlingWatcher": "androidx/wear/widget/drawer/ScrollViewFlingWatcher",
-      "android/support/wear/widget/drawer/NestedScrollViewFlingWatcher": "androidx/wear/widget/drawer/NestedScrollViewFlingWatcher",
-      "android/support/wear/widget/drawer/WearableActionDrawerMenu": "androidx/wear/widget/drawer/WearableActionDrawerMenu",
-      "android/support/wear/widget/drawer/WearableActionDrawerView": "androidx/wear/widget/drawer/WearableActionDrawerView",
-      "android/support/wear/widget/drawer/WearableDrawerView": "androidx/wear/widget/drawer/WearableDrawerView",
-      "android/support/wear/widget/drawer/WearableDrawerLayout": "androidx/wear/widget/drawer/WearableDrawerLayout",
-      "android/support/v4/content/LocalBroadcastManager": "androidx/localbroadcastmanager/content/LocalBroadcastManager",
-      "android/support/v4/print/PrintHelper": "androidx/print/PrintHelper",
-      "android/support/media/ExifInterface": "androidx/exifinterface/media/ExifInterface",
-      "android/support/v7/app/MediaRouteActionProvider": "androidx/mediarouter/app/MediaRouteActionProvider",
-      "android/support/v7/media/MediaRouter": "androidx/mediarouter/media/MediaRouter",
-      "android/support/v7/media/MediaRouteSelector": "androidx/mediarouter/media/MediaRouteSelector",
-      "android/support/v7/app/MediaRouteDialogFactory": "androidx/mediarouter/app/MediaRouteDialogFactory",
-      "android/support/v7/app/MediaRouteButton": "androidx/mediarouter/app/MediaRouteButton",
-      "android/support/v7/mediarouter/R": "androidx/mediarouter/R",
-      "android/support/v7/app/MediaRouterThemeHelper": "androidx/mediarouter/app/MediaRouterThemeHelper",
-      "android/support/v7/app/MediaRouteChooserDialogFragment": "androidx/mediarouter/app/MediaRouteChooserDialogFragment",
-      "android/support/v7/app/MediaRouteControllerDialogFragment": "androidx/mediarouter/app/MediaRouteControllerDialogFragment",
-      "android/support/v7/app/MediaRouteChooserDialog": "androidx/mediarouter/app/MediaRouteChooserDialog",
-      "android/support/v7/app/MediaRouteDialogHelper": "androidx/mediarouter/app/MediaRouteDialogHelper",
-      "android/support/v7/app/MediaRouteControllerDialog": "androidx/mediarouter/app/MediaRouteControllerDialog",
-      "android/support/v7/app/OverlayListView": "androidx/mediarouter/app/OverlayListView",
-      "android/support/v7/app/MediaRouteVolumeSlider": "androidx/mediarouter/app/MediaRouteVolumeSlider",
-      "android/support/v7/app/AlertDialog": "androidx/appcompat/app/AlertDialog",
-      "android/support/v7/app/MediaRouteExpandCollapseButton": "androidx/mediarouter/app/MediaRouteExpandCollapseButton",
-      "android/support/v7/app/MediaRouteDiscoveryFragment": "androidx/mediarouter/app/MediaRouteDiscoveryFragment",
-      "android/support/v7/widget/AppCompatSeekBar": "androidx/appcompat/widget/AppCompatSeekBar",
-      "android/support/v7/media/MediaControlIntent": "androidx/mediarouter/media/MediaControlIntent",
-      "android/support/v7/media/MediaItemMetadata": "androidx/mediarouter/media/MediaItemMetadata",
-      "android/support/v7/media/MediaItemStatus": "androidx/mediarouter/media/MediaItemStatus",
-      "android/support/v7/media/MediaRouteDescriptor": "androidx/mediarouter/media/MediaRouteDescriptor",
-      "android/support/v7/media/MediaRouteDiscoveryRequest": "androidx/mediarouter/media/MediaRouteDiscoveryRequest",
-      "android/support/v7/media/MediaRouteProvider": "androidx/mediarouter/media/MediaRouteProvider",
-      "android/support/v7/media/MediaRouteProviderDescriptor": "androidx/mediarouter/media/MediaRouteProviderDescriptor",
-      "android/support/v7/media/MediaRouteProviderProtocol": "androidx/mediarouter/media/MediaRouteProviderProtocol",
-      "android/support/v7/media/MediaRouteProviderService": "androidx/mediarouter/media/MediaRouteProviderService",
-      "android/support/v7/media/SystemMediaRouteProvider": "androidx/mediarouter/media/SystemMediaRouteProvider",
-      "android/support/v7/media/RemoteControlClientCompat": "androidx/mediarouter/media/RemoteControlClientCompat",
-      "android/support/v7/media/RegisteredMediaRouteProviderWatcher": "androidx/mediarouter/media/RegisteredMediaRouteProviderWatcher",
-      "android/support/v7/media/MediaRouterApi24": "androidx/mediarouter/media/MediaRouterApi24",
-      "android/support/v7/media/MediaRouterJellybean": "androidx/mediarouter/media/MediaRouterJellybean",
-      "android/support/v7/media/MediaRouterJellybeanMr1": "androidx/mediarouter/media/MediaRouterJellybeanMr1",
-      "android/support/v7/media/MediaRouterJellybeanMr2": "androidx/mediarouter/media/MediaRouterJellybeanMr2",
-      "android/support/v7/media/MediaSessionStatus": "androidx/mediarouter/media/MediaSessionStatus",
-      "android/support/v7/media/RegisteredMediaRouteProvider": "androidx/mediarouter/media/RegisteredMediaRouteProvider",
-      "android/support/v7/media/RemotePlaybackClient": "androidx/mediarouter/media/RemotePlaybackClient",
-      "android/support/graphics/drawable/Animatable2Compat": "androidx/vectordrawable/graphics/drawable/Animatable2Compat",
-      "android/support/graphics/drawable/AnimatedVectorDrawableCompat": "androidx/vectordrawable/graphics/drawable/AnimatedVectorDrawableCompat",
-      "android/support/graphics/drawable/VectorDrawableCompat": "androidx/vectordrawable/graphics/drawable/VectorDrawableCompat",
-      "android/support/graphics/drawable/VectorDrawableCommon": "androidx/vectordrawable/graphics/drawable/VectorDrawableCommon",
-      "android/support/graphics/drawable/AndroidResources": "androidx/vectordrawable/graphics/drawable/AndroidResources",
-      "android/support/graphics/drawable/AnimatorInflaterCompat": "androidx/vectordrawable/graphics/drawable/AnimatorInflaterCompat",
-      "android/support/graphics/drawable/AnimationUtilsCompat": "androidx/vectordrawable/graphics/drawable/AnimationUtilsCompat",
-      "android/support/graphics/drawable/PathInterpolatorCompat": "androidx/vectordrawable/graphics/drawable/PathInterpolatorCompat",
-      "android/support/graphics/drawable/ArgbEvaluator": "androidx/vectordrawable/graphics/drawable/ArgbEvaluator",
-      "android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout": "androidx/leanback/preference/internal/OutlineOnlyWithChildrenFrameLayout",
-      "android/support/v17/preference/BaseLeanbackPreferenceFragment": "androidx/leanback/preference/BaseLeanbackPreferenceFragment",
-      "android/support/v14/preference/PreferenceFragment": "androidx/preference/PreferenceFragment",
-      "android/support/v17/preference/R": "androidx/leanback/preference/R",
-      "android/support/v7/preference/PreferenceRecyclerViewAccessibilityDelegate": "androidx/preference/PreferenceRecyclerViewAccessibilityDelegate",
-      "android/support/v7/widget/RecyclerViewAccessibilityDelegate": "androidx/recyclerview/widget/RecyclerViewAccessibilityDelegate",
-      "android/support/v17/preference/LeanbackListPreferenceDialogFragment": "androidx/leanback/preference/LeanbackListPreferenceDialogFragment",
-      "android/support/v7/preference/DialogPreference": "androidx/preference/DialogPreference",
-      "android/support/v14/preference/MultiSelectListPreference": "androidx/preference/MultiSelectListPreference",
-      "android/support/v7/preference/ListPreference": "androidx/preference/ListPreference",
-      "android/support/v17/preference/LeanbackPreferenceDialogFragment": "androidx/leanback/preference/LeanbackPreferenceDialogFragment",
-      "android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21": "androidx/leanback/preference/LeanbackPreferenceFragmentTransitionHelperApi21",
-      "android/support/v7/preference/Preference": "androidx/preference/Preference",
-      "android/support/v17/preference/LeanbackPreferenceFragment": "androidx/leanback/preference/LeanbackPreferenceFragment",
-      "android/support/v7/preference/PreferenceScreen": "androidx/preference/PreferenceScreen",
-      "android/support/v17/preference/LeanbackSettingsFragment": "androidx/leanback/preference/LeanbackSettingsFragment",
-      "android/support/v17/preference/LeanbackSettingsRootView": "androidx/leanback/preference/LeanbackSettingsRootView",
+      "android/support/app/recommendation/ContentRecommendation": "androidx/recommendation/app/ContentRecommendation",
+      "android/support/app/recommendation/RecommendationExtender": "androidx/recommendation/app/RecommendationExtender",
+      "android/support/annotation/FloatRange": "androidx/annotation/FloatRange",
+      "android/support/v4/os/LocaleListCompat": "androidx/core/os/LocaleListCompat",
+      "android/support/design/animation/ArgbEvaluatorCompat": "android/support/design/animation/ArgbEvaluatorCompat",
+      "android/support/design/animation/ChildrenAlphaProperty": "android/support/design/animation/ChildrenAlphaProperty",
+      "android/support/design/animation/R": "android/support/design/animation/R",
+      "android/support/design/animation/DrawableAlphaProperty": "android/support/design/animation/DrawableAlphaProperty",
+      "android/support/design/animation/Positioning": "android/support/design/animation/Positioning",
+      "android/support/design/circularreveal/CircularRevealCompat": "android/support/design/circularreveal/CircularRevealCompat",
+      "android/support/design/circularreveal/CircularRevealWidget": "android/support/design/circularreveal/CircularRevealWidget",
+      "android/support/design/circularreveal/CircularRevealFrameLayout": "android/support/design/circularreveal/CircularRevealFrameLayout",
+      "android/support/design/circularreveal/CircularRevealHelper": "android/support/design/circularreveal/CircularRevealHelper",
+      "android/support/design/circularreveal/CircularRevealGridLayout": "android/support/design/circularreveal/CircularRevealGridLayout",
+      "android/support/design/math/MathUtils": "android/support/design/math/MathUtils",
+      "android/support/design/circularreveal/CircularRevealLinearLayout": "android/support/design/circularreveal/CircularRevealLinearLayout",
+      "android/support/design/circularreveal/CircularRevealRelativeLayout": "android/support/design/circularreveal/CircularRevealRelativeLayout",
       "android/support/transition/AnimatorUtils": "androidx/transition/AnimatorUtils",
       "android/support/transition/AnimatorUtilsImpl": "androidx/transition/AnimatorUtilsImpl",
       "android/support/transition/AnimatorUtilsApi19": "androidx/transition/AnimatorUtilsApi19",
@@ -3263,12 +2900,8 @@
       "android/support/transition/ArcMotion": "androidx/transition/ArcMotion",
       "android/support/transition/PathMotion": "androidx/transition/PathMotion",
       "android/support/transition/Styleable": "androidx/transition/Styleable",
-      "android/support/transition/AutoTransition": "androidx/transition/AutoTransition",
-      "android/support/transition/TransitionSet": "androidx/transition/TransitionSet",
       "android/support/transition/Fade": "androidx/transition/Fade",
-      "android/support/transition/Transition": "androidx/transition/Transition",
       "android/support/transition/ChangeBounds": "androidx/transition/ChangeBounds",
-      "android/support/transition/TransitionValues": "androidx/transition/TransitionValues",
       "android/support/transition/ViewUtils": "androidx/transition/ViewUtils",
       "android/support/transition/ViewOverlayImpl": "androidx/transition/ViewOverlayImpl",
       "android/support/transition/TransitionListenerAdapter": "androidx/transition/TransitionListenerAdapter",
@@ -3294,7 +2927,7 @@
       "android/support/transition/TransitionPropagation": "androidx/transition/TransitionPropagation",
       "android/support/transition/TranslationAnimationCreator": "androidx/transition/TranslationAnimationCreator",
       "android/support/transition/FragmentTransitionSupport": "androidx/transition/FragmentTransitionSupport",
-      "android/support/transition/TransitionManager": "androidx/transition/TransitionManager",
+      "android/support/v4/app/FragmentTransitionImpl": "androidx/fragment/app/FragmentTransitionImpl",
       "android/support/transition/GhostViewApi14": "androidx/transition/GhostViewApi14",
       "android/support/transition/GhostViewApi21": "androidx/transition/GhostViewApi21",
       "android/support/transition/ImageViewUtilsImpl": "androidx/transition/ImageViewUtilsImpl",
@@ -3330,75 +2963,138 @@
       "android/support/transition/ViewUtilsApi14": "androidx/transition/ViewUtilsApi14",
       "android/support/transition/WindowIdApi14": "androidx/transition/WindowIdApi14",
       "android/support/transition/WindowIdApi18": "androidx/transition/WindowIdApi18",
-      "android/support/v14/preference/EditTextPreferenceDialogFragment": "androidx/preference/EditTextPreferenceDialogFragment",
-      "android/support/v14/preference/PreferenceDialogFragment": "androidx/preference/PreferenceDialogFragment",
-      "android/support/v7/preference/EditTextPreference": "androidx/preference/EditTextPreference",
-      "android/support/v14/preference/ListPreferenceDialogFragment": "androidx/preference/ListPreferenceDialogFragment",
-      "android/support/v7/preference/internal/AbstractMultiSelectListPreference": "androidx/preference/internal/AbstractMultiSelectListPreference",
-      "android/support/v7/preference/R": "androidx/preference/R",
-      "android/support/v14/preference/MultiSelectListPreferenceDialogFragment": "androidx/preference/MultiSelectListPreferenceDialogFragment",
-      "android/support/v7/preference/PreferenceGroup": "androidx/preference/PreferenceGroup",
-      "android/support/v7/preference/PreferenceViewHolder": "androidx/preference/PreferenceViewHolder",
-      "android/support/v7/preference/PreferenceManager": "androidx/preference/PreferenceManager",
-      "android/support/v7/preference/PreferenceGroupAdapter": "androidx/preference/PreferenceGroupAdapter",
-      "android/support/v14/preference/SwitchPreference": "androidx/preference/SwitchPreference",
-      "android/support/v7/preference/TwoStatePreference": "androidx/preference/TwoStatePreference",
-      "android/support/v7/internal/widget/PreferenceImageView": "androidx/preference/internal/PreferenceImageView",
-      "android/support/v7/preference/AndroidResources": "androidx/preference/AndroidResources",
-      "android/support/v7/preference/CheckBoxPreference": "androidx/preference/CheckBoxPreference",
-      "android/support/v7/preference/CollapsiblePreferenceGroupController": "androidx/preference/CollapsiblePreferenceGroupController",
-      "android/support/v7/preference/DropDownPreference": "androidx/preference/DropDownPreference",
-      "android/support/v7/preference/EditTextPreferenceDialogFragmentCompat": "androidx/preference/EditTextPreferenceDialogFragmentCompat",
-      "android/support/v7/preference/PreferenceDialogFragmentCompat": "androidx/preference/PreferenceDialogFragmentCompat",
-      "android/support/v7/preference/ListPreferenceDialogFragmentCompat": "androidx/preference/ListPreferenceDialogFragmentCompat",
-      "android/support/v7/preference/MultiSelectListPreferenceDialogFragmentCompat": "androidx/preference/MultiSelectListPreferenceDialogFragmentCompat",
-      "android/support/v7/preference/PreferenceDataStore": "androidx/preference/PreferenceDataStore",
-      "android/support/v7/preference/PreferenceCategory": "androidx/preference/PreferenceCategory",
-      "android/support/v7/preference/PreferenceFragmentCompat": "androidx/preference/PreferenceFragmentCompat",
-      "android/support/v7/preference/PreferenceInflater": "androidx/preference/PreferenceInflater",
-      "android/support/v7/preference/SeekBarPreference": "androidx/preference/SeekBarPreference",
-      "android/support/v7/preference/SwitchPreferenceCompat": "androidx/preference/SwitchPreferenceCompat",
-      "android/support/v7/preference/UnPressableLinearLayout": "androidx/preference/UnPressableLinearLayout",
-      "android/support/v7/view/menu/SubMenuBuilder": "androidx/appcompat/view/menu/SubMenuBuilder",
-      "android/support/v7/widget/LinearLayoutCompat": "androidx/appcompat/widget/LinearLayoutCompat",
-      "android/support/v4/view/PagerTabStrip": "androidx/viewpager/widget/PagerTabStrip",
-      "android/support/v4/view/PagerTitleStrip": "androidx/viewpager/widget/PagerTitleStrip",
-      "android/support/v7/recyclerview/extensions/AsyncListDiffer": "androidx/recyclerview/widget/AsyncListDiffer",
-      "android/support/v7/recyclerview/extensions/ListAdapter": "androidx/recyclerview/widget/ListAdapter",
-      "android/support/v7/util/AsyncListUtil": "androidx/recyclerview/widget/AsyncListUtil",
-      "android/support/v7/util/ThreadUtil": "androidx/recyclerview/widget/ThreadUtil",
-      "android/support/v7/util/TileList": "androidx/recyclerview/widget/TileList",
-      "android/support/v7/util/MessageThreadUtil": "androidx/recyclerview/widget/MessageThreadUtil",
-      "android/support/v7/util/BatchingListUpdateCallback": "androidx/recyclerview/widget/BatchingListUpdateCallback",
-      "android/support/v7/util/SortedList": "androidx/recyclerview/widget/SortedList",
-      "android/support/v7/widget/AdapterHelper": "androidx/recyclerview/widget/AdapterHelper",
-      "android/support/v7/widget/OpReorderer": "androidx/recyclerview/widget/OpReorderer",
-      "android/support/v7/widget/ChildHelper": "androidx/recyclerview/widget/ChildHelper",
-      "android/support/v7/widget/DefaultItemAnimator": "androidx/recyclerview/widget/DefaultItemAnimator",
-      "android/support/v7/widget/DividerItemDecoration": "androidx/recyclerview/widget/DividerItemDecoration",
-      "android/support/v7/widget/FastScroller": "androidx/recyclerview/widget/FastScroller",
-      "android/support/v7/widget/GapWorker": "androidx/recyclerview/widget/GapWorker",
-      "android/support/v7/widget/GridLayoutManager": "androidx/recyclerview/widget/GridLayoutManager",
-      "android/support/v7/widget/LayoutState": "androidx/recyclerview/widget/LayoutState",
-      "android/support/v7/widget/helper/ItemTouchHelper": "androidx/recyclerview/widget/ItemTouchHelper",
-      "android/support/v7/widget/ScrollbarHelper": "androidx/recyclerview/widget/ScrollbarHelper",
-      "android/support/v7/widget/ViewBoundsCheck": "androidx/recyclerview/widget/ViewBoundsCheck",
-      "android/support/v7/widget/LinearSnapHelper": "androidx/recyclerview/widget/LinearSnapHelper",
-      "android/support/v7/widget/SnapHelper": "androidx/recyclerview/widget/SnapHelper",
-      "android/support/v7/widget/PagerSnapHelper": "androidx/recyclerview/widget/PagerSnapHelper",
-      "android/support/v7/widget/PositionMap": "androidx/recyclerview/widget/PositionMap",
-      "android/support/v7/widget/ViewInfoStore": "androidx/recyclerview/widget/ViewInfoStore",
-      "android/support/v7/recyclerview/R": "androidx/recyclerview/R",
-      "android/support/v7/widget/StaggeredGridLayoutManager": "androidx/recyclerview/widget/StaggeredGridLayoutManager",
-      "android/support/v7/widget/helper/ItemTouchUIUtilImpl": "androidx/recyclerview/widget/ItemTouchUIUtilImpl",
-      "android/support/v7/widget/helper/ItemTouchUIUtil": "androidx/recyclerview/widget/ItemTouchUIUtil",
-      "android/support/v7/widget/util/SortedListAdapterCallback": "androidx/recyclerview/widget/SortedListAdapterCallback",
-      "android/support/v4/util/MapCollections": "androidx/collection/MapCollections",
-      "android/support/v4/util/ContainerHelpers": "androidx/collection/ContainerHelpers",
-      "android/support/content/ContentPager": "androidx/contentpager/content/ContentPager",
-      "android/support/content/Query": "androidx/contentpager/content/Query",
-      "android/support/content/InMemoryCursor": "androidx/contentpager/content/InMemoryCursor",
-      "android/support/content/LoaderQueryRunner": "androidx/contentpager/content/LoaderQueryRunner",
+      "android/support/wear/ambient/AmbientDelegate": "androidx/wear/ambient/AmbientDelegate",
+      "android/support/wear/ambient/WearableControllerProvider": "androidx/wear/ambient/WearableControllerProvider",
+      "android/support/wear/ambient/AmbientMode": "androidx/wear/ambient/AmbientMode",
+      "android/support/wear/ambient/AmbientModeSupport": "androidx/wear/ambient/AmbientModeSupport",
+      "android/support/wear/ambient/SharedLibraryVersion": "androidx/wear/ambient/SharedLibraryVersion",
+      "android/support/wear/internal/widget/ResourcesUtil": "androidx/wear/internal/widget/ResourcesUtil",
+      "android/support/annotation/FractionRes": "androidx/annotation/FractionRes",
+      "android/support/wear/internal/widget/drawer/MultiPagePresenter": "androidx/wear/internal/widget/drawer/MultiPagePresenter",
+      "android/support/wear/widget/drawer/WearableNavigationDrawerView": "androidx/wear/widget/drawer/WearableNavigationDrawerView",
+      "android/support/wear/internal/widget/drawer/WearableNavigationDrawerPresenter": "androidx/wear/internal/widget/drawer/WearableNavigationDrawerPresenter",
+      "android/support/wear/widget/drawer/WearableDrawerController": "androidx/wear/widget/drawer/WearableDrawerController",
+      "android/support/wear/internal/widget/drawer/MultiPageUi": "androidx/wear/internal/widget/drawer/MultiPageUi",
+      "android/support/wear/R": "androidx/wear/R",
+      "android/support/wear/widget/drawer/PageIndicatorView": "androidx/wear/widget/drawer/PageIndicatorView",
+      "android/support/wear/internal/widget/drawer/SinglePagePresenter": "androidx/wear/internal/widget/drawer/SinglePagePresenter",
+      "android/support/wear/internal/widget/drawer/SinglePageUi": "androidx/wear/internal/widget/drawer/SinglePageUi",
+      "android/support/wear/widget/CircledImageView": "androidx/wear/widget/CircledImageView",
+      "android/support/wear/utils/MetadataConstants": "androidx/wear/utils/MetadataConstants",
+      "android/support/wear/widget/BezierSCurveInterpolator": "androidx/wear/widget/BezierSCurveInterpolator",
+      "android/support/wear/widget/BoxInsetLayout": "androidx/wear/widget/BoxInsetLayout",
+      "android/support/wear/widget/ProgressDrawable": "androidx/wear/widget/ProgressDrawable",
+      "android/support/wear/widget/CircularProgressLayout": "androidx/wear/widget/CircularProgressLayout",
+      "android/support/v4/widget/CircularProgressDrawable": "androidx/swiperefreshlayout/widget/CircularProgressDrawable",
+      "android/support/wear/widget/CircularProgressLayoutController": "androidx/wear/widget/CircularProgressLayoutController",
+      "android/support/wear/widget/CurvingLayoutCallback": "androidx/wear/widget/CurvingLayoutCallback",
+      "android/support/wear/widget/WearableLinearLayoutManager": "androidx/wear/widget/WearableLinearLayoutManager",
+      "android/support/wear/widget/RoundedDrawable": "androidx/wear/widget/RoundedDrawable",
+      "android/support/wear/widget/ScrollManager": "androidx/wear/widget/ScrollManager",
+      "android/support/wear/widget/SimpleAnimatorListener": "androidx/wear/widget/SimpleAnimatorListener",
+      "android/support/wear/widget/SwipeDismissFrameLayout": "androidx/wear/widget/SwipeDismissFrameLayout",
+      "android/support/wear/widget/SwipeDismissLayout": "androidx/wear/widget/SwipeDismissLayout",
+      "android/support/wear/widget/WearableRecyclerView": "androidx/wear/widget/WearableRecyclerView",
+      "android/support/wear/widget/drawer/AbsListViewFlingWatcher": "androidx/wear/widget/drawer/AbsListViewFlingWatcher",
+      "android/support/wear/widget/drawer/FlingWatcherFactory": "androidx/wear/widget/drawer/FlingWatcherFactory",
+      "android/support/wear/widget/drawer/RecyclerViewFlingWatcher": "androidx/wear/widget/drawer/RecyclerViewFlingWatcher",
+      "android/support/wear/widget/drawer/ScrollViewFlingWatcher": "androidx/wear/widget/drawer/ScrollViewFlingWatcher",
+      "android/support/v4/widget/NestedScrollView": "androidx/core/widget/NestedScrollView",
+      "android/support/wear/widget/drawer/NestedScrollViewFlingWatcher": "androidx/wear/widget/drawer/NestedScrollViewFlingWatcher",
+      "android/support/wear/widget/drawer/WearableActionDrawerMenu": "androidx/wear/widget/drawer/WearableActionDrawerMenu",
+      "android/support/wear/widget/drawer/WearableActionDrawerView": "androidx/wear/widget/drawer/WearableActionDrawerView",
+      "android/support/wear/widget/drawer/WearableDrawerView": "androidx/wear/widget/drawer/WearableDrawerView",
+      "android/support/wear/widget/drawer/WearableDrawerLayout": "androidx/wear/widget/drawer/WearableDrawerLayout",
+      "android/support/v4/view/NestedScrollingParent": "androidx/core/view/NestedScrollingParent",
+      "android/support/v4/view/NestedScrollingParentHelper": "androidx/core/view/NestedScrollingParentHelper",
+      "android/arch/lifecycle/ComputableLiveData": "androidx/lifecycle/ComputableLiveData",
+      "android/arch/core/executor/ArchTaskExecutor": "androidx/arch/core/executor/ArchTaskExecutor",
+      "android/arch/lifecycle/MediatorLiveData": "androidx/lifecycle/MediatorLiveData",
+      "android/arch/lifecycle/MutableLiveData": "androidx/lifecycle/MutableLiveData",
+      "android/arch/core/internal/SafeIterableMap": "androidx/arch/core/internal/SafeIterableMap",
+      "android/arch/lifecycle/Transformations": "androidx/lifecycle/Transformations",
+      "android/arch/core/util/Function": "androidx/arch/core/util/Function",
+      "android/arch/persistence/room/guava/GuavaRoom": "androidx/room/guava/GuavaRoom",
+      "android/arch/persistence/room/RoomSQLiteQuery": "androidx/room/RoomSQLiteQuery",
+      "android/support/v4/app/LoaderManager": "androidx/loader/app/LoaderManager",
+      "android/support/v4/content/Loader": "androidx/loader/content/Loader",
+      "android/arch/lifecycle/ViewModelStoreOwner": "androidx/lifecycle/ViewModelStoreOwner",
+      "android/support/v4/app/LoaderManagerImpl": "androidx/loader/app/LoaderManagerImpl",
+      "android/arch/lifecycle/ViewModelStore": "androidx/lifecycle/ViewModelStore",
+      "android/support/v4/util/DebugUtils": "androidx/core/util/DebugUtils",
+      "android/arch/lifecycle/ViewModelProvider": "androidx/lifecycle/ViewModelProvider",
+      "android/arch/lifecycle/ViewModel": "androidx/lifecycle/ViewModel",
+      "android/support/v4/content/AsyncTaskLoader": "androidx/loader/content/AsyncTaskLoader",
+      "android/support/v4/content/ModernAsyncTask": "androidx/loader/content/ModernAsyncTask",
+      "android/support/v4/os/OperationCanceledException": "androidx/core/os/OperationCanceledException",
+      "android/support/v4/content/CursorLoader": "androidx/loader/content/CursorLoader",
+      "android/support/v4/os/CancellationSignal": "androidx/core/os/CancellationSignal",
+      "android/support/v4/content/ContentResolverCompat": "androidx/core/content/ContentResolverCompat",
+      "android/support/v4/widget/DrawerLayout": "androidx/drawerlayout/widget/DrawerLayout",
+      "android/databinding/adapters/AbsListViewBindingAdapter": "androidx/databinding/adapters/AbsListViewBindingAdapter",
+      "android/databinding/adapters/AbsSeekBarBindingAdapter": "androidx/databinding/adapters/AbsSeekBarBindingAdapter",
+      "android/databinding/adapters/AbsSpinnerBindingAdapter": "androidx/databinding/adapters/AbsSpinnerBindingAdapter",
+      "android/databinding/adapters/ObservableListAdapter": "androidx/databinding/adapters/ObservableListAdapter",
+      "android/databinding/adapters/ActionMenuViewBindingAdapter": "androidx/databinding/adapters/ActionMenuViewBindingAdapter",
+      "android/databinding/adapters/AdapterViewBindingAdapter": "androidx/databinding/adapters/AdapterViewBindingAdapter",
+      "android/databinding/adapters/AutoCompleteTextViewBindingAdapter": "androidx/databinding/adapters/AutoCompleteTextViewBindingAdapter",
+      "android/databinding/adapters/CalendarViewBindingAdapter": "androidx/databinding/adapters/CalendarViewBindingAdapter",
+      "android/databinding/adapters/CardViewBindingAdapter": "androidx/databinding/adapters/CardViewBindingAdapter",
+      "android/databinding/adapters/CheckedTextViewBindingAdapter": "androidx/databinding/adapters/CheckedTextViewBindingAdapter",
+      "android/databinding/adapters/ChronometerBindingAdapter": "androidx/databinding/adapters/ChronometerBindingAdapter",
+      "android/databinding/adapters/CompoundButtonBindingAdapter": "androidx/databinding/adapters/CompoundButtonBindingAdapter",
+      "android/databinding/adapters/Converters": "androidx/databinding/adapters/Converters",
+      "android/databinding/adapters/DatePickerBindingAdapter": "androidx/databinding/adapters/DatePickerBindingAdapter",
+      "android/databinding/adapters/ListenerUtil": "androidx/databinding/adapters/ListenerUtil",
+      "android/databinding/adapters/ExpandableListViewBindingAdapter": "androidx/databinding/adapters/ExpandableListViewBindingAdapter",
+      "android/databinding/adapters/FrameLayoutBindingAdapter": "androidx/databinding/adapters/FrameLayoutBindingAdapter",
+      "android/databinding/adapters/ImageViewBindingAdapter": "androidx/databinding/adapters/ImageViewBindingAdapter",
+      "android/databinding/adapters/LinearLayoutBindingAdapter": "androidx/databinding/adapters/LinearLayoutBindingAdapter",
+      "android/databinding/adapters/NumberPickerBindingAdapter": "androidx/databinding/adapters/NumberPickerBindingAdapter",
+      "android/databinding/adapters/ProgressBarBindingAdapter": "androidx/databinding/adapters/ProgressBarBindingAdapter",
+      "android/databinding/adapters/RadioGroupBindingAdapter": "androidx/databinding/adapters/RadioGroupBindingAdapter",
+      "android/databinding/adapters/RatingBarBindingAdapter": "androidx/databinding/adapters/RatingBarBindingAdapter",
+      "android/databinding/adapters/SearchViewBindingAdapter": "androidx/databinding/adapters/SearchViewBindingAdapter",
+      "android/databinding/adapters/SeekBarBindingAdapter": "androidx/databinding/adapters/SeekBarBindingAdapter",
+      "android/databinding/adapters/SpinnerBindingAdapter": "androidx/databinding/adapters/SpinnerBindingAdapter",
+      "android/databinding/adapters/SwitchBindingAdapter": "androidx/databinding/adapters/SwitchBindingAdapter",
+      "android/databinding/adapters/SwitchCompatBindingAdapter": "androidx/databinding/adapters/SwitchCompatBindingAdapter",
+      "android/support/v7/widget/SwitchCompat": "androidx/appcompat/widget/SwitchCompat",
+      "android/databinding/adapters/TabHostBindingAdapter": "androidx/databinding/adapters/TabHostBindingAdapter",
+      "android/databinding/adapters/TabWidgetBindingAdapter": "androidx/databinding/adapters/TabWidgetBindingAdapter",
+      "android/databinding/adapters/TableLayoutBindingAdapter": "androidx/databinding/adapters/TableLayoutBindingAdapter",
+      "android/databinding/adapters/TextViewBindingAdapter": "androidx/databinding/adapters/TextViewBindingAdapter",
+      "android/databinding/adapters/TimePickerBindingAdapter": "androidx/databinding/adapters/TimePickerBindingAdapter",
+      "android/databinding/adapters/ToolbarBindingAdapter": "androidx/databinding/adapters/ToolbarBindingAdapter",
+      "android/databinding/adapters/VideoViewBindingAdapter": "androidx/databinding/adapters/VideoViewBindingAdapter",
+      "android/databinding/adapters/ViewBindingAdapter": "androidx/databinding/adapters/ViewBindingAdapter",
+      "android/databinding/adapters/ViewGroupBindingAdapter": "androidx/databinding/adapters/ViewGroupBindingAdapter",
+      "android/databinding/adapters/ViewStubBindingAdapter": "androidx/databinding/adapters/ViewStubBindingAdapter",
+      "android/databinding/adapters/ZoomControlsBindingAdapter": "androidx/databinding/adapters/ZoomControlsBindingAdapter",
+      "android/support/media/ExifInterface": "androidx/exifinterface/media/ExifInterface",
+      "android/arch/lifecycle/ErrorMessages": "androidx/lifecycle/ErrorMessages",
+      "android/arch/lifecycle/model/EventMethod": "androidx/lifecycle/model/EventMethod",
+      "android/arch/lifecycle/Elements_extKt": "androidx/lifecycle/Elements_extKt",
+      "android/arch/lifecycle/WriterKt": "androidx/lifecycle/WriterKt",
+      "android/arch/lifecycle/ObserversCollector": "androidx/lifecycle/ObserversCollector",
+      "android/arch/lifecycle/Validator": "androidx/lifecycle/Validator",
+      "android/arch/lifecycle/model/LifecycleObserverInfo": "androidx/lifecycle/model/LifecycleObserverInfo",
+      "android/arch/lifecycle/model/AdapterClassKt": "androidx/lifecycle/model/AdapterClassKt",
+      "android/arch/lifecycle/model/EventMethodCall": "androidx/lifecycle/model/EventMethodCall",
+      "android/arch/lifecycle/model/AdapterClass": "androidx/lifecycle/model/AdapterClass",
+      "android/arch/lifecycle/model/InputModel": "androidx/lifecycle/model/InputModel",
+      "android/arch/lifecycle/Lifecycling": "androidx/lifecycle/Lifecycling",
+      "android/arch/lifecycle/LifecycleProcessor": "androidx/lifecycle/LifecycleProcessor",
+      "android/arch/lifecycle/Input_collectorKt": "androidx/lifecycle/Input_collectorKt",
+      "android/arch/lifecycle/TransformationKt": "androidx/lifecycle/TransformationKt",
+      "android/arch/lifecycle/GeneratedAdapter": "androidx/lifecycle/GeneratedAdapter",
+      "android/arch/lifecycle/MethodCallsLogger": "androidx/lifecycle/MethodCallsLogger",
+      "android/support/design/bottomnavigation/LabelVisibilityMode": "android/support/design/bottomnavigation/LabelVisibilityMode",
+      "android/arch/lifecycle/LifecycleRegistry": "androidx/lifecycle/LifecycleRegistry",
+      "android/arch/lifecycle/GenericLifecycleObserver": "androidx/lifecycle/GenericLifecycleObserver",
+      "android/arch/core/internal/FastSafeIterableMap": "androidx/arch/core/internal/FastSafeIterableMap",
+      "android/arch/lifecycle/LifecycleRegistryOwner": "androidx/lifecycle/LifecycleRegistryOwner",
+      "android/arch/lifecycle/ReportFragment": "androidx/lifecycle/ReportFragment",
       "android/arch/persistence/room/parser/SQLiteParser": "androidx/room/parser/SQLiteParser",
       "android/arch/persistence/room/parser/SQLiteListener": "androidx/room/parser/SQLiteListener",
       "android/arch/persistence/room/parser/SQLiteVisitor": "androidx/room/parser/SQLiteVisitor",
@@ -3532,6 +3228,7 @@
       "android/arch/persistence/room/vo/InsertionMethod": "androidx/room/vo/InsertionMethod",
       "android/arch/persistence/room/vo/DaoMethod": "androidx/room/vo/DaoMethod",
       "android/arch/persistence/room/ext/SupportDbTypeNames": "androidx/room/ext/SupportDbTypeNames",
+      "android/arch/persistence/room/RoomMasterTable": "androidx/room/RoomMasterTable",
       "android/arch/persistence/room/RoomProcessor": "androidx/room/RoomProcessor",
       "android/arch/persistence/room/writer/EntityInsertionAdapterWriter": "androidx/room/writer/EntityInsertionAdapterWriter",
       "android/arch/persistence/room/writer/TableInfoValidationWriter": "androidx/room/writer/TableInfoValidationWriter",
@@ -3550,6 +3247,7 @@
       "android/arch/persistence/room/Dao": "androidx/room/Dao",
       "android/arch/persistence/room/processor/CustomConverterProcessor": "androidx/room/processor/CustomConverterProcessor",
       "android/arch/persistence/room/processor/cache/Cache": "androidx/room/processor/cache/Cache",
+      "android/arch/persistence/room/ColumnInfo": "androidx/room/ColumnInfo",
       "android/arch/persistence/room/Embedded": "androidx/room/Embedded",
       "android/arch/persistence/room/Relation": "androidx/room/Relation",
       "android/arch/persistence/room/Ignore": "androidx/room/Ignore",
@@ -3575,12 +3273,237 @@
       "android/arch/persistence/room/TypeConverter": "androidx/room/TypeConverter",
       "android/arch/persistence/room/TypeConverters": "androidx/room/TypeConverters",
       "android/arch/persistence/room/PrimaryKey": "androidx/room/PrimaryKey",
+      "android/support/design/resources/TextAppearance": "android/support/design/resources/TextAppearance",
+      "android/support/design/resources/R": "android/support/design/resources/R",
+      "android/support/annotation/FontRes": "androidx/annotation/FontRes",
+      "android/support/v13/view/DragAndDropPermissionsCompat": "androidx/core/view/DragAndDropPermissionsCompat",
+      "android/support/v13/view/DragStartHelper": "androidx/core/view/DragStartHelper",
+      "android/support/v13/view/inputmethod/EditorInfoCompat": "androidx/core/view/inputmethod/EditorInfoCompat",
+      "android/support/v13/view/inputmethod/InputConnectionCompat": "androidx/core/view/inputmethod/InputConnectionCompat",
+      "android/support/v13/view/inputmethod/InputContentInfoCompat": "androidx/core/view/inputmethod/InputContentInfoCompat",
+      "android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat": "androidx/core/accessibilityservice/AccessibilityServiceInfoCompat",
+      "android/support/v4/app/ActivityOptionsCompat": "androidx/core/app/ActivityOptionsCompat",
+      "android/support/v4/app/AlarmManagerCompat": "androidx/core/app/AlarmManagerCompat",
+      "android/support/v4/app/AppLaunchChecker": "androidx/core/app/AppLaunchChecker",
+      "android/support/v4/app/AppOpsManagerCompat": "androidx/core/app/AppOpsManagerCompat",
+      "android/support/v4/app/FrameMetricsAggregator": "androidx/core/app/FrameMetricsAggregator",
+      "android/support/v4/app/INotificationSideChannel": "androidx/core/app/INotificationSideChannel",
+      "android/support/v4/app/JobIntentService": "androidx/core/app/JobIntentService",
+      "android/support/v4/app/NavUtils": "androidx/core/app/NavUtils",
+      "android/support/v4/app/RemoteInput": "androidx/core/app/RemoteInput",
+      "android/support/v4/app/NotificationCompatBuilder": "androidx/core/app/NotificationCompatBuilder",
+      "android/support/compat/R": "androidx/core/R",
+      "android/support/v4/text/BidiFormatter": "androidx/core/text/BidiFormatter",
+      "android/support/v4/app/NotificationCompatJellybean": "androidx/core/app/NotificationCompatJellybean",
+      "android/support/v4/app/NotificationCompatExtras": "androidx/core/app/NotificationCompatExtras",
+      "android/support/v4/app/NotificationCompatSideChannelService": "androidx/core/app/NotificationCompatSideChannelService",
+      "android/support/v4/app/NotificationManagerCompat": "androidx/core/app/NotificationManagerCompat",
+      "android/support/annotation/GuardedBy": "androidx/annotation/GuardedBy",
+      "android/support/v4/app/ServiceCompat": "androidx/core/app/ServiceCompat",
+      "android/support/v4/app/ShareCompat": "androidx/core/app/ShareCompat",
+      "android/support/v4/app/TaskStackBuilder": "androidx/core/app/TaskStackBuilder",
+      "android/support/v4/content/FileProvider": "androidx/core/content/FileProvider",
+      "android/support/v4/content/IntentCompat": "androidx/core/content/IntentCompat",
+      "android/support/v4/content/MimeTypeFilter": "androidx/core/content/MimeTypeFilter",
+      "android/support/v4/content/PermissionChecker": "androidx/core/content/PermissionChecker",
+      "android/support/v4/content/SharedPreferencesCompat": "androidx/core/content/SharedPreferencesCompat",
+      "android/support/v4/content/pm/ActivityInfoCompat": "androidx/core/content/pm/ActivityInfoCompat",
+      "android/support/v4/content/pm/ShortcutInfoCompat": "androidx/core/content/pm/ShortcutInfoCompat",
+      "android/support/v4/graphics/drawable/IconCompat": "androidx/core/graphics/drawable/IconCompat",
+      "android/support/v4/content/pm/ShortcutManagerCompat": "androidx/core/content/pm/ShortcutManagerCompat",
+      "android/support/v4/content/res/ConfigurationHelper": "androidx/core/content/res/ConfigurationHelper",
+      "android/support/v4/content/res/FontResourcesParserCompat": "androidx/core/content/res/FontResourcesParserCompat",
+      "android/support/v4/provider/FontRequest": "androidx/core/provider/FontRequest",
+      "android/support/annotation/ArrayRes": "androidx/annotation/ArrayRes",
+      "android/support/v4/provider/FontsContractCompat": "androidx/core/provider/FontsContractCompat",
+      "android/support/v4/graphics/TypefaceCompat": "androidx/core/graphics/TypefaceCompat",
+      "android/support/annotation/AnyRes": "androidx/annotation/AnyRes",
+      "android/support/v4/database/DatabaseUtilsCompat": "androidx/core/database/DatabaseUtilsCompat",
+      "android/support/v4/graphics/BitmapCompat": "androidx/core/graphics/BitmapCompat",
+      "android/support/v4/graphics/PaintCompat": "androidx/core/graphics/PaintCompat",
+      "android/support/v4/graphics/TypefaceCompatApi28Impl": "androidx/core/graphics/TypefaceCompatApi28Impl",
+      "android/support/v4/graphics/TypefaceCompatApi26Impl": "androidx/core/graphics/TypefaceCompatApi26Impl",
+      "android/support/v4/graphics/TypefaceCompatApi24Impl": "androidx/core/graphics/TypefaceCompatApi24Impl",
+      "android/support/v4/graphics/TypefaceCompatApi21Impl": "androidx/core/graphics/TypefaceCompatApi21Impl",
+      "android/support/v4/graphics/TypefaceCompatBaseImpl": "androidx/core/graphics/TypefaceCompatBaseImpl",
+      "android/support/v4/graphics/TypefaceCompatUtil": "androidx/core/graphics/TypefaceCompatUtil",
+      "android/support/v4/graphics/drawable/WrappedDrawable": "androidx/core/graphics/drawable/WrappedDrawable",
+      "android/support/v4/graphics/drawable/WrappedDrawableApi21": "androidx/core/graphics/drawable/WrappedDrawableApi21",
+      "android/support/v4/graphics/drawable/WrappedDrawableApi19": "androidx/core/graphics/drawable/WrappedDrawableApi19",
+      "android/support/v4/graphics/drawable/WrappedDrawableApi14": "androidx/core/graphics/drawable/WrappedDrawableApi14",
+      "android/support/v4/graphics/drawable/RoundedBitmapDrawable": "androidx/core/graphics/drawable/RoundedBitmapDrawable",
+      "android/support/v4/graphics/drawable/RoundedBitmapDrawable21": "androidx/core/graphics/drawable/RoundedBitmapDrawable21",
+      "android/support/v4/graphics/drawable/RoundedBitmapDrawableFactory": "androidx/core/graphics/drawable/RoundedBitmapDrawableFactory",
+      "android/support/v4/hardware/fingerprint/FingerprintManagerCompat": "androidx/core/hardware/fingerprint/FingerprintManagerCompat",
+      "android/support/annotation/RequiresPermission": "androidx/annotation/RequiresPermission",
+      "android/support/v4/internal/view/SupportMenu": "androidx/core/internal/view/SupportMenu",
+      "android/support/v4/internal/view/SupportMenuItem": "androidx/core/internal/view/SupportMenuItem",
+      "android/support/v4/internal/view/SupportSubMenu": "androidx/core/internal/view/SupportSubMenu",
+      "android/support/v4/math/MathUtils": "androidx/core/math/MathUtils",
+      "android/support/v4/net/ConnectivityManagerCompat": "androidx/core/net/ConnectivityManagerCompat",
+      "android/support/v4/net/DatagramSocketWrapper": "androidx/core/net/DatagramSocketWrapper",
+      "android/support/v4/net/TrafficStatsCompat": "androidx/core/net/TrafficStatsCompat",
+      "android/support/v4/os/ConfigurationCompat": "androidx/core/os/ConfigurationCompat",
+      "android/support/v4/os/EnvironmentCompat": "androidx/core/os/EnvironmentCompat",
+      "android/support/v4/os/IResultReceiver": "androidx/core/os/IResultReceiver",
+      "android/support/v4/os/LocaleHelper": "androidx/core/os/LocaleHelper",
+      "android/support/v4/os/LocaleListInterface": "androidx/core/os/LocaleListInterface",
+      "android/support/v4/os/LocaleListHelper": "androidx/core/os/LocaleListHelper",
+      "android/support/annotation/Size": "androidx/annotation/Size",
+      "android/support/v4/os/ParcelableCompat": "androidx/core/os/ParcelableCompat",
+      "android/support/v4/os/ParcelableCompatCreatorCallbacks": "androidx/core/os/ParcelableCompatCreatorCallbacks",
+      "android/support/v4/os/UserManagerCompat": "androidx/core/os/UserManagerCompat",
+      "android/support/v4/provider/SelfDestructiveThread": "androidx/core/provider/SelfDestructiveThread",
+      "android/support/v4/text/TextUtilsCompat": "androidx/core/text/TextUtilsCompat",
+      "android/support/v4/text/ICUCompat": "androidx/core/text/ICUCompat",
+      "android/support/v4/text/util/FindAddress": "androidx/core/text/util/FindAddress",
+      "android/support/v4/text/util/LinkifyCompat": "androidx/core/text/util/LinkifyCompat",
+      "android/support/v4/util/PatternsCompat": "androidx/core/util/PatternsCompat",
+      "android/support/v4/util/AtomicFile": "androidx/core/util/AtomicFile",
+      "android/support/v4/util/LogWriter": "androidx/core/util/LogWriter",
+      "android/support/v4/view/InputDeviceCompat": "androidx/core/view/InputDeviceCompat",
+      "android/support/v4/view/LayoutInflaterCompat": "androidx/core/view/LayoutInflaterCompat",
+      "android/support/v4/view/LayoutInflaterFactory": "androidx/core/view/LayoutInflaterFactory",
+      "android/support/v4/view/MenuCompat": "androidx/core/view/MenuCompat",
+      "android/support/v4/view/MenuItemCompat": "androidx/core/view/MenuItemCompat",
+      "android/support/v4/view/NestedScrollingChild": "androidx/core/view/NestedScrollingChild",
+      "android/support/v4/view/NestedScrollingParent2": "androidx/core/view/NestedScrollingParent2",
+      "android/support/v4/view/ScaleGestureDetectorCompat": "androidx/core/view/ScaleGestureDetectorCompat",
+      "android/support/v4/view/VelocityTrackerCompat": "androidx/core/view/VelocityTrackerCompat",
+      "android/support/v4/view/ViewPropertyAnimatorCompat": "androidx/core/view/ViewPropertyAnimatorCompat",
+      "android/support/v4/view/ViewGroupCompat": "androidx/core/view/ViewGroupCompat",
+      "android/support/v4/view/ViewPropertyAnimatorListener": "androidx/core/view/ViewPropertyAnimatorListener",
+      "android/support/v4/view/ViewPropertyAnimatorUpdateListener": "androidx/core/view/ViewPropertyAnimatorUpdateListener",
+      "android/support/v4/view/ViewPropertyAnimatorListenerAdapter": "androidx/core/view/ViewPropertyAnimatorListenerAdapter",
+      "android/support/v4/view/WindowCompat": "androidx/core/view/WindowCompat",
+      "android/support/v4/view/accessibility/AccessibilityManagerCompat": "androidx/core/view/accessibility/AccessibilityManagerCompat",
+      "android/support/v4/view/accessibility/AccessibilityWindowInfoCompat": "androidx/core/view/accessibility/AccessibilityWindowInfoCompat",
+      "android/support/v4/view/animation/PathInterpolatorApi14": "androidx/core/view/animation/PathInterpolatorApi14",
+      "android/support/v4/view/animation/PathInterpolatorCompat": "androidx/core/view/animation/PathInterpolatorCompat",
+      "android/support/v4/widget/AutoScrollHelper": "androidx/core/widget/AutoScrollHelper",
+      "android/support/v4/widget/AutoSizeableTextView": "androidx/core/widget/AutoSizeableTextView",
+      "android/support/v4/widget/CompoundButtonCompat": "androidx/core/widget/CompoundButtonCompat",
+      "android/support/v4/widget/TintableCompoundButton": "androidx/core/widget/TintableCompoundButton",
+      "android/support/v4/widget/ContentLoadingProgressBar": "androidx/core/widget/ContentLoadingProgressBar",
+      "android/support/v4/widget/ImageViewCompat": "androidx/core/widget/ImageViewCompat",
+      "android/support/v4/widget/ListPopupWindowCompat": "androidx/core/widget/ListPopupWindowCompat",
+      "android/support/v4/widget/ListViewAutoScrollHelper": "androidx/core/widget/ListViewAutoScrollHelper",
+      "android/support/v4/widget/ListViewCompat": "androidx/core/widget/ListViewCompat",
+      "android/support/v4/widget/PopupMenuCompat": "androidx/core/widget/PopupMenuCompat",
+      "android/support/v4/widget/PopupWindowCompat": "androidx/core/widget/PopupWindowCompat",
+      "android/support/v4/widget/ScrollerCompat": "androidx/core/widget/ScrollerCompat",
       "android/support/coordinatorlayout/R": "androidx/coordinatorlayout/R",
       "android/support/v4/widget/DirectedAcyclicGraph": "androidx/coordinatorlayout/widget/DirectedAcyclicGraph",
       "android/support/v4/widget/ViewGroupUtils": "androidx/coordinatorlayout/widget/ViewGroupUtils",
-      "android/support/v4/widget/FocusStrategy": "androidx/customview/widget/FocusStrategy",
-      "android/support/v7/widget/GridLayout": "androidx/gridlayout/widget/GridLayout",
-      "android/support/v7/gridlayout/R": "androidx/gridlayout/R",
+      "android/arch/lifecycle/EmptyActivityLifecycleCallbacks": "androidx/lifecycle/EmptyActivityLifecycleCallbacks",
+      "android/arch/lifecycle/HolderFragment": "androidx/lifecycle/HolderFragment",
+      "android/arch/lifecycle/LifecycleDispatcher": "androidx/lifecycle/LifecycleDispatcher",
+      "android/arch/lifecycle/LifecycleService": "androidx/lifecycle/LifecycleService",
+      "android/arch/lifecycle/ServiceLifecycleDispatcher": "androidx/lifecycle/ServiceLifecycleDispatcher",
+      "android/arch/lifecycle/ProcessLifecycleOwner": "androidx/lifecycle/ProcessLifecycleOwner",
+      "android/arch/lifecycle/ProcessLifecycleOwnerInitializer": "androidx/lifecycle/ProcessLifecycleOwnerInitializer",
+      "android/arch/lifecycle/ViewModelProviders": "androidx/lifecycle/ViewModelProviders",
+      "android/arch/lifecycle/ViewModelStores": "androidx/lifecycle/ViewModelStores",
+      "android/support/animation/AnimationHandler": "androidx/dynamicanimation/animation/AnimationHandler",
+      "android/support/animation/DynamicAnimation": "androidx/dynamicanimation/animation/DynamicAnimation",
+      "android/support/animation/FloatPropertyCompat": "androidx/dynamicanimation/animation/FloatPropertyCompat",
+      "android/support/animation/FloatValueHolder": "androidx/dynamicanimation/animation/FloatValueHolder",
+      "android/support/animation/FlingAnimation": "androidx/dynamicanimation/animation/FlingAnimation",
+      "android/support/animation/Force": "androidx/dynamicanimation/animation/Force",
+      "android/support/animation/SpringAnimation": "androidx/dynamicanimation/animation/SpringAnimation",
+      "android/support/animation/SpringForce": "androidx/dynamicanimation/animation/SpringForce",
+      "android/support/design/transformation/ExpandableBehavior": "android/support/design/transformation/ExpandableBehavior",
+      "android/support/design/transformation/ExpandableTransformationBehavior": "android/support/design/transformation/ExpandableTransformationBehavior",
+      "android/support/design/transformation/FabTransformationBehavior": "android/support/design/transformation/FabTransformationBehavior",
+      "android/support/design/transformation/R": "android/support/design/transformation/R",
+      "android/support/design/transformation/TransformationChildLayout": "android/support/design/transformation/TransformationChildLayout",
+      "android/support/design/transformation/TransformationChildCard": "android/support/design/transformation/TransformationChildCard",
+      "android/support/design/transformation/FabTransformationScrimBehavior": "android/support/design/transformation/FabTransformationScrimBehavior",
+      "android/support/design/transformation/FabTransformationSheetBehavior": "android/support/design/transformation/FabTransformationSheetBehavior",
+      "android/support/design/circularreveal/cardview/CircularRevealCardView": "android/support/design/circularreveal/cardview/CircularRevealCardView",
+      "android/support/content/ContentPager": "androidx/contentpager/content/ContentPager",
+      "android/support/content/Query": "androidx/contentpager/content/Query",
+      "android/support/content/InMemoryCursor": "androidx/contentpager/content/InMemoryCursor",
+      "android/support/content/LoaderQueryRunner": "androidx/contentpager/content/LoaderQueryRunner",
+      "android/support/v4/widget/CursorAdapter": "androidx/cursoradapter/widget/CursorAdapter",
+      "android/support/v4/widget/CursorFilter": "androidx/cursoradapter/widget/CursorFilter",
+      "android/support/v4/widget/ResourceCursorAdapter": "androidx/cursoradapter/widget/ResourceCursorAdapter",
+      "android/support/v4/widget/SimpleCursorAdapter": "androidx/cursoradapter/widget/SimpleCursorAdapter",
+      "android/support/v4/app/ActionBarDrawerToggle": "androidx/legacy/app/ActionBarDrawerToggle",
+      "android/arch/lifecycle/ClassesInfoCache": "androidx/lifecycle/ClassesInfoCache",
+      "android/arch/lifecycle/FullLifecycleObserver": "androidx/lifecycle/FullLifecycleObserver",
+      "android/arch/lifecycle/FullLifecycleObserverAdapter": "androidx/lifecycle/FullLifecycleObserverAdapter",
+      "android/arch/lifecycle/SingleGeneratedAdapterObserver": "androidx/lifecycle/SingleGeneratedAdapterObserver",
+      "android/arch/lifecycle/CompositeGeneratedAdaptersObserver": "androidx/lifecycle/CompositeGeneratedAdaptersObserver",
+      "android/arch/lifecycle/ReflectiveGenericLifecycleObserver": "androidx/lifecycle/ReflectiveGenericLifecycleObserver",
+      "android/support/v4/util/MapCollections": "androidx/collection/MapCollections",
+      "android/support/v4/util/ContainerHelpers": "androidx/collection/ContainerHelpers",
+      "android/support/design/theme/MaterialComponentsViewInflater": "android/support/design/theme/MaterialComponentsViewInflater",
+      "android/support/v7/app/AppCompatViewInflater": "androidx/appcompat/app/AppCompatViewInflater",
+      "android/support/annotation/Keep": "androidx/annotation/Keep",
+      "android/arch/paging/PageResult": "androidx/paging/PageResult",
+      "android/arch/paging/ListDataSource": "androidx/paging/ListDataSource",
+      "android/arch/paging/PositionalDataSource": "androidx/paging/PositionalDataSource",
+      "android/arch/paging/WrapperItemKeyedDataSource": "androidx/paging/WrapperItemKeyedDataSource",
+      "android/arch/paging/DataSource": "androidx/paging/DataSource",
+      "android/arch/paging/PageKeyedDataSource": "androidx/paging/PageKeyedDataSource",
+      "android/arch/paging/ContiguousDataSource": "androidx/paging/ContiguousDataSource",
+      "android/arch/paging/WrapperPageKeyedDataSource": "androidx/paging/WrapperPageKeyedDataSource",
+      "android/arch/paging/ItemKeyedDataSource": "androidx/paging/ItemKeyedDataSource",
+      "android/arch/paging/TiledPagedList": "androidx/paging/TiledPagedList",
+      "android/arch/paging/PagedList": "androidx/paging/PagedList",
+      "android/arch/paging/PagedStorage": "androidx/paging/PagedStorage",
+      "android/support/annotation/AnyThread": "androidx/annotation/AnyThread",
+      "android/arch/paging/TiledDataSource": "androidx/paging/TiledDataSource",
+      "android/arch/paging/WrapperPositionalDataSource": "androidx/paging/WrapperPositionalDataSource",
+      "android/arch/paging/ContiguousPagedList": "androidx/paging/ContiguousPagedList",
+      "android/arch/paging/SnapshotPagedList": "androidx/paging/SnapshotPagedList",
+      "android/support/design/shape/CornerTreatment": "android/support/design/shape/CornerTreatment",
+      "android/support/design/shape/ShapePath": "android/support/design/shape/ShapePath",
+      "android/support/design/shape/CutCornerTreatment": "android/support/design/shape/CutCornerTreatment",
+      "android/support/design/shape/EdgeTreatment": "android/support/design/shape/EdgeTreatment",
+      "android/support/design/shape/InterpolateOnScrollPositionChangeHelper": "android/support/design/shape/InterpolateOnScrollPositionChangeHelper",
+      "android/support/design/shape/MaterialShapeDrawable": "android/support/design/shape/MaterialShapeDrawable",
+      "android/support/design/shape/ShapePathModel": "android/support/design/shape/ShapePathModel",
+      "android/support/design/shape/RoundedCornerTreatment": "android/support/design/shape/RoundedCornerTreatment",
+      "android/support/design/shape/TriangleEdgeTreatment": "android/support/design/shape/TriangleEdgeTreatment",
+      "android/support/design/bottomappbar/BottomAppBar": "android/support/design/bottomappbar/BottomAppBar",
+      "android/support/design/bottomappbar/BottomAppBarTopEdgeTreatment": "android/support/design/bottomappbar/BottomAppBarTopEdgeTreatment",
+      "android/support/v7/widget/ActionMenuView": "androidx/appcompat/widget/ActionMenuView",
+      "android/support/design/bottomappbar/R": "android/support/design/bottomappbar/R",
+      "android/support/annotation/MenuRes": "androidx/annotation/MenuRes",
+      "android/arch/persistence/room/testing/MigrationTestHelper": "androidx/room/testing/MigrationTestHelper",
+      "android/arch/persistence/db/SupportSQLiteDatabase": "androidx/sqlite/db/SupportSQLiteDatabase",
+      "android/arch/persistence/room/util/TableInfo": "androidx/room/util/TableInfo",
+      "android/arch/persistence/room/RoomOpenHelper": "androidx/room/RoomOpenHelper",
+      "android/arch/persistence/db/SupportSQLiteOpenHelper": "androidx/sqlite/db/SupportSQLiteOpenHelper",
+      "android/arch/persistence/room/RoomDatabase": "androidx/room/RoomDatabase",
+      "android/arch/persistence/db/framework/FrameworkSQLiteOpenHelperFactory": "androidx/sqlite/db/framework/FrameworkSQLiteOpenHelperFactory",
+      "android/arch/persistence/room/DatabaseConfiguration": "androidx/room/DatabaseConfiguration",
+      "android/arch/persistence/room/migration/Migration": "androidx/room/migration/Migration",
+      "android/support/v7/graphics/ColorCutQuantizer": "androidx/palette/graphics/ColorCutQuantizer",
+      "android/support/v7/graphics/Target": "androidx/palette/graphics/Target",
+      "android/arch/persistence/room/EmptyResultSetException": "androidx/room/EmptyResultSetException",
+      "android/arch/persistence/room/RxRoom": "androidx/room/RxRoom",
+      "android/arch/persistence/room/InvalidationTracker": "androidx/room/InvalidationTracker",
+      "android/support/v4/view/AsyncLayoutInflater": "androidx/asynclayoutinflater/view/AsyncLayoutInflater",
+      "android/arch/persistence/room/ForeignKey": "androidx/room/ForeignKey",
+      "android/arch/persistence/room/RoomWarnings": "androidx/room/RoomWarnings",
+      "android/arch/persistence/room/Index": "androidx/room/Index",
+      "android/arch/persistence/room/OnConflictStrategy": "androidx/room/OnConflictStrategy",
+      "android/arch/lifecycle/AndroidViewModel": "androidx/lifecycle/AndroidViewModel",
+      "android/support/v4/widget/CircleImageView": "androidx/swiperefreshlayout/widget/CircleImageView",
+      "android/support/v4/widget/SwipeRefreshLayout": "androidx/swiperefreshlayout/widget/SwipeRefreshLayout",
+      "android/support/v4/view/PagerTabStrip": "androidx/viewpager/widget/PagerTabStrip",
+      "android/support/v4/view/PagerTitleStrip": "androidx/viewpager/widget/PagerTitleStrip",
+      "android/support/design/chip/Chip": "android/support/design/chip/Chip",
+      "android/support/design/chip/ChipDrawable": "android/support/design/chip/ChipDrawable",
+      "android/support/design/chip/R": "android/support/design/chip/R",
+      "android/support/v7/widget/AppCompatCheckBox": "androidx/appcompat/widget/AppCompatCheckBox",
+      "android/support/annotation/XmlRes": "androidx/annotation/XmlRes",
+      "android/support/design/canvas/CanvasCompat": "android/support/design/canvas/CanvasCompat",
+      "android/support/design/drawable/DrawableUtils": "android/support/design/drawable/DrawableUtils",
+      "android/support/design/chip/ChipGroup": "android/support/design/chip/ChipGroup",
       "android/support/media/tv/BasePreviewProgram": "androidx/tvprovider/media/tv/BasePreviewProgram",
       "android/support/media/tv/BaseProgram": "androidx/tvprovider/media/tv/BaseProgram",
       "android/support/media/tv/TvContractCompat": "androidx/tvprovider/media/tv/TvContractCompat",
@@ -3593,13 +3516,6 @@
       "android/support/media/tv/PreviewProgram": "androidx/tvprovider/media/tv/PreviewProgram",
       "android/support/media/tv/WatchNextProgram": "androidx/tvprovider/media/tv/WatchNextProgram",
       "android/support/media/tv/Program": "androidx/tvprovider/media/tv/Program",
-      "android/support/v13/app/ActivityCompat": "androidx/legacy/app/ActivityCompat",
-      "android/support/v13/app/FragmentCompat": "androidx/legacy/app/FragmentCompat",
-      "android/support/v13/app/FragmentPagerAdapter": "androidx/legacy/app/FragmentPagerAdapter",
-      "android/support/v13/app/FragmentStatePagerAdapter": "androidx/legacy/app/FragmentStatePagerAdapter",
-      "android/support/v13/app/FragmentTabHost": "androidx/legacy/app/FragmentTabHost",
-      "android/support/v13/view/ViewCompat": "androidx/legacy/view/ViewCompat",
-      "android/support/v4/content/WakefulBroadcastReceiver": "androidx/legacy/content/WakefulBroadcastReceiver",
       "android/support/v7/view/ActionMode": "androidx/appcompat/view/ActionMode",
       "android/support/v7/app/ActionBarDrawerToggle": "androidx/appcompat/app/ActionBarDrawerToggle",
       "android/support/v7/graphics/drawable/DrawerArrowDrawable": "androidx/appcompat/graphics/drawable/DrawerArrowDrawable",
@@ -3631,6 +3547,7 @@
       "android/support/v7/view/StandaloneActionMode": "androidx/appcompat/view/StandaloneActionMode",
       "android/support/v7/widget/TintContextWrapper": "androidx/appcompat/widget/TintContextWrapper",
       "android/support/v7/widget/AppCompatImageView": "androidx/appcompat/widget/AppCompatImageView",
+      "android/support/v7/widget/AppCompatButton": "androidx/appcompat/widget/AppCompatButton",
       "android/support/v7/widget/AppCompatSpinner": "androidx/appcompat/widget/AppCompatSpinner",
       "android/support/v7/widget/AppCompatRadioButton": "androidx/appcompat/widget/AppCompatRadioButton",
       "android/support/v7/widget/AppCompatCheckedTextView": "androidx/appcompat/widget/AppCompatCheckedTextView",
@@ -3686,6 +3603,7 @@
       "android/support/v7/widget/AppCompatHintHelper": "androidx/appcompat/widget/AppCompatHintHelper",
       "android/support/v7/widget/TintInfo": "androidx/appcompat/widget/TintInfo",
       "android/support/v7/widget/AppCompatCompoundButtonHelper": "androidx/appcompat/widget/AppCompatCompoundButtonHelper",
+      "android/support/graphics/drawable/AnimatedVectorDrawableCompat": "androidx/vectordrawable/graphics/drawable/AnimatedVectorDrawableCompat",
       "android/support/v7/widget/ThemeUtils": "androidx/appcompat/widget/ThemeUtils",
       "android/support/v7/widget/WithHint": "androidx/appcompat/widget/WithHint",
       "android/support/v7/widget/AppCompatPopupWindow": "androidx/appcompat/widget/AppCompatPopupWindow",
@@ -3708,23 +3626,115 @@
       "android/support/v7/widget/TintResources": "androidx/appcompat/widget/TintResources",
       "android/support/v7/widget/TooltipCompatHandler": "androidx/appcompat/widget/TooltipCompatHandler",
       "android/support/v7/widget/TooltipPopup": "androidx/appcompat/widget/TooltipPopup",
+      "android/support/percent/PercentFrameLayout": "androidx/percentlayout/widget/PercentFrameLayout",
+      "android/support/percent/PercentLayoutHelper": "androidx/percentlayout/widget/PercentLayoutHelper",
+      "android/support/percent/R": "androidx/percentlayout/R",
+      "android/support/percent/PercentRelativeLayout": "androidx/percentlayout/widget/PercentRelativeLayout",
+      "android/support/v14/preference/EditTextPreferenceDialogFragment": "androidx/preference/EditTextPreferenceDialogFragment",
+      "android/support/v14/preference/PreferenceDialogFragment": "androidx/preference/PreferenceDialogFragment",
+      "android/support/v7/preference/EditTextPreference": "androidx/preference/EditTextPreference",
+      "android/support/v14/preference/ListPreferenceDialogFragment": "androidx/preference/ListPreferenceDialogFragment",
+      "android/support/v7/preference/internal/AbstractMultiSelectListPreference": "androidx/preference/internal/AbstractMultiSelectListPreference",
+      "android/support/v7/preference/R": "androidx/preference/R",
+      "android/support/v14/preference/MultiSelectListPreferenceDialogFragment": "androidx/preference/MultiSelectListPreferenceDialogFragment",
+      "android/support/v7/preference/PreferenceGroup": "androidx/preference/PreferenceGroup",
+      "android/support/v7/preference/PreferenceViewHolder": "androidx/preference/PreferenceViewHolder",
+      "android/support/v7/preference/PreferenceManager": "androidx/preference/PreferenceManager",
+      "android/support/v7/preference/PreferenceGroupAdapter": "androidx/preference/PreferenceGroupAdapter",
+      "android/support/v14/preference/SwitchPreference": "androidx/preference/SwitchPreference",
+      "android/support/v7/preference/TwoStatePreference": "androidx/preference/TwoStatePreference",
+      "android/support/v7/internal/widget/PreferenceImageView": "androidx/preference/internal/PreferenceImageView",
+      "android/support/v7/preference/AndroidResources": "androidx/preference/AndroidResources",
+      "android/support/v7/preference/CheckBoxPreference": "androidx/preference/CheckBoxPreference",
+      "android/support/v7/preference/CollapsiblePreferenceGroupController": "androidx/preference/CollapsiblePreferenceGroupController",
+      "android/support/v7/preference/DropDownPreference": "androidx/preference/DropDownPreference",
+      "android/support/v7/preference/EditTextPreferenceDialogFragmentCompat": "androidx/preference/EditTextPreferenceDialogFragmentCompat",
+      "android/support/v7/preference/PreferenceDialogFragmentCompat": "androidx/preference/PreferenceDialogFragmentCompat",
+      "android/support/v7/preference/ListPreferenceDialogFragmentCompat": "androidx/preference/ListPreferenceDialogFragmentCompat",
+      "android/support/v7/preference/MultiSelectListPreferenceDialogFragmentCompat": "androidx/preference/MultiSelectListPreferenceDialogFragmentCompat",
+      "android/support/v7/preference/PreferenceDataStore": "androidx/preference/PreferenceDataStore",
+      "android/support/v7/preference/PreferenceCategory": "androidx/preference/PreferenceCategory",
+      "android/support/v7/preference/PreferenceFragmentCompat": "androidx/preference/PreferenceFragmentCompat",
+      "android/support/v7/preference/PreferenceInflater": "androidx/preference/PreferenceInflater",
+      "android/support/v7/preference/SeekBarPreference": "androidx/preference/SeekBarPreference",
+      "android/support/v7/preference/SwitchPreferenceCompat": "androidx/preference/SwitchPreferenceCompat",
+      "android/support/v7/preference/UnPressableLinearLayout": "androidx/preference/UnPressableLinearLayout",
+      "android/support/v4/app/BackStackRecord": "androidx/fragment/app/BackStackRecord",
+      "android/support/v4/app/FragmentManagerImpl": "androidx/fragment/app/FragmentManagerImpl",
+      "android/support/v4/app/FragmentHostCallback": "androidx/fragment/app/FragmentHostCallback",
+      "android/support/v4/app/FragmentTransition": "androidx/fragment/app/FragmentTransition",
+      "android/support/v4/app/BackStackState": "androidx/fragment/app/BackStackState",
+      "android/support/v4/app/BaseFragmentActivityApi14": "androidx/fragment/app/BaseFragmentActivityApi14",
+      "android/support/v4/app/BaseFragmentActivityApi16": "androidx/fragment/app/BaseFragmentActivityApi16",
+      "android/support/v4/app/FragmentContainer": "androidx/fragment/app/FragmentContainer",
+      "android/support/v4/app/FragmentManagerNonConfig": "androidx/fragment/app/FragmentManagerNonConfig",
+      "android/support/v4/app/SuperNotCalledException": "androidx/fragment/app/SuperNotCalledException",
+      "android/support/v4/app/FragmentController": "androidx/fragment/app/FragmentController",
+      "android/support/v4/app/FragmentState": "androidx/fragment/app/FragmentState",
+      "android/support/v4/app/FragmentManagerState": "androidx/fragment/app/FragmentManagerState",
+      "android/support/v4/app/FragmentPagerAdapter": "androidx/fragment/app/FragmentPagerAdapter",
+      "android/support/v4/app/FragmentStatePagerAdapter": "androidx/fragment/app/FragmentStatePagerAdapter",
+      "android/support/v4/app/FragmentTabHost": "androidx/fragment/app/FragmentTabHost",
+      "android/support/annotation/AnimRes": "androidx/annotation/AnimRes",
+      "android/support/v4/app/OneShotPreDrawListener": "androidx/fragment/app/OneShotPreDrawListener",
+      "android/support/v4/app/FragmentTransitionCompat21": "androidx/fragment/app/FragmentTransitionCompat21",
+      "android/support/v4/app/ListFragment": "androidx/fragment/app/ListFragment",
       "android/arch/core/executor/JunitTaskExecutorRule": "androidx/arch/core/executor/JunitTaskExecutorRule",
       "android/arch/core/executor/TaskExecutorWithFakeMainThread": "androidx/arch/core/executor/TaskExecutorWithFakeMainThread",
       "android/arch/core/executor/TaskExecutor": "androidx/arch/core/executor/TaskExecutor",
       "android/arch/core/executor/testing/CountingTaskExecutorRule": "androidx/arch/core/executor/testing/CountingTaskExecutorRule",
       "android/arch/core/executor/DefaultTaskExecutor": "androidx/arch/core/executor/DefaultTaskExecutor",
       "android/arch/core/executor/testing/InstantTaskExecutorRule": "androidx/arch/core/executor/testing/InstantTaskExecutorRule",
-      "android/support/text/emoji/widget/EmojiAppCompatButton": "androidx/emoji/widget/EmojiAppCompatButton",
-      "android/support/text/emoji/widget/EmojiAppCompatEditText": "androidx/emoji/widget/EmojiAppCompatEditText",
-      "android/support/text/emoji/widget/EmojiAppCompatTextView": "androidx/emoji/widget/EmojiAppCompatTextView",
-      "android/support/design/card/MaterialCardView": "android/support/design/card/MaterialCardView",
-      "android/support/design/card/R": "android/support/design/card/R",
-      "android/support/design/card/MaterialCardViewHelper": "android/support/design/card/MaterialCardViewHelper",
-      "android/arch/lifecycle/ClassesInfoCache": "androidx/lifecycle/ClassesInfoCache",
-      "android/arch/lifecycle/FullLifecycleObserverAdapter": "androidx/lifecycle/FullLifecycleObserverAdapter",
-      "android/arch/lifecycle/SingleGeneratedAdapterObserver": "androidx/lifecycle/SingleGeneratedAdapterObserver",
-      "android/arch/lifecycle/CompositeGeneratedAdaptersObserver": "androidx/lifecycle/CompositeGeneratedAdaptersObserver",
-      "android/arch/lifecycle/ReflectiveGenericLifecycleObserver": "androidx/lifecycle/ReflectiveGenericLifecycleObserver",
+      "android/support/multidex/MultiDex": "androidx/multidex/MultiDex",
+      "android/arch/paging/AsyncPagedListDiffer": "androidx/paging/AsyncPagedListDiffer",
+      "android/arch/paging/PagedStorageDiffHelper": "androidx/paging/PagedStorageDiffHelper",
+      "android/arch/paging/LivePagedListBuilder": "androidx/paging/LivePagedListBuilder",
+      "android/arch/paging/LivePagedListProvider": "androidx/paging/LivePagedListProvider",
+      "android/arch/paging/PagedListAdapter": "androidx/paging/PagedListAdapter",
+      "android/arch/lifecycle/LiveDataReactiveStreams": "androidx/lifecycle/LiveDataReactiveStreams",
+      "android/support/design/circularreveal/coordinatorlayout/CircularRevealCoordinatorLayout": "android/support/design/circularreveal/coordinatorlayout/CircularRevealCoordinatorLayout",
+      "android/support/multidex/ZipUtil": "androidx/multidex/ZipUtil",
+      "android/support/multidex/MultiDexExtractor": "androidx/multidex/MultiDexExtractor",
+      "android/support/multidex/MultiDexApplication": "androidx/multidex/MultiDexApplication",
+      "android/arch/persistence/room/EntityDeletionOrUpdateAdapter": "androidx/room/EntityDeletionOrUpdateAdapter",
+      "android/arch/persistence/room/SharedSQLiteStatement": "androidx/room/SharedSQLiteStatement",
+      "android/arch/persistence/db/SupportSQLiteStatement": "androidx/sqlite/db/SupportSQLiteStatement",
+      "android/arch/persistence/room/EntityInsertionAdapter": "androidx/room/EntityInsertionAdapter",
+      "android/arch/persistence/room/Room": "androidx/room/Room",
+      "android/arch/persistence/db/SimpleSQLiteQuery": "androidx/sqlite/db/SimpleSQLiteQuery",
+      "android/arch/persistence/db/SupportSQLiteQuery": "androidx/sqlite/db/SupportSQLiteQuery",
+      "android/arch/persistence/db/SupportSQLiteProgram": "androidx/sqlite/db/SupportSQLiteProgram",
+      "android/arch/persistence/room/paging/LimitOffsetDataSource": "androidx/room/paging/LimitOffsetDataSource",
+      "android/arch/persistence/room/util/StringUtil": "androidx/room/util/StringUtil",
+      "android/arch/lifecycle/DefaultLifecycleObserver": "androidx/lifecycle/DefaultLifecycleObserver",
+      "android/support/design/button/MaterialButton": "android/support/design/button/MaterialButton",
+      "android/support/design/button/R": "android/support/design/button/R",
+      "android/support/design/button/MaterialButtonHelper": "android/support/design/button/MaterialButtonHelper",
+      "android/support/design/button/MaterialButtonBackgroundDrawable": "android/support/design/button/MaterialButtonBackgroundDrawable",
+      "android/support/text/emoji/EmojiProcessor": "androidx/emoji/text/EmojiProcessor",
+      "android/support/text/emoji/EmojiMetadata": "androidx/emoji/text/EmojiMetadata",
+      "android/support/text/emoji/EmojiSpan": "androidx/emoji/text/EmojiSpan",
+      "android/support/text/emoji/TypefaceEmojiSpan": "androidx/emoji/text/TypefaceEmojiSpan",
+      "android/support/annotation/CheckResult": "androidx/annotation/CheckResult",
+      "android/support/text/emoji/widget/SpannableBuilder": "androidx/emoji/widget/SpannableBuilder",
+      "android/support/text/emoji/FontRequestEmojiCompatConfig": "androidx/emoji/text/FontRequestEmojiCompatConfig",
+      "android/support/text/emoji/MetadataListReader": "androidx/emoji/text/MetadataListReader",
+      "android/support/text/emoji/widget/EditTextAttributeHelper": "androidx/emoji/widget/EditTextAttributeHelper",
+      "android/support/text/emoji/R": "androidx/emoji/R",
+      "android/support/text/emoji/widget/EmojiButton": "androidx/emoji/widget/EmojiButton",
+      "android/support/text/emoji/widget/EmojiTextViewHelper": "androidx/emoji/widget/EmojiTextViewHelper",
+      "android/support/text/emoji/widget/EmojiEditText": "androidx/emoji/widget/EmojiEditText",
+      "android/support/text/emoji/widget/EmojiEditTextHelper": "androidx/emoji/widget/EmojiEditTextHelper",
+      "android/support/text/emoji/widget/EmojiTextWatcher": "androidx/emoji/widget/EmojiTextWatcher",
+      "android/support/text/emoji/widget/EmojiEditableFactory": "androidx/emoji/widget/EmojiEditableFactory",
+      "android/support/text/emoji/widget/EmojiKeyListener": "androidx/emoji/widget/EmojiKeyListener",
+      "android/support/text/emoji/widget/EmojiInputConnection": "androidx/emoji/widget/EmojiInputConnection",
+      "android/support/text/emoji/widget/EmojiExtractEditText": "androidx/emoji/widget/EmojiExtractEditText",
+      "android/support/text/emoji/widget/EmojiExtractTextLayout": "androidx/emoji/widget/EmojiExtractTextLayout",
+      "android/support/text/emoji/widget/ExtractButtonCompat": "androidx/emoji/widget/ExtractButtonCompat",
+      "android/support/text/emoji/widget/EmojiInputFilter": "androidx/emoji/widget/EmojiInputFilter",
+      "android/support/text/emoji/widget/EmojiTextView": "androidx/emoji/widget/EmojiTextView",
+      "android/support/text/emoji/widget/EmojiTransformationMethod": "androidx/emoji/widget/EmojiTransformationMethod",
       "android/support/customtabs/CustomTabsCallback": "androidx/browser/customtabs/CustomTabsCallback",
       "android/support/customtabs/CustomTabsClient": "androidx/browser/customtabs/CustomTabsClient",
       "android/support/customtabs/CustomTabsServiceConnection": "androidx/browser/customtabs/CustomTabsServiceConnection",
@@ -3739,34 +3749,38 @@
       "android/support/customtabs/PostMessageServiceConnection": "androidx/browser/customtabs/PostMessageServiceConnection",
       "android/support/customtabs/TrustedWebUtils": "androidx/browser/customtabs/TrustedWebUtils",
       "android/support/customtabs/R": "androidx/browser/R",
-      "android/arch/lifecycle/AndroidViewModel": "androidx/lifecycle/AndroidViewModel",
-      "android/support/design/circularreveal/coordinatorlayout/CircularRevealCoordinatorLayout": "android/support/design/circularreveal/coordinatorlayout/CircularRevealCoordinatorLayout",
-      "android/support/percent/PercentFrameLayout": "androidx/percentlayout/widget/PercentFrameLayout",
-      "android/support/percent/PercentLayoutHelper": "androidx/percentlayout/widget/PercentLayoutHelper",
-      "android/support/percent/R": "androidx/percentlayout/R",
-      "android/support/percent/PercentRelativeLayout": "androidx/percentlayout/widget/PercentRelativeLayout",
+      "android/arch/persistence/db/framework/FrameworkSQLiteDatabase": "androidx/sqlite/db/framework/FrameworkSQLiteDatabase",
+      "android/arch/persistence/db/framework/FrameworkSQLiteProgram": "androidx/sqlite/db/framework/FrameworkSQLiteProgram",
+      "android/arch/persistence/db/framework/FrameworkSQLiteStatement": "androidx/sqlite/db/framework/FrameworkSQLiteStatement",
+      "android/arch/persistence/db/framework/FrameworkSQLiteOpenHelper": "androidx/sqlite/db/framework/FrameworkSQLiteOpenHelper",
+      "android/support/v7/widget/GridLayout": "androidx/gridlayout/widget/GridLayout",
+      "android/support/v7/gridlayout/R": "androidx/gridlayout/R",
       "android/arch/persistence/db/SupportSQLiteQueryBuilder": "androidx/sqlite/db/SupportSQLiteQueryBuilder",
-      "android/support/design/animation/R": "android/support/design/animation/R",
-      "android/arch/paging/PageResult": "androidx/paging/PageResult",
-      "android/arch/paging/ListDataSource": "androidx/paging/ListDataSource",
-      "android/arch/paging/WrapperItemKeyedDataSource": "androidx/paging/WrapperItemKeyedDataSource",
-      "android/arch/paging/PageKeyedDataSource": "androidx/paging/PageKeyedDataSource",
-      "android/arch/paging/ContiguousDataSource": "androidx/paging/ContiguousDataSource",
-      "android/arch/paging/WrapperPageKeyedDataSource": "androidx/paging/WrapperPageKeyedDataSource",
-      "android/arch/paging/ItemKeyedDataSource": "androidx/paging/ItemKeyedDataSource",
-      "android/arch/paging/TiledPagedList": "androidx/paging/TiledPagedList",
-      "android/arch/paging/TiledDataSource": "androidx/paging/TiledDataSource",
-      "android/arch/paging/WrapperPositionalDataSource": "androidx/paging/WrapperPositionalDataSource",
-      "android/arch/paging/ContiguousPagedList": "androidx/paging/ContiguousPagedList",
-      "android/arch/paging/SnapshotPagedList": "androidx/paging/SnapshotPagedList",
-      "android/support/v4/view/AsyncLayoutInflater": "androidx/asynclayoutinflater/view/AsyncLayoutInflater",
-      "android/arch/persistence/room/ForeignKey": "androidx/room/ForeignKey",
-      "android/arch/persistence/room/RoomWarnings": "androidx/room/RoomWarnings",
-      "android/arch/persistence/room/Index": "androidx/room/Index",
-      "android/arch/persistence/room/OnConflictStrategy": "androidx/room/OnConflictStrategy",
-      "android/support/design/circularreveal/CircularRevealGridLayout": "android/support/design/circularreveal/CircularRevealGridLayout",
-      "android/support/design/circularreveal/CircularRevealLinearLayout": "android/support/design/circularreveal/CircularRevealLinearLayout",
-      "android/support/design/circularreveal/CircularRevealRelativeLayout": "android/support/design/circularreveal/CircularRevealRelativeLayout"
+      "android/support/v13/app/ActivityCompat": "androidx/legacy/app/ActivityCompat",
+      "android/support/v13/app/FragmentCompat": "androidx/legacy/app/FragmentCompat",
+      "android/support/v13/app/FragmentPagerAdapter": "androidx/legacy/app/FragmentPagerAdapter",
+      "android/support/v13/app/FragmentStatePagerAdapter": "androidx/legacy/app/FragmentStatePagerAdapter",
+      "android/support/v13/app/FragmentTabHost": "androidx/legacy/app/FragmentTabHost",
+      "android/support/v13/view/ViewCompat": "androidx/legacy/view/ViewCompat",
+      "android/support/annotation/BinderThread": "androidx/annotation/BinderThread",
+      "android/support/annotation/ColorLong": "androidx/annotation/ColorLong",
+      "android/support/annotation/HalfFloat": "androidx/annotation/HalfFloat",
+      "android/support/annotation/IntDef": "androidx/annotation/IntDef",
+      "android/support/annotation/InterpolatorRes": "androidx/annotation/InterpolatorRes",
+      "android/support/annotation/LongDef": "androidx/annotation/LongDef",
+      "android/support/annotation/NavigationRes": "androidx/annotation/NavigationRes",
+      "android/support/annotation/PluralsRes": "androidx/annotation/PluralsRes",
+      "android/support/annotation/RawRes": "androidx/annotation/RawRes",
+      "android/support/annotation/StringDef": "androidx/annotation/StringDef",
+      "android/support/annotation/TransitionRes": "androidx/annotation/TransitionRes",
+      "android/support/text/emoji/widget/EmojiAppCompatButton": "androidx/emoji/widget/EmojiAppCompatButton",
+      "android/support/text/emoji/widget/EmojiAppCompatEditText": "androidx/emoji/widget/EmojiAppCompatEditText",
+      "android/support/text/emoji/widget/EmojiAppCompatTextView": "androidx/emoji/widget/EmojiAppCompatTextView",
+      "android/support/graphics/drawable/Animatable2Compat": "androidx/vectordrawable/graphics/drawable/Animatable2Compat",
+      "android/support/graphics/drawable/AnimatorInflaterCompat": "androidx/vectordrawable/graphics/drawable/AnimatorInflaterCompat",
+      "android/support/graphics/drawable/AnimationUtilsCompat": "androidx/vectordrawable/graphics/drawable/AnimationUtilsCompat",
+      "android/support/graphics/drawable/PathInterpolatorCompat": "androidx/vectordrawable/graphics/drawable/PathInterpolatorCompat",
+      "android/support/graphics/drawable/ArgbEvaluator": "androidx/vectordrawable/graphics/drawable/ArgbEvaluator"
     }
   },
   "proGuardMap": {
diff --git a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/CoreRemapperImpl.kt b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/CoreRemapperImpl.kt
index aa769dd..37a22da 100644
--- a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/CoreRemapperImpl.kt
+++ b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/CoreRemapperImpl.kt
@@ -68,11 +68,11 @@
             return value
         }
 
-        val result = context.config.typesMap.mapType(type)
-        if (result != null) {
-            changesDone = changesDone || result != type
-            Log.i(TAG, "Map string: '%s' -> '%s'", type, result)
-            return result.toDotNotation()
+        val mappedType = context.config.typesMap.mapType(type)
+        if (mappedType != null) {
+            changesDone = changesDone || mappedType != type
+            Log.i(TAG, "Map string: '%s' -> '%s'", type, mappedType)
+            return mappedType.toDotNotation()
         }
 
         // We might be working with an internal type or field reference, e.g.
@@ -88,10 +88,10 @@
 
         // Try rewrite rules
         if (context.useFallbackIfTypeIsMissing) {
-            val result = context.config.rulesMap.rewriteType(type)
-            if (result != null) {
-                Log.i(TAG, "Map string: '%s' -> '%s' via fallback", value, result)
-                return result.toDotNotation()
+            val rewrittenType = context.config.rulesMap.rewriteType(type)
+            if (rewrittenType != null) {
+                Log.i(TAG, "Map string: '%s' -> '%s' via fallback", value, rewrittenType)
+                return rewrittenType.toDotNotation()
             }
         }
 
@@ -119,4 +119,4 @@
 
         return path
     }
-}
\ No newline at end of file
+}
diff --git a/leanback-preference/build.gradle b/leanback-preference/build.gradle
index a6e0d27..4f49bef 100644
--- a/leanback-preference/build.gradle
+++ b/leanback-preference/build.gradle
@@ -30,4 +30,5 @@
     inceptionYear = "2015"
     description = "Android Support Leanback Preference v17"
     minSdkVersion = 17
+    failOnDeprecationWarnings = false
 }
\ No newline at end of file
diff --git a/leanback/build.gradle b/leanback/build.gradle
index 56b7fc5..a1e468b 100644
--- a/leanback/build.gradle
+++ b/leanback/build.gradle
@@ -37,4 +37,6 @@
     inceptionYear = "2014"
     description = "Android Support Leanback v17"
     minSdkVersion = 17
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/legacy/v13/build.gradle b/legacy/v13/build.gradle
index d8ef8f7..c881632 100644
--- a/legacy/v13/build.gradle
+++ b/legacy/v13/build.gradle
@@ -16,4 +16,5 @@
     mavenGroup = LibraryGroups.LEGACY
     inceptionYear = "2011"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnDeprecationWarnings = false
 }
diff --git a/lifecycle/extensions/build.gradle b/lifecycle/extensions/build.gradle
index a2be25d..14a974c 100644
--- a/lifecycle/extensions/build.gradle
+++ b/lifecycle/extensions/build.gradle
@@ -55,4 +55,5 @@
     inceptionYear = "2017"
     description = "Android Lifecycle Extensions"
     url = SupportLibraryExtension.ARCHITECTURE_URL
+    failOnDeprecationWarnings = false
 }
diff --git a/lifecycle/livedata-core/build.gradle b/lifecycle/livedata-core/build.gradle
index 76f6c83..e9e1cfd 100644
--- a/lifecycle/livedata-core/build.gradle
+++ b/lifecycle/livedata-core/build.gradle
@@ -42,4 +42,5 @@
     inceptionYear = "2017"
     description = "Android Lifecycle LiveData Core"
     url = SupportLibraryExtension.ARCHITECTURE_URL
+    failOnUncheckedWarnings = false
 }
diff --git a/lifecycle/runtime/build.gradle b/lifecycle/runtime/build.gradle
index baa2b32..40b250c 100644
--- a/lifecycle/runtime/build.gradle
+++ b/lifecycle/runtime/build.gradle
@@ -34,4 +34,5 @@
     inceptionYear '2017'
     description "Android Lifecycle Runtime"
     url SupportLibraryExtension.ARCHITECTURE_URL
+    failOnDeprecationWarnings = false
 }
\ No newline at end of file
diff --git a/lifecycle/viewmodel/build.gradle b/lifecycle/viewmodel/build.gradle
index 1494733..cc71b39 100644
--- a/lifecycle/viewmodel/build.gradle
+++ b/lifecycle/viewmodel/build.gradle
@@ -44,4 +44,5 @@
     inceptionYear = "2017"
     description = "Android Lifecycle ViewModel"
     url = SupportLibraryExtension.ARCHITECTURE_URL
+    failOnUncheckedWarnings = false
 }
\ No newline at end of file
diff --git a/loader/build.gradle b/loader/build.gradle
index 8c99ea5..9a34ff2 100644
--- a/loader/build.gradle
+++ b/loader/build.gradle
@@ -25,4 +25,5 @@
     mavenGroup = LibraryGroups.LOADER
     inceptionYear = "2011"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnUncheckedWarnings = false
 }
diff --git a/media-widget/api/current.txt b/media-widget/api/current.txt
new file mode 100644
index 0000000..d531c3f
--- /dev/null
+++ b/media-widget/api/current.txt
@@ -0,0 +1,36 @@
+package androidx.media.widget {
+
+  public class MediaControlView2 extends android.view.ViewGroup {
+    ctor public MediaControlView2(android.content.Context);
+    ctor public MediaControlView2(android.content.Context, android.util.AttributeSet);
+    ctor public MediaControlView2(android.content.Context, android.util.AttributeSet, int);
+    ctor public MediaControlView2(android.content.Context, android.util.AttributeSet, int, int);
+    method public void onMeasure(int, int);
+    method public void requestPlayButtonFocus();
+  }
+
+  public class VideoView2 extends android.view.ViewGroup {
+    ctor public VideoView2(android.content.Context);
+    ctor public VideoView2(android.content.Context, android.util.AttributeSet);
+    ctor public VideoView2(android.content.Context, android.util.AttributeSet, int);
+    ctor public VideoView2(android.content.Context, android.util.AttributeSet, int, int);
+    method public androidx.media.widget.MediaControlView2 getMediaControlView2();
+    method public float getSpeed();
+    method public int getViewType();
+    method public boolean isSubtitleEnabled();
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
+    method public void onMeasure(int, int);
+    method public void setAudioAttributes(android.media.AudioAttributes);
+    method public void setAudioFocusRequest(int);
+    method public void setMediaControlView2(androidx.media.widget.MediaControlView2, long);
+    method public void setSpeed(float);
+    method public void setSubtitleEnabled(boolean);
+    method public void setVideoUri(android.net.Uri, java.util.Map<java.lang.String, java.lang.String>);
+    method public void setViewType(int);
+    field public static final int VIEW_TYPE_SURFACEVIEW = 0; // 0x0
+    field public static final int VIEW_TYPE_TEXTUREVIEW = 1; // 0x1
+  }
+
+}
+
diff --git a/media-widget/build.gradle b/media-widget/build.gradle
index de3f9d9..e6ff65d 100644
--- a/media-widget/build.gradle
+++ b/media-widget/build.gradle
@@ -37,10 +37,13 @@
 }
 
 supportLibrary {
-    name = "Android Media Support Library"
+    name = "Android Support Media Widget"
     publish = true
     mavenVersion = LibraryVersions.SUPPORT_LIBRARY
     mavenGroup = LibraryGroups.MEDIA
     inceptionYear = "2011"
-    description = "Android Media Support Library"
+    description = "Android Support Media Widget"
+    minSdkVersion = 19
+    failOnDeprecationWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/media-widget/src/main/java/androidx/media/widget/BaseLayout.java b/media-widget/src/main/java/androidx/media/widget/BaseLayout.java
index 0b6988a..982513a 100644
--- a/media-widget/src/main/java/androidx/media/widget/BaseLayout.java
+++ b/media-widget/src/main/java/androidx/media/widget/BaseLayout.java
@@ -39,7 +39,7 @@
     }
 
     BaseLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
-        this(context, attrs, 0);
+        super(context, attrs);
     }
 
     BaseLayout(@NonNull Context context, @Nullable AttributeSet attrs,
diff --git a/media-widget/src/main/java/androidx/media/widget/MediaControlView2.java b/media-widget/src/main/java/androidx/media/widget/MediaControlView2.java
index 89fa946..ded03cd 100644
--- a/media-widget/src/main/java/androidx/media/widget/MediaControlView2.java
+++ b/media-widget/src/main/java/androidx/media/widget/MediaControlView2.java
@@ -27,6 +27,7 @@
 import android.support.v4.media.session.PlaybackStateCompat;
 import android.util.AttributeSet;
 import android.view.Gravity;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -60,41 +61,34 @@
 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.
- * It provides a wide range of UI including buttons such as "Play/Pause", "Rewind", "Fast Forward",
- * "Subtitle", "Full Screen", and it is also possible to add multiple custom buttons.
+ * A View that contains the controls for {@link android.media.MediaPlayer}.
+ * It provides a wide range of buttons that serve the following functions: play/pause,
+ * rewind/fast-forward, skip to next/previous, select subtitle track, enter/exit full screen mode,
+ * adjust video quality, select audio track, mute/unmute, and adjust playback speed.
  *
  * <p>
  * <em> MediaControlView2 can be initialized in two different ways: </em>
- * 1) When VideoView2 is initialized, it automatically initializes a MediaControlView2 instance and
- * adds it to the view.
- * 2) Initialize MediaControlView2 programmatically and add it to a ViewGroup instance.
+ * 1) When initializing {@link VideoView2} a default MediaControlView2 is created.
+ * 2) Initialize MediaControlView2 programmatically and add it to a {@link ViewGroup} instance.
  *
  * In the first option, VideoView2 automatically connects MediaControlView2 to MediaController,
- * which is necessary to communicate with MediaSession2. In the second option, however, the
- * developer needs to manually retrieve a MediaController instance and set it to MediaControlView2
- * by calling setController(MediaController controller).
+ * which is necessary to communicate with MediaSession. In the second option, however, the
+ * developer needs to manually retrieve a MediaController instance from MediaSession and set it to
+ * MediaControlView2.
  *
  * <p>
  * There is no separate method that handles the show/hide behavior for MediaControlView2. Instead,
- * one can directly change the visibility of this view by calling View.setVisibility(int). The
- * values supported are View.VISIBLE and View.GONE.
- * In addition, the following customization is supported:
- * Set focus to the play/pause button by calling requestPlayButtonFocus().
+ * one can directly change the visibility of this view by calling {@link View#setVisibility(int)}.
+ * The values supported are View.VISIBLE and View.GONE.
  *
  * <p>
- * It is also possible to add custom buttons with custom icons and actions inside MediaControlView2.
- * Those buttons will be shown when the overflow button is clicked.
- * See VideoView2#setCustomActions for more details on how to add.
+ * In addition, the following customizations are supported:
+ * 1) Set focus to the play/pause button by calling requestPlayButtonFocus().
+ * 2) Set full screen mode
+ *
  */
 @RequiresApi(21) // TODO correct minSdk API use incompatibilities and remove before release.
-@RestrictTo(LIBRARY_GROUP)
 public class MediaControlView2 extends BaseLayout {
     /**
      * @hide
@@ -185,10 +179,6 @@
 
     private static final String TAG = "MediaControlView2";
 
-    static final String ARGUMENT_KEY_FULLSCREEN = "fullScreen";
-
-    // TODO: Make these constants public api to support custom video view.
-    // TODO: Combine these constants into one regarding TrackInfo.
     static final String KEY_VIDEO_TRACK_COUNT = "VideoTrackCount";
     static final String KEY_AUDIO_TRACK_COUNT = "AudioTrackCount";
     static final String KEY_SUBTITLE_TRACK_COUNT = "SubtitleTrackCount";
@@ -196,8 +186,6 @@
     static final String KEY_SELECTED_AUDIO_INDEX = "SelectedAudioIndex";
     static final String KEY_SELECTED_SUBTITLE_INDEX = "SelectedSubtitleIndex";
     static final String EVENT_UPDATE_TRACK_STATUS = "UpdateTrackStatus";
-
-    // TODO: Remove this once integrating with MediaSession2 & MediaMetadata2
     static final String KEY_STATE_IS_ADVERTISEMENT = "MediaTypeAdvertisement";
     static final String EVENT_UPDATE_MEDIA_TYPE_STATUS = "UpdateMediaTypeStatus";
 
@@ -205,8 +193,6 @@
     static final String COMMAND_SHOW_SUBTITLE = "showSubtitle";
     // String for sending command to hide subtitle to MediaSession.
     static final String COMMAND_HIDE_SUBTITLE = "hideSubtitle";
-    // TODO: remove once the implementation is revised
-    public static final String COMMAND_SET_FULLSCREEN = "setFullscreen";
     // String for sending command to select audio track to MediaSession.
     static final String COMMAND_SELECT_AUDIO_TRACK = "SelectTrack";
     // String for sending command to set playback speed to MediaSession.
@@ -230,7 +216,6 @@
 
     private static final int SIZE_TYPE_EMBEDDED = 0;
     private static final int SIZE_TYPE_FULL = 1;
-    // TODO: add support for Minimal size type.
     private static final int SIZE_TYPE_MINIMAL = 2;
 
     private static final int MAX_PROGRESS = 1000;
@@ -246,6 +231,7 @@
     private MediaControllerCompat.TransportControls mControls;
     private PlaybackStateCompat mPlaybackState;
     private MediaMetadataCompat mMetadata;
+    private OnFullScreenRequestListener mFullScreenRequestListener;
     private int mDuration;
     private int mPrevState;
     private int mPrevWidth;
@@ -284,9 +270,6 @@
     private TextView mTitleView;
     private View mAdExternalLink;
     private ImageButton mBackButton;
-    // TODO (b/77158231) revive
-    // private MediaRouteButton mRouteButton;
-    // private MediaRouteSelector mRouteSelector;
 
     // Relating to Center View
     private ViewGroup mCenterView;
@@ -354,20 +337,18 @@
 
     public MediaControlView2(@NonNull Context context, @Nullable AttributeSet attrs,
             int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
+        super(context, attrs, defStyleAttr);
+        initialize(context);
     }
 
     public MediaControlView2(@NonNull Context context, @Nullable AttributeSet attrs,
             int defStyleAttr, int defStyleRes) {
-//        super((instance, superProvider, privateProvider) ->
-//                ApiLoader.getProvider().createMediaControlView2(
-//                        (MediaControlView2) instance, superProvider, privateProvider,
-//                        attrs, defStyleAttr, defStyleRes),
-//                context, attrs, defStyleAttr, defStyleRes);
-//        mProvider.initialize(attrs, defStyleAttr, defStyleRes);
         super(context, attrs, defStyleAttr, defStyleRes);
+        initialize(context);
+    }
 
-        mResources = getContext().getResources();
+    void initialize(Context context) {
+        mResources = context.getResources();
         // Inflate MediaControlView2 from XML
         mRoot = makeControllerView();
         addView(mRoot);
@@ -375,27 +356,33 @@
 
     /**
      * Sets MediaSession2 token to control corresponding MediaSession2.
+     * @hide
      */
+    @RestrictTo(LIBRARY_GROUP)
     public void setMediaSessionToken(SessionToken2 token) {
-        //mProvider.setMediaSessionToken_impl(token);
     }
 
     /**
      * Registers a callback to be invoked when the fullscreen mode should be changed.
      * @param l The callback that will be run
+     * @hide TODO unhide
      */
-    public void setOnFullScreenListener(OnFullScreenListener l) {
-        //mProvider.setOnFullScreenListener_impl(l);
+    @RestrictTo(LIBRARY_GROUP)
+    public void setFullScreenRequestListener(OnFullScreenRequestListener l) {
+        mFullScreenRequestListener = l;
     }
 
     /**
+     * Sets MediaController instance to MediaControlView2, which makes it possible to send and
+     * receive data between MediaControlView2 and VideoView2. This method does not need to be called
+     * when MediaControlView2 is initialized with VideoView2.
      * @hide TODO: remove once the implementation is revised
      */
     @RestrictTo(LIBRARY_GROUP)
     public void setController(MediaControllerCompat controller) {
         mController = controller;
         if (controller != null) {
-            mControls = controller.getTransportControls();
+            mControls = mController.getTransportControls();
             // Set mMetadata and mPlaybackState to existing MediaSession variables since they may
             // be called before the callback is called
             mPlaybackState = mController.getPlaybackState();
@@ -429,8 +416,6 @@
      */
     @RestrictTo(LIBRARY_GROUP)
     public void setButtonVisibility(@Button int button, /*@Visibility*/ int visibility) {
-        // TODO: add member variables for Fast-Forward/Prvious/Rewind buttons to save visibility in
-        // order to prevent being overriden inside updateLayout().
         switch (button) {
             case MediaControlView2.BUTTON_PLAY_PAUSE:
                 if (mPlayPauseButton != null && canPause()) {
@@ -499,12 +484,14 @@
     /**
      * Interface definition of a callback to be invoked to inform the fullscreen mode is changed.
      * Application should handle the fullscreen mode accordingly.
+     * @hide  TODO unhide
      */
-    public interface OnFullScreenListener {
+    @RestrictTo(LIBRARY_GROUP)
+    public interface OnFullScreenRequestListener {
         /**
          * Called to indicate a fullscreen mode change.
          */
-        void onFullScreen(View view, boolean fullScreen);
+        void onFullScreenRequest(View view, boolean fullScreen);
     }
 
     @Override
@@ -517,7 +504,6 @@
         return false;
     }
 
-    // TODO: Should this function be removed?
     @Override
     public boolean onTrackballEvent(MotionEvent ev) {
         return false;
@@ -551,7 +537,6 @@
                     R.dimen.mcv2_embedded_icon_size);
             int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
 
-            // TODO: add support for Advertisement Mode.
             if (mMediaType == MEDIA_TYPE_DEFAULT) {
                 // Max number of icons inside BottomBarRightView for Music mode is 4.
                 int maxIconCount = 4;
@@ -581,7 +566,6 @@
             mPrevWidth = currWidth;
             mPrevHeight = currHeight;
         }
-        // TODO: move this to a different location.
         // Update title bar parameters in order to avoid overlap between title view and the right
         // side of the title bar.
         updateTitleBarLayout();
@@ -591,7 +575,6 @@
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
 
-        // TODO: Merge the below code with disableUnsupportedButtons().
         if (mPlayPauseButton != null) {
             mPlayPauseButton.setEnabled(enabled);
         }
@@ -626,20 +609,6 @@
         }
     }
 
-    // TODO (b/77158231) revive once androidx.mediarouter.* packagaes are available.
-    /*
-    void setRouteSelector(MediaRouteSelector selector) {
-        mRouteSelector = selector;
-        if (mRouteSelector != null && !mRouteSelector.isEmpty()) {
-            mRouteButton.setRouteSelector(selector, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
-            mRouteButton.setVisibility(View.VISIBLE);
-        } else {
-            mRouteButton.setRouteSelector(MediaRouteSelector.EMPTY);
-            mRouteButton.setVisibility(View.GONE);
-        }
-    }
-    */
-
     ///////////////////////////////////////////////////
     // Protected or private methods
     ///////////////////////////////////////////////////
@@ -698,14 +667,12 @@
      *
      * @return The controller view.
      */
-    // TODO: This was "protected". Determine if it should be protected in MCV2.
     private ViewGroup makeControllerView() {
         ViewGroup root = (ViewGroup) inflateLayout(getContext(), R.layout.media_controller);
         initControllerView(root);
         return root;
     }
 
-    // TODO(b/76444971) make sure this is compatible with ApiHelper's one in updatable.
     private View inflateLayout(Context context, int resId) {
         LayoutInflater inflater = (LayoutInflater) context
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -723,9 +690,6 @@
             mBackButton.setOnClickListener(mBackListener);
             mBackButton.setVisibility(View.GONE);
         }
-        // TODO (b/77158231) revive
-        // mRouteButton = v.findViewById(R.id.cast);
-
         // Relating to Center View
         mCenterView = v.findViewById(R.id.center_view);
         mTransportControls = inflateTransportControls(R.layout.embedded_transport_controls);
@@ -778,7 +742,6 @@
         mFullScreenButton = v.findViewById(R.id.fullscreen);
         if (mFullScreenButton != null) {
             mFullScreenButton.setOnClickListener(mFullScreenListener);
-            // TODO: Show Fullscreen button when only it is possible.
         }
         mOverflowButtonRight = v.findViewById(R.id.overflow_right);
         if (mOverflowButtonRight != null) {
@@ -840,13 +803,6 @@
             if (mFfwdButton != null && !canSeekForward()) {
                 mFfwdButton.setEnabled(false);
             }
-            // TODO What we really should do is add a canSeek to the MediaPlayerControl interface;
-            // this scheme can break the case when applications want to allow seek through the
-            // progress bar but disable forward/backward buttons.
-            //
-            // However, currently the flags SEEK_BACKWARD_AVAILABLE, SEEK_FORWARD_AVAILABLE,
-            // and SEEK_AVAILABLE are all (un)set together; as such the aforementioned issue
-            // shouldn't arise in existing applications.
             if (mProgress != null && !canSeekBackward() && !canSeekForward()) {
                 mProgress.setEnabled(false);
             }
@@ -1078,7 +1034,11 @@
     private final OnClickListener mBackListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
-            // TODO: implement
+            View parent = (View) getParent();
+            if (parent != null) {
+                parent.onKeyDown(KeyEvent.KEYCODE_BACK,
+                        new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
+            }
         }
     };
 
@@ -1105,8 +1065,11 @@
     private final OnClickListener mFullScreenListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
+            if (mFullScreenRequestListener == null) {
+                return;
+            }
+
             final boolean isEnteringFullScreen = !mIsFullScreen;
-            // TODO: Re-arrange the button layouts according to the UX.
             if (isEnteringFullScreen) {
                 mFullScreenButton.setImageDrawable(
                         mResources.getDrawable(R.drawable.ic_fullscreen_exit, null));
@@ -1114,11 +1077,9 @@
                 mFullScreenButton.setImageDrawable(
                         mResources.getDrawable(R.drawable.ic_fullscreen, null));
             }
-            Bundle args = new Bundle();
-            args.putBoolean(ARGUMENT_KEY_FULLSCREEN, isEnteringFullScreen);
-            mController.sendCommand(COMMAND_SET_FULLSCREEN, args, null);
-
             mIsFullScreen = isEnteringFullScreen;
+            mFullScreenRequestListener.onFullScreenRequest(MediaControlView2.this,
+                    mIsFullScreen);
         }
     };
 
@@ -1183,7 +1144,6 @@
                         mSubSettingsAdapter.setCheckPosition(mSelectedSpeedIndex);
                         mSettingsMode = SETTINGS_MODE_PLAYBACK_SPEED;
                     } else if (position == SETTINGS_MODE_HELP) {
-                        // TODO: implement this.
                         mSettingsWindow.dismiss();
                         return;
                     }
@@ -1214,7 +1174,6 @@
                     mSettingsWindow.dismiss();
                     break;
                 case SETTINGS_MODE_HELP:
-                    // TODO: implement this.
                     break;
                 case SETTINGS_MODE_SUBTITLE_TRACK:
                     if (position != mSelectedSubtitleTrackIndex) {
@@ -1240,7 +1199,6 @@
                     mSettingsWindow.dismiss();
                     break;
                 case SETTINGS_MODE_VIDEO_QUALITY:
-                    // TODO: add support for video quality
                     mSelectedVideoQualityIndex = position;
                     mSettingsWindow.dismiss();
                     break;
@@ -1361,10 +1319,6 @@
         int embeddedWidth = mTimeView.getWidth() + embeddedBottomBarRightWidthMax;
         int screenMaxLength = Math.max(screenWidth, screenHeight);
 
-        if (fullWidth > screenMaxLength) {
-            // TODO: screen may be smaller than the length needed for Full size.
-        }
-
         boolean isFullSize = (mMediaType == MEDIA_TYPE_DEFAULT) ? (currWidth == screenMaxLength) :
                 (currWidth == screenWidth && currHeight == screenHeight);
 
@@ -1523,7 +1477,6 @@
                 mRewButton.setVisibility(View.GONE);
             }
         }
-        // TODO: Add support for Next and Previous buttons
         mNextButton = v.findViewById(R.id.next);
         if (mNextButton != null) {
             mNextButton.setOnClickListener(mNextListener);
@@ -1598,7 +1551,6 @@
                 mSettingsWindowMargin - totalHeight, Gravity.BOTTOM | Gravity.RIGHT);
     }
 
-    @RequiresApi(26) // TODO correct minSdk API use incompatibilities and remove before release.
     private class MediaControllerCallback extends MediaControllerCompat.Callback {
         @Override
         public void onPlaybackStateChanged(PlaybackStateCompat state) {
@@ -1670,16 +1622,12 @@
                 for (final PlaybackStateCompat.CustomAction action : customActions) {
                     ImageButton button = new ImageButton(getContext(),
                             null /* AttributeSet */, 0 /* Style */);
-                    // TODO: Apply R.style.BottomBarButton to this button using library context.
                     // Refer Constructor with argument (int defStyleRes) of View.java
                     button.setImageResource(action.getIcon());
-                    button.setTooltipText(action.getName());
                     final String actionString = action.getAction().toString();
                     button.setOnClickListener(new OnClickListener() {
                         @Override
                         public void onClick(View v) {
-                            // TODO: Currently, we are just sending extras that came from session.
-                            // Is it the right behavior?
                             mControls.sendCustomAction(actionString, action.getExtras());
                             setVisibility(View.VISIBLE);
                         }
@@ -1708,7 +1656,6 @@
                     mAudioTrackCount = extras.getInt(KEY_AUDIO_TRACK_COUNT);
                     mAudioTrackList = new ArrayList<String>();
                     if (mAudioTrackCount > 0) {
-                        // TODO: add more text about track info.
                         for (int i = 0; i < mAudioTrackCount; i++) {
                             String track = mResources.getString(
                                     R.string.MediaControlView2_audio_track_number_text, i + 1);
@@ -1787,14 +1734,12 @@
         @Override
         public long getItemId(int position) {
             // Auto-generated method stub--does not have any purpose here
-            // TODO: implement this.
             return 0;
         }
 
         @Override
         public Object getItem(int position) {
             // Auto-generated method stub--does not have any purpose here
-            // TODO: implement this.
             return null;
         }
 
@@ -1838,7 +1783,6 @@
         }
     }
 
-    // TODO: extend this class from SettingsAdapter
     private class SubSettingsAdapter extends BaseAdapter {
         private List<String> mTexts;
         private int mCheckPosition;
@@ -1865,14 +1809,12 @@
         @Override
         public long getItemId(int position) {
             // Auto-generated method stub--does not have any purpose here
-            // TODO: implement this.
             return 0;
         }
 
         @Override
         public Object getItem(int position) {
             // Auto-generated method stub--does not have any purpose here
-            // TODO: implement this.
             return null;
         }
 
diff --git a/media-widget/src/main/java/androidx/media/widget/SubtitleView.java b/media-widget/src/main/java/androidx/media/widget/SubtitleView.java
new file mode 100644
index 0000000..1faff2f
--- /dev/null
+++ b/media-widget/src/main/java/androidx/media/widget/SubtitleView.java
@@ -0,0 +1,144 @@
+/*
+ * 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.media.widget;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.os.Looper;
+import android.util.AttributeSet;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.media.subtitle.SubtitleController.Anchor;
+import androidx.media.subtitle.SubtitleTrack.RenderingWidget;
+
+@RequiresApi(21)
+class SubtitleView extends BaseLayout implements Anchor {
+    private static final String TAG = "SubtitleView";
+
+    private RenderingWidget mSubtitleWidget;
+    private RenderingWidget.OnChangedListener mSubtitlesChangedListener;
+
+    SubtitleView(Context context) {
+        this(context, null);
+    }
+
+    SubtitleView(Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    SubtitleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    SubtitleView(
+            Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public void setSubtitleWidget(RenderingWidget subtitleWidget) {
+        if (mSubtitleWidget == subtitleWidget) {
+            return;
+        }
+
+        final boolean attachedToWindow = isAttachedToWindow();
+        if (mSubtitleWidget != null) {
+            if (attachedToWindow) {
+                mSubtitleWidget.onDetachedFromWindow();
+            }
+
+            mSubtitleWidget.setOnChangedListener(null);
+        }
+        mSubtitleWidget = subtitleWidget;
+
+        if (subtitleWidget != null) {
+            if (mSubtitlesChangedListener == null) {
+                mSubtitlesChangedListener = new RenderingWidget.OnChangedListener() {
+                    @Override
+                    public void onChanged(RenderingWidget renderingWidget) {
+                        invalidate();
+                    }
+                };
+            }
+
+            setWillNotDraw(false);
+            subtitleWidget.setOnChangedListener(mSubtitlesChangedListener);
+
+            if (attachedToWindow) {
+                subtitleWidget.onAttachedToWindow();
+                requestLayout();
+            }
+        } else {
+            setWillNotDraw(true);
+        }
+
+        invalidate();
+    }
+
+    @Override
+    public Looper getSubtitleLooper() {
+        return Looper.getMainLooper();
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        if (mSubtitleWidget != null) {
+            mSubtitleWidget.onAttachedToWindow();
+        }
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        if (mSubtitleWidget != null) {
+            mSubtitleWidget.onDetachedFromWindow();
+        }
+    }
+
+    @Override
+    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+
+        if (mSubtitleWidget != null) {
+            final int width = getWidth() - getPaddingLeft() - getPaddingRight();
+            final int height = getHeight() - getPaddingTop() - getPaddingBottom();
+
+            mSubtitleWidget.setSize(width, height);
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+
+        if (mSubtitleWidget != null) {
+            final int saveCount = canvas.save();
+            canvas.translate(getPaddingLeft(), getPaddingTop());
+            mSubtitleWidget.draw(canvas);
+            canvas.restoreToCount(saveCount);
+        }
+    }
+
+    @Override
+    public CharSequence getAccessibilityClassName() {
+        return SubtitleView.class.getName();
+    }
+}
diff --git a/media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java b/media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java
index d417bd2..0af3044 100644
--- a/media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.media.MediaPlayer;
-import android.util.AttributeSet;
 import android.util.Log;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
@@ -30,7 +29,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 
-@RequiresApi(21)
+@RequiresApi(28)
 class VideoSurfaceView extends SurfaceView implements VideoViewInterface, SurfaceHolder.Callback {
     private static final String TAG = "VideoSurfaceView";
     private static final boolean DEBUG = true; // STOPSHIP: Log.isLoggable(TAG, Log.DEBUG);
@@ -41,24 +40,8 @@
     private boolean mIsTakingOverOldView;
     private VideoViewInterface mOldView;
 
-
     VideoSurfaceView(Context context) {
-        this(context, null);
-    }
-
-    VideoSurfaceView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        getHolder().addCallback(this);
-    }
-
-    @RequiresApi(21)
-    VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr,
-                            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
+        super(context, null);
         getHolder().addCallback(this);
     }
 
diff --git a/media-widget/src/main/java/androidx/media/widget/VideoTextureView.java b/media-widget/src/main/java/androidx/media/widget/VideoTextureView.java
index cdc833b..3b87c7e 100644
--- a/media-widget/src/main/java/androidx/media/widget/VideoTextureView.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoTextureView.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.graphics.SurfaceTexture;
 import android.media.MediaPlayer;
-import android.util.AttributeSet;
 import android.util.Log;
 import android.view.Surface;
 import android.view.TextureView;
@@ -30,7 +29,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 
-@RequiresApi(21)
+@RequiresApi(28)
 class VideoTextureView extends TextureView
         implements VideoViewInterface, TextureView.SurfaceTextureListener {
     private static final String TAG = "VideoTextureView";
@@ -44,20 +43,7 @@
     private VideoViewInterface mOldView;
 
     VideoTextureView(Context context) {
-        this(context, null);
-    }
-
-    VideoTextureView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    VideoTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    VideoTextureView(
-            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
+        super(context, null);
         setSurfaceTextureListener(this);
     }
 
diff --git a/media-widget/src/main/java/androidx/media/widget/VideoView2.java b/media-widget/src/main/java/androidx/media/widget/VideoView2.java
index a8ea450..6b33304 100644
--- a/media-widget/src/main/java/androidx/media/widget/VideoView2.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoView2.java
@@ -31,7 +31,9 @@
 import android.media.AudioManager;
 import android.media.MediaMetadataRetriever;
 import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnSubtitleDataListener;
 import android.media.PlaybackParams;
+import android.media.SubtitleData;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.ResultReceiver;
@@ -63,6 +65,9 @@
 import androidx.media.MediaItem2;
 import androidx.media.MediaMetadata2;
 import androidx.media.SessionToken2;
+import androidx.media.subtitle.ClosedCaptionRenderer;
+import androidx.media.subtitle.SubtitleController;
+import androidx.media.subtitle.SubtitleTrack;
 import androidx.palette.graphics.Palette;
 
 import java.io.IOException;
@@ -73,11 +78,9 @@
 import java.util.Map;
 import java.util.concurrent.Executor;
 
-// TODO: Replace MediaSession wtih MediaSession2 once MediaSession2 is submitted.
 /**
- * @hide
- * Displays a video file.  VideoView2 class is a View class which is wrapping {@link MediaPlayer}
- * so that developers can easily implement a video rendering application.
+ * Displays a video file.  VideoView2 class is a ViewGroup class which is wrapping
+ * {@link MediaPlayer} so that developers can easily implement a video rendering application.
  *
  * <p>
  * <em> Data sources that VideoView2 supports : </em>
@@ -98,20 +101,12 @@
  * VideoView2 covers and inherits the most of
  * VideoView's functionalities. The main differences are
  * <ul>
- * <li> VideoView2 inherits FrameLayout and renders videos using SurfaceView and TextureView
+ * <li> VideoView2 inherits ViewGroup and renders videos using SurfaceView and TextureView
  * selectively while VideoView inherits SurfaceView class.
  * <li> VideoView2 is integrated with MediaControlView2 and a default MediaControlView2 instance is
- * attached to VideoView2 by default. If a developer does not want to use the default
- * MediaControlView2, needs to set enableControlView attribute to false. For instance,
- * <pre>
- * &lt;VideoView2
- *     android:id="@+id/video_view"
- *     xmlns:widget="http://schemas.android.com/apk/com.android.media.update"
- *     widget:enableControlView="false" /&gt;
- * </pre>
- * If a developer wants to attach a customed MediaControlView2, then set enableControlView attribute
- * to false and assign the customed media control widget using {@link #setMediaControlView2}.
- * <li> VideoView2 is integrated with MediaPlayer while VideoView is integrated with MediaPlayer.
+ * attached to VideoView2 by default.
+ * <li> If a developer wants to attach a customed MediaControlView2,
+ * assign the customed media control widget using {@link #setMediaControlView2}.
  * <li> VideoView2 is integrated with MediaSession and so it responses with media key events.
  * A VideoView2 keeps a MediaSession instance internally and connects it to a corresponding
  * MediaControlView2 instance.
@@ -133,8 +128,7 @@
  * and restore these on their own in {@link android.app.Activity#onSaveInstanceState} and
  * {@link android.app.Activity#onRestoreInstanceState}.
  */
-@RequiresApi(21) // TODO correct minSdk API use incompatibilities and remove before release.
-@RestrictTo(LIBRARY_GROUP)
+@RequiresApi(28) // TODO correct minSdk API use incompatibilities and remove before release.
 public class VideoView2 extends BaseLayout implements VideoViewInterface.SurfaceListener {
     /** @hide */
     @RestrictTo(LIBRARY_GROUP)
@@ -160,7 +154,7 @@
     public static final int VIEW_TYPE_TEXTUREVIEW = 1;
 
     private static final String TAG = "VideoView2";
-    private static final boolean DEBUG = true; // STOPSHIP: Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final long DEFAULT_SHOW_CONTROLLER_INTERVAL_MS = 2000;
 
     private static final int STATE_ERROR = -1;
@@ -176,7 +170,6 @@
 
     private static final int SIZE_TYPE_EMBEDDED = 0;
     private static final int SIZE_TYPE_FULL = 1;
-    // TODO: add support for Minimal size type.
     private static final int SIZE_TYPE_MINIMAL = 2;
 
     private AccessibilityManager mAccessibilityManager;
@@ -187,7 +180,6 @@
 
     private Pair<Executor, OnCustomActionListener> mCustomActionListenerRecord;
     private OnViewTypeChangedListener mViewTypeChangedListener;
-    private OnFullScreenRequestListener mFullScreenRequestListener;
 
     private VideoViewInterface mCurrentView;
     private VideoTextureView mTextureView;
@@ -204,7 +196,6 @@
     private Bundle mMediaTypeData;
     private String mTitle;
 
-    // TODO: move music view inside SurfaceView/TextureView or implement VideoViewInterface.
     private WindowManager mManager;
     private Resources mResources;
     private View mMusicView;
@@ -230,102 +221,24 @@
 
     private ArrayList<Integer> mVideoTrackIndices;
     private ArrayList<Integer> mAudioTrackIndices;
-    // private ArrayList<Pair<Integer, SubtitleTrack>> mSubtitleTrackIndices;
-    // private SubtitleController mSubtitleController;
+    private ArrayList<Pair<Integer, SubtitleTrack>> mSubtitleTrackIndices;
+    private SubtitleController mSubtitleController;
 
     // selected video/audio/subtitle track index as MediaPlayer returns
     private int mSelectedVideoTrackIndex;
     private int mSelectedAudioTrackIndex;
     private int mSelectedSubtitleTrackIndex;
 
-    // private SubtitleView mSubtitleView;
+    private SubtitleView mSubtitleView;
     private boolean mSubtitleEnabled;
 
     private float mSpeed;
-    // TODO: Remove mFallbackSpeed when integration with MediaPlayer's new setPlaybackParams().
-    // Refer: https://docs.google.com/document/d/1nzAfns6i2hJ3RkaUre3QMT6wsDedJ5ONLiA_OOBFFX8/edit
     private float mFallbackSpeed;  // keep the original speed before 'pause' is called.
     private float mVolumeLevelFloat;
     private int mVolumeLevel;
 
     private long mShowControllerIntervalMs;
 
-    // private MediaRouter mMediaRouter;
-    // private MediaRouteSelector mRouteSelector;
-    // private MediaRouter.RouteInfo mRoute;
-    // private RoutePlayer mRoutePlayer;
-
-    // TODO (b/77158231)
-    /*
-    private final MediaRouter.Callback mRouterCallback = new MediaRouter.Callback() {
-        @Override
-        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
-            if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
-                // Stop local playback (if necessary)
-                resetPlayer();
-                mRoute = route;
-                mRoutePlayer = new RoutePlayer(getContext(), route);
-                mRoutePlayer.setPlayerEventCallback(new RoutePlayer.PlayerEventCallback() {
-                    @Override
-                    public void onPlayerStateChanged(MediaItemStatus itemStatus) {
-                        PlaybackStateCompat.Builder psBuilder = new PlaybackStateCompat.Builder();
-                        psBuilder.setActions(RoutePlayer.PLAYBACK_ACTIONS);
-                        long position = itemStatus.getContentPosition();
-                        switch (itemStatus.getPlaybackState()) {
-                            case MediaItemStatus.PLAYBACK_STATE_PENDING:
-                                psBuilder.setState(PlaybackStateCompat.STATE_NONE, position, 0);
-                                mCurrentState = STATE_IDLE;
-                                break;
-                            case MediaItemStatus.PLAYBACK_STATE_PLAYING:
-                                psBuilder.setState(PlaybackStateCompat.STATE_PLAYING, position, 1);
-                                mCurrentState = STATE_PLAYING;
-                                break;
-                            case MediaItemStatus.PLAYBACK_STATE_PAUSED:
-                                psBuilder.setState(PlaybackStateCompat.STATE_PAUSED, position, 0);
-                                mCurrentState = STATE_PAUSED;
-                                break;
-                            case MediaItemStatus.PLAYBACK_STATE_BUFFERING:
-                                psBuilder.setState(
-                                        PlaybackStateCompat.STATE_BUFFERING, position, 0);
-                                mCurrentState = STATE_PAUSED;
-                                break;
-                            case MediaItemStatus.PLAYBACK_STATE_FINISHED:
-                                psBuilder.setState(PlaybackStateCompat.STATE_STOPPED, position, 0);
-                                mCurrentState = STATE_PLAYBACK_COMPLETED;
-                                break;
-                        }
-
-                        PlaybackStateCompat pbState = psBuilder.build();
-                        mMediaSession.setPlaybackState(pbState);
-
-                        MediaMetadataCompat.Builder mmBuilder = new MediaMetadataCompat.Builder();
-                        mmBuilder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION,
-                                itemStatus.getContentDuration());
-                        mMediaSession.setMetadata(mmBuilder.build());
-                    }
-                });
-                // Start remote playback (if necessary)
-                mRoutePlayer.openVideo(mDsd);
-            }
-        }
-
-        @Override
-        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route, int reason) {
-            if (mRoute != null && mRoutePlayer != null) {
-                mRoutePlayer.release();
-                mRoutePlayer = null;
-            }
-            if (mRoute == route) {
-                mRoute = null;
-            }
-            if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
-                // TODO: Resume local playback  (if necessary)
-                openVideo(mDsd);
-            }
-        }
-    };
-    */
-
     public VideoView2(@NonNull Context context) {
         this(context, null);
     }
@@ -335,19 +248,22 @@
     }
 
     public VideoView2(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
+        super(context, attrs, defStyleAttr);
+        initialize(context, attrs);
     }
 
     public VideoView2(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        initialize(context, attrs);
+    }
 
+    void initialize(Context context, AttributeSet attrs) {
         mVideoWidth = 0;
         mVideoHeight = 0;
         mSpeed = 1.0f;
         mFallbackSpeed = mSpeed;
         mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
-        // TODO: add attributes to get this value.
         mShowControllerIntervalMs = DEFAULT_SHOW_CONTROLLER_INTERVAL_MS;
 
         mAccessibilityManager = (AccessibilityManager) context.getSystemService(
@@ -360,9 +276,8 @@
         setFocusableInTouchMode(true);
         requestFocus();
 
-        // TODO: try to keep a single child at a time rather than always having both.
-        mTextureView = new VideoTextureView(getContext());
-        mSurfaceView = new VideoSurfaceView(getContext());
+        mTextureView = new VideoTextureView(context);
+        mSurfaceView = new VideoSurfaceView(context);
         LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
                 LayoutParams.MATCH_PARENT);
         mTextureView.setLayoutParams(params);
@@ -373,23 +288,22 @@
         addView(mTextureView);
         addView(mSurfaceView);
 
-        // mSubtitleView = new SubtitleView(getContext());
-        // mSubtitleView.setLayoutParams(params);
-        // mSubtitleView.setBackgroundColor(0);
-        // addView(mSubtitleView);
+        mSubtitleView = new SubtitleView(context);
+        mSubtitleView.setLayoutParams(params);
+        mSubtitleView.setBackgroundColor(0);
+        addView(mSubtitleView);
 
         boolean enableControlView = (attrs == null) || attrs.getAttributeBooleanValue(
                 "http://schemas.android.com/apk/res/android",
                 "enableControlView", true);
         if (enableControlView) {
-            mMediaControlView = new MediaControlView2(getContext());
+            mMediaControlView = new MediaControlView2(context);
         }
 
         mSubtitleEnabled = (attrs == null) || attrs.getAttributeBooleanValue(
                 "http://schemas.android.com/apk/res/android",
                 "enableSubtitle", false);
 
-        // TODO: Choose TextureView when SurfaceView cannot be created.
         // Choose surface view by default
         int viewType = (attrs == null) ? VideoView2.VIEW_TYPE_SURFACEVIEW
                 : attrs.getAttributeIntValue(
@@ -406,15 +320,6 @@
             mSurfaceView.setVisibility(View.GONE);
             mCurrentView = mTextureView;
         }
-
-        // TODO (b/77158231)
-        /*
-        MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder();
-        builder.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
-        builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO);
-        builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
-        mRouteSelector = builder.build();
-        */
     }
 
     /**
@@ -427,10 +332,6 @@
     public void setMediaControlView2(MediaControlView2 mediaControlView, long intervalMs) {
         mMediaControlView = mediaControlView;
         mShowControllerIntervalMs = intervalMs;
-        // TODO: Call MediaControlView2.setRouteSelector only when cast availalbe.
-        // TODO (b/77158231)
-        // mMediaControlView.setRouteSelector(mRouteSelector);
-
         if (isAttachedToWindow()) {
             attachMediaControlView();
         }
@@ -529,7 +430,6 @@
      * be reset to the normal speed 1.0f.
      * @param speed the playback speed. It should be positive.
      */
-    // TODO: Support this via MediaController2.
     public void setSpeed(float speed) {
         if (speed <= 0.0f) {
             Log.e(TAG, "Unsupported speed (" + speed + ") is ignored.");
@@ -543,6 +443,16 @@
     }
 
     /**
+     * Returns playback speed.
+     *
+     * It returns the same value that has been set by {@link #setSpeed}, if it was available value.
+     * If {@link #setSpeed} has not been called before, then the normal speed 1.0f will be returned.
+     */
+    public float getSpeed() {
+        return mSpeed;
+    }
+
+    /**
      * Sets which type of audio focus will be requested during the playback, or configures playback
      * to not request audio focus. Valid values for focus requests are
      * {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
@@ -585,7 +495,7 @@
      *
      * @param path the path of the video.
      *
-     * @hide TODO remove
+     * @hide
      */
     @RestrictTo(LIBRARY_GROUP)
     public void setVideoPath(String path) {
@@ -597,7 +507,7 @@
      *
      * @param uri the URI of the video.
      *
-     * @hide TODO remove
+     * @hide
      */
     @RestrictTo(LIBRARY_GROUP)
     public void setVideoUri(Uri uri) {
@@ -613,11 +523,8 @@
      *                changed with key/value pairs through the headers parameter with
      *                "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value
      *                to disallow or allow cross domain redirection.
-     *
-     * @hide TODO remove
      */
-    @RestrictTo(LIBRARY_GROUP)
-    public void setVideoUri(Uri uri, Map<String, String> headers) {
+    public void setVideoUri(Uri uri, @Nullable Map<String, String> headers) {
         mSeekWhenPrepared = 0;
         openVideo(uri, headers);
     }
@@ -627,9 +534,11 @@
      * object to VideoView2 is {@link #setDataSource}.
      * @param mediaItem the MediaItem2 to play
      * @see #setDataSource
+     *
+     * @hide
      */
+    @RestrictTo(LIBRARY_GROUP)
     public void setMediaItem(@NonNull MediaItem2 mediaItem) {
-        //mProvider.setMediaItem_impl(mediaItem);
     }
 
     /**
@@ -640,7 +549,6 @@
      */
     @RestrictTo(LIBRARY_GROUP)
     public void setDataSource(@NonNull DataSourceDesc dataSource) {
-        //mProvider.setDataSource_impl(dataSource);
     }
 
     /**
@@ -689,7 +597,7 @@
      *                   buttons in {@link MediaControlView2}.
      * @param executor executor to run callbacks on.
      * @param listener A listener to be called when a custom button is clicked.
-     * @hide  TODO remove
+     * @hide
      */
     @RestrictTo(LIBRARY_GROUP)
     public void setCustomActions(List<PlaybackStateCompat.CustomAction> actionList,
@@ -714,16 +622,6 @@
         mViewTypeChangedListener = l;
     }
 
-    /**
-     * Registers a callback to be invoked when the fullscreen mode should be changed.
-     * @param l The callback that will be run
-     * @hide  TODO remove
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    public void setFullScreenRequestListener(OnFullScreenRequestListener l) {
-        mFullScreenRequestListener = l;
-    }
-
     @Override
     public void onAttachedToWindow() {
         super.onAttachedToWindow();
@@ -733,12 +631,7 @@
         mMediaSession.setCallback(new MediaSessionCallback());
         mMediaSession.setActive(true);
         mMediaController = mMediaSession.getController();
-        // TODO (b/77158231)
-        // mMediaRouter = MediaRouter.getInstance(getContext());
-        // mMediaRouter.setMediaSession(mMediaSession);
-        // mMediaRouter.addCallback(mRouteSelector, mRouterCallback);
         attachMediaControlView();
-        // TODO: remove this after moving MediaSession creating code inside initializing VideoView2
         if (mCurrentState == STATE_PREPARED) {
             extractTracks();
             extractMetadata();
@@ -794,7 +687,6 @@
 
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
-        // TODO: Test touch event handling logic thoroughly and simplify the logic.
         return super.dispatchTouchEvent(ev);
     }
 
@@ -862,19 +754,6 @@
     }
 
     /**
-     * Interface definition of a callback to be invoked to inform the fullscreen mode is changed.
-     * Application should handle the fullscreen mode accordingly.
-     * @hide  TODO remove
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    public interface OnFullScreenRequestListener {
-        /**
-         * Called to indicate a fullscreen mode change.
-         */
-        void onFullScreenRequest(View view, boolean fullScreen);
-    }
-
-    /**
      * Interface definition of a callback to be invoked to inform that a custom action is performed.
      * @hide  TODO remove
      */
@@ -894,7 +773,11 @@
     // Implements VideoViewInterface.SurfaceListener
     ///////////////////////////////////////////////////
 
+    /**
+     * @hide
+     */
     @Override
+    @RestrictTo(LIBRARY_GROUP)
     public void onSurfaceCreated(View view, int width, int height) {
         if (DEBUG) {
             Log.d(TAG, "onSurfaceCreated(). mCurrentState=" + mCurrentState
@@ -906,7 +789,11 @@
         }
     }
 
+    /**
+     * @hide
+     */
     @Override
+    @RestrictTo(LIBRARY_GROUP)
     public void onSurfaceDestroyed(View view) {
         if (DEBUG) {
             Log.d(TAG, "onSurfaceDestroyed(). mCurrentState=" + mCurrentState
@@ -914,16 +801,23 @@
         }
     }
 
+    /**
+     * @hide
+     */
     @Override
+    @RestrictTo(LIBRARY_GROUP)
     public void onSurfaceChanged(View view, int width, int height) {
-        // TODO: Do we need to call requestLayout here?
         if (DEBUG) {
             Log.d(TAG, "onSurfaceChanged(). width/height: " + width + "/" + height
                     + ", " + view.toString());
         }
     }
 
+    /**
+     * @hide
+     */
     @Override
+    @RestrictTo(LIBRARY_GROUP)
     public void onSurfaceTakeOverDone(VideoViewInterface view) {
         if (DEBUG) {
             Log.d(TAG, "onSurfaceTakeOverDone(). Now current view is: " + view);
@@ -951,8 +845,6 @@
     }
 
     private boolean isInPlaybackState() {
-        // TODO (b/77158231)
-        // return (mMediaPlayer != null || mRoutePlayer != null)
         return (mMediaPlayer != null)
                 && mCurrentState != STATE_ERROR
                 && mCurrentState != STATE_IDLE
@@ -960,8 +852,6 @@
     }
 
     private boolean needToStart() {
-        // TODO (b/77158231)
-        // return (mMediaPlayer != null || mRoutePlayer != null)
         return (mMediaPlayer != null)
                 && isAudioGranted()
                 && isWaitingPlayback();
@@ -989,11 +879,6 @@
                 case AudioManager.AUDIOFOCUS_LOSS:
                 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
-                    // There is no way to distinguish pause() by transient
-                    // audio focus loss and by other explicit actions.
-                    // TODO: If we can distinguish those cases, change the code to resume when it
-                    // gains audio focus again for AUDIOFOCUS_LOSS_TRANSIENT and
-                    // AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
                     mAudioFocused = false;
                     if (isInPlaybackState() && mMediaPlayer.isPlaying()) {
                         mMediaController.getTransportControls().pause();
@@ -1032,8 +917,6 @@
     private void openVideo(Uri uri, Map<String, String> headers) {
         resetPlayer();
         if (isRemotePlayback()) {
-            // TODO (b/77158231)
-            // mRoutePlayer.openVideo(dsd);
             return;
         }
 
@@ -1045,10 +928,9 @@
             mCurrentView.assignSurfaceToMediaPlayer(mMediaPlayer);
 
             final Context context = getContext();
-            // TODO: Add timely firing logic for more accurate sync between CC and video frame
-            // mSubtitleController = new SubtitleController(context);
-            // mSubtitleController.registerRenderer(new ClosedCaptionRenderer(context));
-            // mSubtitleController.setAnchor((SubtitleController.Anchor) mSubtitleView);
+            mSubtitleController = new SubtitleController(context);
+            mSubtitleController.registerRenderer(new ClosedCaptionRenderer(context));
+            mSubtitleController.setAnchor((SubtitleController.Anchor) mSubtitleView);
 
             mMediaPlayer.setOnPreparedListener(mPreparedListener);
             mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
@@ -1061,7 +943,7 @@
             mCurrentBufferPercentage = -1;
             mMediaPlayer.setDataSource(getContext(), uri, headers);
             mMediaPlayer.setAudioAttributes(mAudioAttributes);
-            // mMediaPlayer.setOnSubtitleDataListener(mSubtitleListener);
+            mMediaPlayer.setOnSubtitleDataListener(mSubtitleListener);
             // we don't set the target state here either, but preserve the
             // target state that was there before.
             mCurrentState = STATE_PREPARING;
@@ -1112,38 +994,6 @@
 
     private void updatePlaybackState() {
         if (mStateBuilder == null) {
-            /*
-            // Get the capabilities of the player for this stream
-            mMetadata = mMediaPlayer.getMetadata(MediaPlayer.METADATA_ALL,
-                    MediaPlayer.BYPASS_METADATA_FILTER);
-
-            // Add Play action as default
-            long playbackActions = PlaybackStateCompat.ACTION_PLAY;
-            if (mMetadata != null) {
-                if (!mMetadata.has(Metadata.PAUSE_AVAILABLE)
-                        || mMetadata.getBoolean(Metadata.PAUSE_AVAILABLE)) {
-                    playbackActions |= PlaybackStateCompat.ACTION_PAUSE;
-                }
-                if (!mMetadata.has(Metadata.SEEK_BACKWARD_AVAILABLE)
-                        || mMetadata.getBoolean(Metadata.SEEK_BACKWARD_AVAILABLE)) {
-                    playbackActions |= PlaybackStateCompat.ACTION_REWIND;
-                }
-                if (!mMetadata.has(Metadata.SEEK_FORWARD_AVAILABLE)
-                        || mMetadata.getBoolean(Metadata.SEEK_FORWARD_AVAILABLE)) {
-                    playbackActions |= PlaybackStateCompat.ACTION_FAST_FORWARD;
-                }
-                if (!mMetadata.has(Metadata.SEEK_AVAILABLE)
-                        || mMetadata.getBoolean(Metadata.SEEK_AVAILABLE)) {
-                    playbackActions |= PlaybackStateCompat.ACTION_SEEK_TO;
-                }
-            } else {
-                playbackActions |= (PlaybackStateCompat.ACTION_PAUSE
-                        | PlaybackStateCompat.ACTION_REWIND
-                        | PlaybackStateCompat.ACTION_FAST_FORWARD
-                        | PlaybackStateCompat.ACTION_SEEK_TO);
-            }
-            */
-            // TODO determine the actionable list based the metadata info.
             long playbackActions = PlaybackStateCompat.ACTION_PLAY
                     | PlaybackStateCompat.ACTION_PAUSE
                     | PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD
@@ -1162,8 +1012,6 @@
         if (mCurrentState != STATE_ERROR
                 && mCurrentState != STATE_IDLE
                 && mCurrentState != STATE_PREPARING) {
-            // TODO: this should be replaced with MediaPlayer2.getBufferedPosition() once it is
-            // implemented.
             if (mCurrentBufferPercentage == -1) {
                 mStateBuilder.setBufferedPosition(-1);
             } else {
@@ -1210,7 +1058,6 @@
     };
 
     private void showController() {
-        // TODO: Decide what to show when the state is not in playback state
         if (mMediaControlView == null || !isInPlaybackState()
                 || (mIsMusicMediaType && mSizeType == SIZE_TYPE_FULL)) {
             return;
@@ -1234,7 +1081,6 @@
 
     private void applySpeed() {
         if (android.os.Build.VERSION.SDK_INT < 23) {
-            // TODO: MediaPlayer2 will cover this, or implement with SoundPool.
             return;
         }
         PlaybackParams params = mMediaPlayer.getPlaybackParams().allowDefaults();
@@ -1245,11 +1091,6 @@
                 mFallbackSpeed = mSpeed;
             } catch (IllegalArgumentException e) {
                 Log.e(TAG, "PlaybackParams has unsupported value: " + e);
-                // TODO: should revise this part after integrating with MP2.
-                // If mSpeed had an illegal value for speed rate, system will determine best
-                // handling (see PlaybackParams.AUDIO_FALLBACK_MODE_DEFAULT).
-                // Note: The pre-MP2 returns 0.0f when it is paused. In this case, VideoView2 will
-                // use mFallbackSpeed instead.
                 float fallbackSpeed = mMediaPlayer.getPlaybackParams().allowDefaults().getSpeed();
                 if (fallbackSpeed > 0.0f) {
                     mFallbackSpeed = fallbackSpeed;
@@ -1272,10 +1113,8 @@
         if (!isInPlaybackState()) {
             return;
         }
-    /*
         if (select) {
             if (mSubtitleTrackIndices.size() > 0) {
-                // TODO: make this selection dynamic
                 mSelectedSubtitleTrackIndex = mSubtitleTrackIndices.get(0).first;
                 mSubtitleController.selectTrack(mSubtitleTrackIndices.get(0).second);
                 mMediaPlayer.selectTrack(mSelectedSubtitleTrackIndex);
@@ -1288,31 +1127,25 @@
                 mSubtitleView.setVisibility(View.GONE);
             }
         }
-    */
     }
 
     private void extractTracks() {
         MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
         mVideoTrackIndices = new ArrayList<>();
         mAudioTrackIndices = new ArrayList<>();
-        /*
         mSubtitleTrackIndices = new ArrayList<>();
         mSubtitleController.reset();
-        */
         for (int i = 0; i < trackInfos.length; ++i) {
             int trackType = trackInfos[i].getTrackType();
             if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
                 mVideoTrackIndices.add(i);
             } else if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
                 mAudioTrackIndices.add(i);
-                /*
-            } else if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
-                    || trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
+            } else if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
                 SubtitleTrack track = mSubtitleController.addTrack(trackInfos[i].getFormat());
                 if (track != null) {
                     mSubtitleTrackIndices.add(new Pair<>(i, track));
                 }
-                */
             }
         }
         // Select first tracks as default
@@ -1329,12 +1162,10 @@
         Bundle data = new Bundle();
         data.putInt(MediaControlView2.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size());
         data.putInt(MediaControlView2.KEY_AUDIO_TRACK_COUNT, mAudioTrackIndices.size());
-        /*
         data.putInt(MediaControlView2.KEY_SUBTITLE_TRACK_COUNT, mSubtitleTrackIndices.size());
         if (mSubtitleTrackIndices.size() > 0) {
             selectOrDeselectSubtitle(mSubtitleEnabled);
         }
-        */
         mMediaSession.sendSessionEvent(MediaControlView2.EVENT_UPDATE_TRACK_STATUS, data);
     }
 
@@ -1369,12 +1200,10 @@
             Bitmap bitmap = BitmapFactory.decodeByteArray(album, 0, album.length);
             mMusicAlbumDrawable = new BitmapDrawable(bitmap);
 
-            // TODO: replace with visualizer
             Palette.Builder builder = Palette.from(bitmap);
             builder.generate(new Palette.PaletteAsyncListener() {
                 @Override
                 public void onGenerated(Palette palette) {
-                    // TODO: add dominant color for default album image.
                     mDominantColor = palette.getDominantColor(0);
                     if (mMusicView != null) {
                         mMusicView.setBackgroundColor(mDominantColor);
@@ -1448,7 +1277,6 @@
         addView(mMusicView, 0);
     }
 
-    /*
     OnSubtitleDataListener mSubtitleListener =
             new OnSubtitleDataListener() {
                 @Override
@@ -1476,7 +1304,6 @@
                     }
                 }
             };
-            */
 
     MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
             new MediaPlayer.OnVideoSizeChangedListener() {
@@ -1508,8 +1335,6 @@
             // Create and set playback state for MediaControlView2
             updatePlaybackState();
 
-            // TODO: change this to send TrackInfos to MediaControlView2
-            // TODO: create MediaSession when initializing VideoView2
             if (mMediaSession != null) {
                 extractTracks();
             }
@@ -1553,20 +1378,12 @@
             // Get and set duration and title values as MediaMetadata for MediaControlView2
             MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
 
-            // TODO: Get title via other public APIs.
-            /*
-            if (mMetadata != null && mMetadata.has(Metadata.TITLE)) {
-                mTitle = mMetadata.getString(Metadata.TITLE);
-            }
-            */
             builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle);
             builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
 
             if (mMediaSession != null) {
                 mMediaSession.setMetadata(builder.build());
 
-                // TODO: merge this code with the above code when integrating with
-                // MediaSession2.
                 if (mNeedUpdateMediaType) {
                     mMediaSession.sendSessionEvent(
                             MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS, mMediaTypeData);
@@ -1637,12 +1454,9 @@
         @Override
         public void onCommand(String command, Bundle args, ResultReceiver receiver) {
             if (isRemotePlayback()) {
-                // TODO (b/77158231)
-                // mRoutePlayer.onCommand(command, args, receiver);
             } else {
                 switch (command) {
                     case MediaControlView2.COMMAND_SHOW_SUBTITLE:
-                        /*
                         int subtitleIndex = args.getInt(
                                 MediaControlView2.KEY_SELECTED_SUBTITLE_INDEX,
                                 INVALID_TRACK_INDEX);
@@ -1653,18 +1467,10 @@
                                 setSubtitleEnabled(true);
                             }
                         }
-                        */
                         break;
                     case MediaControlView2.COMMAND_HIDE_SUBTITLE:
                         setSubtitleEnabled(false);
                         break;
-                    case MediaControlView2.COMMAND_SET_FULLSCREEN:
-                        if (mFullScreenRequestListener != null) {
-                            mFullScreenRequestListener.onFullScreenRequest(
-                                    VideoView2.this,
-                                    args.getBoolean(MediaControlView2.ARGUMENT_KEY_FULLSCREEN));
-                        }
-                        break;
                     case MediaControlView2.COMMAND_SELECT_AUDIO_TRACK:
                         int audioIndex = args.getInt(MediaControlView2.KEY_SELECTED_AUDIO_INDEX,
                                 INVALID_TRACK_INDEX);
@@ -1715,8 +1521,6 @@
 
             if ((isInPlaybackState() && mCurrentView.hasAvailableSurface()) || mIsMusicMediaType) {
                 if (isRemotePlayback()) {
-                    // TODO (b/77158231)
-                    // mRoutePlayer.onPlay();
                 } else {
                     applySpeed();
                     mMediaPlayer.start();
@@ -1737,8 +1541,6 @@
         public void onPause() {
             if (isInPlaybackState()) {
                 if (isRemotePlayback()) {
-                    // TODO (b/77158231)
-                    // mRoutePlayer.onPause();
                     mCurrentState = STATE_PAUSED;
                 } else if (mMediaPlayer.isPlaying()) {
                     mMediaPlayer.pause();
@@ -1758,10 +1560,7 @@
         public void onSeekTo(long pos) {
             if (isInPlaybackState()) {
                 if (isRemotePlayback()) {
-                    // TODO (b/77158231)
-                    // mRoutePlayer.onSeekTo(pos);
                 } else {
-                    // TODO Refactor VideoView2 with FooImplBase and FooImplApiXX.
                     if (android.os.Build.VERSION.SDK_INT < 26) {
                         mMediaPlayer.seekTo((int) pos);
                     } else {
@@ -1778,8 +1577,6 @@
         @Override
         public void onStop() {
             if (isRemotePlayback()) {
-                // TODO (b/77158231)
-                // mRoutePlayer.onStop();
             } else {
                 resetPlayer();
             }
diff --git a/media/src/androidTest/java/androidx/media/MediaBrowser2Test.java b/media/src/androidTest/java/androidx/media/MediaBrowser2Test.java
index 4b75986..3b7e0e3 100644
--- a/media/src/androidTest/java/androidx/media/MediaBrowser2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaBrowser2Test.java
@@ -29,9 +29,11 @@
 import static org.junit.Assert.assertNotEquals;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Process;
 import android.os.ResultReceiver;
+import android.support.test.filters.SdkSuppress;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -65,17 +67,15 @@
  * {@link MediaController2} works cleanly.
  */
 // TODO(jaewan): Implement host-side test so browser and service can run in different processes.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-@Ignore
 public class MediaBrowser2Test extends MediaController2Test {
     private static final String TAG = "MediaBrowser2Test";
 
     @Override
     TestControllerInterface onCreateController(final @NonNull SessionToken2 token,
-            @Nullable ControllerCallback callback) throws InterruptedException {
-        final BrowserCallback browserCallback =
-                callback != null ? (BrowserCallback) callback : new BrowserCallback() {};
+            final @Nullable ControllerCallback callback) throws InterruptedException {
         final AtomicReference<TestControllerInterface> controller = new AtomicReference<>();
         sHandler.postAndSync(new Runnable() {
             @Override
@@ -84,7 +84,7 @@
                 // Looper. Otherwise, MediaBrowserCompat will post all the commands to the handler
                 // and commands wouldn't be run if tests codes waits on the test handler.
                 controller.set(new TestMediaBrowser(
-                        mContext, token, new TestBrowserCallback(browserCallback)));
+                        mContext, token, new TestBrowserCallback(callback)));
             }
         });
         return controller.get();
@@ -120,7 +120,9 @@
                     Bundle rootHints, String rootMediaId, Bundle rootExtra) {
                 assertTrue(TestUtils.equals(param, rootHints));
                 assertEquals(ROOT_ID, rootMediaId);
-                assertTrue(TestUtils.equals(EXTRAS, rootExtra));
+                // Note that TestUtils#equals() cannot be used for this because
+                // MediaBrowserServiceCompat adds extra_client_version to the rootHints.
+                assertTrue(TestUtils.contains(rootExtra, EXTRAS));
                 latch.countDown();
             }
         };
@@ -316,6 +318,7 @@
         assertTrue(latchForGetSearchResult.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
     }
 
+    @Ignore
     @Test
     public void testSearchTakesTime() throws InterruptedException {
         prepareLooper();
@@ -342,6 +345,7 @@
                 MockMediaLibraryService2.SEARCH_TIME_IN_MS + WAIT_TIME_MS, TimeUnit.MILLISECONDS));
     }
 
+    @Ignore
     @Test
     public void testSearchEmptyResult() throws InterruptedException {
         prepareLooper();
@@ -504,7 +508,7 @@
 
         TestBrowserCallback(ControllerCallback callbackProxy) {
             if (callbackProxy == null) {
-                throw new IllegalArgumentException("Callback proxy shouldn't be null. Test bug");
+                callbackProxy = new BrowserCallback() {};
             }
             mCallbackProxy = callbackProxy;
         }
@@ -690,9 +694,9 @@
         private final BrowserCallback mCallback;
 
         public TestMediaBrowser(@NonNull Context context, @NonNull SessionToken2 token,
-                @NonNull ControllerCallback callback) {
-            super(context, token, sHandlerExecutor, (BrowserCallback) callback);
-            mCallback = (BrowserCallback) callback;
+                @NonNull BrowserCallback callback) {
+            super(context, token, sHandlerExecutor, callback);
+            mCallback = callback;
         }
 
         @Override
diff --git a/media/src/androidTest/java/androidx/media/MediaController2Test.java b/media/src/androidTest/java/androidx/media/MediaController2Test.java
index 75c9e50..d60a01e 100644
--- a/media/src/androidTest/java/androidx/media/MediaController2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaController2Test.java
@@ -49,7 +49,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -212,6 +211,7 @@
         final long position = 150000;
         final long bufferedPosition = 900000;
         final float speed = 0.5f;
+        final long timeDiff = 102;
         final MediaItem2 currentMediaItem = TestUtils.createMediaItemWithMetadata();
 
         mPlayer.mLastPlayerState = state;
@@ -221,18 +221,12 @@
         mPlayer.mPlaybackSpeed = speed;
         mMockAgent.mCurrentMediaItem = currentMediaItem;
 
-        long time1 = System.currentTimeMillis();
         MediaController2 controller = createController(mSession.getToken());
-        long time2 = System.currentTimeMillis();
+        controller.setTimeDiff(timeDiff);
         assertEquals(state, controller.getPlayerState());
         assertEquals(bufferedPosition, controller.getBufferedPosition());
         assertEquals(speed, controller.getPlaybackSpeed(), 0.0f);
-        long positionLowerBound = (long) (position + speed * (System.currentTimeMillis() - time2));
-        long currentPosition = controller.getCurrentPosition();
-        long positionUpperBound = (long) (position + speed * (System.currentTimeMillis() - time1));
-        assertTrue("curPos=" + currentPosition + ", lowerBound=" + positionLowerBound
-                        + ", upperBound=" + positionUpperBound,
-                positionLowerBound <= currentPosition && currentPosition <= positionUpperBound);
+        assertEquals(position + (long) (speed * timeDiff), controller.getCurrentPosition());
         assertEquals(currentMediaItem, controller.getCurrentMediaItem());
     }
 
@@ -420,6 +414,77 @@
         }
     }
 
+
+    @Test
+    public void testControllerCallback_onSeekCompleted() throws InterruptedException {
+        prepareLooper();
+        final long testSeekPosition = 400;
+        final long testPosition = 500;
+        final CountDownLatch latch = new CountDownLatch(1);
+        final ControllerCallback callback = new ControllerCallback() {
+            @Override
+            public void onSeekCompleted(MediaController2 controller, long position) {
+                controller.setTimeDiff(Long.valueOf(0));
+                assertEquals(testSeekPosition, position);
+                assertEquals(testPosition, controller.getCurrentPosition());
+                latch.countDown();
+            }
+        };
+        final MediaController2 controller = createController(mSession.getToken(), true, callback);
+        mPlayer.mCurrentPosition = testPosition;
+        mPlayer.notifySeekCompleted(testSeekPosition);
+        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+    }
+
+    @Test
+    public void testControllerCallback_onBufferingStateChanged() throws InterruptedException {
+        prepareLooper();
+        final List<MediaItem2> testPlaylist = TestUtils.createPlaylist(3);
+        final MediaItem2 testItem = testPlaylist.get(0);
+        final int testBufferingState = MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_PLAYABLE;
+        final long testBufferingPosition = 500;
+        final CountDownLatch latch = new CountDownLatch(1);
+        final ControllerCallback callback = new ControllerCallback() {
+            @Override
+            public void onBufferingStateChanged(MediaController2 controller, MediaItem2 item,
+                    int state) {
+                controller.setTimeDiff(Long.valueOf(0));
+                assertEquals(testItem, item);
+                assertEquals(testBufferingState, state);
+                assertEquals(testBufferingState, controller.getBufferingState());
+                assertEquals(testBufferingPosition, controller.getBufferedPosition());
+                latch.countDown();
+            }
+        };
+        final MediaController2 controller = createController(mSession.getToken(), true, callback);
+        mSession.setPlaylist(testPlaylist, null);
+        mPlayer.mBufferedPosition = testBufferingPosition;
+        mPlayer.notifyBufferingStateChanged(testItem.getDataSourceDesc(), testBufferingState);
+        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+    }
+
+    @Test
+    public void testControllerCallback_onPlayerStateChanged() throws InterruptedException {
+        prepareLooper();
+        final int testPlayerState = MediaPlayerBase.PLAYER_STATE_PLAYING;
+        final long testPosition = 500;
+        final CountDownLatch latch = new CountDownLatch(1);
+        final ControllerCallback callback = new ControllerCallback() {
+            @Override
+            public void onPlayerStateChanged(MediaController2 controller, int state) {
+                controller.setTimeDiff(Long.valueOf(0));
+                assertEquals(testPlayerState, state);
+                assertEquals(testPlayerState, controller.getPlayerState());
+                assertEquals(testPosition, controller.getCurrentPosition());
+                latch.countDown();
+            }
+        };
+        final MediaController2 controller = createController(mSession.getToken(), true, callback);
+        mPlayer.mCurrentPosition = testPosition;
+        mPlayer.notifyPlaybackState(testPlayerState);
+        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+    }
+
     @Test
     public void testAddPlaylistItem() throws InterruptedException {
         prepareLooper();
@@ -1065,30 +1130,29 @@
         };
         TestServiceRegistry.getInstance().setSessionCallback(sessionCallback);
 
-        mController = createController(TestUtils.getServiceToken(mContext, id));
+        final SessionCommand2 testCommand = new SessionCommand2("testConnectToService", null);
+        final CountDownLatch controllerLatch = new CountDownLatch(1);
+        mController = createController(TestUtils.getServiceToken(mContext, id), true,
+                new ControllerCallback() {
+                    @Override
+                    public void onCustomCommand(MediaController2 controller,
+                            SessionCommand2 command, Bundle args, ResultReceiver receiver) {
+                        if (testCommand.equals(command)) {
+                            controllerLatch.countDown();
+                        }
+                    }
+                }
+        );
         assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
-        // Test command from controller to session service
-        // TODO: Re enable when transport control works
-        /*
+        // Test command from controller to session service.
         mController.play();
         assertTrue(mPlayer.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         assertTrue(mPlayer.mPlayCalled);
-        */
 
-        // Test command from session service to controller
-        // TODO(jaewan): Add equivalent tests again
-        /*
-        final CountDownLatch latch = new CountDownLatch(1);
-        mController.registerPlayerEventCallback((state) -> {
-            assertNotNull(state);
-            assertEquals(PlaybackState.STATE_REWINDING, state.getState());
-            latch.countDown();
-        }, sHandler);
-        mPlayer.notifyPlaybackState(
-                TestUtils.createPlaybackState(PlaybackState.STATE_REWINDING));
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        */
+        // Test command from session service to controller.
+        mSession.sendCustomCommand(testCommand, null);
+        assertTrue(controllerLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
     }
 
     @Test
@@ -1097,15 +1161,11 @@
         testControllerAfterSessionIsClosed(mSession.getToken().getId());
     }
 
-    // TODO(jaewan): Re-enable this test
-    @Ignore
     @Test
     public void testControllerAfterSessionIsClosed_sessionService() throws InterruptedException {
         prepareLooper();
-        /*
-        connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID));
+        testConnectToService(MockMediaSessionService2.ID);
         testControllerAfterSessionIsClosed(MockMediaSessionService2.ID);
-        */
     }
 
     @Test
@@ -1192,14 +1252,12 @@
         testControllerAfterSessionIsClosed(id);
     }
 
-    @Ignore
     @Test
     public void testClose_sessionService() throws InterruptedException {
         prepareLooper();
         testCloseFromService(MockMediaSessionService2.ID);
     }
 
-    @Ignore
     @Test
     public void testClose_libraryService() throws InterruptedException {
         prepareLooper();
diff --git a/media/src/androidTest/java/androidx/media/MediaPlayer2Test.java b/media/src/androidTest/java/androidx/media/MediaPlayer2Test.java
index f565e8a..aff005d 100644
--- a/media/src/androidTest/java/androidx/media/MediaPlayer2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaPlayer2Test.java
@@ -29,6 +29,7 @@
 import android.media.MediaRecorder;
 import android.media.MediaTimestamp;
 import android.media.PlaybackParams;
+import android.media.SubtitleData;
 import android.media.SyncParams;
 import android.media.audiofx.AudioEffect;
 import android.media.audiofx.Visualizer;
@@ -36,6 +37,7 @@
 import android.os.Build;
 import android.os.Environment;
 import android.support.test.filters.LargeTest;
+import android.support.test.filters.MediumTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.Log;
@@ -54,9 +56,11 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
+import java.util.concurrent.BlockingDeque;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -81,7 +85,7 @@
 
     @Before
     @Override
-    public void setUp() throws Exception {
+    public void setUp() throws Throwable {
         super.setUp();
         mRecordedFilePath = new File(Environment.getExternalStorageDirectory(),
                 "mediaplayer_record.out").getAbsolutePath();
@@ -97,61 +101,8 @@
         }
     }
 
-    // Bug 13652927
-    public void testVorbisCrash() throws Exception {
-        MediaPlayer2 mp = mPlayer;
-        MediaPlayer2 mp2 = mPlayer2;
-        AssetFileDescriptor afd2 = mResources.openRawResourceFd(R.raw.testmp3_2);
-        mp2.setDataSource(new DataSourceDesc.Builder()
-                .setDataSource(afd2.getFileDescriptor(), afd2.getStartOffset(), afd2.getLength())
-                .build());
-        final Monitor onPrepareCalled = new Monitor();
-        final Monitor onErrorCalled = new Monitor();
-        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
-            @Override
-            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
-                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
-                    onPrepareCalled.signal();
-                }
-            }
-
-            @Override
-            public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
-                onErrorCalled.signal();
-            }
-        };
-        mp2.setMediaPlayer2EventCallback(mExecutor, ecb);
-        mp2.prepare();
-        onPrepareCalled.waitForSignal();
-        afd2.close();
-        mp2.clearMediaPlayer2EventCallback();
-
-        mp2.loopCurrent(true);
-        mp2.play();
-
-        for (int i = 0; i < 20; i++) {
-            try {
-                AssetFileDescriptor afd = mResources.openRawResourceFd(R.raw.bug13652927);
-                mp.setDataSource(new DataSourceDesc.Builder()
-                        .setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
-                            afd.getLength())
-                        .build());
-                mp.setMediaPlayer2EventCallback(mExecutor, ecb);
-                onPrepareCalled.reset();
-                mp.prepare();
-                onErrorCalled.waitForSignal();
-                afd.close();
-            } catch (Exception e) {
-                // expected to fail
-                Log.i("@@@", "failed: " + e);
-            }
-            Thread.sleep(500);
-            assertTrue("media player died",
-                    mp2.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
-            mp.reset();
-        }
-    }
-
+    @Test
+    @MediumTest
     public void testPlayNullSourcePath() throws Exception {
         final Monitor onSetDataSourceCalled = new Monitor();
         MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
@@ -172,6 +123,8 @@
         onSetDataSourceCalled.waitForSignal();
     }
 
+    @Test
+    @LargeTest
     public void testPlayAudioFromDataURI() throws Exception {
         final int mp3Duration = 34909;
         final int tolerance = 70;
@@ -220,9 +173,6 @@
                     .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                     .build();
             mp.setAudioAttributes(attributes);
-            /* FIXME: ensure screen is on while testing.
-            mp.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
-            */
 
             assertFalse(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
             onPlayCalled.reset();
@@ -284,6 +234,8 @@
         }
     }
 
+    @Test
+    @LargeTest
     public void testPlayAudio() throws Exception {
         final int resid = R.raw.testmp3_2;
         final int mp3Duration = 34909;
@@ -414,7 +366,6 @@
                         .setInternalLegacyStreamType(AudioManager.STREAM_MUSIC)
                         .build();
                 mp.setAudioAttributes(attributes);
-                mp.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
 
                 assertFalse(mp.isPlaying());
                 onPlayCalled.reset();
@@ -445,6 +396,8 @@
     }
     */
 
+    @Test
+    @LargeTest
     public void testPlayAudioLooping() throws Exception {
         final int resid = R.raw.testmp3;
 
@@ -462,8 +415,10 @@
                         @Override
                         public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd,
                                 int what, int extra) {
-                            Log.i("@@@", "got oncompletion");
-                            onCompletionCalled.signal();
+                            if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
+                                Log.i("@@@", "got oncompletion");
+                                onCompletionCalled.signal();
+                            }
                         }
 
                         @Override
@@ -500,6 +455,8 @@
         }
     }
 
+    @Test
+    @LargeTest
     public void testPlayMidi() throws Exception {
         final int resid = R.raw.midi8sec;
         final int midiDuration = 8000;
@@ -867,6 +824,8 @@
         assertEquals(Integer.parseInt(rotation), angle);
     }
 
+    @Test
+    @LargeTest
     public void testPlaylist() throws Exception {
         if (!checkLoadResource(
                 R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz)) {
@@ -1452,14 +1411,14 @@
         }
     }
 
+    @Test
+    @LargeTest
     public void testDeselectTrackForSubtitleTracks() throws Throwable {
         if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
             return; // skip;
         }
 
-        /* FIXME: find out counter part of waitForIdleSync.
-        getInstrumentation().waitForIdleSync();
-        */
+        mInstrumentation.waitForIdleSync();
 
         MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
             @Override
@@ -1482,21 +1441,18 @@
                     mOnDeselectTrackCalled.signal();
                 }
             }
-        };
-        synchronized (mEventCbLock) {
-            mEventCallbacks.add(ecb);
-        }
 
-        /* TODO: uncomment once API is available in supportlib.
-        mPlayer.setOnSubtitleDataListener(new MediaPlayer2.OnSubtitleDataListener() {
             @Override
-            public void onSubtitleData(MediaPlayer2 mp, SubtitleData data) {
+            public void onSubtitleData(
+                    MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) {
                 if (data != null && data.getData() != null) {
                     mOnSubtitleDataCalled.signal();
                 }
             }
-        });
-        */
+        };
+        synchronized (mEventCbLock) {
+            mEventCallbacks.add(ecb);
+        }
 
         mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
 
@@ -1539,22 +1495,13 @@
         mPlayer.reset();
     }
 
+    @Test
+    @LargeTest
     public void testChangeSubtitleTrack() throws Throwable {
         if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
             return; // skip;
         }
 
-        /* TODO: uncomment once API is available in supportlib.
-        mPlayer.setOnSubtitleDataListener(new MediaPlayer2.OnSubtitleDataListener() {
-            @Override
-            public void onSubtitleData(MediaPlayer2 mp, SubtitleData data) {
-                if (data != null && data.getData() != null) {
-                    mOnSubtitleDataCalled.signal();
-                }
-            }
-        });
-        */
-
         MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
             @Override
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
@@ -1571,6 +1518,14 @@
                     mOnPlayCalled.signal();
                 }
             }
+
+            @Override
+            public void onSubtitleData(
+                    MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) {
+                if (data != null && data.getData() != null) {
+                    mOnSubtitleDataCalled.signal();
+                }
+            }
         };
         synchronized (mEventCbLock) {
             mEventCallbacks.add(ecb);
@@ -1660,10 +1615,77 @@
         mPlayer.reset();
     }
 
+    @Test
+    @LargeTest
+    public void testMediaTimeDiscontinuity() throws Exception {
+        if (!checkLoadResource(
+                R.raw.bbb_s1_320x240_mp4_h264_mp2_800kbps_30fps_aac_lc_5ch_240kbps_44100hz)) {
+            return; // skip
+        }
+
+        final BlockingDeque<MediaTimestamp> timestamps = new LinkedBlockingDeque<>();
+        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
+            @Override
+            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
+                if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
+                    mOnSeekCompleteCalled.signal();
+                }
+            }
+            @Override
+            public void onMediaTimeDiscontinuity(
+                    MediaPlayer2 mp, DataSourceDesc dsd, MediaTimestamp timestamp) {
+                timestamps.add(timestamp);
+                mOnMediaTimeDiscontinuityCalled.signal();
+            }
+        };
+        synchronized (mEventCbLock) {
+            mEventCallbacks.add(ecb);
+        }
+
+        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
+        mPlayer.prepare();
+
+        // Timestamp needs to be reported when playback starts.
+        mOnMediaTimeDiscontinuityCalled.reset();
+        mPlayer.play();
+        do {
+            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
+        } while (Math.abs(timestamps.getLast().getMediaClockRate() - 1.0f) > 0.01f);
+
+        // Timestamp needs to be reported when seeking is done.
+        mOnSeekCompleteCalled.reset();
+        mOnMediaTimeDiscontinuityCalled.reset();
+        mPlayer.seekTo(3000);
+        mOnSeekCompleteCalled.waitForSignal();
+        do {
+            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
+        } while (Math.abs(timestamps.getLast().getMediaClockRate() - 1.0f) > 0.01f);
+
+        // Timestamp needs to be updated when playback rate changes.
+        mOnMediaTimeDiscontinuityCalled.reset();
+        mPlayer.setPlaybackParams(new PlaybackParams().setSpeed(0.5f));
+        mOnMediaTimeDiscontinuityCalled.waitForSignal();
+        do {
+            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
+        } while (Math.abs(timestamps.getLast().getMediaClockRate() - 0.5f) > 0.01f);
+
+        // Timestamp needs to be updated when player is paused.
+        mOnMediaTimeDiscontinuityCalled.reset();
+        mPlayer.pause();
+        mOnMediaTimeDiscontinuityCalled.waitForSignal();
+        do {
+            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
+        } while (Math.abs(timestamps.getLast().getMediaClockRate() - 0.0f) > 0.01f);
+
+        mPlayer.reset();
+    }
+
     /*
      *  This test assumes the resources being tested are between 8 and 14 seconds long
      *  The ones being used here are 10 seconds long.
      */
+    @Test
+    @LargeTest
     public void testResumeAtEnd() throws Throwable {
         int testsRun = testResumeAtEnd(R.raw.loudsoftmp3)
                 + testResumeAtEnd(R.raw.loudsoftwav)
diff --git a/media/src/androidTest/java/androidx/media/MediaPlayer2TestBase.java b/media/src/androidTest/java/androidx/media/MediaPlayer2TestBase.java
index 215993a..41fef64 100644
--- a/media/src/androidTest/java/androidx/media/MediaPlayer2TestBase.java
+++ b/media/src/androidTest/java/androidx/media/MediaPlayer2TestBase.java
@@ -15,20 +15,29 @@
  */
 package androidx.media;
 
+import static android.content.Context.KEYGUARD_SERVICE;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.app.Instrumentation;
+import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.media.AudioManager;
 import android.media.MediaTimestamp;
+import android.media.SubtitleData;
 import android.media.TimedMetaData;
 import android.net.Uri;
+import android.os.PersistableBundle;
+import android.os.PowerManager;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.view.SurfaceHolder;
+import android.view.WindowManager;
 
 import androidx.annotation.CallSuper;
 
@@ -41,6 +50,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.logging.Logger;
@@ -65,6 +75,7 @@
     protected Monitor mOnCompletionCalled = new Monitor();
     protected Monitor mOnInfoCalled = new Monitor();
     protected Monitor mOnErrorCalled = new Monitor();
+    protected Monitor mOnMediaTimeDiscontinuityCalled = new Monitor();
     protected int mCallStatus;
 
     protected Context mContext;
@@ -75,34 +86,35 @@
     protected MediaPlayer2 mPlayer = null;
     protected MediaPlayer2 mPlayer2 = null;
     protected MediaStubActivity mActivity;
+    protected Instrumentation mInstrumentation;
 
     protected final Object mEventCbLock = new Object();
-    protected List<MediaPlayer2.MediaPlayer2EventCallback> mEventCallbacks =
-            new ArrayList<MediaPlayer2.MediaPlayer2EventCallback>();
+    protected List<MediaPlayer2.MediaPlayer2EventCallback> mEventCallbacks = new ArrayList<>();
     protected final Object mEventCbLock2 = new Object();
-    protected List<MediaPlayer2.MediaPlayer2EventCallback> mEventCallbacks2 =
-            new ArrayList<MediaPlayer2.MediaPlayer2EventCallback>();
+    protected List<MediaPlayer2.MediaPlayer2EventCallback> mEventCallbacks2 = new ArrayList<>();
 
     @Rule
     public ActivityTestRule<MediaStubActivity> mActivityRule =
             new ActivityTestRule<>(MediaStubActivity.class);
+    public PowerManager.WakeLock mScreenLock;
+    private KeyguardManager mKeyguardManager;
 
     // convenience functions to create MediaPlayer2
-    protected static MediaPlayer2 createMediaPlayer2(Context context, Uri uri) {
+    protected MediaPlayer2 createMediaPlayer2(Context context, Uri uri) {
         return createMediaPlayer2(context, uri, null);
     }
 
-    protected static MediaPlayer2 createMediaPlayer2(Context context, Uri uri,
+    protected MediaPlayer2 createMediaPlayer2(Context context, Uri uri,
             SurfaceHolder holder) {
         AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
         int s = am.generateAudioSessionId();
         return createMediaPlayer2(context, uri, holder, null, s > 0 ? s : 0);
     }
 
-    protected static MediaPlayer2 createMediaPlayer2(Context context, Uri uri, SurfaceHolder holder,
+    protected MediaPlayer2 createMediaPlayer2(Context context, Uri uri, SurfaceHolder holder,
             AudioAttributesCompat audioAttributes, int audioSessionId) {
         try {
-            MediaPlayer2 mp = MediaPlayer2.create();
+            MediaPlayer2 mp = createMediaPlayer2OnUiThread();
             final AudioAttributesCompat aa = audioAttributes != null ? audioAttributes :
                     new AudioAttributesCompat.Builder().build();
             mp.setAudioAttributes(aa);
@@ -144,13 +156,13 @@
         return null;
     }
 
-    protected static MediaPlayer2 createMediaPlayer2(Context context, int resid) {
+    protected MediaPlayer2 createMediaPlayer2(Context context, int resid) {
         AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
         int s = am.generateAudioSessionId();
         return createMediaPlayer2(context, resid, null, s > 0 ? s : 0);
     }
 
-    protected static MediaPlayer2 createMediaPlayer2(Context context, int resid,
+    protected MediaPlayer2 createMediaPlayer2(Context context, int resid,
             AudioAttributesCompat audioAttributes, int audioSessionId) {
         try {
             AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
@@ -158,7 +170,7 @@
                 return null;
             }
 
-            MediaPlayer2 mp = MediaPlayer2.create();
+            MediaPlayer2 mp = createMediaPlayer2OnUiThread();
 
             final AudioAttributesCompat aa = audioAttributes != null ? audioAttributes :
                     new AudioAttributesCompat.Builder().build();
@@ -204,6 +216,20 @@
         return null;
     }
 
+    private MediaPlayer2 createMediaPlayer2OnUiThread() {
+        final MediaPlayer2[] mp = new MediaPlayer2[1];
+        try {
+            mActivityRule.runOnUiThread(new Runnable() {
+                public void run() {
+                    mp[0] = MediaPlayer2.create();
+                }
+            });
+        } catch (Throwable throwable) {
+            fail("Failed to create MediaPlayer2 instance on UI thread.");
+        }
+        return mp[0];
+    }
+
     public static class Monitor {
         private int mNumSignal;
 
@@ -258,8 +284,23 @@
 
     @Before
     @CallSuper
-    public void setUp() throws Exception {
+    public void setUp() throws Throwable {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mKeyguardManager = (KeyguardManager)
+                mInstrumentation.getTargetContext().getSystemService(KEYGUARD_SERVICE);
         mActivity = mActivityRule.getActivity();
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Keep screen on while testing.
+                mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+                mActivity.setTurnScreenOn(true);
+                mActivity.setShowWhenLocked(true);
+                mKeyguardManager.requestDismissKeyguard(mActivity, null);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
         try {
             mActivityRule.runOnUiThread(new Runnable() {
                 public void run() {
@@ -344,11 +385,11 @@
             }
 
             @Override
-            public void onMediaTimeChanged(MediaPlayer2 mp, DataSourceDesc dsd,
+            public void onMediaTimeDiscontinuity(MediaPlayer2 mp, DataSourceDesc dsd,
                     MediaTimestamp timestamp) {
                 synchronized (cbLock) {
                     for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
-                        ecb.onMediaTimeChanged(mp, dsd, timestamp);
+                        ecb.onMediaTimeDiscontinuity(mp, dsd, timestamp);
                     }
                 }
             }
@@ -361,6 +402,15 @@
                     }
                 }
             }
+            @Override
+            public  void onSubtitleData(MediaPlayer2 mp, DataSourceDesc dsd,
+                    final SubtitleData data) {
+                synchronized (cbLock) {
+                    for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
+                        ecb.onSubtitleData(mp, dsd, data);
+                    }
+                }
+            }
         });
     }
 
@@ -490,11 +540,7 @@
 
         boolean audioOnly = (width != null && width.intValue() == -1)
                 || (height != null && height.intValue() == -1);
-
         mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
-        /* FIXME: ensure that screen is on in activity level.
-        mPlayer.setScreenOnWhilePlaying(true);
-        */
 
         synchronized (mEventCbLock) {
             mEventCallbacks.add(new MediaPlayer2.MediaPlayer2EventCallback() {
@@ -566,6 +612,42 @@
             Thread.sleep(playTime);
         }
 
+        // validate a few MediaMetrics.
+        PersistableBundle metrics = mPlayer.getMetrics();
+        if (metrics == null) {
+            fail("MediaPlayer.getMetrics() returned null metrics");
+        } else if (metrics.isEmpty()) {
+            fail("MediaPlayer.getMetrics() returned empty metrics");
+        } else {
+
+            int size = metrics.size();
+            Set<String> keys = metrics.keySet();
+
+            if (keys == null) {
+                fail("MediaMetricsSet returned no keys");
+            } else if (keys.size() != size) {
+                fail("MediaMetricsSet.keys().size() mismatch MediaMetricsSet.size()");
+            }
+
+            // we played something; so one of these should be non-null
+            String vmime = metrics.getString(MediaPlayer2.MetricsConstants.MIME_TYPE_VIDEO, null);
+            String amime = metrics.getString(MediaPlayer2.MetricsConstants.MIME_TYPE_AUDIO, null);
+            if (vmime == null && amime == null) {
+                fail("getMetrics() returned neither video nor audio mime value");
+            }
+
+            long duration = metrics.getLong(MediaPlayer2.MetricsConstants.DURATION, -2);
+            if (duration == -2) {
+                fail("getMetrics() didn't return a duration");
+            }
+            long playing = metrics.getLong(MediaPlayer2.MetricsConstants.PLAYING, -2);
+            if (playing == -2) {
+                fail("getMetrics() didn't return a playing time");
+            }
+            if (!keys.contains(MediaPlayer2.MetricsConstants.PLAYING)) {
+                fail("MediaMetricsSet.keys() missing: " + MediaPlayer2.MetricsConstants.PLAYING);
+            }
+        }
         mPlayer.reset();
     }
 
diff --git a/media/src/androidTest/java/androidx/media/MediaSession2Test.java b/media/src/androidTest/java/androidx/media/MediaSession2Test.java
index 5e7ed0e..2283ea2 100644
--- a/media/src/androidTest/java/androidx/media/MediaSession2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaSession2Test.java
@@ -200,13 +200,38 @@
                     }
                 });
 
-        mPlayer.notifyBufferingState(targetItem, targetBufferingState);
+        mPlayer.notifyBufferingStateChanged(targetItem.getDataSourceDesc(), targetBufferingState);
         assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
         assertTrue(latchForControllerCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
         assertEquals(targetBufferingState, controller.getBufferingState());
     }
 
     @Test
+    public void testSeekCompleted() throws Exception {
+        prepareLooper();
+        final long testPosition = 1001;
+        final CountDownLatch latch = new CountDownLatch(1);
+        final SessionCallback callback = new SessionCallback() {
+            @Override
+            public void onSeekCompleted(MediaSession2 session, MediaPlayerBase mpb, long position) {
+                assertEquals(mPlayer, mpb);
+                assertEquals(testPosition, position);
+                latch.countDown();
+            }
+        };
+
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setPlayer(mPlayer)
+                .setPlaylistAgent(mMockAgent)
+                .setId("testSeekCompleted")
+                .setSessionCallback(sHandlerExecutor, callback).build()) {
+            mPlayer.mCurrentPosition = testPosition;
+            mPlayer.notifySeekCompleted(testPosition);
+            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        }
+    }
+
+    @Test
     public void testCurrentDataSourceChanged() throws Exception {
         prepareLooper();
         final int listSize = 5;
diff --git a/media/src/androidTest/java/androidx/media/MockPlayer.java b/media/src/androidTest/java/androidx/media/MockPlayer.java
index 49b1a19..19b43fb 100644
--- a/media/src/androidTest/java/androidx/media/MockPlayer.java
+++ b/media/src/androidTest/java/androidx/media/MockPlayer.java
@@ -155,21 +155,6 @@
         }
     }
 
-    public void notifyBufferingState(final MediaItem2 item, final int bufferingState) {
-        mLastBufferingState = bufferingState;
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            final PlayerEventCallback callback = mCallbacks.keyAt(i);
-            final Executor executor = mCallbacks.valueAt(i);
-            executor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    callback.onBufferingStateChanged(
-                            MockPlayer.this, item.getDataSourceDesc(), bufferingState);
-                }
-            });
-        }
-    }
-
     public void notifyCurrentDataSourceChanged(final DataSourceDesc dsd) {
         for (int i = 0; i < mCallbacks.size(); i++) {
             final PlayerEventCallback callback = mCallbacks.keyAt(i);
@@ -223,6 +208,19 @@
         }
     }
 
+    public void notifySeekCompleted(final long position) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            final PlayerEventCallback callback = mCallbacks.keyAt(i);
+            final Executor executor = mCallbacks.valueAt(i);
+            executor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    callback.onSeekCompleted(MockPlayer.this, position);
+                }
+            });
+        }
+    }
+
     public void notifyError(int what) {
         for (int i = 0; i < mCallbacks.size(); i++) {
             final PlayerEventCallback callback = mCallbacks.keyAt(i);
diff --git a/media/src/androidTest/java/androidx/media/TestUtils.java b/media/src/androidTest/java/androidx/media/TestUtils.java
index 1e3ba9b..160b392 100644
--- a/media/src/androidTest/java/androidx/media/TestUtils.java
+++ b/media/src/androidTest/java/androidx/media/TestUtils.java
@@ -68,17 +68,28 @@
      *     incorrect if any bundle contains a bundle.
      */
     public static boolean equals(Bundle a, Bundle b) {
+        return contains(a, b) && contains(b, a);
+    }
+
+    /**
+     * Checks whether a Bundle contains another bundle.
+     *
+     * @param a a bundle
+     * @param b another bundle
+     * @return {@code true} if a contains b. {@code false} otherwise. This may be incorrect if any
+     *      bundle contains a bundle.
+     */
+    public static boolean contains(Bundle a, Bundle b) {
         if (a == b) {
             return true;
         }
         if (a == null || b == null) {
+            return b == null;
+        }
+        if (!a.keySet().containsAll(b.keySet())) {
             return false;
         }
-        if (!a.keySet().containsAll(b.keySet())
-                || !b.keySet().containsAll(a.keySet())) {
-            return false;
-        }
-        for (String key : a.keySet()) {
+        for (String key : b.keySet()) {
             if (!Objects.equals(a.get(key), b.get(key))) {
                 return false;
             }
diff --git a/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java b/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
index a0e839b..dab83d8 100644
--- a/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
+++ b/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
@@ -1862,7 +1862,7 @@
                 mCallbacksMessenger = new Messenger(mHandler);
                 mHandler.setCallbacksMessenger(mCallbacksMessenger);
                 try {
-                    mServiceBinderWrapper.registerCallbackMessenger(mCallbacksMessenger);
+                    mServiceBinderWrapper.registerCallbackMessenger(mContext, mCallbacksMessenger);
                 } catch (RemoteException e) {
                     Log.i(TAG, "Remote error registering client messenger." );
                 }
@@ -2147,8 +2147,10 @@
             sendRequest(CLIENT_MSG_GET_MEDIA_ITEM, data, callbacksMessenger);
         }
 
-        void registerCallbackMessenger(Messenger callbackMessenger) throws RemoteException {
+        void registerCallbackMessenger(Context context, Messenger callbackMessenger)
+                throws RemoteException {
             Bundle data = new Bundle();
+            data.putString(DATA_PACKAGE_NAME, context.getPackageName());
             data.putBundle(DATA_ROOT_HINTS, mRootHints);
             sendRequest(CLIENT_MSG_REGISTER_CALLBACK_MESSENGER, data, callbackMessenger);
         }
diff --git a/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java b/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
index 1d78fc8..6e35977 100644
--- a/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -31,8 +31,10 @@
 import android.media.MediaMetadataRetriever;
 import android.media.Rating;
 import android.media.RemoteControlClient;
+import android.media.session.MediaSession;
 import android.net.Uri;
 import android.os.BadParcelableException;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
@@ -55,9 +57,12 @@
 import android.view.ViewConfiguration;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.core.app.BundleCompat;
+import androidx.media.MediaSessionManager;
+import androidx.media.MediaSessionManager.RemoteUserInfo;
 import androidx.media.VolumeProviderCompat;
 import androidx.media.session.MediaButtonReceiver;
 
@@ -383,6 +388,12 @@
     // Maximum size of the bitmap in dp.
     private static final int MAX_BITMAP_SIZE_IN_DP = 320;
 
+    private static final String LEGACY_CONTROLLER = "android.media.session.MediaController";
+    private static final String DATA_CALLING_PACKAGE = "data_calling_pkg";
+    private static final String DATA_CALLING_PID = "data_calling_pid";
+    private static final String DATA_CALLING_UID = "data_calling_uid";
+    private static final String DATA_EXTRAS = "data_extras";
+
     // Maximum size of the bitmap in px. It shouldn't be changed.
     static int sMaxBitmapSize;
 
@@ -449,7 +460,11 @@
             mbrIntent = PendingIntent.getBroadcast(context,
                     0/* requestCode, ignored */, mediaButtonIntent, 0/* flags */);
         }
-        if (android.os.Build.VERSION.SDK_INT >= 21) {
+        if (android.os.Build.VERSION.SDK_INT >= 28) {
+            mImpl = new MediaSessionImplApi28(context, tag);
+            // Set default callback to respond to controllers' extra binder requests.
+            setCallback(new Callback() {});
+        } else if (android.os.Build.VERSION.SDK_INT >= 21) {
             mImpl = new MediaSessionImplApi21(context, tag);
             // Set default callback to respond to controllers' extra binder requests.
             setCallback(new Callback() {});
@@ -802,6 +817,20 @@
     }
 
     /**
+     * @hide
+     * Gets the controller information who sent the current request.
+     * <p>
+     * Note: This is only valid while in a request callback, such as {@link Callback#onPlay}.
+     *
+     * @throws IllegalStateException If this method is called outside of {@link Callback} methods.
+     * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo)
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public final @NonNull RemoteUserInfo getCurrentControllerInfo() {
+        return mImpl.getCurrentControllerInfo();
+    }
+
+    /**
      * Returns the name of the package that sent the last media button, transport control, or
      * command from controllers and the system. This is only valid while in a request callback, such
      * as {@link Callback#onPlay}. This method is not available and returns null on pre-N devices.
@@ -1822,6 +1851,7 @@
         Object getRemoteControlClient();
 
         String getCallingPackage();
+        RemoteUserInfo getCurrentControllerInfo();
     }
 
     static class MediaSessionImplBase implements MediaSessionImpl {
@@ -1918,30 +1948,19 @@
             }
         }
 
-        void postToHandler(int what) {
-            postToHandler(what, null);
-        }
-
-        void postToHandler(int what, int arg1) {
-            postToHandler(what, null, arg1);
-        }
-
-        void postToHandler(int what, Object obj) {
-            postToHandler(what, obj, null);
-        }
-
-        void postToHandler(int what, Object obj, int arg1) {
+        void postToHandler(int what, int arg1, int arg2, Object obj, Bundle extras) {
             synchronized (mLock) {
                 if (mHandler != null) {
-                    mHandler.post(what, obj, arg1);
-                }
-            }
-        }
-
-        void postToHandler(int what, Object obj, Bundle extras) {
-            synchronized (mLock) {
-                if (mHandler != null) {
-                    mHandler.post(what, obj, extras);
+                    Message msg = mHandler.obtainMessage(what, arg1, arg2, obj);
+                    Bundle data = new Bundle();
+                    data.putString(DATA_CALLING_PACKAGE, LEGACY_CONTROLLER);
+                    data.putInt(DATA_CALLING_PID, Binder.getCallingPid());
+                    data.putInt(DATA_CALLING_UID, Binder.getCallingUid());
+                    if (extras == null) {
+                        data.putBundle(DATA_EXTRAS, extras);
+                    }
+                    msg.setData(data);
+                    msg.sendToTarget();
                 }
             }
         }
@@ -2282,6 +2301,16 @@
             sendExtras(extras);
         }
 
+        @Override
+        public RemoteUserInfo getCurrentControllerInfo() {
+            synchronized (mLock) {
+                if (mHandler != null) {
+                    return mHandler.getRemoteUserInfo();
+                }
+            }
+            return null;
+        }
+
         // Registers/unregisters components as needed.
         boolean update() {
             boolean registeredRcc = false;
@@ -2792,6 +2821,26 @@
             public boolean isTransportControlEnabled() {
                 return (mFlags & FLAG_HANDLES_TRANSPORT_CONTROLS) != 0;
             }
+
+            void postToHandler(int what) {
+                MediaSessionImplBase.this.postToHandler(what, 0, 0, null, null);
+            }
+
+            void postToHandler(int what, int arg1) {
+                MediaSessionImplBase.this.postToHandler(what, arg1, 0, null, null);
+            }
+
+            void postToHandler(int what, Object obj) {
+                MediaSessionImplBase.this.postToHandler(what, 0, 0, obj, null);
+            }
+
+            void postToHandler(int what, Object obj, int arg1) {
+                MediaSessionImplBase.this.postToHandler(what, arg1, 0, obj, null);
+            }
+
+            void postToHandler(int what, Object obj, Bundle extras) {
+                MediaSessionImplBase.this.postToHandler(what, 0, 0, obj, extras);
+            }
         }
 
         private static final class Command {
@@ -2843,138 +2892,133 @@
             private static final int KEYCODE_MEDIA_PAUSE = 127;
             private static final int KEYCODE_MEDIA_PLAY = 126;
 
+            private RemoteUserInfo mRemoteUserInfo;
+
             public MessageHandler(Looper looper) {
                 super(looper);
             }
 
-            public void post(int what, Object obj, Bundle bundle) {
-                Message msg = obtainMessage(what, obj);
-                msg.setData(bundle);
-                msg.sendToTarget();
-            }
-
-            public void post(int what, Object obj) {
-                obtainMessage(what, obj).sendToTarget();
-            }
-
-            public void post(int what) {
-                post(what, null);
-            }
-
-            public void post(int what, Object obj, int arg1) {
-                obtainMessage(what, arg1, 0, obj).sendToTarget();
-            }
-
             @Override
             public void handleMessage(Message msg) {
                 MediaSessionCompat.Callback cb = mCallback;
                 if (cb == null) {
                     return;
                 }
-                switch (msg.what) {
-                    case MSG_COMMAND:
-                        Command cmd = (Command) msg.obj;
-                        cb.onCommand(cmd.command, cmd.extras, cmd.stub);
-                        break;
-                    case MSG_MEDIA_BUTTON:
-                        KeyEvent keyEvent = (KeyEvent) msg.obj;
-                        Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
-                        intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-                        // Let the Callback handle events first before using the default behavior
-                        if (!cb.onMediaButtonEvent(intent)) {
-                            onMediaButtonEvent(keyEvent, cb);
-                        }
-                        break;
-                    case MSG_PREPARE:
-                        cb.onPrepare();
-                        break;
-                    case MSG_PREPARE_MEDIA_ID:
-                        cb.onPrepareFromMediaId((String) msg.obj, msg.getData());
-                        break;
-                    case MSG_PREPARE_SEARCH:
-                        cb.onPrepareFromSearch((String) msg.obj, msg.getData());
-                        break;
-                    case MSG_PREPARE_URI:
-                        cb.onPrepareFromUri((Uri) msg.obj, msg.getData());
-                        break;
-                    case MSG_PLAY:
-                        cb.onPlay();
-                        break;
-                    case MSG_PLAY_MEDIA_ID:
-                        cb.onPlayFromMediaId((String) msg.obj, msg.getData());
-                        break;
-                    case MSG_PLAY_SEARCH:
-                        cb.onPlayFromSearch((String) msg.obj, msg.getData());
-                        break;
-                    case MSG_PLAY_URI:
-                        cb.onPlayFromUri((Uri) msg.obj, msg.getData());
-                        break;
-                    case MSG_SKIP_TO_ITEM:
-                        cb.onSkipToQueueItem((Long) msg.obj);
-                        break;
-                    case MSG_PAUSE:
-                        cb.onPause();
-                        break;
-                    case MSG_STOP:
-                        cb.onStop();
-                        break;
-                    case MSG_NEXT:
-                        cb.onSkipToNext();
-                        break;
-                    case MSG_PREVIOUS:
-                        cb.onSkipToPrevious();
-                        break;
-                    case MSG_FAST_FORWARD:
-                        cb.onFastForward();
-                        break;
-                    case MSG_REWIND:
-                        cb.onRewind();
-                        break;
-                    case MSG_SEEK_TO:
-                        cb.onSeekTo((Long) msg.obj);
-                        break;
-                    case MSG_RATE:
-                        cb.onSetRating((RatingCompat) msg.obj);
-                        break;
-                    case MSG_RATE_EXTRA:
-                        cb.onSetRating((RatingCompat) msg.obj, msg.getData());
-                        break;
-                    case MSG_CUSTOM_ACTION:
-                        cb.onCustomAction((String) msg.obj, msg.getData());
-                        break;
-                    case MSG_ADD_QUEUE_ITEM:
-                        cb.onAddQueueItem((MediaDescriptionCompat) msg.obj);
-                        break;
-                    case MSG_ADD_QUEUE_ITEM_AT:
-                        cb.onAddQueueItem((MediaDescriptionCompat) msg.obj, msg.arg1);
-                        break;
-                    case MSG_REMOVE_QUEUE_ITEM:
-                        cb.onRemoveQueueItem((MediaDescriptionCompat) msg.obj);
-                        break;
-                    case MSG_REMOVE_QUEUE_ITEM_AT:
-                        if (mQueue != null) {
-                            QueueItem item = (msg.arg1 >= 0 && msg.arg1 < mQueue.size())
-                                    ? mQueue.get(msg.arg1) : null;
-                            if (item != null) {
-                                cb.onRemoveQueueItem(item.getDescription());
+
+                Bundle data = msg.getData();
+                mRemoteUserInfo = new RemoteUserInfo(data.getString(DATA_CALLING_PACKAGE),
+                        data.getInt(DATA_CALLING_PID), data.getInt(DATA_CALLING_UID));
+                data = data.getBundle(DATA_EXTRAS);
+
+                try {
+                    switch (msg.what) {
+                        case MSG_COMMAND:
+                            Command cmd = (Command) msg.obj;
+                            cb.onCommand(cmd.command, cmd.extras, cmd.stub);
+                            break;
+                        case MSG_MEDIA_BUTTON:
+                            KeyEvent keyEvent = (KeyEvent) msg.obj;
+                            Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+                            intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+                            // Let the Callback handle events first before using the default
+                            // behavior
+                            if (!cb.onMediaButtonEvent(intent)) {
+                                onMediaButtonEvent(keyEvent, cb);
                             }
-                        }
-                        break;
-                    case MSG_ADJUST_VOLUME:
-                        adjustVolume(msg.arg1, 0);
-                        break;
-                    case MSG_SET_VOLUME:
-                        setVolumeTo(msg.arg1, 0);
-                        break;
-                    case MSG_SET_CAPTIONING_ENABLED:
-                        cb.onSetCaptioningEnabled((boolean) msg.obj);
-                        break;
-                    case MSG_SET_REPEAT_MODE:
-                        cb.onSetRepeatMode(msg.arg1);
-                        break;
-                    case MSG_SET_SHUFFLE_MODE:
-                        cb.onSetShuffleMode(msg.arg1);
-                        break;
+                            break;
+                        case MSG_PREPARE:
+                            cb.onPrepare();
+                            break;
+                        case MSG_PREPARE_MEDIA_ID:
+                            cb.onPrepareFromMediaId((String) msg.obj, data);
+                            break;
+                        case MSG_PREPARE_SEARCH:
+                            cb.onPrepareFromSearch((String) msg.obj, data);
+                            break;
+                        case MSG_PREPARE_URI:
+                            cb.onPrepareFromUri((Uri) msg.obj, data);
+                            break;
+                        case MSG_PLAY:
+                            cb.onPlay();
+                            break;
+                        case MSG_PLAY_MEDIA_ID:
+                            cb.onPlayFromMediaId((String) msg.obj, data);
+                            break;
+                        case MSG_PLAY_SEARCH:
+                            cb.onPlayFromSearch((String) msg.obj, data);
+                            break;
+                        case MSG_PLAY_URI:
+                            cb.onPlayFromUri((Uri) msg.obj, data);
+                            break;
+                        case MSG_SKIP_TO_ITEM:
+                            cb.onSkipToQueueItem((Long) msg.obj);
+                            break;
+                        case MSG_PAUSE:
+                            cb.onPause();
+                            break;
+                        case MSG_STOP:
+                            cb.onStop();
+                            break;
+                        case MSG_NEXT:
+                            cb.onSkipToNext();
+                            break;
+                        case MSG_PREVIOUS:
+                            cb.onSkipToPrevious();
+                            break;
+                        case MSG_FAST_FORWARD:
+                            cb.onFastForward();
+                            break;
+                        case MSG_REWIND:
+                            cb.onRewind();
+                            break;
+                        case MSG_SEEK_TO:
+                            cb.onSeekTo((Long) msg.obj);
+                            break;
+                        case MSG_RATE:
+                            cb.onSetRating((RatingCompat) msg.obj);
+                            break;
+                        case MSG_RATE_EXTRA:
+                            cb.onSetRating((RatingCompat) msg.obj, data);
+                            break;
+                        case MSG_CUSTOM_ACTION:
+                            cb.onCustomAction((String) msg.obj, data);
+                            break;
+                        case MSG_ADD_QUEUE_ITEM:
+                            cb.onAddQueueItem((MediaDescriptionCompat) msg.obj);
+                            break;
+                        case MSG_ADD_QUEUE_ITEM_AT:
+                            cb.onAddQueueItem((MediaDescriptionCompat) msg.obj, msg.arg1);
+                            break;
+                        case MSG_REMOVE_QUEUE_ITEM:
+                            cb.onRemoveQueueItem((MediaDescriptionCompat) msg.obj);
+                            break;
+                        case MSG_REMOVE_QUEUE_ITEM_AT:
+                            if (mQueue != null) {
+                                QueueItem item = (msg.arg1 >= 0 && msg.arg1 < mQueue.size())
+                                        ? mQueue.get(msg.arg1) : null;
+                                if (item != null) {
+                                    cb.onRemoveQueueItem(item.getDescription());
+                                }
+                            }
+                            break;
+                        case MSG_ADJUST_VOLUME:
+                            adjustVolume(msg.arg1, 0);
+                            break;
+                        case MSG_SET_VOLUME:
+                            setVolumeTo(msg.arg1, 0);
+                            break;
+                        case MSG_SET_CAPTIONING_ENABLED:
+                            cb.onSetCaptioningEnabled((boolean) msg.obj);
+                            break;
+                        case MSG_SET_REPEAT_MODE:
+                            cb.onSetRepeatMode(msg.arg1);
+                            break;
+                        case MSG_SET_SHUFFLE_MODE:
+                            cb.onSetShuffleMode(msg.arg1);
+                            break;
+                    }
+                } finally {
+                    mRemoteUserInfo = null;
                 }
             }
 
@@ -3028,6 +3072,10 @@
                         break;
                 }
             }
+
+            RemoteUserInfo getRemoteUserInfo() {
+                return mRemoteUserInfo;
+            }
         }
     }
 
@@ -3050,7 +3098,8 @@
                         new RemoteControlClient.OnPlaybackPositionUpdateListener() {
                             @Override
                             public void onPlaybackPositionUpdate(long newPositionMs) {
-                                postToHandler(MessageHandler.MSG_SEEK_TO, newPositionMs);
+                                postToHandler(
+                                        MessageHandler.MSG_SEEK_TO, -1, -1, newPositionMs, null);
                             }
                         };
                 mRcc.setPlaybackPositionUpdateListener(listener);
@@ -3135,8 +3184,8 @@
                             public void onMetadataUpdate(int key, Object newValue) {
                                 if (key == MediaMetadataEditor.RATING_KEY_BY_USER
                                         && newValue instanceof Rating) {
-                                    postToHandler(MessageHandler.MSG_RATE,
-                                            RatingCompat.fromRating(newValue));
+                                    postToHandler(MessageHandler.MSG_RATE, -1, -1,
+                                            RatingCompat.fromRating(newValue), null);
                                 }
                             }
                         };
@@ -3410,6 +3459,11 @@
             }
         }
 
+        @Override
+        public RemoteUserInfo getCurrentControllerInfo() {
+            return null;
+        }
+
         class ExtraSession extends IMediaSession.Stub {
             @Override
             public void sendCommand(String command, Bundle args, ResultReceiverWrapper cb) {
@@ -3703,4 +3757,25 @@
             }
         }
     }
+
+    @RequiresApi(28)
+    static class MediaSessionImplApi28 extends MediaSessionImplApi21 {
+        private MediaSession mSession;
+
+        MediaSessionImplApi28(Context context, String tag) {
+            super(context, tag);
+        }
+
+        MediaSessionImplApi28(Object mediaSession) {
+            super(mediaSession);
+            mSession = (MediaSession) mediaSession;
+        }
+
+        @Override
+        public final @NonNull RemoteUserInfo getCurrentControllerInfo() {
+            android.media.session.MediaSessionManager.RemoteUserInfo info =
+                    mSession.getCurrentControllerInfo();
+            return new RemoteUserInfo(info.getPackageName(), info.getPid(), info.getUid());
+        }
+    }
 }
diff --git a/media/src/main/java/androidx/media/MediaBrowser2.java b/media/src/main/java/androidx/media/MediaBrowser2.java
index 6ef7fcf..04f666e 100644
--- a/media/src/main/java/androidx/media/MediaBrowser2.java
+++ b/media/src/main/java/androidx/media/MediaBrowser2.java
@@ -19,6 +19,7 @@
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
 import android.content.Context;
+import android.os.BadParcelableException;
 import android.os.Bundle;
 import android.support.v4.media.MediaBrowserCompat;
 import android.support.v4.media.MediaBrowserCompat.ItemCallback;
@@ -195,13 +196,20 @@
                 }
             });
         } else {
-            MediaBrowserCompat newBrowser = new MediaBrowserCompat(getContext(),
-                    getSessionToken().getComponentName(), new GetLibraryRootCallback(extras),
-                    extras);
-            newBrowser.connect();
-            synchronized (mLock) {
-                mBrowserCompats.put(extras, newBrowser);
-            }
+            getCallbackExecutor().execute(new Runnable() {
+                @Override
+                public void run() {
+                    // Do this on the callback executor to set the looper of MediaBrowserCompat's
+                    // callback handler to this looper.
+                    MediaBrowserCompat newBrowser = new MediaBrowserCompat(getContext(),
+                            getSessionToken().getComponentName(),
+                            new GetLibraryRootCallback(extras), extras);
+                    synchronized (mLock) {
+                        mBrowserCompats.put(extras, newBrowser);
+                    }
+                    newBrowser.connect();
+                }
+            });
         }
     }
 
@@ -218,16 +226,17 @@
         if (parentId == null) {
             throw new IllegalArgumentException("parentId shouldn't be null");
         }
-        // TODO: Document this behavior
-        Bundle option;
-        if (extras != null && (extras.containsKey(MediaBrowserCompat.EXTRA_PAGE)
-                || extras.containsKey(MediaBrowserCompat.EXTRA_PAGE_SIZE))) {
-            option = new Bundle(extras);
-            option.remove(MediaBrowserCompat.EXTRA_PAGE);
-            option.remove(MediaBrowserCompat.EXTRA_PAGE_SIZE);
-        } else {
-            option = extras;
+        // TODO: Revisit using default browser is OK. Here's my concern.
+        //       Assume that MediaBrowser2 is connected with the MediaBrowserServiceCompat.
+        //       Since MediaBrowserServiceCompat can call MediaBrowserServiceCompat#
+        //       getBrowserRootHints(), the service may refuse calls from MediaBrowser2.
+        //       It may be safe because there's not much app that implements MediaBrowserService
+        //       for sharing contents.
+        MediaBrowserCompat browser = getBrowserCompat();
+        if (browser == null) {
+            return;
         }
+        // TODO: Document that this API creates new SubscriptionCallback for each calls.
         SubscribeCallback callback = new SubscribeCallback();
         synchronized (mLock) {
             List<SubscribeCallback> list = mSubscribeCallbacks.get(parentId);
@@ -237,11 +246,11 @@
             }
             list.add(callback);
         }
-        // TODO: Revisit using default browser is OK. Here's my concern.
-        //       Assume that MediaBrowser2 is connected with the MediaBrowserServiceCompat.
-        //       Since MediaBrowserServiceCompat can call MediaBrowserServiceCompat#
-        //       getBrowserRootHints(), the service may refuse calls from MediaBrowser2
-        getBrowserCompat().subscribe(parentId, option, callback);
+        if (extras == null) {
+            browser.subscribe(parentId, callback);
+        } else {
+            browser.subscribe(parentId, extras, callback);
+        }
     }
 
     /**
@@ -257,6 +266,10 @@
         if (parentId == null) {
             throw new IllegalArgumentException("parentId shouldn't be null");
         }
+        MediaBrowserCompat browser = getBrowserCompat();
+        if (browser == null) {
+            return;
+        }
         // Note: don't use MediaBrowserCompat#unsubscribe(String) here, to keep the subscription
         // callback for getChildren.
         synchronized (mLock) {
@@ -264,7 +277,6 @@
             if (list == null) {
                 return;
             }
-            MediaBrowserCompat browser = getBrowserCompat();
             for (int i = 0; i < list.size(); i++) {
                 browser.unsubscribe(parentId, list.get(i));
             }
@@ -288,12 +300,16 @@
         if (page < 1 || pageSize < 1) {
             throw new IllegalArgumentException("Neither page nor pageSize should be less than 1");
         }
-        Bundle options = new Bundle(extras);
+        MediaBrowserCompat browser = getBrowserCompat();
+        if (browser == null) {
+            return;
+        }
+
+        Bundle options = MediaUtils2.createBundle(extras);
         options.putInt(MediaBrowserCompat.EXTRA_PAGE, page);
         options.putInt(MediaBrowserCompat.EXTRA_PAGE_SIZE, pageSize);
         // TODO: Revisit using default browser is OK. See TODO in subscribe
-        getBrowserCompat().subscribe(parentId, options,
-                new GetChildrenCallback(parentId, page, pageSize));
+        browser.subscribe(parentId, options, new GetChildrenCallback(parentId, page, pageSize));
     }
 
     /**
@@ -304,7 +320,11 @@
      */
     public void getItem(@NonNull final String mediaId) {
         // TODO: Revisit using default browser is OK. See TODO in subscribe
-        getBrowserCompat().getItem(mediaId, new ItemCallback() {
+        MediaBrowserCompat browser = getBrowserCompat();
+        if (browser == null) {
+            return;
+        }
+        browser.getItem(mediaId, new ItemCallback() {
             @Override
             public void onItemLoaded(final MediaItem item) {
                 getCallbackExecutor().execute(new Runnable() {
@@ -367,6 +387,20 @@
         }
     }
 
+    private Bundle getExtrasWithoutPagination(Bundle extras) {
+        if (extras == null) {
+            return null;
+        }
+        extras.setClassLoader(getContext().getClassLoader());
+        try {
+            extras.remove(MediaBrowserCompat.EXTRA_PAGE);
+            extras.remove(MediaBrowserCompat.EXTRA_PAGE_SIZE);
+        } catch (BadParcelableException e) {
+            // Pass through...
+        }
+        return extras;
+    }
+
     private class GetLibraryRootCallback extends MediaBrowserCompat.ConnectionCallback {
         private final Bundle mExtras;
 
@@ -472,7 +506,7 @@
 
         @Override
         public void onChildrenLoaded(final String parentId, List<MediaItem> children,
-                final Bundle options) {
+                Bundle options) {
             final List<MediaItem2> items;
             if (children == null) {
                 items = null;
@@ -482,12 +516,17 @@
                     items.add(MediaUtils2.createMediaItem2(children.get(i)));
                 }
             }
+            final Bundle extras = getExtrasWithoutPagination(options);
             getCallbackExecutor().execute(new Runnable() {
                 @Override
                 public void run() {
+                    MediaBrowserCompat browser = getBrowserCompat();
+                    if (browser == null) {
+                        return;
+                    }
                     getCallback().onGetChildrenDone(MediaBrowser2.this, parentId, mPage, mPageSize,
-                            items, options);
-                    getBrowserCompat().unsubscribe(mParentId, GetChildrenCallback.this);
+                            items, extras);
+                    browser.unsubscribe(mParentId, GetChildrenCallback.this);
                 }
             });
         }
diff --git a/media/src/main/java/androidx/media/MediaBrowserProtocol.java b/media/src/main/java/androidx/media/MediaBrowserProtocol.java
index 5c85880..02e0014 100644
--- a/media/src/main/java/androidx/media/MediaBrowserProtocol.java
+++ b/media/src/main/java/androidx/media/MediaBrowserProtocol.java
@@ -29,6 +29,7 @@
 
     public static final String DATA_CALLBACK_TOKEN = "data_callback_token";
     public static final String DATA_CALLING_UID = "data_calling_uid";
+    public static final String DATA_CALLING_PID = "data_calling_pid";
     public static final String DATA_MEDIA_ITEM_ID = "data_media_item_id";
     public static final String DATA_MEDIA_ITEM_LIST = "data_media_item_list";
     public static final String DATA_MEDIA_SESSION_TOKEN = "data_media_session_token";
diff --git a/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java b/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
index 8f24837..aa8392f 100644
--- a/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
+++ b/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
@@ -17,6 +17,7 @@
 package androidx.media;
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 import static androidx.media.MediaBrowserProtocol.CLIENT_MSG_ADD_SUBSCRIPTION;
 import static androidx.media.MediaBrowserProtocol.CLIENT_MSG_CONNECT;
 import static androidx.media.MediaBrowserProtocol.CLIENT_MSG_DISCONNECT;
@@ -27,6 +28,7 @@
 import static androidx.media.MediaBrowserProtocol.CLIENT_MSG_SEND_CUSTOM_ACTION;
 import static androidx.media.MediaBrowserProtocol.CLIENT_MSG_UNREGISTER_CALLBACK_MESSENGER;
 import static androidx.media.MediaBrowserProtocol.DATA_CALLBACK_TOKEN;
+import static androidx.media.MediaBrowserProtocol.DATA_CALLING_PID;
 import static androidx.media.MediaBrowserProtocol.DATA_CALLING_UID;
 import static androidx.media.MediaBrowserProtocol.DATA_CUSTOM_ACTION;
 import static androidx.media.MediaBrowserProtocol.DATA_CUSTOM_ACTION_EXTRAS;
@@ -61,6 +63,7 @@
 import android.os.Messenger;
 import android.os.Parcel;
 import android.os.RemoteException;
+import android.service.media.MediaBrowserService;
 import android.support.v4.media.MediaBrowserCompat;
 import android.support.v4.media.session.IMediaSession;
 import android.support.v4.media.session.MediaSessionCompat;
@@ -76,6 +79,7 @@
 import androidx.collection.ArrayMap;
 import androidx.core.app.BundleCompat;
 import androidx.core.util.Pair;
+import androidx.media.MediaSessionManager.RemoteUserInfo;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -167,9 +171,10 @@
     /** @hide */
     @RestrictTo(LIBRARY)
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag=true, value = { RESULT_FLAG_OPTION_NOT_HANDLED,
-            RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED, RESULT_FLAG_ON_SEARCH_NOT_IMPLEMENTED })
-    private @interface ResultFlags { }
+    @IntDef(flag = true, value = {RESULT_FLAG_OPTION_NOT_HANDLED,
+            RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED, RESULT_FLAG_ON_SEARCH_NOT_IMPLEMENTED})
+    private @interface ResultFlags {
+    }
 
     final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap<>();
     ConnectionRecord mCurConnection;
@@ -182,6 +187,7 @@
         void setSessionToken(MediaSessionCompat.Token token);
         void notifyChildrenChanged(final String parentId, final Bundle options);
         Bundle getBrowserRootHints();
+        RemoteUserInfo getCurrentBrowserInfo();
     }
 
     class MediaBrowserServiceImplBase implements MediaBrowserServiceImpl {
@@ -206,7 +212,7 @@
                 @Override
                 public void run() {
                     Iterator<ConnectionRecord> iter = mConnections.values().iterator();
-                    while (iter.hasNext()){
+                    while (iter.hasNext()) {
                         ConnectionRecord connection = iter.next();
                         try {
                             connection.callbacks.onConnect(connection.root.getRootId(), token,
@@ -246,10 +252,19 @@
         public Bundle getBrowserRootHints() {
             if (mCurConnection == null) {
                 throw new IllegalStateException("This should be called inside of onLoadChildren,"
-                        + " onLoadItem or onSearch methods");
+                        + " onLoadItem, onSearch, or onCustomAction methods");
             }
             return mCurConnection.rootHints == null ? null : new Bundle(mCurConnection.rootHints);
         }
+
+        @Override
+        public RemoteUserInfo getCurrentBrowserInfo() {
+            if (mCurConnection == null) {
+                throw new IllegalStateException("This should be called inside of onLoadChildren,"
+                        + " onLoadItem, onSearch, or onCustomAction methods");
+            }
+            return mCurConnection.browserInfo;
+        }
     }
 
     @RequiresApi(21)
@@ -298,19 +313,6 @@
         }
 
         @Override
-        public Bundle getBrowserRootHints() {
-            if (mMessenger == null) {
-                // TODO: Handle getBrowserRootHints when connected with framework MediaBrowser.
-                return null;
-            }
-            if (mCurConnection == null) {
-                throw new IllegalStateException("This should be called inside of onLoadChildren,"
-                        + " onLoadItem or onSearch methods");
-            }
-            return mCurConnection.rootHints == null ? null : new Bundle(mCurConnection.rootHints);
-        }
-
-        @Override
         public MediaBrowserServiceCompatApi21.BrowserRoot onGetRoot(
                 String clientPackageName, int clientUid, Bundle rootHints) {
             Bundle rootExtras = null;
@@ -393,6 +395,28 @@
                 }
             });
         }
+
+        @Override
+        public Bundle getBrowserRootHints() {
+            if (mMessenger == null) {
+                // TODO: Handle getBrowserRootHints when connected with framework MediaBrowser.
+                return null;
+            }
+            if (mCurConnection == null) {
+                throw new IllegalStateException("This should be called inside of onLoadChildren,"
+                        + " onLoadItem, onSearch, or onCustomAction methods");
+            }
+            return mCurConnection.rootHints == null ? null : new Bundle(mCurConnection.rootHints);
+        }
+
+        @Override
+        public RemoteUserInfo getCurrentBrowserInfo() {
+            if (mCurConnection == null) {
+                throw new IllegalStateException("This should be called inside of onLoadChildren,"
+                        + " onLoadItem, onSearch, or onCustomAction methods");
+            }
+            return mCurConnection.browserInfo;
+        }
     }
 
     @RequiresApi(23)
@@ -488,6 +512,17 @@
         }
     }
 
+    @RequiresApi(28)
+    class MediaBrowserServiceImplApi28 extends MediaBrowserServiceImplApi26 {
+        @Override
+        public RemoteUserInfo getCurrentBrowserInfo() {
+            android.media.session.MediaSessionManager.RemoteUserInfo userInfoObj =
+                    ((MediaBrowserService) mServiceObj).getCurrentBrowserInfo();
+            return new RemoteUserInfo(
+                    userInfoObj.getPackageName(), userInfoObj.getPid(), userInfoObj.getUid());
+        }
+    }
+
     private final class ServiceHandler extends Handler {
         private final ServiceBinderImpl mServiceBinderImpl = new ServiceBinderImpl();
 
@@ -500,7 +535,8 @@
             switch (msg.what) {
                 case CLIENT_MSG_CONNECT:
                     mServiceBinderImpl.connect(data.getString(DATA_PACKAGE_NAME),
-                            data.getInt(DATA_CALLING_UID), data.getBundle(DATA_ROOT_HINTS),
+                            data.getInt(DATA_CALLING_PID), data.getInt(DATA_CALLING_UID),
+                            data.getBundle(DATA_ROOT_HINTS),
                             new ServiceCallbacksCompat(msg.replyTo));
                     break;
                 case CLIENT_MSG_DISCONNECT:
@@ -524,7 +560,8 @@
                     break;
                 case CLIENT_MSG_REGISTER_CALLBACK_MESSENGER:
                     mServiceBinderImpl.registerCallbacks(new ServiceCallbacksCompat(msg.replyTo),
-                            data.getBundle(DATA_ROOT_HINTS));
+                            data.getString(DATA_PACKAGE_NAME), data.getInt(DATA_CALLING_PID),
+                            data.getInt(DATA_CALLING_UID), data.getBundle(DATA_ROOT_HINTS));
                     break;
                 case CLIENT_MSG_UNREGISTER_CALLBACK_MESSENGER:
                     mServiceBinderImpl.unregisterCallbacks(new ServiceCallbacksCompat(msg.replyTo));
@@ -555,6 +592,7 @@
             Bundle data = msg.getData();
             data.setClassLoader(MediaBrowserCompat.class.getClassLoader());
             data.putInt(DATA_CALLING_UID, Binder.getCallingUid());
+            data.putInt(DATA_CALLING_PID, Binder.getCallingPid());
             return super.sendMessageAtTime(msg, uptimeMillis);
         }
 
@@ -571,13 +609,23 @@
      * All the info about a connection.
      */
     private class ConnectionRecord implements IBinder.DeathRecipient {
-        String pkg;
-        Bundle rootHints;
-        ServiceCallbacks callbacks;
-        BrowserRoot root;
-        HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>();
+        public final String pkg;
+        public final int pid;
+        public final int uid;
+        public final RemoteUserInfo browserInfo;
+        public final Bundle rootHints;
+        public final ServiceCallbacks callbacks;
+        public final HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>();
+        public BrowserRoot root;
 
-        ConnectionRecord() {
+        ConnectionRecord(String pkg, int pid, int uid, Bundle rootHints,
+                ServiceCallbacks callback) {
+            this.pkg = pkg;
+            this.pid = pid;
+            this.uid = uid;
+            this.browserInfo = new RemoteUserInfo(pkg, pid, uid);
+            this.rootHints = rootHints;
+            this.callbacks = callback;
         }
 
         @Override
@@ -740,7 +788,7 @@
         ServiceBinderImpl() {
         }
 
-        public void connect(final String pkg, final int uid, final Bundle rootHints,
+        public void connect(final String pkg, final int pid, final int uid, final Bundle rootHints,
                 final ServiceCallbacks callbacks) {
 
             if (!isValidPackage(pkg, uid)) {
@@ -756,13 +804,11 @@
                     // Clear out the old subscriptions. We are getting new ones.
                     mConnections.remove(b);
 
-                    final ConnectionRecord connection = new ConnectionRecord();
-                    connection.pkg = pkg;
-                    connection.rootHints = rootHints;
-                    connection.callbacks = callbacks;
-
-                    connection.root =
-                            MediaBrowserServiceCompat.this.onGetRoot(pkg, uid, rootHints);
+                    final ConnectionRecord connection = new ConnectionRecord(pkg, pid, uid,
+                            rootHints, callbacks);
+                    mCurConnection = connection;
+                    connection.root = MediaBrowserServiceCompat.this.onGetRoot(pkg, uid, rootHints);
+                    mCurConnection = null;
 
                     // If they didn't return something, don't allow this client.
                     if (connection.root == null) {
@@ -872,7 +918,8 @@
         }
 
         // Used when {@link MediaBrowserProtocol#EXTRA_MESSENGER_BINDER} is used.
-        public void registerCallbacks(final ServiceCallbacks callbacks, final Bundle rootHints) {
+        public void registerCallbacks(final ServiceCallbacks callbacks, final String pkg,
+                final int pid, final int uid, final Bundle rootHints) {
             mHandler.postOrRun(new Runnable() {
                 @Override
                 public void run() {
@@ -880,9 +927,8 @@
                     // Clear out the old subscriptions. We are getting new ones.
                     mConnections.remove(b);
 
-                    final ConnectionRecord connection = new ConnectionRecord();
-                    connection.callbacks = callbacks;
-                    connection.rootHints = rootHints;
+                    final ConnectionRecord connection = new ConnectionRecord(pkg, pid, uid,
+                            rootHints, callbacks);
                     mConnections.put(b, connection);
                     try {
                         b.linkToDeath(connection, 0);
@@ -1031,7 +1077,9 @@
     @Override
     public void onCreate() {
         super.onCreate();
-        if (Build.VERSION.SDK_INT >= 26) {
+        if (Build.VERSION.SDK_INT >= 28) {
+            mImpl = new MediaBrowserServiceImplApi28();
+        } else if (Build.VERSION.SDK_INT >= 26) {
             mImpl = new MediaBrowserServiceImplApi26();
         } else if (Build.VERSION.SDK_INT >= 23) {
             mImpl = new MediaBrowserServiceImplApi23();
@@ -1253,6 +1301,23 @@
     }
 
     /**
+     * @hide
+     * Gets the browser information who sent the current request.
+     *
+     * @throws IllegalStateException If this method is called outside of {@link #onGetRoot} or
+     *             {@link #onLoadChildren} or {@link #onLoadItem}.
+     * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo)
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public final RemoteUserInfo getCurrentBrowserInfo() {
+        if (mCurConnection == null) {
+            throw new IllegalStateException("This should be called inside of onGetRoot or"
+                    + " onLoadChildren or onLoadItem methods");
+        }
+        return mImpl.getCurrentBrowserInfo();
+    }
+
+    /**
      * Notifies all connected media browsers that the children of
      * the specified parent id have changed in some way.
      * This will cause browsers to fetch subscribed content again.
diff --git a/media/src/main/java/androidx/media/MediaConstants2.java b/media/src/main/java/androidx/media/MediaConstants2.java
index 68a9a19..6f1132a 100644
--- a/media/src/main/java/androidx/media/MediaConstants2.java
+++ b/media/src/main/java/androidx/media/MediaConstants2.java
@@ -33,8 +33,10 @@
             "androidx.media.session.event.ON_PLAYBACK_INFO_CHANGED";
     static final String SESSION_EVENT_ON_PLAYBACK_SPEED_CHANGED =
             "androidx.media.session.event.ON_PLAYBACK_SPEED_CHANGED";
-    static final String SESSION_EVENT_ON_BUFFERING_STATE_CHAGNED =
+    static final String SESSION_EVENT_ON_BUFFERING_STATE_CHANGED =
             "androidx.media.session.event.ON_BUFFERING_STATE_CHANGED";
+    static final String SESSION_EVENT_ON_SEEK_COMPLETED =
+            "androidx.media.session.event.ON_SEEK_COMPLETED";
     static final String SESSION_EVENT_ON_REPEAT_MODE_CHANGED =
             "androidx.media.session.event.ON_REPEAT_MODE_CHANGED";
     static final String SESSION_EVENT_ON_SHUFFLE_MODE_CHANGED =
diff --git a/media/src/main/java/androidx/media/MediaController2.java b/media/src/main/java/androidx/media/MediaController2.java
index 1da552d..027178c 100644
--- a/media/src/main/java/androidx/media/MediaController2.java
+++ b/media/src/main/java/androidx/media/MediaController2.java
@@ -58,7 +58,7 @@
 import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_CONNECT;
 import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_DISCONNECT;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_BUFFERING_STATE_CHAGNED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_BUFFERING_STATE_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_CURRENT_MEDIA_ITEM_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ERROR;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED;
@@ -68,6 +68,7 @@
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYLIST_METADATA_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_REPEAT_MODE_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ROUTES_INFO_CHANGED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_SEEK_COMPLETED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_SHUFFLE_MODE_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_SEND_CUSTOM_COMMAND;
 import static androidx.media.MediaConstants2.SESSION_EVENT_SET_CUSTOM_LAYOUT;
@@ -130,6 +131,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.annotation.VisibleForTesting;
 import androidx.media.MediaPlaylistAgent.RepeatMode;
 import androidx.media.MediaPlaylistAgent.ShuffleMode;
 import androidx.media.MediaSession2.CommandButton;
@@ -542,8 +544,14 @@
                 }
                 case SESSION_EVENT_ON_PLAYER_STATE_CHANGED: {
                     int playerState = extras.getInt(ARGUMENT_PLAYER_STATE);
+                    PlaybackStateCompat state =
+                            extras.getParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT);
+                    if (state == null) {
+                        return;
+                    }
                     synchronized (mLock) {
                         mPlayerState = playerState;
+                        mPlaybackStateCompat = state;
                     }
                     mCallback.onPlayerStateChanged(MediaController2.this, playerState);
                     break;
@@ -653,18 +661,33 @@
                             MediaController2.this, state.getPlaybackSpeed());
                     break;
                 }
-                case SESSION_EVENT_ON_BUFFERING_STATE_CHAGNED: {
+                case SESSION_EVENT_ON_BUFFERING_STATE_CHANGED: {
                     MediaItem2 item = MediaItem2.fromBundle(extras.getBundle(ARGUMENT_MEDIA_ITEM));
                     int bufferingState = extras.getInt(ARGUMENT_BUFFERING_STATE);
-                    if (item == null) {
+                    PlaybackStateCompat state =
+                            extras.getParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT);
+                    if (item == null || state == null) {
                         return;
                     }
                     synchronized (mLock) {
                         mBufferingState = bufferingState;
+                        mPlaybackStateCompat = state;
                     }
                     mCallback.onBufferingStateChanged(MediaController2.this, item, bufferingState);
                     break;
                 }
+                case SESSION_EVENT_ON_SEEK_COMPLETED: {
+                    long position = extras.getLong(ARGUMENT_SEEK_POSITION);
+                    PlaybackStateCompat state =
+                            extras.getParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT);
+                    if (state == null) {
+                        return;
+                    }
+                    synchronized (mLock) {
+                        mPlaybackStateCompat = state;
+                    }
+                    mCallback.onSeekCompleted(MediaController2.this, position);
+                }
             }
         }
     }
@@ -723,6 +746,9 @@
     @GuardedBy("mLock")
     private MediaMetadataCompat mMediaMetadataCompat;
 
+    // For testing.
+    private Long mTimeDiff;
+
     // Assignment should be used with the lock hold, but should be used without a lock to prevent
     // potential deadlock.
     @GuardedBy("mLock")
@@ -1197,7 +1223,7 @@
                 return UNKNOWN_TIME;
             }
             if (mPlaybackStateCompat != null) {
-                long timeDiff = SystemClock.elapsedRealtime()
+                long timeDiff = (mTimeDiff != null) ? mTimeDiff : SystemClock.elapsedRealtime()
                         - mPlaybackStateCompat.getLastPositionUpdateTime();
                 long expectedPosition = mPlaybackStateCompat.getPosition()
                         + (long) (mPlaybackStateCompat.getPlaybackSpeed() * timeDiff);
@@ -1208,6 +1234,15 @@
     }
 
     /**
+     * Sets the time diff forcefully when calculating current position.
+     * @param timeDiff {@code null} for reset.
+     */
+    @VisibleForTesting
+    void setTimeDiff(Long timeDiff) {
+        mTimeDiff = timeDiff;
+    }
+
+    /**
      * Get the lastly cached playback speed from
      * {@link ControllerCallback#onPlaybackSpeedChanged(MediaController2, float)}.
      *
@@ -1684,11 +1719,16 @@
     }
 
     private void connectToService() {
-        synchronized (mLock) {
-            mBrowserCompat = new MediaBrowserCompat(mContext, mToken.getComponentName(),
-                    new ConnectionCallback(), sDefaultRootExtras);
-            mBrowserCompat.connect();
-        }
+        mCallbackExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                synchronized (mLock) {
+                    mBrowserCompat = new MediaBrowserCompat(mContext, mToken.getComponentName(),
+                            new ConnectionCallback(), sDefaultRootExtras);
+                    mBrowserCompat.connect();
+                }
+            }
+        });
     }
 
     private void sendCommand(int commandCode) {
diff --git a/media/src/main/java/androidx/media/MediaLibraryService2.java b/media/src/main/java/androidx/media/MediaLibraryService2.java
index edd97c3..5a3a26c 100644
--- a/media/src/main/java/androidx/media/MediaLibraryService2.java
+++ b/media/src/main/java/androidx/media/MediaLibraryService2.java
@@ -23,8 +23,10 @@
 
 import android.app.PendingIntent;
 import android.content.Intent;
+import android.os.BadParcelableException;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.Process;
 import android.support.v4.media.MediaBrowserCompat.MediaItem;
 
 import androidx.annotation.NonNull;
@@ -36,7 +38,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 
 /**
@@ -291,7 +292,7 @@
          */
         public void notifyChildrenChanged(@NonNull ControllerInfo controller,
                 @NonNull String parentId, int itemCount, @Nullable Bundle extras) {
-            Bundle options = new Bundle(extras);
+            Bundle options = MediaUtils2.createBundle(extras);
             options.putInt(MediaBrowser2.EXTRA_ITEM_COUNT, itemCount);
             options.putBundle(MediaBrowser2.EXTRA_TARGET, controller.toBundle());
         }
@@ -308,7 +309,7 @@
         // This is for the backward compatibility.
         public void notifyChildrenChanged(@NonNull String parentId, int itemCount,
                 @Nullable Bundle extras) {
-            Bundle options = new Bundle(extras);
+            Bundle options = MediaUtils2.createBundle(extras);
             options.putInt(MediaBrowser2.EXTRA_ITEM_COUNT, itemCount);
             getServiceCompat().notifyChildrenChanged(parentId, options);
         }
@@ -494,7 +495,6 @@
                 // controller.
                 return sDefaultBrowserRoot;
             }
-            final CountDownLatch latch = new CountDownLatch(1);
             // TODO: Revisit this when we support caller information.
             final ControllerInfo info = new ControllerInfo(MediaLibraryService2.this, clientUid, -1,
                     clientPackageName, null);
@@ -526,36 +526,47 @@
         @Override
         public void onLoadChildren(final String parentId, final Result<List<MediaItem>> result,
                 final Bundle options) {
+            result.detach();
             final ControllerInfo controller = getController();
             getLibrarySession().getCallbackExecutor().execute(new Runnable() {
                 @Override
                 public void run() {
-                    int page = options.getInt(EXTRA_PAGE, -1);
-                    int pageSize = options.getInt(EXTRA_PAGE_SIZE, -1);
-                    if (page >= 0 && pageSize >= 0) {
-                        // Requesting the list of children through the pagenation.
-                        List<MediaItem2> children = getLibrarySession().getCallback().onGetChildren(
-                                getLibrarySession(), controller, parentId, page, pageSize, options);
-                        if (children == null) {
-                            result.sendError(null);
-                        } else {
-                            List<MediaItem> list = new ArrayList<>();
-                            for (int i = 0; i < children.size(); i++) {
-                                list.add(MediaUtils2.createMediaItem(children.get(i)));
+                    if (options != null) {
+                        options.setClassLoader(MediaLibraryService2.this.getClassLoader());
+                        try {
+                            int page = options.getInt(EXTRA_PAGE, -1);
+                            int pageSize = options.getInt(EXTRA_PAGE_SIZE, -1);
+                            if (page >= 0 && pageSize >= 0) {
+                                // Requesting the list of children through the pagenation.
+                                List<MediaItem2> children = getLibrarySession().getCallback()
+                                        .onGetChildren(getLibrarySession(), controller, parentId,
+                                                page,
+                                                pageSize, options);
+                                if (children == null) {
+                                    result.sendResult(null);
+                                } else {
+                                    List<MediaItem> list = new ArrayList<>();
+                                    for (int i = 0; i < children.size(); i++) {
+                                        list.add(MediaUtils2.createMediaItem(children.get(i)));
+                                    }
+                                    result.sendResult(list);
+                                }
+                                return;
                             }
-                            result.sendResult(list);
+                        } catch (BadParcelableException e) {
+                            // pass-through.
                         }
-                    } else {
-                        // Only wants to register callbacks
-                        getLibrarySession().getCallback().onSubscribe(getLibrarySession(),
-                                controller, parentId, options);
                     }
+                    // No valid pagination info. Only wants to register callbacks
+                    getLibrarySession().getCallback().onSubscribe(getLibrarySession(),
+                            controller, parentId, options);
                 }
             });
         }
 
         @Override
         public void onLoadItem(final String itemId, final Result<MediaItem> result) {
+            result.detach();
             final ControllerInfo controller = getController();
             getLibrarySession().getCallbackExecutor().execute(new Runnable() {
                 @Override
@@ -563,7 +574,7 @@
                     MediaItem2 item = getLibrarySession().getCallback().onGetItem(
                             getLibrarySession(), controller, itemId);
                     if (item == null) {
-                        result.sendError(null);
+                        result.sendResult(null);
                     } else {
                         result.sendResult(MediaUtils2.createMediaItem(item));
                     }
@@ -583,7 +594,8 @@
 
         private ControllerInfo getController() {
             // TODO: Implement, by using getBrowserRootHints() / getCurrentBrowserInfo() / ...
-            return null;
+            return new ControllerInfo(MediaLibraryService2.this, Process.myUid(), Process.myPid(),
+                    getPackageName(), null);
         }
     }
 }
diff --git a/media/src/main/java/androidx/media/MediaPlayer2.java b/media/src/main/java/androidx/media/MediaPlayer2.java
index 1864d72..f1cd3b6 100644
--- a/media/src/main/java/androidx/media/MediaPlayer2.java
+++ b/media/src/main/java/androidx/media/MediaPlayer2.java
@@ -28,6 +28,7 @@
 import android.media.MediaTimestamp;
 import android.media.PlaybackParams;
 import android.media.ResourceBusyException;
+import android.media.SubtitleData;
 import android.media.SyncParams;
 import android.media.TimedMetaData;
 import android.media.UnsupportedSchemeException;
@@ -47,7 +48,6 @@
 import java.util.UUID;
 import java.util.concurrent.Executor;
 
-
 /**
  * @hide
  * MediaPlayer2 class can be used to control playback
@@ -832,10 +832,7 @@
      *
      *  Additional vendor-specific fields may also be present in
      *  the return value.
-     *  @hide
-     *  TODO: This method is not ready for public. Currently returns metrics data in MediaPlayer1.
      */
-    @RestrictTo(LIBRARY_GROUP)
     public abstract PersistableBundle getMetrics();
 
     /**
@@ -1229,13 +1226,26 @@
                 @CallStatus int status) { }
 
         /**
-         * Called to indicate media clock has changed.
+         * Called when a discontinuity in the normal progression of the media time is detected.
+         * The "normal progression" of media time is defined as the expected increase of the
+         * playback position when playing media, relative to the playback speed (for instance every
+         * second, media time increases by two seconds when playing at 2x).<br>
+         * Discontinuities are encountered in the following cases:
+         * <ul>
+         * <li>when the player is starved for data and cannot play anymore</li>
+         * <li>when the player encounters a playback error</li>
+         * <li>when the a seek operation starts, and when it's completed</li>
+         * <li>when the playback speed changes</li>
+         * <li>when the playback state changes</li>
+         * <li>when the player is reset</li>
+         * </ul>
          *
          * @param mp the MediaPlayer2 the media time pertains to.
          * @param dsd the DataSourceDesc of this data source
-         * @param timestamp the new media clock.
+         * @param timestamp the timestamp that correlates media time, system time and clock rate,
+         *     or {@link MediaTimestamp#TIMESTAMP_UNKNOWN} in an error case.
          */
-        public void onMediaTimeChanged(
+        public void onMediaTimeDiscontinuity(
                 MediaPlayer2 mp, DataSourceDesc dsd, MediaTimestamp timestamp) { }
 
         /**
@@ -1247,12 +1257,14 @@
          */
         public void onCommandLabelReached(MediaPlayer2 mp, @NonNull Object label) { }
 
-        /* TODO : uncomment below once API is available in supportlib.
+        /**
          * Called when when a player subtitle track has new subtitle data available.
          * @param mp the player that reports the new subtitle data
+         * @param dsd the DataSourceDesc of this data source
          * @param data the subtitle data
          */
-        // public void onSubtitleData(MediaPlayer2 mp, @NonNull SubtitleData data) { }
+        public void onSubtitleData(
+                MediaPlayer2 mp, DataSourceDesc dsd, @NonNull SubtitleData data) { }
     }
 
     /**
@@ -1512,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
      */
@@ -1609,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,
@@ -1661,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
      */
@@ -1676,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 {}
@@ -2008,4 +2001,100 @@
             super(detailMessage);
         }
     }
+
+    /**
+     * Definitions for the metrics that are reported via the {@link #getMetrics} call.
+     */
+    public static final class MetricsConstants {
+        private MetricsConstants() {}
+
+        /**
+         * Key to extract the MIME type of the video track
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String MIME_TYPE_VIDEO = "android.media.mediaplayer.video.mime";
+
+        /**
+         * Key to extract the codec being used to decode the video track
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String CODEC_VIDEO = "android.media.mediaplayer.video.codec";
+
+        /**
+         * Key to extract the width (in pixels) of the video track
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String WIDTH = "android.media.mediaplayer.width";
+
+        /**
+         * Key to extract the height (in pixels) of the video track
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String HEIGHT = "android.media.mediaplayer.height";
+
+        /**
+         * Key to extract the count of video frames played
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String FRAMES = "android.media.mediaplayer.frames";
+
+        /**
+         * Key to extract the count of video frames dropped
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String FRAMES_DROPPED = "android.media.mediaplayer.dropped";
+
+        /**
+         * Key to extract the MIME type of the audio track
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String MIME_TYPE_AUDIO = "android.media.mediaplayer.audio.mime";
+
+        /**
+         * Key to extract the codec being used to decode the audio track
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String CODEC_AUDIO = "android.media.mediaplayer.audio.codec";
+
+        /**
+         * Key to extract the duration (in milliseconds) of the
+         * media being played
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is a long.
+         */
+        public static final String DURATION = "android.media.mediaplayer.durationMs";
+
+        /**
+         * Key to extract the playing time (in milliseconds) of the
+         * media being played
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is a long.
+         */
+        public static final String PLAYING = "android.media.mediaplayer.playingMs";
+
+        /**
+         * Key to extract the count of errors encountered while
+         * playing the media
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String ERRORS = "android.media.mediaplayer.err";
+
+        /**
+         * Key to extract an (optional) error code detected while
+         * playing the media
+         * from the {@link MediaPlayer2#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String ERROR_CODE = "android.media.mediaplayer.errcode";
+
+    }
 }
diff --git a/media/src/main/java/androidx/media/MediaPlayer2Impl.java b/media/src/main/java/androidx/media/MediaPlayer2Impl.java
index 3b3e119..d9338d3 100644
--- a/media/src/main/java/androidx/media/MediaPlayer2Impl.java
+++ b/media/src/main/java/androidx/media/MediaPlayer2Impl.java
@@ -28,6 +28,7 @@
 import android.media.MediaTimestamp;
 import android.media.PlaybackParams;
 import android.media.ResourceBusyException;
+import android.media.SubtitleData;
 import android.media.SyncParams;
 import android.media.TimedMetaData;
 import android.media.UnsupportedSchemeException;
@@ -70,13 +71,14 @@
 
     private static final String TAG = "MediaPlayer2Impl";
 
-    private static final int NEXT_SOURCE_STATE_ERROR = -1;
-    private static final int NEXT_SOURCE_STATE_INIT = 0;
-    private static final int NEXT_SOURCE_STATE_PREPARING = 1;
-    private static final int NEXT_SOURCE_STATE_PREPARED = 2;
+    private static final int SOURCE_STATE_ERROR = -1;
+    private static final int SOURCE_STATE_INIT = 0;
+    private static final int SOURCE_STATE_PREPARING = 1;
+    private static final int SOURCE_STATE_PREPARED = 2;
 
     private static ArrayMap<Integer, Integer> sInfoEventMap;
     private static ArrayMap<Integer, Integer> sErrorEventMap;
+    private static ArrayMap<Integer, Integer> sPrepareDrmStatusMap;
 
     static {
         sInfoEventMap = new ArrayMap<>();
@@ -106,24 +108,22 @@
         sErrorEventMap.put(MediaPlayer.MEDIA_ERROR_MALFORMED, MEDIA_ERROR_MALFORMED);
         sErrorEventMap.put(MediaPlayer.MEDIA_ERROR_UNSUPPORTED, MEDIA_ERROR_UNSUPPORTED);
         sErrorEventMap.put(MediaPlayer.MEDIA_ERROR_TIMED_OUT, MEDIA_ERROR_TIMED_OUT);
+
+        sPrepareDrmStatusMap = new ArrayMap<>();
+        sPrepareDrmStatusMap.put(
+                MediaPlayer.PREPARE_DRM_STATUS_SUCCESS, PREPARE_DRM_STATUS_SUCCESS);
+        sPrepareDrmStatusMap.put(
+                MediaPlayer.PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR,
+                PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR);
+        sPrepareDrmStatusMap.put(
+                MediaPlayer.PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR,
+                PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR);
+        sPrepareDrmStatusMap.put(
+                MediaPlayer.PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR,
+                PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR);
     }
 
-    private MediaPlayer mPlayer;  // MediaPlayer is thread-safe.
-
-    private final Object mSrcLock = new Object();
-    //--- guarded by |mSrcLock| start
-    private long mSrcIdGenerator = 0;
-    private DataSourceDesc mCurrentDSD;
-    private long mCurrentSrcId = mSrcIdGenerator++;
-    private List<DataSourceDesc> mNextDSDs;
-    private long mNextSrcId = mSrcIdGenerator++;
-    private int mNextSourceState = NEXT_SOURCE_STATE_INIT;
-    private boolean mNextSourcePlayPending = false;
-    //--- guarded by |mSrcLock| end
-
-    private AtomicInteger mBufferedPercentageCurrent = new AtomicInteger(0);
-    private AtomicInteger mBufferedPercentageNext = new AtomicInteger(0);
-    private volatile float mVolume = 1.0f;
+    private MediaPlayerSourceQueue mPlayer;
 
     private HandlerThread mHandlerThread;
     private final Handler mTaskHandler;
@@ -135,8 +135,6 @@
 
     private final Object mLock = new Object();
     //--- guarded by |mLock| start
-    @PlayerState private int mPlayerState;
-    @BuffState private int mBufferingState;
     private AudioAttributesCompat mAudioAttributes;
     private ArrayList<Pair<Executor, MediaPlayer2EventCallback>> mMp2EventCallbackRecords =
             new ArrayList<>();
@@ -146,6 +144,18 @@
             new ArrayList<>();
     //--- guarded by |mLock| end
 
+    private void handleDataSourceError(final DataSourceError err) {
+        if (err == null) {
+            return;
+        }
+        notifyMediaPlayer2Event(new Mp2EventNotifier() {
+            @Override
+            public void notify(MediaPlayer2EventCallback callback) {
+                callback.onError(MediaPlayer2Impl.this, err.mDSD, err.mWhat, err.mExtra);
+            }
+        });
+    }
+
     /**
      * Default constructor.
      * <p>When done with the MediaPlayer2Impl, you should call  {@link #close()},
@@ -157,10 +167,10 @@
         mHandlerThread.start();
         Looper looper = mHandlerThread.getLooper();
         mTaskHandler = new Handler(looper);
-        mPlayer = new MediaPlayer();
-        mPlayerState = PLAYER_STATE_IDLE;
-        mBufferingState = BUFFERING_STATE_UNKNOWN;
-        setUpListeners();
+
+        // TODO: To make sure MediaPlayer1 listeners work, the caller thread should have a looper.
+        // Fix the framework or document this behavior.
+        mPlayer = new MediaPlayerSourceQueue();
     }
 
     /**
@@ -204,8 +214,7 @@
         addTask(new Task(CALL_COMPLETED_PLAY, false) {
             @Override
             void process() {
-                mPlayer.start();
-                setPlayerState(PLAYER_STATE_PLAYING);
+                mPlayer.play();
             }
         });
     }
@@ -226,7 +235,6 @@
             @Override
             void process() throws IOException {
                 mPlayer.prepareAsync();
-                setBufferingState(BUFFERING_STATE_BUFFERING_AND_STARVED);
             }
         });
     }
@@ -242,7 +250,6 @@
             @Override
             void process() {
                 mPlayer.pause();
-                setPlayerState(PLAYER_STATE_PAUSED);
             }
         });
     }
@@ -295,14 +302,12 @@
     @Override
     public long getBufferedPosition() {
         // Use cached buffered percent for now.
-        return getDuration() * mBufferedPercentageCurrent.get() / 100;
+        return mPlayer.getBufferedPosition();
     }
 
     @Override
     public @PlayerState int getPlayerState() {
-        synchronized (mLock) {
-            return mPlayerState;
-        }
+        return mPlayer.getPlayerState();
     }
 
     /**
@@ -312,9 +317,7 @@
      */
     @Override
     public @BuffState int getBufferingState() {
-        synchronized (mLock) {
-            return mBufferingState;
-        }
+        return  mPlayer.getBufferingState();
     }
 
     /**
@@ -361,13 +364,10 @@
             void process() {
                 Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
                 // TODO: setDataSource could update exist data source
-                synchronized (mSrcLock) {
-                    mCurrentDSD = dsd;
-                    mCurrentSrcId = mSrcIdGenerator++;
-                    try {
-                        handleDataSource(true /* isCurrent */, dsd, mCurrentSrcId);
-                    } catch (IOException e) {
-                    }
+                try {
+                    mPlayer.setFirst(dsd);
+                } catch (IOException e) {
+                    Log.e(TAG, "process: setDataSource", e);
                 }
             }
         });
@@ -387,21 +387,7 @@
             @Override
             void process() {
                 Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
-                synchronized (mSrcLock) {
-                    mNextDSDs = new ArrayList<DataSourceDesc>(1);
-                    mNextDSDs.add(dsd);
-                    mNextSrcId = mSrcIdGenerator++;
-                    mNextSourceState = NEXT_SOURCE_STATE_INIT;
-                    mNextSourcePlayPending = false;
-                }
-                /* FIXME : define and handle state.
-                int state = getMediaPlayer2State();
-                if (state != MEDIAPLAYER2_STATE_IDLE) {
-                    synchronized (mSrcLock) {
-                        prepareNextDataSource_l();
-                    }
-                }
-                */
+                handleDataSourceError(mPlayer.setNext(dsd));
             }
         });
     }
@@ -427,30 +413,14 @@
                                 "DataSourceDesc in the source list cannot be null.");
                     }
                 }
-
-                synchronized (mSrcLock) {
-                    mNextDSDs = new ArrayList(dsds);
-                    mNextSrcId = mSrcIdGenerator++;
-                    mNextSourceState = NEXT_SOURCE_STATE_INIT;
-                    mNextSourcePlayPending = false;
-                }
-                /* FIXME : define and handle state.
-                int state = getMediaPlayer2State();
-                if (state != MEDIAPLAYER2_STATE_IDLE) {
-                    synchronized (mSrcLock) {
-                        prepareNextDataSource_l();
-                    }
-                }
-                */
+                handleDataSourceError(mPlayer.setNextMultiple(dsds));
             }
         });
     }
 
     @Override
     public @NonNull DataSourceDesc getCurrentDataSource() {
-        synchronized (mSrcLock) {
-            return mCurrentDSD;
-        }
+        return mPlayer.getFirst().getDSD();
     }
 
     /**
@@ -521,8 +491,7 @@
         addTask(new Task(CALL_COMPLETED_SET_PLAYER_VOLUME, false) {
             @Override
             void process() {
-                mVolume = volume;
-                mPlayer.setVolume(volume, volume);
+                mPlayer.setVolume(volume);
             }
         });
     }
@@ -534,7 +503,7 @@
      */
     @Override
     public float getPlayerVolume() {
-        return mVolume;
+        return mPlayer.getVolume();
     }
 
     /**
@@ -650,14 +619,15 @@
         }
     }
 
-    private void handleDataSource(boolean isCurrent, @NonNull final DataSourceDesc dsd, long srcId)
+    private static void handleDataSource(MediaPlayerSource src)
             throws IOException {
+        final DataSourceDesc dsd = src.getDSD();
         Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
 
-        // TODO: handle the case isCurrent is false.
+        MediaPlayer player = src.mPlayer;
         switch (dsd.getType()) {
             case DataSourceDesc.TYPE_CALLBACK:
-                mPlayer.setDataSource(new MediaDataSource() {
+                player.setDataSource(new MediaDataSource() {
                     Media2DataSource mDataSource = dsd.getMedia2DataSource();
                     @Override
                     public int readAt(long position, byte[] buffer, int offset, int size)
@@ -678,14 +648,14 @@
                 break;
 
             case DataSourceDesc.TYPE_FD:
-                mPlayer.setDataSource(
+                player.setDataSource(
                         dsd.getFileDescriptor(),
                         dsd.getFileDescriptorOffset(),
                         dsd.getFileDescriptorLength());
                 break;
 
             case DataSourceDesc.TYPE_URI:
-                mPlayer.setDataSource(
+                player.setDataSource(
                         dsd.getUriContext(),
                         dsd.getUri(),
                         dsd.getUriHeaders(),
@@ -871,9 +841,12 @@
     @Override
     public void reset() {
         mPlayer.reset();
-        setPlayerState(PLAYER_STATE_IDLE);
-        setBufferingState(BUFFERING_STATE_UNKNOWN);
-        /* FIXME: reset other internal variables. */
+        synchronized (mLock) {
+            mAudioAttributes = null;
+            mMp2EventCallbackRecords.clear();
+            mPlayerEventCallbackMap.clear();
+            mDrmEventCallbackRecords.clear();
+        }
     }
 
     /**
@@ -1230,8 +1203,9 @@
         mPlayer.setOnDrmConfigHelper(new MediaPlayer.OnDrmConfigHelper() {
             @Override
             public void onDrmConfig(MediaPlayer mp) {
-                /** FIXME: pass the right DSD. */
-                listener.onDrmConfig(MediaPlayer2Impl.this, null);
+                MediaPlayerSource src = mPlayer.getSourceForPlayer(mp);
+                DataSourceDesc dsd = src == null ? null : src.getDSD();
+                listener.onDrmConfig(MediaPlayer2Impl.this, dsd);
             }
         });
     }
@@ -1340,16 +1314,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());
+        }
     }
 
 
@@ -1443,16 +1412,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());
+        }
     }
 
 
@@ -1504,7 +1468,7 @@
     private void setPlaybackParamsInternal(final PlaybackParams params) {
         PlaybackParams current = mPlayer.getPlaybackParams();
         mPlayer.setPlaybackParams(params);
-        if (Math.abs(current.getSpeed() - params.getSpeed()) > 0.0001f) {
+        if (current.getSpeed() != params.getSpeed()) {
             notifyPlayerEvent(new PlayerEventNotifier() {
                 @Override
                 public void notify(PlayerEventCallback cb) {
@@ -1514,36 +1478,6 @@
         }
     }
 
-    private void setPlayerState(@PlayerState final int state) {
-        synchronized (mLock) {
-            if (mPlayerState == state) {
-                return;
-            }
-            mPlayerState = state;
-        }
-        notifyPlayerEvent(new PlayerEventNotifier() {
-            @Override
-            public void notify(PlayerEventCallback cb) {
-                cb.onPlayerStateChanged(MediaPlayer2Impl.this, state);
-            }
-        });
-    }
-
-    private void setBufferingState(@BuffState final int state) {
-        synchronized (mLock) {
-            if (mBufferingState == state) {
-                return;
-            }
-            mBufferingState = state;
-        }
-        notifyPlayerEvent(new PlayerEventNotifier() {
-            @Override
-            public void notify(PlayerEventCallback cb) {
-                cb.onBufferingStateChanged(MediaPlayer2Impl.this, mCurrentDSD, state);
-            }
-        });
-    }
-
     private void notifyMediaPlayer2Event(final Mp2EventNotifier notifier) {
         List<Pair<Executor, MediaPlayer2EventCallback>> records;
         synchronized (mLock) {
@@ -1577,6 +1511,21 @@
         }
     }
 
+    private void notifyDrmEvent(final DrmEventNotifier notifier) {
+        List<Pair<Executor, DrmEventCallback>> records;
+        synchronized (mLock) {
+            records = new ArrayList<>(mDrmEventCallbackRecords);
+        }
+        for (final Pair<Executor, DrmEventCallback> record : records) {
+            record.first.execute(new Runnable() {
+                @Override
+                public void run() {
+                    notifier.notify(record.second);
+                }
+            });
+        }
+    }
+
     private interface Mp2EventNotifier {
         void notify(MediaPlayer2EventCallback callback);
     }
@@ -1585,28 +1534,34 @@
         void notify(PlayerEventCallback callback);
     }
 
-    private void setUpListeners() {
-        mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+    private interface DrmEventNotifier {
+        void notify(DrmEventCallback callback);
+    }
+
+    private void setUpListeners(final MediaPlayerSource src) {
+        MediaPlayer p = src.mPlayer;
+        p.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
             @Override
             public void onPrepared(MediaPlayer mp) {
-                setPlayerState(PLAYER_STATE_PAUSED);
-                setBufferingState(BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
+                handleDataSourceError(mPlayer.onPrepared(mp));
                 notifyMediaPlayer2Event(new Mp2EventNotifier() {
                     @Override
                     public void notify(MediaPlayer2EventCallback callback) {
-                        callback.onInfo(MediaPlayer2Impl.this, mCurrentDSD, MEDIA_INFO_PREPARED, 0);
+                        MediaPlayer2Impl mp2 = MediaPlayer2Impl.this;
+                        DataSourceDesc dsd = src.getDSD();
+                        callback.onInfo(mp2, dsd, MEDIA_INFO_PREPARED, 0);
                     }
                 });
                 notifyPlayerEvent(new PlayerEventNotifier() {
                     @Override
                     public void notify(PlayerEventCallback cb) {
-                        cb.onMediaPrepared(MediaPlayer2Impl.this, mCurrentDSD);
+                        cb.onMediaPrepared(MediaPlayer2Impl.this, src.getDSD());
                     }
                 });
                 synchronized (mTaskLock) {
                     if (mCurrentTask != null
                             && mCurrentTask.mMediaCallType == CALL_COMPLETED_PREPARE
-                            && mCurrentTask.mDSD == mCurrentDSD
+                            && mCurrentTask.mDSD == src.getDSD()
                             && mCurrentTask.mNeedToWaitForEventToComplete) {
                         mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
                         mCurrentTask = null;
@@ -1615,18 +1570,18 @@
                 }
             }
         });
-        mPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
+        p.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
             @Override
             public void onVideoSizeChanged(MediaPlayer mp, final int width, final int height) {
                 notifyMediaPlayer2Event(new Mp2EventNotifier() {
                     @Override
                     public void notify(MediaPlayer2EventCallback cb) {
-                        cb.onVideoSizeChanged(MediaPlayer2Impl.this, mCurrentDSD, width, height);
+                        cb.onVideoSizeChanged(MediaPlayer2Impl.this, src.getDSD(), width, height);
                     }
                 });
             }
         });
-        mPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+        p.setOnInfoListener(new MediaPlayer.OnInfoListener() {
             @Override
             public boolean onInfo(MediaPlayer mp, int what, int extra) {
                 switch (what) {
@@ -1634,50 +1589,50 @@
                         notifyMediaPlayer2Event(new Mp2EventNotifier() {
                             @Override
                             public void notify(MediaPlayer2EventCallback cb) {
-                                cb.onInfo(MediaPlayer2Impl.this, mCurrentDSD,
+                                cb.onInfo(MediaPlayer2Impl.this, src.getDSD(),
                                         MEDIA_INFO_VIDEO_RENDERING_START, 0);
                             }
                         });
                         break;
                     case MediaPlayer.MEDIA_INFO_BUFFERING_START:
-                        setBufferingState(BUFFERING_STATE_BUFFERING_AND_STARVED);
+                        mPlayer.setBufferingState(mp, BUFFERING_STATE_BUFFERING_AND_STARVED);
                         break;
                     case MediaPlayer.MEDIA_INFO_BUFFERING_END:
-                        setBufferingState(BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
+                        mPlayer.setBufferingState(mp, BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
                         break;
                 }
                 return false;
             }
         });
-        mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+        p.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
             @Override
             public void onCompletion(MediaPlayer mp) {
-                setPlayerState(PLAYER_STATE_PAUSED);
+                handleDataSourceError(mPlayer.onCompletion(mp));
                 notifyMediaPlayer2Event(new Mp2EventNotifier() {
                     @Override
                     public void notify(MediaPlayer2EventCallback cb) {
-                        cb.onInfo(MediaPlayer2Impl.this, mCurrentDSD, MEDIA_INFO_PLAYBACK_COMPLETE,
-                                0);
+                        MediaPlayer2Impl mp2 = MediaPlayer2Impl.this;
+                        DataSourceDesc dsd = src.getDSD();
+                        cb.onInfo(mp2, dsd, MEDIA_INFO_PLAYBACK_COMPLETE, 0);
                     }
                 });
             }
         });
-        mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+        p.setOnErrorListener(new MediaPlayer.OnErrorListener() {
             @Override
             public boolean onError(MediaPlayer mp, final int what, final int extra) {
-                setPlayerState(PLAYER_STATE_ERROR);
-                setBufferingState(BUFFERING_STATE_UNKNOWN);
+                mPlayer.onError(mp);
                 notifyMediaPlayer2Event(new Mp2EventNotifier() {
                     @Override
                     public void notify(MediaPlayer2EventCallback cb) {
                         int w = sErrorEventMap.getOrDefault(what, MEDIA_ERROR_UNKNOWN);
-                        cb.onError(MediaPlayer2Impl.this, mCurrentDSD, w, extra);
+                        cb.onError(MediaPlayer2Impl.this, src.getDSD(), w, extra);
                     }
                 });
                 return true;
             }
         });
-        mPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
+        p.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
             @Override
             public void onSeekComplete(MediaPlayer mp) {
                 synchronized (mTaskLock) {
@@ -1700,7 +1655,7 @@
                 });
             }
         });
-        mPlayer.setOnTimedMetaDataAvailableListener(
+        p.setOnTimedMetaDataAvailableListener(
                 new MediaPlayer.OnTimedMetaDataAvailableListener() {
                     @Override
                     public void onTimedMetaDataAvailable(MediaPlayer mp, final TimedMetaData data) {
@@ -1708,40 +1663,90 @@
                             @Override
                             public void notify(MediaPlayer2EventCallback cb) {
                                 cb.onTimedMetaDataAvailable(
-                                        MediaPlayer2Impl.this, mCurrentDSD, data);
+                                        MediaPlayer2Impl.this, src.getDSD(), data);
                             }
                         });
                     }
                 });
-        mPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+        p.setOnInfoListener(new MediaPlayer.OnInfoListener() {
             @Override
             public boolean onInfo(MediaPlayer mp, final int what, final int extra) {
                 notifyMediaPlayer2Event(new Mp2EventNotifier() {
                     @Override
                     public void notify(MediaPlayer2EventCallback cb) {
                         int w = sInfoEventMap.getOrDefault(what, MEDIA_INFO_UNKNOWN);
-                        cb.onInfo(MediaPlayer2Impl.this, mCurrentDSD, w, extra);
+                        cb.onInfo(MediaPlayer2Impl.this, src.getDSD(), w, extra);
                     }
                 });
                 return true;
             }
         });
-        mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
+        p.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
             @Override
             public void onBufferingUpdate(MediaPlayer mp, final int percent) {
                 if (percent >= 100) {
-                    setBufferingState(BUFFERING_STATE_BUFFERING_COMPLETE);
+                    mPlayer.setBufferingState(mp, BUFFERING_STATE_BUFFERING_COMPLETE);
                 }
-                mBufferedPercentageCurrent.set(percent);
+                src.mBufferedPercentage.set(percent);
                 notifyMediaPlayer2Event(new Mp2EventNotifier() {
                     @Override
                     public void notify(MediaPlayer2EventCallback cb) {
-                        cb.onInfo(MediaPlayer2Impl.this, mCurrentDSD,
+                        cb.onInfo(MediaPlayer2Impl.this, src.getDSD(),
                                 MEDIA_INFO_BUFFERING_UPDATE, percent);
                     }
                 });
             }
         });
+        p.setOnMediaTimeDiscontinuityListener(
+                new MediaPlayer.OnMediaTimeDiscontinuityListener() {
+                    @Override
+                    public void onMediaTimeDiscontinuity(
+                            MediaPlayer mp, final MediaTimestamp timestamp) {
+                        notifyMediaPlayer2Event(new Mp2EventNotifier() {
+                            @Override
+                            public void notify(MediaPlayer2EventCallback cb) {
+                                cb.onMediaTimeDiscontinuity(
+                                        MediaPlayer2Impl.this, src.getDSD(), timestamp);
+                            }
+                        });
+                    }
+                });
+        p.setOnSubtitleDataListener(new MediaPlayer.OnSubtitleDataListener() {
+            @Override
+            public  void onSubtitleData(MediaPlayer mp, final SubtitleData data) {
+                notifyMediaPlayer2Event(new Mp2EventNotifier() {
+                    @Override
+                    public void notify(MediaPlayer2EventCallback cb) {
+                        cb.onSubtitleData(MediaPlayer2Impl.this, src.getDSD(), data);
+                    }
+                });
+            }
+        });
+        p.setOnDrmInfoListener(new MediaPlayer.OnDrmInfoListener() {
+            @Override
+            public void onDrmInfo(MediaPlayer mp, final MediaPlayer.DrmInfo drmInfo) {
+                notifyDrmEvent(new DrmEventNotifier() {
+                    @Override
+                    public void notify(DrmEventCallback cb) {
+                        cb.onDrmInfo(MediaPlayer2Impl.this, src.getDSD(),
+                                new DrmInfoImpl(drmInfo.getPssh(), drmInfo.getSupportedSchemes()));
+                    }
+                });
+            }
+        });
+        p.setOnDrmPreparedListener(new MediaPlayer.OnDrmPreparedListener() {
+            @Override
+            public void onDrmPrepared(MediaPlayer mp, final int status) {
+                notifyDrmEvent(new DrmEventNotifier() {
+                    @Override
+                    public void notify(DrmEventCallback cb) {
+                        int s = sPrepareDrmStatusMap.getOrDefault(
+                                status, PREPARE_DRM_STATUS_PREPARATION_ERROR);
+                        cb.onDrmPrepared(MediaPlayer2Impl.this, src.getDSD(), s);
+                    }
+                });
+            }
+        });
     }
 
     /**
@@ -1944,14 +1949,10 @@
                 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;
             }
-            synchronized (mSrcLock) {
-                mDSD = mCurrentDSD;
-            }
+            mDSD = getCurrentDataSource();
 
             if (!mNeedToWaitForEventToComplete || status != CALL_STATUS_NO_ERROR) {
 
@@ -1979,4 +1980,427 @@
             });
         }
     };
+
+    private static class DataSourceError {
+        final DataSourceDesc mDSD;
+        final int mWhat;
+
+        final int mExtra;
+        DataSourceError(DataSourceDesc dsd, int what, int extra) {
+            mDSD = dsd;
+            mWhat = what;
+            mExtra = extra;
+        }
+
+    }
+
+    private class MediaPlayerSource {
+
+        volatile DataSourceDesc mDSD;
+        final MediaPlayer mPlayer = new MediaPlayer();
+        final AtomicInteger mBufferedPercentage = new AtomicInteger(0);
+        int mSourceState = SOURCE_STATE_INIT;
+        @BuffState int mBufferingState = BUFFERING_STATE_UNKNOWN;
+        @PlayerState int mPlayerState = PLAYER_STATE_IDLE;
+        boolean mPlayPending;
+
+        MediaPlayerSource(final DataSourceDesc dsd) {
+            mDSD = dsd;
+            setUpListeners(this);
+        }
+
+        DataSourceDesc getDSD() {
+            return mDSD;
+        }
+
+    }
+
+    private class MediaPlayerSourceQueue {
+
+        List<MediaPlayerSource> mQueue = new ArrayList<>();
+        float mVolume = 1.0f;
+        Surface mSurface;
+
+        MediaPlayerSourceQueue() {
+            mQueue.add(new MediaPlayerSource(null));
+        }
+
+        synchronized MediaPlayer getCurrentPlayer() {
+            return mQueue.get(0).mPlayer;
+        }
+
+        synchronized MediaPlayerSource getFirst() {
+            return mQueue.get(0);
+        }
+
+        synchronized void setFirst(DataSourceDesc dsd) throws IOException {
+            if (mQueue.isEmpty()) {
+                mQueue.add(0, new MediaPlayerSource(dsd));
+            } else {
+                mQueue.get(0).mDSD = dsd;
+                setUpListeners(mQueue.get(0));
+            }
+            handleDataSource(mQueue.get(0));
+        }
+
+        synchronized DataSourceError setNext(DataSourceDesc dsd) {
+            MediaPlayerSource src = new MediaPlayerSource(dsd);
+            if (mQueue.isEmpty()) {
+                mQueue.add(src);
+                return prepareMediaPlayerSource(0);
+            } else {
+                mQueue.add(1, src);
+                return prepareMediaPlayerSource(1);
+            }
+        }
+
+        synchronized DataSourceError setNextMultiple(List<DataSourceDesc> descs) {
+            List<MediaPlayerSource> sources = new ArrayList<>();
+            for (DataSourceDesc dsd: descs) {
+                sources.add(new MediaPlayerSource(dsd));
+            }
+            if (mQueue.isEmpty()) {
+                mQueue.addAll(sources);
+                return prepareMediaPlayerSource(0);
+            } else {
+                mQueue.addAll(1, sources);
+                return prepareMediaPlayerSource(1);
+            }
+        }
+
+        synchronized void play() {
+            MediaPlayerSource src = mQueue.get(0);
+            if (src.mSourceState == SOURCE_STATE_PREPARED) {
+                src.mPlayer.start();
+                setPlayerState(src.mPlayer, PLAYER_STATE_PLAYING);
+            }
+        }
+
+        synchronized void prepare() {
+            getCurrentPlayer().prepareAsync();
+        }
+
+        synchronized void release() {
+            getCurrentPlayer().release();
+        }
+
+        synchronized void prepareAsync() {
+            MediaPlayer mp = getCurrentPlayer();
+            mp.prepareAsync();
+            setBufferingState(mp, BUFFERING_STATE_BUFFERING_AND_STARVED);
+        }
+
+        synchronized void pause() {
+            MediaPlayer mp = getCurrentPlayer();
+            mp.pause();
+            setPlayerState(mp, PLAYER_STATE_PAUSED);
+        }
+
+        synchronized long getCurrentPosition() {
+            return getCurrentPlayer().getCurrentPosition();
+        }
+
+        synchronized long getDuration() {
+            return getCurrentPlayer().getDuration();
+        }
+
+        synchronized long getBufferedPosition() {
+            MediaPlayerSource src = mQueue.get(0);
+            return (long) src.mPlayer.getDuration() * src.mBufferedPercentage.get() / 100;
+        }
+
+        synchronized void setAudioAttributes(AudioAttributes attributes) {
+            getCurrentPlayer().setAudioAttributes(attributes);
+        }
+
+        synchronized DataSourceError onPrepared(MediaPlayer mp) {
+            for (int i = 0; i < mQueue.size(); i++) {
+                MediaPlayerSource src = mQueue.get(i);
+                if (mp == src.mPlayer) {
+                    if (i == 0) {
+                        if (src.mPlayPending) {
+                            src.mPlayPending = false;
+                            src.mPlayer.start();
+                            setPlayerState(src.mPlayer, PLAYER_STATE_PLAYING);
+                        } else {
+                            setPlayerState(src.mPlayer, PLAYER_STATE_PAUSED);
+                        }
+                    }
+                    src.mSourceState = SOURCE_STATE_PREPARED;
+                    setBufferingState(src.mPlayer, BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
+                    return prepareMediaPlayerSource(i + 1);
+                }
+            }
+            return null;
+        }
+
+        synchronized DataSourceError onCompletion(MediaPlayer mp) {
+            if (!mQueue.isEmpty() && mp == getCurrentPlayer()) {
+                if (mQueue.size() == 1) {
+                    setPlayerState(mp, PLAYER_STATE_PAUSED);
+                    return null;
+                }
+                mp.release();
+                final MediaPlayerSource src1 = mQueue.remove(0);
+                final MediaPlayerSource src2 = mQueue.get(0);
+                if (src1.mPlayerState != src2.mPlayerState) {
+                    notifyPlayerEvent(new PlayerEventNotifier() {
+                        @Override
+                        public void notify(PlayerEventCallback cb) {
+                            cb.onPlayerStateChanged(MediaPlayer2Impl.this, src2.mPlayerState);
+                        }
+                    });
+                }
+
+            }
+
+            DataSourceError err = null;
+            final MediaPlayerSource src = mQueue.get(0);
+            src.mPlayer.setSurface(mSurface);
+            src.mPlayer.setVolume(mVolume, mVolume);
+            if (src.mSourceState == SOURCE_STATE_PREPARED) {
+                // start next source only when it's in prepared state.
+                src.mPlayer.start();
+                notifyMediaPlayer2Event(new Mp2EventNotifier() {
+                    @Override
+                    public void notify(MediaPlayer2EventCallback callback) {
+                        callback.onInfo(MediaPlayer2Impl.this, src.getDSD(),
+                                MEDIA_INFO_STARTED_AS_NEXT, 0);
+                    }
+                });
+
+            } else {
+                if (src.mSourceState == SOURCE_STATE_INIT) {
+                    err = prepareMediaPlayerSource(0);
+                }
+                src.mPlayPending = true;
+            }
+            return err;
+        }
+
+        synchronized void onError(MediaPlayer mp) {
+            setPlayerState(mp, PLAYER_STATE_ERROR);
+            setBufferingState(mp, BUFFERING_STATE_UNKNOWN);
+        }
+
+        synchronized DataSourceError prepareMediaPlayerSource(int n) {
+            if (n >= mQueue.size()
+                    || mQueue.get(n).mSourceState != SOURCE_STATE_INIT
+                    || getPlayerState() == PLAYER_STATE_IDLE) {
+                // There is no next source or it's in preparing or prepared state.
+                return null;
+            }
+
+            MediaPlayerSource src = mQueue.get(n);
+            try {
+                src.mSourceState = SOURCE_STATE_PREPARING;
+                handleDataSource(src);
+                src.mPlayer.prepareAsync();
+                return null;
+            } catch (Exception e) {
+                DataSourceDesc dsd = src.getDSD();
+                setPlayerState(src.mPlayer, PLAYER_STATE_ERROR);
+                return new DataSourceError(dsd, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED);
+            }
+
+        }
+
+        synchronized void setLooping(boolean loop) {
+            getCurrentPlayer().setLooping(loop);
+        }
+
+        synchronized void setPlaybackParams(PlaybackParams playbackParams) {
+            getCurrentPlayer().setPlaybackParams(playbackParams);
+        }
+
+        synchronized float getVolume() {
+            return mVolume;
+        }
+
+        synchronized void setVolume(float volume) {
+            mVolume = volume;
+            getCurrentPlayer().setVolume(volume, volume);
+        }
+
+        synchronized void setSurface(Surface surface) {
+            mSurface = surface;
+            getCurrentPlayer().setSurface(surface);
+        }
+
+        synchronized int getVideoWidth() {
+            return getCurrentPlayer().getVideoWidth();
+        }
+
+        synchronized int getVideoHeight() {
+            return getCurrentPlayer().getVideoHeight();
+        }
+
+        synchronized PersistableBundle getMetrics() {
+            return getCurrentPlayer().getMetrics();
+        }
+
+        synchronized PlaybackParams getPlaybackParams() {
+            return getCurrentPlayer().getPlaybackParams();
+        }
+
+        synchronized void setSyncParams(SyncParams params) {
+            getCurrentPlayer().setSyncParams(params);
+        }
+
+        synchronized SyncParams getSyncParams() {
+            return getCurrentPlayer().getSyncParams();
+        }
+
+        synchronized void seekTo(long msec, int mode) {
+            getCurrentPlayer().seekTo(msec, mode);
+        }
+
+        synchronized void reset() {
+            MediaPlayerSource src = mQueue.get(0);
+            src.mPlayer.reset();
+            src.mBufferedPercentage.set(0);
+            mVolume = 1.0f;
+            setPlayerState(src.mPlayer, PLAYER_STATE_IDLE);
+            setBufferingState(src.mPlayer, BUFFERING_STATE_UNKNOWN);
+        }
+
+        synchronized MediaTimestamp getTimestamp() {
+            return getCurrentPlayer().getTimestamp();
+        }
+
+        synchronized void setAudioSessionId(int sessionId) {
+            getCurrentPlayer().setAudioSessionId(sessionId);
+        }
+
+        synchronized int getAudioSessionId() {
+            return getCurrentPlayer().getAudioSessionId();
+        }
+
+        synchronized void attachAuxEffect(int effectId) {
+            getCurrentPlayer().attachAuxEffect(effectId);
+        }
+
+        synchronized void setAuxEffectSendLevel(float level) {
+            getCurrentPlayer().setAuxEffectSendLevel(level);
+        }
+
+        synchronized MediaPlayer.TrackInfo[] getTrackInfo() {
+            return getCurrentPlayer().getTrackInfo();
+        }
+
+        synchronized int getSelectedTrack(int trackType) {
+            return getCurrentPlayer().getSelectedTrack(trackType);
+        }
+
+        synchronized void selectTrack(int index) {
+            getCurrentPlayer().selectTrack(index);
+        }
+
+        synchronized void deselectTrack(int index) {
+            getCurrentPlayer().deselectTrack(index);
+        }
+
+        synchronized MediaPlayer.DrmInfo getDrmInfo() {
+            return getCurrentPlayer().getDrmInfo();
+        }
+
+        synchronized void prepareDrm(UUID uuid)
+                throws ResourceBusyException, MediaPlayer.ProvisioningServerErrorException,
+                MediaPlayer.ProvisioningNetworkErrorException, UnsupportedSchemeException {
+            getCurrentPlayer().prepareDrm(uuid);
+        }
+
+        synchronized void releaseDrm() throws MediaPlayer.NoDrmSchemeException {
+            getCurrentPlayer().releaseDrm();
+        }
+
+        synchronized byte[] provideKeyResponse(byte[] keySetId, byte[] response)
+                throws DeniedByServerException, MediaPlayer.NoDrmSchemeException {
+            return getCurrentPlayer().provideKeyResponse(keySetId, response);
+        }
+
+        synchronized void restoreKeys(byte[] keySetId) throws MediaPlayer.NoDrmSchemeException {
+            getCurrentPlayer().restoreKeys(keySetId);
+        }
+
+        synchronized String getDrmPropertyString(String propertyName)
+                throws MediaPlayer.NoDrmSchemeException {
+            return getCurrentPlayer().getDrmPropertyString(propertyName);
+        }
+
+        synchronized void setDrmPropertyString(String propertyName, String value)
+                throws MediaPlayer.NoDrmSchemeException {
+            getCurrentPlayer().setDrmPropertyString(propertyName, value);
+        }
+
+        synchronized void setOnDrmConfigHelper(MediaPlayer.OnDrmConfigHelper onDrmConfigHelper) {
+            getCurrentPlayer().setOnDrmConfigHelper(onDrmConfigHelper);
+        }
+
+        synchronized MediaDrm.KeyRequest getKeyRequest(byte[] keySetId, byte[] initData,
+                String mimeType,
+                int keyType, Map<String, String> optionalParameters)
+                throws MediaPlayer.NoDrmSchemeException {
+            return getCurrentPlayer().getKeyRequest(keySetId, initData, mimeType, keyType,
+                    optionalParameters);
+        }
+
+        synchronized void setPlayerState(MediaPlayer mp, @PlayerState final int state) {
+            for (final MediaPlayerSource src: mQueue) {
+                if (src.mPlayer != mp) {
+                    continue;
+                }
+                if (src.mPlayerState == state) {
+                    return;
+                }
+                src.mPlayerState = state;
+                notifyPlayerEvent(new PlayerEventNotifier() {
+                    @Override
+                    public void notify(PlayerEventCallback cb) {
+                        cb.onPlayerStateChanged(MediaPlayer2Impl.this, state);
+                    }
+                });
+                return;
+            }
+        }
+
+        synchronized void setBufferingState(MediaPlayer mp, @BuffState final int state) {
+            for (final MediaPlayerSource src: mQueue) {
+                if (src.mPlayer != mp) {
+                    continue;
+                }
+                if (src.mBufferingState == state) {
+                    return;
+                }
+                src.mBufferingState = state;
+                notifyPlayerEvent(new PlayerEventNotifier() {
+                    @Override
+                    public void notify(PlayerEventCallback cb) {
+                        MediaPlayer2Impl mp2 = MediaPlayer2Impl.this;
+                        DataSourceDesc dsd = src.getDSD();
+                        cb.onBufferingStateChanged(mp2, dsd, state);
+                    }
+                });
+                return;
+            }
+        }
+
+        synchronized @BuffState int getBufferingState() {
+            return mQueue.get(0).mBufferingState;
+        }
+
+        synchronized @PlayerState int getPlayerState() {
+            return mQueue.get(0).mPlayerState;
+        }
+
+        synchronized MediaPlayerSource getSourceForPlayer(MediaPlayer mp) {
+            for (MediaPlayerSource src: mQueue) {
+                if (src.mPlayer == mp) {
+                    return src;
+                }
+            }
+            return null;
+        }
+    }
+
 }
diff --git a/media/src/main/java/androidx/media/MediaSession2ImplBase.java b/media/src/main/java/androidx/media/MediaSession2ImplBase.java
index e474b45..fc598f1 100644
--- a/media/src/main/java/androidx/media/MediaSession2ImplBase.java
+++ b/media/src/main/java/androidx/media/MediaSession2ImplBase.java
@@ -90,8 +90,6 @@
     @GuardedBy("mLock")
     private OnDataSourceMissingHelper mDsmHelper;
     @GuardedBy("mLock")
-    private PlaybackStateCompat mPlaybackStateCompat;
-    @GuardedBy("mLock")
     private PlaybackInfo mPlaybackInfo;
 
     MediaSession2ImplBase(Context context, MediaSessionCompat sessionCompat, String id,
@@ -1047,6 +1045,21 @@
             });
         }
 
+        @Override
+        public void onSeekCompleted(final MediaPlayerBase mpb, final long position) {
+            final MediaSession2ImplBase session = getSession();
+            if (session == null) {
+                return;
+            }
+            session.getCallbackExecutor().execute(new Runnable() {
+                @Override
+                public void run() {
+                    session.getCallback().onSeekCompleted(session.getInstance(), mpb, position);
+                    session.getSession2Stub().notifySeekCompleted(position);
+                }
+            });
+        }
+
         private MediaSession2ImplBase getSession() {
             final MediaSession2ImplBase session = mSession.get();
             if (session == null && DEBUG) {
diff --git a/media/src/main/java/androidx/media/MediaSession2StubImplBase.java b/media/src/main/java/androidx/media/MediaSession2StubImplBase.java
index 48e641e..1300698 100644
--- a/media/src/main/java/androidx/media/MediaSession2StubImplBase.java
+++ b/media/src/main/java/androidx/media/MediaSession2StubImplBase.java
@@ -55,7 +55,7 @@
 import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_CONNECT;
 import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_DISCONNECT;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_BUFFERING_STATE_CHAGNED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_BUFFERING_STATE_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_CURRENT_MEDIA_ITEM_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ERROR;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED;
@@ -65,6 +65,7 @@
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYLIST_METADATA_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_REPEAT_MODE_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ROUTES_INFO_CHANGED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_SEEK_COMPLETED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_ON_SHUFFLE_MODE_CHANGED;
 import static androidx.media.MediaConstants2.SESSION_EVENT_SEND_CUSTOM_COMMAND;
 import static androidx.media.MediaConstants2.SESSION_EVENT_SET_CUSTOM_LAYOUT;
@@ -561,6 +562,8 @@
             public void run(ControllerInfo controller) throws RemoteException {
                 Bundle bundle = new Bundle();
                 bundle.putInt(ARGUMENT_PLAYER_STATE, state);
+                bundle.putParcelable(
+                        ARGUMENT_PLAYBACK_STATE_COMPAT, mSession.getPlaybackStateCompat());
                 controller.getControllerBinder().onEvent(
                         SESSION_EVENT_ON_PLAYER_STATE_CHANGED, bundle);
             }
@@ -587,8 +590,23 @@
                 Bundle bundle = new Bundle();
                 bundle.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
                 bundle.putInt(ARGUMENT_BUFFERING_STATE, bufferingState);
+                bundle.putParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT,
+                        mSession.getPlaybackStateCompat());
                 controller.getControllerBinder().onEvent(
-                        SESSION_EVENT_ON_BUFFERING_STATE_CHAGNED, bundle);
+                        SESSION_EVENT_ON_BUFFERING_STATE_CHANGED, bundle);
+            }
+        });
+    }
+
+    void notifySeekCompleted(final long position) {
+        notifyAll(new Session2Runnable() {
+            @Override
+            public void run(ControllerInfo controller) throws RemoteException {
+                Bundle bundle = new Bundle();
+                bundle.putLong(ARGUMENT_SEEK_POSITION, position);
+                bundle.putParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT,
+                        mSession.getPlaybackStateCompat());
+                controller.getControllerBinder().onEvent(SESSION_EVENT_ON_SEEK_COMPLETED, bundle);
             }
         });
     }
diff --git a/media/src/main/java/androidx/media/MediaSessionManager.java b/media/src/main/java/androidx/media/MediaSessionManager.java
new file mode 100644
index 0000000..43fe097
--- /dev/null
+++ b/media/src/main/java/androidx/media/MediaSessionManager.java
@@ -0,0 +1,160 @@
+/*
+ * 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.media;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.Context;
+import android.os.Build;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.core.os.BuildCompat;
+
+/**
+ * @hide
+ * Provides support for interacting with {@link MediaSessionCompat media sessions} that
+ * applications have published to express their ongoing media playback state.
+ *
+ * @see MediaSessionCompat
+ * @see MediaControllerCompat
+ */
+@RestrictTo(LIBRARY_GROUP)
+public final class MediaSessionManager {
+    static final String TAG = "MediaSessionManager";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static MediaSessionManager sSessionManager;
+
+    MediaSessionManagerImpl mImpl;
+
+    /**
+     * Gets an instance of the media session manager associated with the context.
+     *
+     * @return The MediaSessionManager instance for this context.
+     */
+    public static synchronized MediaSessionManager getSessionManager(Context context) {
+        if (sSessionManager == null) {
+            sSessionManager = new MediaSessionManager(context.getApplicationContext());
+        }
+        return sSessionManager;
+    }
+
+    private MediaSessionManager(Context context) {
+        if (BuildCompat.isAtLeastP()) {
+            mImpl = new MediaSessionManagerImplApi28(context);
+        } else if (Build.VERSION.SDK_INT >= 21) {
+            mImpl = new MediaSessionManagerImplApi21(context);
+        } else {
+            mImpl = new MediaSessionManagerImplBase(context);
+        }
+    }
+
+    /**
+     * Checks whether the remote user is a trusted app.
+     * <p>
+     * An app is trusted if the app holds the android.Manifest.permission.MEDIA_CONTENT_CONTROL
+     * permission or has an enabled notification listener.
+     *
+     * @param userInfo The remote user info from either
+     *            {@link MediaSessionCompat#getCurrentControllerInfo()} and
+     *            {@link MediaBrowserServiceCompat#getCurrentBrowserInfo()}.
+     * @return {@code true} if the remote user is trusted and its package name matches with the UID.
+     *            {@code false} otherwise.
+     */
+    public boolean isTrustedForMediaControl(@NonNull RemoteUserInfo userInfo) {
+        if (userInfo == null) {
+            throw new IllegalArgumentException("userInfo should not be null");
+        }
+        return mImpl.isTrustedForMediaControl(userInfo.mImpl);
+    }
+
+    Context getContext() {
+        return mImpl.getContext();
+    }
+
+    interface MediaSessionManagerImpl {
+        Context getContext();
+        boolean isTrustedForMediaControl(RemoteUserInfoImpl userInfo);
+    }
+
+    interface RemoteUserInfoImpl {
+        String getPackageName();
+        int getPid();
+        int getUid();
+    }
+
+    /**
+     * Information of a remote user of {@link android.support.v4.media.session.MediaSessionCompat}
+     * or {@link MediaBrowserServiceCompat}.
+     * This can be used to decide whether the remote user is trusted app.
+     *
+     * @see #isTrustedForMediaControl(RemoteUserInfo)
+     */
+    public static final class RemoteUserInfo {
+        /**
+         * Used by {@link #getPackageName()} when the session is connected to the legacy controller
+         * whose exact package name cannot be obtained.
+         */
+        public static String LEGACY_CONTROLLER = "android.media.session.MediaController";
+
+        RemoteUserInfoImpl mImpl;
+
+        public RemoteUserInfo(String packageName, int pid, int uid) {
+            if (BuildCompat.isAtLeastP()) {
+                mImpl = new MediaSessionManagerImplApi28.RemoteUserInfo(packageName, pid, uid);
+            } else {
+                mImpl = new MediaSessionManagerImplBase.RemoteUserInfo(packageName, pid, uid);
+            }
+        }
+
+        /**
+         * @return package name of the controller. Can be {@link #LEGACY_CONTROLLER} if the package
+         *         name cannot be obtained.
+         */
+        public String getPackageName() {
+            return mImpl.getPackageName();
+        }
+
+        /**
+         * @return pid of the controller
+         */
+        public int getPid() {
+            return mImpl.getPid();
+        }
+
+        /**
+         * @return uid of the controller
+         */
+        public int getUid() {
+            return mImpl.getUid();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return mImpl.equals(obj);
+        }
+
+        @Override
+        public int hashCode() {
+            return mImpl.hashCode();
+        }
+    }
+}
diff --git a/media/src/main/java/androidx/media/MediaSessionManagerImplApi21.java b/media/src/main/java/androidx/media/MediaSessionManagerImplApi21.java
new file mode 100644
index 0000000..4fefe70
--- /dev/null
+++ b/media/src/main/java/androidx/media/MediaSessionManagerImplApi21.java
@@ -0,0 +1,48 @@
+/*
+ * 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.media;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+@RequiresApi(21)
+class MediaSessionManagerImplApi21 extends MediaSessionManagerImplBase {
+    MediaSessionManagerImplApi21(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    @Override
+    public boolean isTrustedForMediaControl(
+            @NonNull MediaSessionManager.RemoteUserInfoImpl userInfo) {
+
+        return hasMediaControlPermission(userInfo) || super.isTrustedForMediaControl(userInfo);
+    }
+
+    /**
+     * Checks the caller has android.Manifest.permission.MEDIA_CONTENT_CONTROL permission.
+     */
+    private boolean hasMediaControlPermission(
+            @NonNull MediaSessionManager.RemoteUserInfoImpl userInfo) {
+        return getContext().checkPermission(
+                android.Manifest.permission.MEDIA_CONTENT_CONTROL,
+                userInfo.getPid(), userInfo.getUid()) == PackageManager.PERMISSION_GRANTED;
+    }
+}
diff --git a/media/src/main/java/androidx/media/MediaSessionManagerImplApi28.java b/media/src/main/java/androidx/media/MediaSessionManagerImplApi28.java
new file mode 100644
index 0000000..48344fa
--- /dev/null
+++ b/media/src/main/java/androidx/media/MediaSessionManagerImplApi28.java
@@ -0,0 +1,64 @@
+/*
+ * 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.media;
+
+import android.content.Context;
+
+import androidx.annotation.RequiresApi;
+
+@RequiresApi(28)
+class MediaSessionManagerImplApi28 extends MediaSessionManagerImplApi21 {
+    android.media.session.MediaSessionManager mObject;
+
+    MediaSessionManagerImplApi28(Context context) {
+        super(context);
+        mObject = (android.media.session.MediaSessionManager) context
+                .getSystemService(Context.MEDIA_SESSION_SERVICE);
+    }
+
+    @Override
+    public boolean isTrustedForMediaControl(MediaSessionManager.RemoteUserInfoImpl userInfo) {
+        if (userInfo instanceof RemoteUserInfo) {
+            return mObject.isTrustedForMediaControl(((RemoteUserInfo) userInfo).mObject);
+        }
+        return false;
+    }
+
+    static final class RemoteUserInfo implements MediaSessionManager.RemoteUserInfoImpl {
+        android.media.session.MediaSessionManager.RemoteUserInfo mObject;
+
+        RemoteUserInfo(String packageName, int pid, int uid) {
+            mObject = new android.media.session.MediaSessionManager.RemoteUserInfo(
+                    packageName, pid, uid);
+        }
+
+        @Override
+        public String getPackageName() {
+            return mObject.getPackageName();
+        }
+
+        @Override
+        public int getPid() {
+            return mObject.getPid();
+        }
+
+        @Override
+        public int getUid() {
+            return mObject.getUid();
+        }
+    }
+}
diff --git a/media/src/main/java/androidx/media/MediaSessionManagerImplBase.java b/media/src/main/java/androidx/media/MediaSessionManagerImplBase.java
new file mode 100644
index 0000000..6ff575e
--- /dev/null
+++ b/media/src/main/java/androidx/media/MediaSessionManagerImplBase.java
@@ -0,0 +1,150 @@
+/*
+ * 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.media;
+
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.core.util.ObjectsCompat;
+
+class MediaSessionManagerImplBase implements MediaSessionManager.MediaSessionManagerImpl {
+    private static final String TAG = MediaSessionManager.TAG;
+    private static final boolean DEBUG = MediaSessionManager.DEBUG;
+
+    private static final String PERMISSION_STATUS_BAR_SERVICE =
+            "android.permission.STATUS_BAR_SERVICE";
+    private static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";
+
+    Context mContext;
+    ContentResolver mContentResolver;
+
+    MediaSessionManagerImplBase(Context context) {
+        mContext = context;
+        mContentResolver = mContext.getContentResolver();
+    }
+
+    @Override
+    public Context getContext() {
+        return mContext;
+    }
+
+    @Override
+    public boolean isTrustedForMediaControl(
+            @NonNull MediaSessionManager.RemoteUserInfoImpl userInfo) {
+        ApplicationInfo applicationInfo;
+        try {
+            applicationInfo = mContext.getPackageManager().getApplicationInfo(
+                    userInfo.getPackageName(), 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            if (DEBUG) {
+                Log.d(TAG, "Package " + userInfo.getPackageName() + " doesn't exist");
+            }
+            return false;
+        }
+
+        if (applicationInfo.uid != userInfo.getUid()) {
+            if (DEBUG) {
+                Log.d(TAG, "Package name " + userInfo.getPackageName()
+                        + " doesn't match with the uid " + userInfo.getUid());
+            }
+            return false;
+        }
+        return mContext.checkPermission(PERMISSION_STATUS_BAR_SERVICE,
+                userInfo.getPid(), userInfo.getUid()) == PackageManager.PERMISSION_GRANTED
+                || userInfo.getUid() == Process.SYSTEM_UID
+                || isEnabledNotificationListener(userInfo);
+    }
+
+    /**
+     * This checks if the component is an enabled notification listener for the
+     * specified user. Enabled components may only operate on behalf of the user
+     * they're running as.
+     *
+     * @return True if the component is enabled, false otherwise
+     */
+    @SuppressWarnings("StringSplitter")
+    boolean isEnabledNotificationListener(
+            @NonNull MediaSessionManager.RemoteUserInfoImpl userInfo) {
+        final String enabledNotifListeners = Settings.Secure.getString(mContentResolver,
+                ENABLED_NOTIFICATION_LISTENERS);
+        if (enabledNotifListeners != null) {
+            final String[] components = enabledNotifListeners.split(":");
+            for (int i = 0; i < components.length; i++) {
+                final ComponentName component =
+                        ComponentName.unflattenFromString(components[i]);
+                if (component != null) {
+                    if (component.getPackageName().equals(userInfo.getPackageName())) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    static class RemoteUserInfo implements MediaSessionManager.RemoteUserInfoImpl {
+        private String mPackageName;
+        private int mPid;
+        private int mUid;
+
+        RemoteUserInfo(String packageName, int pid, int uid) {
+            mPackageName = packageName;
+            mPid = pid;
+            mUid = uid;
+        }
+
+        @Override
+        public String getPackageName() {
+            return mPackageName;
+        }
+
+        @Override
+        public int getPid() {
+            return mPid;
+        }
+
+        @Override
+        public int getUid() {
+            return mUid;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof RemoteUserInfo)) {
+                return false;
+            }
+            RemoteUserInfo otherUserInfo = (RemoteUserInfo) obj;
+            return TextUtils.equals(mPackageName, otherUserInfo.mPackageName)
+                    && mPid == otherUserInfo.mPid
+                    && mUid == otherUserInfo.mUid;
+        }
+
+        @Override
+        public int hashCode() {
+            return ObjectsCompat.hash(mPackageName, mPid, mUid);
+        }
+    }
+}
+
diff --git a/media/src/main/java/androidx/media/MediaSessionService2.java b/media/src/main/java/androidx/media/MediaSessionService2.java
index 7bad65c..81dc877 100644
--- a/media/src/main/java/androidx/media/MediaSessionService2.java
+++ b/media/src/main/java/androidx/media/MediaSessionService2.java
@@ -97,7 +97,6 @@
  * <p>
  * After the binding, session's
  * {@link MediaSession2.SessionCallback#onConnect(MediaSession2, ControllerInfo)}
- *
  * will be called to accept or reject connection request from a controller. If the connection is
  * rejected, the controller will unbind. If it's accepted, the controller will be available to use
  * and keep binding.
@@ -106,6 +105,9 @@
  * is called and service would become a foreground service. It's needed to keep playback after the
  * controller is destroyed. The session service becomes background service when the playback is
  * stopped.
+ * <p>
+ * The service is destroyed when the session is closed, or no media controller is bounded to the
+ * session while the service is not running as a foreground service.
  * <a name="Permissions"></a>
  * <h3>Permissions</h3>
  * <p>
diff --git a/media/src/main/java/androidx/media/MediaUtils2.java b/media/src/main/java/androidx/media/MediaUtils2.java
index 657e24d..9d68623 100644
--- a/media/src/main/java/androidx/media/MediaUtils2.java
+++ b/media/src/main/java/androidx/media/MediaUtils2.java
@@ -428,4 +428,8 @@
     static boolean isDefaultLibraryRootHint(Bundle bundle) {
         return bundle != null && bundle.getBoolean(MediaConstants2.ROOT_EXTRA_DEFAULT, false);
     }
+
+    static Bundle createBundle(Bundle bundle) {
+        return (bundle == null) ? new Bundle() : new Bundle(bundle);
+    }
 }
diff --git a/media/src/main/java/androidx/media/SessionToken2.java b/media/src/main/java/androidx/media/SessionToken2.java
index eb42297..18c436c 100644
--- a/media/src/main/java/androidx/media/SessionToken2.java
+++ b/media/src/main/java/androidx/media/SessionToken2.java
@@ -23,7 +23,6 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.media.session.MediaSessionManager;
 import android.os.Bundle;
 import android.support.v4.media.session.MediaSessionCompat;
 import android.text.TextUtils;
@@ -43,7 +42,7 @@
  * This may be passed to apps by the session owner to allow them to create a
  * {@link MediaController2} to communicate with the session.
  * <p>
- * It can be also obtained by {@link MediaSessionManager}.
+ * It can be also obtained by MediaSessionManager.
  */
 // New version of MediaSession.Token for following reasons
 //   - Stop implementing Parcelable for updatable support
diff --git a/media/src/main/java/androidx/media/subtitle/Cea608CCParser.java b/media/src/main/java/androidx/media/subtitle/Cea608CCParser.java
new file mode 100644
index 0000000..9205fba
--- /dev/null
+++ b/media/src/main/java/androidx/media/subtitle/Cea608CCParser.java
@@ -0,0 +1,987 @@
+/*
+ * 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.media.subtitle;
+
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.TextPaint;
+import android.text.style.CharacterStyle;
+import android.text.style.StyleSpan;
+import android.text.style.UnderlineSpan;
+import android.text.style.UpdateAppearance;
+import android.util.Log;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * CCParser processes CEA-608 closed caption data.
+ *
+ * It calls back into OnDisplayChangedListener upon
+ * display change with styled text for rendering.
+ *
+ */
+class Cea608CCParser {
+    public static final int MAX_ROWS = 15;
+    public static final int MAX_COLS = 32;
+
+    private static final String TAG = "Cea608CCParser";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final int INVALID = -1;
+
+    // EIA-CEA-608: Table 70 - Control Codes
+    private static final int RCL = 0x20;
+    private static final int BS  = 0x21;
+    private static final int AOF = 0x22;
+    private static final int AON = 0x23;
+    private static final int DER = 0x24;
+    private static final int RU2 = 0x25;
+    private static final int RU3 = 0x26;
+    private static final int RU4 = 0x27;
+    private static final int FON = 0x28;
+    private static final int RDC = 0x29;
+    private static final int TR  = 0x2a;
+    private static final int RTD = 0x2b;
+    private static final int EDM = 0x2c;
+    private static final int CR  = 0x2d;
+    private static final int ENM = 0x2e;
+    private static final int EOC = 0x2f;
+
+    // Transparent Space
+    private static final char TS = '\u00A0';
+
+    // Captioning Modes
+    private static final int MODE_UNKNOWN = 0;
+    private static final int MODE_PAINT_ON = 1;
+    private static final int MODE_ROLL_UP = 2;
+    private static final int MODE_POP_ON = 3;
+    private static final int MODE_TEXT = 4;
+
+    private final DisplayListener mListener;
+
+    private int mMode = MODE_PAINT_ON;
+    private int mRollUpSize = 4;
+    private int mPrevCtrlCode = INVALID;
+
+    private CCMemory mDisplay = new CCMemory();
+    private CCMemory mNonDisplay = new CCMemory();
+    private CCMemory mTextMem = new CCMemory();
+
+    Cea608CCParser(DisplayListener listener) {
+        mListener = listener;
+    }
+
+    public void parse(byte[] data) {
+        CCData[] ccData = CCData.fromByteArray(data);
+
+        for (int i = 0; i < ccData.length; i++) {
+            if (DEBUG) {
+                Log.d(TAG, ccData[i].toString());
+            }
+
+            if (handleCtrlCode(ccData[i])
+                    || handleTabOffsets(ccData[i])
+                    || handlePACCode(ccData[i])
+                    || handleMidRowCode(ccData[i])) {
+                continue;
+            }
+
+            handleDisplayableChars(ccData[i]);
+        }
+    }
+
+    interface DisplayListener {
+        void onDisplayChanged(SpannableStringBuilder[] styledTexts);
+        CaptionStyle getCaptionStyle();
+    }
+
+    private CCMemory getMemory() {
+        // get the CC memory to operate on for current mode
+        switch (mMode) {
+            case MODE_POP_ON:
+                return mNonDisplay;
+            case MODE_TEXT:
+                // TODO(chz): support only caption mode for now,
+                // in text mode, dump everything to text mem.
+                return mTextMem;
+            case MODE_PAINT_ON:
+            case MODE_ROLL_UP:
+                return mDisplay;
+            default:
+                Log.w(TAG, "unrecoginized mode: " + mMode);
+        }
+        return mDisplay;
+    }
+
+    private boolean handleDisplayableChars(CCData ccData) {
+        if (!ccData.isDisplayableChar()) {
+            return false;
+        }
+
+        // Extended char includes 1 automatic backspace
+        if (ccData.isExtendedChar()) {
+            getMemory().bs();
+        }
+
+        getMemory().writeText(ccData.getDisplayText());
+
+        if (mMode == MODE_PAINT_ON || mMode == MODE_ROLL_UP) {
+            updateDisplay();
+        }
+
+        return true;
+    }
+
+    private boolean handleMidRowCode(CCData ccData) {
+        StyleCode m = ccData.getMidRow();
+        if (m != null) {
+            getMemory().writeMidRowCode(m);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean handlePACCode(CCData ccData) {
+        PAC pac = ccData.getPAC();
+
+        if (pac != null) {
+            if (mMode == MODE_ROLL_UP) {
+                getMemory().moveBaselineTo(pac.getRow(), mRollUpSize);
+            }
+            getMemory().writePAC(pac);
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean handleTabOffsets(CCData ccData) {
+        int tabs = ccData.getTabOffset();
+
+        if (tabs > 0) {
+            getMemory().tab(tabs);
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean handleCtrlCode(CCData ccData) {
+        int ctrlCode = ccData.getCtrlCode();
+
+        if (mPrevCtrlCode != INVALID && mPrevCtrlCode == ctrlCode) {
+            // discard double ctrl codes (but if there's a 3rd one, we still take that)
+            mPrevCtrlCode = INVALID;
+            return true;
+        }
+
+        switch(ctrlCode) {
+            case RCL:
+                // select pop-on style
+                mMode = MODE_POP_ON;
+                break;
+            case BS:
+                getMemory().bs();
+                break;
+            case DER:
+                getMemory().der();
+                break;
+            case RU2:
+            case RU3:
+            case RU4:
+                mRollUpSize = (ctrlCode - 0x23);
+                // erase memory if currently in other style
+                if (mMode != MODE_ROLL_UP) {
+                    mDisplay.erase();
+                    mNonDisplay.erase();
+                }
+                // select roll-up style
+                mMode = MODE_ROLL_UP;
+                break;
+            case FON:
+                Log.i(TAG, "Flash On");
+                break;
+            case RDC:
+                // select paint-on style
+                mMode = MODE_PAINT_ON;
+                break;
+            case TR:
+                mMode = MODE_TEXT;
+                mTextMem.erase();
+                break;
+            case RTD:
+                mMode = MODE_TEXT;
+                break;
+            case EDM:
+                // erase display memory
+                mDisplay.erase();
+                updateDisplay();
+                break;
+            case CR:
+                if (mMode == MODE_ROLL_UP) {
+                    getMemory().rollUp(mRollUpSize);
+                } else {
+                    getMemory().cr();
+                }
+                if (mMode == MODE_ROLL_UP) {
+                    updateDisplay();
+                }
+                break;
+            case ENM:
+                // erase non-display memory
+                mNonDisplay.erase();
+                break;
+            case EOC:
+                // swap display/non-display memory
+                swapMemory();
+                // switch to pop-on style
+                mMode = MODE_POP_ON;
+                updateDisplay();
+                break;
+            case INVALID:
+            default:
+                mPrevCtrlCode = INVALID;
+                return false;
+        }
+
+        mPrevCtrlCode = ctrlCode;
+
+        // handled
+        return true;
+    }
+
+    private void updateDisplay() {
+        if (mListener != null) {
+            CaptionStyle captionStyle = mListener.getCaptionStyle();
+            mListener.onDisplayChanged(mDisplay.getStyledText(captionStyle));
+        }
+    }
+
+    private void swapMemory() {
+        CCMemory temp = mDisplay;
+        mDisplay = mNonDisplay;
+        mNonDisplay = temp;
+    }
+
+    private static class StyleCode {
+        static final int COLOR_WHITE = 0;
+        static final int COLOR_GREEN = 1;
+        static final int COLOR_BLUE = 2;
+        static final int COLOR_CYAN = 3;
+        static final int COLOR_RED = 4;
+        static final int COLOR_YELLOW = 5;
+        static final int COLOR_MAGENTA = 6;
+        static final int COLOR_INVALID = 7;
+
+        static final int STYLE_ITALICS   = 0x00000001;
+        static final int STYLE_UNDERLINE = 0x00000002;
+
+        static final String[] sColorMap = {
+            "WHITE", "GREEN", "BLUE", "CYAN", "RED", "YELLOW", "MAGENTA", "INVALID"
+        };
+
+        final int mStyle;
+        final int mColor;
+
+        static StyleCode fromByte(byte data2) {
+            int style = 0;
+            int color = (data2 >> 1) & 0x7;
+
+            if ((data2 & 0x1) != 0) {
+                style |= STYLE_UNDERLINE;
+            }
+
+            if (color == COLOR_INVALID) {
+                // WHITE ITALICS
+                color = COLOR_WHITE;
+                style |= STYLE_ITALICS;
+            }
+
+            return new StyleCode(style, color);
+        }
+
+        StyleCode(int style, int color) {
+            mStyle = style;
+            mColor = color;
+        }
+
+        boolean isItalics() {
+            return (mStyle & STYLE_ITALICS) != 0;
+        }
+
+        boolean isUnderline() {
+            return (mStyle & STYLE_UNDERLINE) != 0;
+        }
+
+        int getColor() {
+            return mColor;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder str = new StringBuilder();
+            str.append("{");
+            str.append(sColorMap[mColor]);
+            if ((mStyle & STYLE_ITALICS) != 0) {
+                str.append(", ITALICS");
+            }
+            if ((mStyle & STYLE_UNDERLINE) != 0) {
+                str.append(", UNDERLINE");
+            }
+            str.append("}");
+
+            return str.toString();
+        }
+    }
+
+    private static class PAC extends StyleCode {
+        final int mRow;
+        final int mCol;
+
+        static PAC fromBytes(byte data1, byte data2) {
+            int[] rowTable = {11, 1, 3, 12, 14, 5, 7, 9};
+            int row = rowTable[data1 & 0x07] + ((data2 & 0x20) >> 5);
+            int style = 0;
+            if ((data2 & 1) != 0) {
+                style |= STYLE_UNDERLINE;
+            }
+            if ((data2 & 0x10) != 0) {
+                // indent code
+                int indent = (data2 >> 1) & 0x7;
+                return new PAC(row, indent * 4, style, COLOR_WHITE);
+            } else {
+                // style code
+                int color = (data2 >> 1) & 0x7;
+
+                if (color == COLOR_INVALID) {
+                    // WHITE ITALICS
+                    color = COLOR_WHITE;
+                    style |= STYLE_ITALICS;
+                }
+                return new PAC(row, -1, style, color);
+            }
+        }
+
+        PAC(int row, int col, int style, int color) {
+            super(style, color);
+            mRow = row;
+            mCol = col;
+        }
+
+        boolean isIndentPAC() {
+            return (mCol >= 0);
+        }
+
+        int getRow() {
+            return mRow;
+        }
+
+        int getCol() {
+            return mCol;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("{%d, %d}, %s",
+                    mRow, mCol, super.toString());
+        }
+    }
+
+    /**
+     * Mutable version of BackgroundSpan to facilitate text rendering with edge styles.
+     */
+    public static class MutableBackgroundColorSpan extends CharacterStyle
+            implements UpdateAppearance {
+        private int mColor;
+
+        MutableBackgroundColorSpan(int color) {
+            mColor = color;
+        }
+
+        public void setBackgroundColor(int color) {
+            mColor = color;
+        }
+
+        public int getBackgroundColor() {
+            return mColor;
+        }
+
+        @Override
+        public void updateDrawState(TextPaint ds) {
+            ds.bgColor = mColor;
+        }
+    }
+
+    /* CCLineBuilder keeps track of displayable chars, as well as
+     * MidRow styles and PACs, for a single line of CC memory.
+     *
+     * It generates styled text via getStyledText() method.
+     */
+    private static class CCLineBuilder {
+        private final StringBuilder mDisplayChars;
+        private final StyleCode[] mMidRowStyles;
+        private final StyleCode[] mPACStyles;
+
+        CCLineBuilder(String str) {
+            mDisplayChars = new StringBuilder(str);
+            mMidRowStyles = new StyleCode[mDisplayChars.length()];
+            mPACStyles = new StyleCode[mDisplayChars.length()];
+        }
+
+        void setCharAt(int index, char ch) {
+            mDisplayChars.setCharAt(index, ch);
+            mMidRowStyles[index] = null;
+        }
+
+        void setMidRowAt(int index, StyleCode m) {
+            mDisplayChars.setCharAt(index, ' ');
+            mMidRowStyles[index] = m;
+        }
+
+        void setPACAt(int index, PAC pac) {
+            mPACStyles[index] = pac;
+        }
+
+        char charAt(int index) {
+            return mDisplayChars.charAt(index);
+        }
+
+        int length() {
+            return mDisplayChars.length();
+        }
+
+        void applyStyleSpan(
+                SpannableStringBuilder styledText,
+                StyleCode s, int start, int end) {
+            if (s.isItalics()) {
+                styledText.setSpan(
+                        new StyleSpan(android.graphics.Typeface.ITALIC),
+                        start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            }
+            if (s.isUnderline()) {
+                styledText.setSpan(
+                        new UnderlineSpan(),
+                        start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            }
+        }
+
+        SpannableStringBuilder getStyledText(CaptionStyle captionStyle) {
+            SpannableStringBuilder styledText = new SpannableStringBuilder(mDisplayChars);
+            int start = -1, next = 0;
+            int styleStart = -1;
+            StyleCode curStyle = null;
+            while (next < mDisplayChars.length()) {
+                StyleCode newStyle = null;
+                if (mMidRowStyles[next] != null) {
+                    // apply mid-row style change
+                    newStyle = mMidRowStyles[next];
+                } else if (mPACStyles[next] != null && (styleStart < 0 || start < 0)) {
+                    // apply PAC style change, only if:
+                    // 1. no style set, or
+                    // 2. style set, but prev char is none-displayable
+                    newStyle = mPACStyles[next];
+                }
+                if (newStyle != null) {
+                    curStyle = newStyle;
+                    if (styleStart >= 0 && start >= 0) {
+                        applyStyleSpan(styledText, newStyle, styleStart, next);
+                    }
+                    styleStart = next;
+                }
+
+                if (mDisplayChars.charAt(next) != TS) {
+                    if (start < 0) {
+                        start = next;
+                    }
+                } else if (start >= 0) {
+                    int expandedStart = mDisplayChars.charAt(start) == ' ' ? start : start - 1;
+                    int expandedEnd = mDisplayChars.charAt(next - 1) == ' ' ? next : next + 1;
+                    styledText.setSpan(
+                            new MutableBackgroundColorSpan(captionStyle.backgroundColor),
+                            expandedStart, expandedEnd,
+                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+                    if (styleStart >= 0) {
+                        applyStyleSpan(styledText, curStyle, styleStart, expandedEnd);
+                    }
+                    start = -1;
+                }
+                next++;
+            }
+
+            return styledText;
+        }
+    }
+
+    /*
+     * CCMemory models a console-style display.
+     */
+    private static class CCMemory {
+        private final String mBlankLine;
+        private final CCLineBuilder[] mLines = new CCLineBuilder[MAX_ROWS + 2];
+        private int mRow;
+        private int mCol;
+
+        CCMemory() {
+            char[] blank = new char[MAX_COLS + 2];
+            Arrays.fill(blank, TS);
+            mBlankLine = new String(blank);
+        }
+
+        void erase() {
+            // erase all lines
+            for (int i = 0; i < mLines.length; i++) {
+                mLines[i] = null;
+            }
+            mRow = MAX_ROWS;
+            mCol = 1;
+        }
+
+        void der() {
+            if (mLines[mRow] != null) {
+                for (int i = 0; i < mCol; i++) {
+                    if (mLines[mRow].charAt(i) != TS) {
+                        for (int j = mCol; j < mLines[mRow].length(); j++) {
+                            mLines[j].setCharAt(j, TS);
+                        }
+                        return;
+                    }
+                }
+                mLines[mRow] = null;
+            }
+        }
+
+        void tab(int tabs) {
+            moveCursorByCol(tabs);
+        }
+
+        void bs() {
+            moveCursorByCol(-1);
+            if (mLines[mRow] != null) {
+                mLines[mRow].setCharAt(mCol, TS);
+                if (mCol == MAX_COLS - 1) {
+                    // Spec recommendation:
+                    // if cursor was at col 32, move cursor
+                    // back to col 31 and erase both col 31&32
+                    mLines[mRow].setCharAt(MAX_COLS, TS);
+                }
+            }
+        }
+
+        void cr() {
+            moveCursorTo(mRow + 1, 1);
+        }
+
+        void rollUp(int windowSize) {
+            int i;
+            for (i = 0; i <= mRow - windowSize; i++) {
+                mLines[i] = null;
+            }
+            int startRow = mRow - windowSize + 1;
+            if (startRow < 1) {
+                startRow = 1;
+            }
+            for (i = startRow; i < mRow; i++) {
+                mLines[i] = mLines[i + 1];
+            }
+            for (i = mRow; i < mLines.length; i++) {
+                // clear base row
+                mLines[i] = null;
+            }
+            // default to col 1, in case PAC is not sent
+            mCol = 1;
+        }
+
+        void writeText(String text) {
+            for (int i = 0; i < text.length(); i++) {
+                getLineBuffer(mRow).setCharAt(mCol, text.charAt(i));
+                moveCursorByCol(1);
+            }
+        }
+
+        void writeMidRowCode(StyleCode m) {
+            getLineBuffer(mRow).setMidRowAt(mCol, m);
+            moveCursorByCol(1);
+        }
+
+        void writePAC(PAC pac) {
+            if (pac.isIndentPAC()) {
+                moveCursorTo(pac.getRow(), pac.getCol());
+            } else {
+                moveCursorTo(pac.getRow(), 1);
+            }
+            getLineBuffer(mRow).setPACAt(mCol, pac);
+        }
+
+        SpannableStringBuilder[] getStyledText(CaptionStyle captionStyle) {
+            ArrayList<SpannableStringBuilder> rows = new ArrayList<>(MAX_ROWS);
+            for (int i = 1; i <= MAX_ROWS; i++) {
+                rows.add(mLines[i] != null ? mLines[i].getStyledText(captionStyle) : null);
+            }
+            return rows.toArray(new SpannableStringBuilder[MAX_ROWS]);
+        }
+
+        private static int clamp(int x, int min, int max) {
+            return x < min ? min : (x > max ? max : x);
+        }
+
+        private void moveCursorTo(int row, int col) {
+            mRow = clamp(row, 1, MAX_ROWS);
+            mCol = clamp(col, 1, MAX_COLS);
+        }
+
+        private void moveCursorToRow(int row) {
+            mRow = clamp(row, 1, MAX_ROWS);
+        }
+
+        private void moveCursorByCol(int col) {
+            mCol = clamp(mCol + col, 1, MAX_COLS);
+        }
+
+        private void moveBaselineTo(int baseRow, int windowSize) {
+            if (mRow == baseRow) {
+                return;
+            }
+            int actualWindowSize = windowSize;
+            if (baseRow < actualWindowSize) {
+                actualWindowSize = baseRow;
+            }
+            if (mRow < actualWindowSize) {
+                actualWindowSize = mRow;
+            }
+
+            int i;
+            if (baseRow < mRow) {
+                // copy from bottom to top row
+                for (i = actualWindowSize - 1; i >= 0; i--) {
+                    mLines[baseRow - i] = mLines[mRow - i];
+                }
+            } else {
+                // copy from top to bottom row
+                for (i = 0; i < actualWindowSize; i++) {
+                    mLines[baseRow - i] = mLines[mRow - i];
+                }
+            }
+            // clear rest of the rows
+            for (i = 0; i <= baseRow - windowSize; i++) {
+                mLines[i] = null;
+            }
+            for (i = baseRow + 1; i < mLines.length; i++) {
+                mLines[i] = null;
+            }
+        }
+
+        private CCLineBuilder getLineBuffer(int row) {
+            if (mLines[row] == null) {
+                mLines[row] = new CCLineBuilder(mBlankLine);
+            }
+            return mLines[row];
+        }
+    }
+
+    /*
+     * CCData parses the raw CC byte pair into displayable chars,
+     * misc control codes, Mid-Row or Preamble Address Codes.
+     */
+    private static class CCData {
+        private final byte mType;
+        private final byte mData1;
+        private final byte mData2;
+
+        private static final String[] sCtrlCodeMap = {
+            "RCL", "BS" , "AOF", "AON",
+            "DER", "RU2", "RU3", "RU4",
+            "FON", "RDC", "TR" , "RTD",
+            "EDM", "CR" , "ENM", "EOC",
+        };
+
+        private static final String[] sSpecialCharMap = {
+            "\u00AE",
+            "\u00B0",
+            "\u00BD",
+            "\u00BF",
+            "\u2122",
+            "\u00A2",
+            "\u00A3",
+            "\u266A", // Eighth note
+            "\u00E0",
+            "\u00A0", // Transparent space
+            "\u00E8",
+            "\u00E2",
+            "\u00EA",
+            "\u00EE",
+            "\u00F4",
+            "\u00FB",
+        };
+
+        private static final String[] sSpanishCharMap = {
+            // Spanish and misc chars
+            "\u00C1", // A
+            "\u00C9", // E
+            "\u00D3", // I
+            "\u00DA", // O
+            "\u00DC", // U
+            "\u00FC", // u
+            "\u2018", // opening single quote
+            "\u00A1", // inverted exclamation mark
+            "*",
+            "'",
+            "\u2014", // em dash
+            "\u00A9", // Copyright
+            "\u2120", // Servicemark
+            "\u2022", // round bullet
+            "\u201C", // opening double quote
+            "\u201D", // closing double quote
+            // French
+            "\u00C0",
+            "\u00C2",
+            "\u00C7",
+            "\u00C8",
+            "\u00CA",
+            "\u00CB",
+            "\u00EB",
+            "\u00CE",
+            "\u00CF",
+            "\u00EF",
+            "\u00D4",
+            "\u00D9",
+            "\u00F9",
+            "\u00DB",
+            "\u00AB",
+            "\u00BB"
+        };
+
+        private static final String[] sProtugueseCharMap = {
+            // Portuguese
+            "\u00C3",
+            "\u00E3",
+            "\u00CD",
+            "\u00CC",
+            "\u00EC",
+            "\u00D2",
+            "\u00F2",
+            "\u00D5",
+            "\u00F5",
+            "{",
+            "}",
+            "\\",
+            "^",
+            "_",
+            "|",
+            "~",
+            // German and misc chars
+            "\u00C4",
+            "\u00E4",
+            "\u00D6",
+            "\u00F6",
+            "\u00DF",
+            "\u00A5",
+            "\u00A4",
+            "\u2502", // vertical bar
+            "\u00C5",
+            "\u00E5",
+            "\u00D8",
+            "\u00F8",
+            "\u250C", // top-left corner
+            "\u2510", // top-right corner
+            "\u2514", // lower-left corner
+            "\u2518", // lower-right corner
+        };
+
+        static CCData[] fromByteArray(byte[] data) {
+            CCData[] ccData = new CCData[data.length / 3];
+
+            for (int i = 0; i < ccData.length; i++) {
+                ccData[i] = new CCData(
+                        data[i * 3],
+                        data[i * 3 + 1],
+                        data[i * 3 + 2]);
+            }
+
+            return ccData;
+        }
+
+        CCData(byte type, byte data1, byte data2) {
+            mType = type;
+            mData1 = data1;
+            mData2 = data2;
+        }
+
+        int getCtrlCode() {
+            if ((mData1 == 0x14 || mData1 == 0x1c)
+                    && mData2 >= 0x20 && mData2 <= 0x2f) {
+                return mData2;
+            }
+            return INVALID;
+        }
+
+        StyleCode getMidRow() {
+            // only support standard Mid-row codes, ignore
+            // optional background/foreground mid-row codes
+            if ((mData1 == 0x11 || mData1 == 0x19)
+                    && mData2 >= 0x20 && mData2 <= 0x2f) {
+                return StyleCode.fromByte(mData2);
+            }
+            return null;
+        }
+
+        PAC getPAC() {
+            if ((mData1 & 0x70) == 0x10
+                    && (mData2 & 0x40) == 0x40
+                    && ((mData1 & 0x07) != 0 || (mData2 & 0x20) == 0)) {
+                return PAC.fromBytes(mData1, mData2);
+            }
+            return null;
+        }
+
+        int getTabOffset() {
+            if ((mData1 == 0x17 || mData1 == 0x1f)
+                    && mData2 >= 0x21 && mData2 <= 0x23) {
+                return mData2 & 0x3;
+            }
+            return 0;
+        }
+
+        boolean isDisplayableChar() {
+            return isBasicChar() || isSpecialChar() || isExtendedChar();
+        }
+
+        String getDisplayText() {
+            String str = getBasicChars();
+
+            if (str == null) {
+                str =  getSpecialChar();
+
+                if (str == null) {
+                    str = getExtendedChar();
+                }
+            }
+
+            return str;
+        }
+
+        private String ctrlCodeToString(int ctrlCode) {
+            return sCtrlCodeMap[ctrlCode - 0x20];
+        }
+
+        private boolean isBasicChar() {
+            return mData1 >= 0x20 && mData1 <= 0x7f;
+        }
+
+        private boolean isSpecialChar() {
+            return ((mData1 == 0x11 || mData1 == 0x19)
+                    && mData2 >= 0x30 && mData2 <= 0x3f);
+        }
+
+        private boolean isExtendedChar() {
+            return ((mData1 == 0x12 || mData1 == 0x1A
+                    || mData1 == 0x13 || mData1 == 0x1B)
+                    && mData2 >= 0x20 && mData2 <= 0x3f);
+        }
+
+        private char getBasicChar(byte data) {
+            char c;
+            // replace the non-ASCII ones
+            switch (data) {
+                case 0x2A: c = '\u00E1'; break;
+                case 0x5C: c = '\u00E9'; break;
+                case 0x5E: c = '\u00ED'; break;
+                case 0x5F: c = '\u00F3'; break;
+                case 0x60: c = '\u00FA'; break;
+                case 0x7B: c = '\u00E7'; break;
+                case 0x7C: c = '\u00F7'; break;
+                case 0x7D: c = '\u00D1'; break;
+                case 0x7E: c = '\u00F1'; break;
+                case 0x7F: c = '\u2588'; break; // Full block
+                default: c = (char) data; break;
+            }
+            return c;
+        }
+
+        private String getBasicChars() {
+            if (mData1 >= 0x20 && mData1 <= 0x7f) {
+                StringBuilder builder = new StringBuilder(2);
+                builder.append(getBasicChar(mData1));
+                if (mData2 >= 0x20 && mData2 <= 0x7f) {
+                    builder.append(getBasicChar(mData2));
+                }
+                return builder.toString();
+            }
+
+            return null;
+        }
+
+        private String getSpecialChar() {
+            if ((mData1 == 0x11 || mData1 == 0x19)
+                    && mData2 >= 0x30 && mData2 <= 0x3f) {
+                return sSpecialCharMap[mData2 - 0x30];
+            }
+
+            return null;
+        }
+
+        private String getExtendedChar() {
+            if ((mData1 == 0x12 || mData1 == 0x1A) && mData2 >= 0x20 && mData2 <= 0x3f) {
+                // 1 Spanish/French char
+                return sSpanishCharMap[mData2 - 0x20];
+            } else if ((mData1 == 0x13 || mData1 == 0x1B) && mData2 >= 0x20 && mData2 <= 0x3f) {
+                // 1 Portuguese/German/Danish char
+                return sProtugueseCharMap[mData2 - 0x20];
+            }
+
+            return null;
+        }
+
+        @Override
+        public String toString() {
+            String str;
+
+            if (mData1 < 0x10 && mData2 < 0x10) {
+                // Null Pad, ignore
+                return String.format("[%d]Null: %02x %02x", mType, mData1, mData2);
+            }
+
+            int ctrlCode = getCtrlCode();
+            if (ctrlCode != INVALID) {
+                return String.format("[%d]%s", mType, ctrlCodeToString(ctrlCode));
+            }
+
+            int tabOffset = getTabOffset();
+            if (tabOffset > 0) {
+                return String.format("[%d]Tab%d", mType, tabOffset);
+            }
+
+            PAC pac = getPAC();
+            if (pac != null) {
+                return String.format("[%d]PAC: %s", mType, pac.toString());
+            }
+
+            StyleCode m = getMidRow();
+            if (m != null) {
+                return String.format("[%d]Mid-row: %s", mType, m.toString());
+            }
+
+            if (isDisplayableChar()) {
+                return String.format("[%d]Displayable: %s (%02x %02x)",
+                        mType, getDisplayText(), mData1, mData2);
+            }
+
+            return String.format("[%d]Invalid: %02x %02x", mType, mData1, mData2);
+        }
+    }
+}
diff --git a/media/src/main/java/androidx/media/subtitle/ClosedCaptionRenderer.java b/media/src/main/java/androidx/media/subtitle/ClosedCaptionRenderer.java
new file mode 100644
index 0000000..90ff516
--- /dev/null
+++ b/media/src/main/java/androidx/media/subtitle/ClosedCaptionRenderer.java
@@ -0,0 +1,402 @@
+/*
+ * 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.media.subtitle;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.media.MediaFormat;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.TextPaint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.media.R;
+
+import java.util.ArrayList;
+
+// Note: This is forked from android.media.ClosedCaptionRenderer since P
+/**
+ * @hide
+ */
+@RequiresApi(28)
+@RestrictTo(LIBRARY_GROUP)
+public class ClosedCaptionRenderer extends SubtitleController.Renderer {
+    private final Context mContext;
+    private Cea608CCWidget mCCWidget;
+
+    public ClosedCaptionRenderer(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public boolean supports(MediaFormat format) {
+        if (format.containsKey(MediaFormat.KEY_MIME)) {
+            String mimeType = format.getString(MediaFormat.KEY_MIME);
+            return MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mimeType);
+        }
+        return false;
+    }
+
+    @Override
+    public SubtitleTrack createTrack(MediaFormat format) {
+        String mimeType = format.getString(MediaFormat.KEY_MIME);
+        if (MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mimeType)) {
+            if (mCCWidget == null) {
+                mCCWidget = new Cea608CCWidget(mContext);
+            }
+            return new Cea608CaptionTrack(mCCWidget, format);
+        }
+        throw new RuntimeException("No matching format: " + format.toString());
+    }
+
+    static class Cea608CaptionTrack extends SubtitleTrack {
+        private final Cea608CCParser mCCParser;
+        private final Cea608CCWidget mRenderingWidget;
+
+        Cea608CaptionTrack(Cea608CCWidget renderingWidget, MediaFormat format) {
+            super(format);
+
+            mRenderingWidget = renderingWidget;
+            mCCParser = new Cea608CCParser(mRenderingWidget);
+        }
+
+        @Override
+        public void onData(byte[] data, boolean eos, long runID) {
+            mCCParser.parse(data);
+        }
+
+        @Override
+        public RenderingWidget getRenderingWidget() {
+            return mRenderingWidget;
+        }
+
+        @Override
+        public void updateView(ArrayList<Cue> activeCues) {
+            // Overriding with NO-OP, CC rendering by-passes this
+        }
+    }
+
+    /**
+     * Widget capable of rendering CEA-608 closed captions.
+     */
+    class Cea608CCWidget extends ClosedCaptionWidget implements Cea608CCParser.DisplayListener {
+        private static final String DUMMY_TEXT = "1234567890123456789012345678901234";
+        private final Rect mTextBounds = new Rect();
+
+        Cea608CCWidget(Context context) {
+            this(context, null);
+        }
+
+        Cea608CCWidget(Context context, AttributeSet attrs) {
+            this(context, attrs, 0);
+        }
+
+        Cea608CCWidget(Context context, AttributeSet attrs, int defStyle) {
+            this(context, attrs, defStyle, 0);
+        }
+
+        Cea608CCWidget(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
+        }
+
+        @Override
+        public ClosedCaptionLayout createCaptionLayout(Context context) {
+            return new CCLayout(context);
+        }
+
+        @Override
+        public void onDisplayChanged(SpannableStringBuilder[] styledTexts) {
+            ((CCLayout) mClosedCaptionLayout).update(styledTexts);
+
+            if (mListener != null) {
+                mListener.onChanged(this);
+            }
+        }
+
+        @Override
+        public CaptionStyle getCaptionStyle() {
+            return mCaptionStyle;
+        }
+
+        private class CCLineBox extends TextView {
+            private static final float FONT_PADDING_RATIO = 0.75f;
+            private static final float EDGE_OUTLINE_RATIO = 0.1f;
+            private static final float EDGE_SHADOW_RATIO = 0.05f;
+            private float mOutlineWidth;
+            private float mShadowRadius;
+            private float mShadowOffset;
+
+            private int mTextColor = Color.WHITE;
+            private int mBgColor = Color.BLACK;
+            private int mEdgeType = CaptionStyle.EDGE_TYPE_NONE;
+            private int mEdgeColor = Color.TRANSPARENT;
+
+            CCLineBox(Context context) {
+                super(context);
+                setGravity(Gravity.CENTER);
+                setBackgroundColor(Color.TRANSPARENT);
+                setTextColor(Color.WHITE);
+                setTypeface(Typeface.MONOSPACE);
+                setVisibility(View.INVISIBLE);
+
+                final Resources res = getContext().getResources();
+
+                // get the default (will be updated later during measure)
+                mOutlineWidth = res.getDimensionPixelSize(
+                        R.dimen.subtitle_outline_width);
+                mShadowRadius = res.getDimensionPixelSize(
+                        R.dimen.subtitle_shadow_radius);
+                mShadowOffset = res.getDimensionPixelSize(
+                        R.dimen.subtitle_shadow_offset);
+            }
+
+            void setCaptionStyle(CaptionStyle captionStyle) {
+                mTextColor = captionStyle.foregroundColor;
+                mBgColor = captionStyle.backgroundColor;
+                mEdgeType = captionStyle.edgeType;
+                mEdgeColor = captionStyle.edgeColor;
+
+                setTextColor(mTextColor);
+                if (mEdgeType == CaptionStyle.EDGE_TYPE_DROP_SHADOW) {
+                    setShadowLayer(mShadowRadius, mShadowOffset, mShadowOffset, mEdgeColor);
+                } else {
+                    setShadowLayer(0, 0, 0, 0);
+                }
+                invalidate();
+            }
+
+            @Override
+            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+                float fontSize = MeasureSpec.getSize(heightMeasureSpec) * FONT_PADDING_RATIO;
+                setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize);
+
+                mOutlineWidth = EDGE_OUTLINE_RATIO * fontSize + 1.0f;
+                mShadowRadius = EDGE_SHADOW_RATIO * fontSize + 1.0f;
+                mShadowOffset = mShadowRadius;
+
+                // set font scale in the X direction to match the required width
+                setScaleX(1.0f);
+                getPaint().getTextBounds(DUMMY_TEXT, 0, DUMMY_TEXT.length(), mTextBounds);
+                float actualTextWidth = mTextBounds.width();
+                float requiredTextWidth = MeasureSpec.getSize(widthMeasureSpec);
+                setScaleX(requiredTextWidth / actualTextWidth);
+
+                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            }
+
+            @Override
+            protected void onDraw(Canvas c) {
+                if (mEdgeType == CaptionStyle.EDGE_TYPE_UNSPECIFIED
+                        || mEdgeType == CaptionStyle.EDGE_TYPE_NONE
+                        || mEdgeType == CaptionStyle.EDGE_TYPE_DROP_SHADOW) {
+                    // these edge styles don't require a second pass
+                    super.onDraw(c);
+                    return;
+                }
+
+                if (mEdgeType == CaptionStyle.EDGE_TYPE_OUTLINE) {
+                    drawEdgeOutline(c);
+                } else {
+                    // Raised or depressed
+                    drawEdgeRaisedOrDepressed(c);
+                }
+            }
+
+            @SuppressWarnings("WrongCall")
+            private void drawEdgeOutline(Canvas c) {
+                TextPaint textPaint = getPaint();
+
+                Paint.Style previousStyle = textPaint.getStyle();
+                Paint.Join previousJoin = textPaint.getStrokeJoin();
+                float previousWidth = textPaint.getStrokeWidth();
+
+                setTextColor(mEdgeColor);
+                textPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+                textPaint.setStrokeJoin(Paint.Join.ROUND);
+                textPaint.setStrokeWidth(mOutlineWidth);
+
+                // Draw outline and background only.
+                super.onDraw(c);
+
+                // Restore original settings.
+                setTextColor(mTextColor);
+                textPaint.setStyle(previousStyle);
+                textPaint.setStrokeJoin(previousJoin);
+                textPaint.setStrokeWidth(previousWidth);
+
+                // Remove the background.
+                setBackgroundSpans(Color.TRANSPARENT);
+                // Draw foreground only.
+                super.onDraw(c);
+                // Restore the background.
+                setBackgroundSpans(mBgColor);
+            }
+
+            @SuppressWarnings("WrongCall")
+            private void drawEdgeRaisedOrDepressed(Canvas c) {
+                TextPaint textPaint = getPaint();
+
+                Paint.Style previousStyle = textPaint.getStyle();
+                textPaint.setStyle(Paint.Style.FILL);
+
+                final boolean raised = mEdgeType == CaptionStyle.EDGE_TYPE_RAISED;
+                final int colorUp = raised ? Color.WHITE : mEdgeColor;
+                final int colorDown = raised ? mEdgeColor : Color.WHITE;
+                final float offset = mShadowRadius / 2f;
+
+                // Draw background and text with shadow up
+                setShadowLayer(mShadowRadius, -offset, -offset, colorUp);
+                super.onDraw(c);
+
+                // Remove the background.
+                setBackgroundSpans(Color.TRANSPARENT);
+
+                // Draw text with shadow down
+                setShadowLayer(mShadowRadius, +offset, +offset, colorDown);
+                super.onDraw(c);
+
+                // Restore settings
+                textPaint.setStyle(previousStyle);
+
+                // Restore the background.
+                setBackgroundSpans(mBgColor);
+            }
+
+            private void setBackgroundSpans(int color) {
+                CharSequence text = getText();
+                if (text instanceof Spannable) {
+                    Spannable spannable = (Spannable) text;
+                    Cea608CCParser.MutableBackgroundColorSpan[] bgSpans = spannable.getSpans(
+                            0, spannable.length(), Cea608CCParser.MutableBackgroundColorSpan.class);
+                    for (int i = 0; i < bgSpans.length; i++) {
+                        bgSpans[i].setBackgroundColor(color);
+                    }
+                }
+            }
+        }
+
+        private class CCLayout extends LinearLayout implements ClosedCaptionLayout {
+            private static final int MAX_ROWS = Cea608CCParser.MAX_ROWS;
+            private static final float SAFE_AREA_RATIO = 0.9f;
+
+            private final CCLineBox[] mLineBoxes = new CCLineBox[MAX_ROWS];
+
+            CCLayout(Context context) {
+                super(context);
+                setGravity(Gravity.START);
+                setOrientation(LinearLayout.VERTICAL);
+                for (int i = 0; i < MAX_ROWS; i++) {
+                    mLineBoxes[i] = new CCLineBox(getContext());
+                    addView(mLineBoxes[i], LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+                }
+            }
+
+            @Override
+            public void setCaptionStyle(CaptionStyle captionStyle) {
+                for (int i = 0; i < MAX_ROWS; i++) {
+                    mLineBoxes[i].setCaptionStyle(captionStyle);
+                }
+            }
+
+            @Override
+            public void setFontScale(float fontScale) {
+                // Ignores the font scale changes of the system wide CC preference.
+            }
+
+            void update(SpannableStringBuilder[] textBuffer) {
+                for (int i = 0; i < MAX_ROWS; i++) {
+                    if (textBuffer[i] != null) {
+                        mLineBoxes[i].setText(textBuffer[i], TextView.BufferType.SPANNABLE);
+                        mLineBoxes[i].setVisibility(View.VISIBLE);
+                    } else {
+                        mLineBoxes[i].setVisibility(View.INVISIBLE);
+                    }
+                }
+            }
+
+            @Override
+            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+                int safeWidth = getMeasuredWidth();
+                int safeHeight = getMeasuredHeight();
+
+                // CEA-608 assumes 4:3 video
+                if (safeWidth * 3 >= safeHeight * 4) {
+                    safeWidth = safeHeight * 4 / 3;
+                } else {
+                    safeHeight = safeWidth * 3 / 4;
+                }
+                safeWidth = (int) (safeWidth * SAFE_AREA_RATIO);
+                safeHeight = (int) (safeHeight * SAFE_AREA_RATIO);
+
+                int lineHeight = safeHeight / MAX_ROWS;
+                int lineHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                        lineHeight, MeasureSpec.EXACTLY);
+                int lineWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                        safeWidth, MeasureSpec.EXACTLY);
+
+                for (int i = 0; i < MAX_ROWS; i++) {
+                    mLineBoxes[i].measure(lineWidthMeasureSpec, lineHeightMeasureSpec);
+                }
+            }
+
+            @Override
+            protected void onLayout(boolean changed, int l, int t, int r, int b) {
+                // safe caption area
+                int viewPortWidth = r - l;
+                int viewPortHeight = b - t;
+                int safeWidth, safeHeight;
+                // CEA-608 assumes 4:3 video
+                if (viewPortWidth * 3 >= viewPortHeight * 4) {
+                    safeWidth = viewPortHeight * 4 / 3;
+                    safeHeight = viewPortHeight;
+                } else {
+                    safeWidth = viewPortWidth;
+                    safeHeight = viewPortWidth * 3 / 4;
+                }
+                safeWidth = (int) (safeWidth * SAFE_AREA_RATIO);
+                safeHeight = (int) (safeHeight * SAFE_AREA_RATIO);
+                int left = (viewPortWidth - safeWidth) / 2;
+                int top = (viewPortHeight - safeHeight) / 2;
+
+                for (int i = 0; i < MAX_ROWS; i++) {
+                    mLineBoxes[i].layout(
+                            left,
+                            top + safeHeight * i / MAX_ROWS,
+                            left + safeWidth,
+                            top + safeHeight * (i + 1) / MAX_ROWS);
+                }
+            }
+        }
+    }
+}
diff --git a/media/src/main/java/androidx/media/subtitle/ClosedCaptionWidget.java b/media/src/main/java/androidx/media/subtitle/ClosedCaptionWidget.java
new file mode 100644
index 0000000..a3d3e47
--- /dev/null
+++ b/media/src/main/java/androidx/media/subtitle/ClosedCaptionWidget.java
@@ -0,0 +1,167 @@
+/*
+ * 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.media.subtitle;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
+
+import androidx.annotation.RequiresApi;
+
+/**
+ * Abstract widget class to render a closed caption track.
+ */
+@RequiresApi(28)
+abstract class ClosedCaptionWidget extends ViewGroup implements SubtitleTrack.RenderingWidget {
+
+    interface ClosedCaptionLayout {
+        void setCaptionStyle(CaptionStyle captionStyle);
+        void setFontScale(float scale);
+    }
+
+    /** Captioning manager, used to obtain and track caption properties. */
+    private final CaptioningManager mManager;
+
+    /** Current caption style. */
+    protected CaptionStyle mCaptionStyle;
+
+    /** Callback for rendering changes. */
+    protected OnChangedListener mListener;
+
+    /** Concrete layout of CC. */
+    protected ClosedCaptionLayout mClosedCaptionLayout;
+
+    /** Whether a caption style change listener is registered. */
+    private boolean mHasChangeListener;
+
+    ClosedCaptionWidget(Context context) {
+        this(context, null);
+    }
+
+    ClosedCaptionWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    ClosedCaptionWidget(Context context, AttributeSet attrs, int defStyle) {
+        this(context, attrs, defStyle, 0);
+    }
+
+    ClosedCaptionWidget(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        // Cannot render text over video when layer type is hardware.
+        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+
+        mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+        mCaptionStyle = mManager.getUserStyle();
+
+        mClosedCaptionLayout = createCaptionLayout(context);
+        mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
+        mClosedCaptionLayout.setFontScale(mManager.getFontScale());
+        addView((ViewGroup) mClosedCaptionLayout, LayoutParams.MATCH_PARENT,
+                LayoutParams.MATCH_PARENT);
+
+        requestLayout();
+    }
+
+    public abstract ClosedCaptionLayout createCaptionLayout(Context context);
+
+    @Override
+    public void setOnChangedListener(OnChangedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
+        final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+
+        measure(widthSpec, heightSpec);
+        layout(0, 0, width, height);
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        if (visible) {
+            setVisibility(View.VISIBLE);
+        } else {
+            setVisibility(View.GONE);
+        }
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        ((ViewGroup) mClosedCaptionLayout).measure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        ((ViewGroup) mClosedCaptionLayout).layout(l, t, r, b);
+    }
+
+    /**
+     * Manages whether this renderer is listening for caption style changes.
+     */
+    private final CaptioningChangeListener mCaptioningListener = new CaptioningChangeListener() {
+        @Override
+        public void onUserStyleChanged(CaptionStyle userStyle) {
+            mCaptionStyle = userStyle;
+            mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
+        }
+
+        @Override
+        public void onFontScaleChanged(float fontScale) {
+            mClosedCaptionLayout.setFontScale(fontScale);
+        }
+    };
+
+    private void manageChangeListener() {
+        final boolean needsListener = isAttachedToWindow() && getVisibility() == View.VISIBLE;
+        if (mHasChangeListener != needsListener) {
+            mHasChangeListener = needsListener;
+
+            if (needsListener) {
+                mManager.addCaptioningChangeListener(mCaptioningListener);
+            } else {
+                mManager.removeCaptioningChangeListener(mCaptioningListener);
+            }
+        }
+    }
+}
+
diff --git a/media/src/main/java/androidx/media/subtitle/MediaTimeProvider.java b/media/src/main/java/androidx/media/subtitle/MediaTimeProvider.java
new file mode 100644
index 0000000..b6f0a14
--- /dev/null
+++ b/media/src/main/java/androidx/media/subtitle/MediaTimeProvider.java
@@ -0,0 +1,100 @@
+/*
+ * 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.media.subtitle;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import androidx.annotation.RestrictTo;
+
+// Note: This is just copied from android.media.MediaTimeProvider.
+/**
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+public interface MediaTimeProvider {
+    // we do not allow negative media time
+    /**
+     * Presentation time value if no timed event notification is requested.
+     */
+    long NO_TIME = -1;
+
+    /**
+     * Cancels all previous notification request from this listener if any.  It
+     * registers the listener to get seek and stop notifications.  If timeUs is
+     * not negative, it also registers the listener for a timed event
+     * notification when the presentation time reaches (becomes greater) than
+     * the value specified.  This happens immediately if the current media time
+     * is larger than or equal to timeUs.
+     *
+     * @param timeUs presentation time to get timed event callback at (or
+     *               {@link #NO_TIME})
+     */
+    void notifyAt(long timeUs, OnMediaTimeListener listener);
+
+    /**
+     * Cancels all previous notification request from this listener if any.  It
+     * registers the listener to get seek and stop notifications.  If the media
+     * is stopped, the listener will immediately receive a stop notification.
+     * Otherwise, it will receive a timed event notificaton.
+     */
+    void scheduleUpdate(OnMediaTimeListener listener);
+
+    /**
+     * Cancels all previous notification request from this listener if any.
+     */
+    void cancelNotifications(OnMediaTimeListener listener);
+
+    /**
+     * Get the current presentation time.
+     *
+     * @param precise   Whether getting a precise time is important. This is
+     *                  more costly.
+     * @param monotonic Whether returned time should be monotonic: that is,
+     *                  greater than or equal to the last returned time.  Don't
+     *                  always set this to true.  E.g. this has undesired
+     *                  consequences if the media is seeked between calls.
+     * @throws IllegalStateException if the media is not initialized
+     */
+    long getCurrentTimeUs(boolean precise, boolean monotonic)
+            throws IllegalStateException;
+
+    /**
+     * Mediatime listener
+     */
+    public interface OnMediaTimeListener {
+        /**
+         * Called when the registered time was reached naturally.
+         *
+         * @param timeUs current media time
+         */
+        void onTimedEvent(long timeUs);
+
+        /**
+         * Called when the media time changed due to seeking.
+         *
+         * @param timeUs current media time
+         */
+        void onSeek(long timeUs);
+
+        /**
+         * Called when the playback stopped.  This is not called on pause, only
+         * on full stop, at which point there is no further current media time.
+         */
+        void onStop();
+    }
+}
+
diff --git a/media/src/main/java/androidx/media/subtitle/SubtitleController.java b/media/src/main/java/androidx/media/subtitle/SubtitleController.java
new file mode 100644
index 0000000..b6dfc2b
--- /dev/null
+++ b/media/src/main/java/androidx/media/subtitle/SubtitleController.java
@@ -0,0 +1,534 @@
+/*
+ * 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.media.subtitle;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.Context;
+import android.media.MediaFormat;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.TrackInfo;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.view.accessibility.CaptioningManager;
+
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.media.subtitle.SubtitleTrack.RenderingWidget;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+// Note: This is forked from android.media.SubtitleController since P
+/**
+ * The subtitle controller provides the architecture to display subtitles for a
+ * media source.  It allows specifying which tracks to display, on which anchor
+ * to display them, and also allows adding external, out-of-band subtitle tracks.
+ *
+ * @hide
+ */
+@RequiresApi(28)
+@RestrictTo(LIBRARY_GROUP)
+public class SubtitleController {
+    private MediaTimeProvider mTimeProvider;
+    private ArrayList<Renderer> mRenderers;
+    private ArrayList<SubtitleTrack> mTracks;
+    private final Object mRenderersLock = new Object();
+    private final Object mTracksLock = new Object();
+    private SubtitleTrack mSelectedTrack;
+    private boolean mShowing;
+    private CaptioningManager mCaptioningManager;
+    private Handler mHandler;
+
+    private static final int WHAT_SHOW = 1;
+    private static final int WHAT_HIDE = 2;
+    private static final int WHAT_SELECT_TRACK = 3;
+    private static final int WHAT_SELECT_DEFAULT_TRACK = 4;
+
+    private final Handler.Callback mCallback = new Handler.Callback() {
+        @Override
+        public boolean handleMessage(Message msg) {
+            switch (msg.what) {
+                case WHAT_SHOW:
+                    doShow();
+                    return true;
+                case WHAT_HIDE:
+                    doHide();
+                    return true;
+                case WHAT_SELECT_TRACK:
+                    doSelectTrack((SubtitleTrack) msg.obj);
+                    return true;
+                case WHAT_SELECT_DEFAULT_TRACK:
+                    doSelectDefaultTrack();
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    };
+
+    private CaptioningManager.CaptioningChangeListener mCaptioningChangeListener =
+            new CaptioningManager.CaptioningChangeListener() {
+                @Override
+                public void onEnabledChanged(boolean enabled) {
+                    selectDefaultTrack();
+                }
+
+                @Override
+                public void onLocaleChanged(Locale locale) {
+                    selectDefaultTrack();
+                }
+            };
+
+    public SubtitleController(Context context) {
+        this(context, null, null);
+    }
+
+    /**
+     * Creates a subtitle controller for a media playback object that implements
+     * the MediaTimeProvider interface.
+     *
+     * @param timeProvider
+     */
+    public SubtitleController(
+            Context context,
+            MediaTimeProvider timeProvider,
+            Listener listener) {
+        mTimeProvider = timeProvider;
+        mListener = listener;
+
+        mRenderers = new ArrayList<Renderer>();
+        mShowing = false;
+        mTracks = new ArrayList<SubtitleTrack>();
+        mCaptioningManager =
+            (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        mCaptioningManager.removeCaptioningChangeListener(
+                mCaptioningChangeListener);
+        super.finalize();
+    }
+
+    /**
+     * @return the available subtitle tracks for this media. These include
+     * the tracks found by {@link MediaPlayer} as well as any tracks added
+     * manually via {@link #addTrack}.
+     */
+    public SubtitleTrack[] getTracks() {
+        synchronized (mTracksLock) {
+            SubtitleTrack[] tracks = new SubtitleTrack[mTracks.size()];
+            mTracks.toArray(tracks);
+            return tracks;
+        }
+    }
+
+    /**
+     * @return the currently selected subtitle track
+     */
+    public SubtitleTrack getSelectedTrack() {
+        return mSelectedTrack;
+    }
+
+    private RenderingWidget getRenderingWidget() {
+        if (mSelectedTrack == null) {
+            return null;
+        }
+        return mSelectedTrack.getRenderingWidget();
+    }
+
+    /**
+     * Selects a subtitle track.  As a result, this track will receive
+     * in-band data from the {@link MediaPlayer}.  However, this does
+     * not change the subtitle visibility.
+     *
+     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
+     *
+     * @param track The subtitle track to select.  This must be one of the
+     *              tracks in {@link #getTracks}.
+     * @return true if the track was successfully selected.
+     */
+    public boolean selectTrack(SubtitleTrack track) {
+        if (track != null && !mTracks.contains(track)) {
+            return false;
+        }
+
+        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_TRACK, track));
+        return true;
+    }
+
+    private void doSelectTrack(SubtitleTrack track) {
+        mTrackIsExplicit = true;
+        if (mSelectedTrack == track) {
+            return;
+        }
+
+        if (mSelectedTrack != null) {
+            mSelectedTrack.hide();
+            mSelectedTrack.setTimeProvider(null);
+        }
+
+        mSelectedTrack = track;
+        if (mAnchor != null) {
+            mAnchor.setSubtitleWidget(getRenderingWidget());
+        }
+
+        if (mSelectedTrack != null) {
+            mSelectedTrack.setTimeProvider(mTimeProvider);
+            mSelectedTrack.show();
+        }
+
+        if (mListener != null) {
+            mListener.onSubtitleTrackSelected(track);
+        }
+    }
+
+    /**
+     * @return the default subtitle track based on system preferences, or null,
+     * if no such track exists in this manager.
+     *
+     * Supports HLS-flags: AUTOSELECT, FORCED & DEFAULT.
+     *
+     * 1. If captioning is disabled, only consider FORCED tracks. Otherwise,
+     * consider all tracks, but prefer non-FORCED ones.
+     * 2. If user selected "Default" caption language:
+     *   a. If there is a considered track with DEFAULT=yes, returns that track
+     *      (favor the first one in the current language if there are more than
+     *      one default tracks, or the first in general if none of them are in
+     *      the current language).
+     *   b. Otherwise, if there is a track with AUTOSELECT=yes in the current
+     *      language, return that one.
+     *   c. If there are no default tracks, and no autoselectable tracks in the
+     *      current language, return null.
+     * 3. If there is a track with the caption language, select that one.  Prefer
+     * the one with AUTOSELECT=no.
+     *
+     * The default values for these flags are DEFAULT=no, AUTOSELECT=yes
+     * and FORCED=no.
+     */
+    public SubtitleTrack getDefaultTrack() {
+        SubtitleTrack bestTrack = null;
+        int bestScore = -1;
+
+        Locale selectedLocale = mCaptioningManager.getLocale();
+        Locale locale = selectedLocale;
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        boolean selectForced = !mCaptioningManager.isEnabled();
+
+        synchronized (mTracksLock) {
+            for (SubtitleTrack track: mTracks) {
+                MediaFormat format = track.getFormat();
+                String language = format.getString(MediaFormat.KEY_LANGUAGE);
+                boolean forced = MediaFormatUtil
+                        .getInteger(format, MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0;
+                boolean autoselect = MediaFormatUtil
+                        .getInteger(format, MediaFormat.KEY_IS_AUTOSELECT, 1) != 0;
+                boolean is_default = MediaFormatUtil
+                        .getInteger(format, MediaFormat.KEY_IS_DEFAULT, 0) != 0;
+
+                boolean languageMatches = locale == null
+                        || locale.getLanguage().equals("")
+                        || locale.getISO3Language().equals(language)
+                        || locale.getLanguage().equals(language);
+                // is_default is meaningless unless caption language is 'default'
+                int score = (forced ? 0 : 8)
+                        + (((selectedLocale == null) && is_default) ? 4 : 0)
+                        + (autoselect ? 0 : 2) + (languageMatches ? 1 : 0);
+
+                if (selectForced && !forced) {
+                    continue;
+                }
+
+                // we treat null locale/language as matching any language
+                if ((selectedLocale == null && is_default)
+                        || (languageMatches && (autoselect || forced || selectedLocale != null))) {
+                    if (score > bestScore) {
+                        bestScore = score;
+                        bestTrack = track;
+                    }
+                }
+            }
+        }
+        return bestTrack;
+    }
+
+    static class MediaFormatUtil {
+        MediaFormatUtil() { }
+        static int getInteger(MediaFormat format, String name, int defaultValue) {
+            try {
+                return format.getInteger(name);
+            } catch (NullPointerException | ClassCastException e) {
+                /* no such field or field of different type */
+            }
+            return defaultValue;
+        }
+    }
+
+    private boolean mTrackIsExplicit = false;
+    private boolean mVisibilityIsExplicit = false;
+
+    /** should be called from anchor thread */
+    public void selectDefaultTrack() {
+        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_DEFAULT_TRACK));
+    }
+
+    private void doSelectDefaultTrack() {
+        if (mTrackIsExplicit) {
+            if (mVisibilityIsExplicit) {
+                return;
+            }
+            // If track selection is explicit, but visibility
+            // is not, it falls back to the captioning setting
+            if (mCaptioningManager.isEnabled()
+                    || (mSelectedTrack != null && MediaFormatUtil.getInteger(
+                            mSelectedTrack.getFormat(),
+                            MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0)) {
+                show();
+            } else if (mSelectedTrack != null
+                    && mSelectedTrack.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+                hide();
+            }
+            mVisibilityIsExplicit = false;
+        }
+
+        // We can have a default (forced) track even if captioning
+        // is not enabled.  This is handled by getDefaultTrack().
+        // Show this track unless subtitles were explicitly hidden.
+        SubtitleTrack track = getDefaultTrack();
+        if (track != null) {
+            selectTrack(track);
+            mTrackIsExplicit = false;
+            if (!mVisibilityIsExplicit) {
+                show();
+                mVisibilityIsExplicit = false;
+            }
+        }
+    }
+
+    /** must be called from anchor thread */
+    public void reset() {
+        checkAnchorLooper();
+        hide();
+        selectTrack(null);
+        mTracks.clear();
+        mTrackIsExplicit = false;
+        mVisibilityIsExplicit = false;
+        mCaptioningManager.removeCaptioningChangeListener(
+                mCaptioningChangeListener);
+    }
+
+    /**
+     * Adds a new, external subtitle track to the manager.
+     *
+     * @param format the format of the track that will include at least
+     *               the MIME type {@link MediaFormat@KEY_MIME}.
+     * @return the created {@link SubtitleTrack} object
+     */
+    public SubtitleTrack addTrack(MediaFormat format) {
+        synchronized (mRenderersLock) {
+            for (Renderer renderer: mRenderers) {
+                if (renderer.supports(format)) {
+                    SubtitleTrack track = renderer.createTrack(format);
+                    if (track != null) {
+                        synchronized (mTracksLock) {
+                            if (mTracks.size() == 0) {
+                                mCaptioningManager.addCaptioningChangeListener(
+                                        mCaptioningChangeListener);
+                            }
+                            mTracks.add(track);
+                        }
+                        return track;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Show the selected (or default) subtitle track.
+     *
+     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
+     */
+    public void show() {
+        processOnAnchor(mHandler.obtainMessage(WHAT_SHOW));
+    }
+
+    private void doShow() {
+        mShowing = true;
+        mVisibilityIsExplicit = true;
+        if (mSelectedTrack != null) {
+            mSelectedTrack.show();
+        }
+    }
+
+    /**
+     * Hide the selected (or default) subtitle track.
+     *
+     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
+     */
+    public void hide() {
+        processOnAnchor(mHandler.obtainMessage(WHAT_HIDE));
+    }
+
+    private void doHide() {
+        mVisibilityIsExplicit = true;
+        if (mSelectedTrack != null) {
+            mSelectedTrack.hide();
+        }
+        mShowing = false;
+    }
+
+    /**
+     * Interface for supporting a single or multiple subtitle types in {@link MediaPlayer}.
+     */
+    public abstract static class Renderer {
+        /**
+         * Called by {@link MediaPlayer}'s {@link SubtitleController} when a new
+         * subtitle track is detected, to see if it should use this object to
+         * parse and display this subtitle track.
+         *
+         * @param format the format of the track that will include at least
+         *               the MIME type {@link MediaFormat@KEY_MIME}.
+         *
+         * @return true if and only if the track format is supported by this
+         * renderer
+         */
+        public abstract boolean supports(MediaFormat format);
+
+        /**
+         * Called by {@link MediaPlayer}'s {@link SubtitleController} for each
+         * subtitle track that was detected and is supported by this object to
+         * create a {@link SubtitleTrack} object.  This object will be created
+         * for each track that was found.  If the track is selected for display,
+         * this object will be used to parse and display the track data.
+         *
+         * @param format the format of the track that will include at least
+         *               the MIME type {@link MediaFormat@KEY_MIME}.
+         * @return a {@link SubtitleTrack} object that will be used to parse
+         * and render the subtitle track.
+         */
+        public abstract SubtitleTrack createTrack(MediaFormat format);
+    }
+
+    /**
+     * Add support for a subtitle format in {@link MediaPlayer}.
+     *
+     * @param renderer a {@link SubtitleController.Renderer} object that adds
+     *                 support for a subtitle format.
+     */
+    public void registerRenderer(Renderer renderer) {
+        synchronized (mRenderersLock) {
+            // TODO how to get available renderers in the system
+            if (!mRenderers.contains(renderer)) {
+                // TODO should added renderers override existing ones (to allow replacing?)
+                mRenderers.add(renderer);
+            }
+        }
+    }
+
+    /**
+     * Returns true if one of the registered renders supports given media format.
+     *
+     * @param format a {@link MediaFormat} object
+     * @return true if this SubtitleController has a renderer that supports
+     * the media format.
+     */
+    public boolean hasRendererFor(MediaFormat format) {
+        synchronized (mRenderersLock) {
+            // TODO how to get available renderers in the system
+            for (Renderer renderer: mRenderers) {
+                if (renderer.supports(format)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Subtitle anchor, an object that is able to display a subtitle renderer,
+     * e.g. a VideoView.
+     */
+    public interface Anchor {
+        /**
+         * Anchor should use the supplied subtitle rendering widget, or
+         * none if it is null.
+         */
+        void setSubtitleWidget(RenderingWidget subtitleWidget);
+
+        /**
+         * Anchors provide the looper on which all track visibility changes
+         * (track.show/hide, setSubtitleWidget) will take place.
+         */
+        Looper getSubtitleLooper();
+    }
+
+    private Anchor mAnchor;
+
+    /**
+     *  called from anchor's looper (if any, both when unsetting and
+     *  setting)
+     */
+    public void setAnchor(Anchor anchor) {
+        if (mAnchor == anchor) {
+            return;
+        }
+
+        if (mAnchor != null) {
+            checkAnchorLooper();
+            mAnchor.setSubtitleWidget(null);
+        }
+        mAnchor = anchor;
+        mHandler = null;
+        if (mAnchor != null) {
+            mHandler = new Handler(mAnchor.getSubtitleLooper(), mCallback);
+            checkAnchorLooper();
+            mAnchor.setSubtitleWidget(getRenderingWidget());
+        }
+    }
+
+    private void checkAnchorLooper() {
+        assert mHandler != null : "Should have a looper already";
+        assert Looper.myLooper() == mHandler.getLooper()
+                : "Must be called from the anchor's looper";
+    }
+
+    private void processOnAnchor(Message m) {
+        assert mHandler != null : "Should have a looper already";
+        if (Looper.myLooper() == mHandler.getLooper()) {
+            mHandler.dispatchMessage(m);
+        } else {
+            mHandler.sendMessage(m);
+        }
+    }
+
+    interface Listener {
+        /**
+         * Called when a subtitle track has been selected.
+         *
+         * @param track selected subtitle track or null
+         */
+        void onSubtitleTrackSelected(SubtitleTrack track);
+    }
+
+    private Listener mListener;
+}
diff --git a/media/src/main/java/androidx/media/subtitle/SubtitleTrack.java b/media/src/main/java/androidx/media/subtitle/SubtitleTrack.java
new file mode 100644
index 0000000..30c1316
--- /dev/null
+++ b/media/src/main/java/androidx/media/subtitle/SubtitleTrack.java
@@ -0,0 +1,715 @@
+/*
+ * 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.media.subtitle;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.graphics.Canvas;
+import android.media.MediaFormat;
+import android.media.MediaPlayer.TrackInfo;
+import android.media.SubtitleData;
+import android.os.Handler;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.Pair;
+
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+// Note: This is forked from android.media.SubtitleTrack since P
+/**
+ * A subtitle track abstract base class that is responsible for parsing and displaying
+ * an instance of a particular type of subtitle.
+ *
+ * @hide
+ */
+@RequiresApi(28)
+@RestrictTo(LIBRARY_GROUP)
+public abstract class SubtitleTrack implements MediaTimeProvider.OnMediaTimeListener {
+    private static final String TAG = "SubtitleTrack";
+    private long mLastUpdateTimeMs;
+    private long mLastTimeMs;
+
+    private Runnable mRunnable;
+
+    private final LongSparseArray<Run> mRunsByEndTime = new LongSparseArray<Run>();
+    private final LongSparseArray<Run> mRunsByID = new LongSparseArray<Run>();
+
+    private CueList mCues;
+    private final ArrayList<Cue> mActiveCues = new ArrayList<Cue>();
+    protected boolean mVisible;
+
+    public boolean DEBUG = false;
+
+    protected Handler mHandler = new Handler();
+
+    private MediaFormat mFormat;
+
+    public SubtitleTrack(MediaFormat format) {
+        mFormat = format;
+        mCues = new CueList();
+        clearActiveCues();
+        mLastTimeMs = -1;
+    }
+
+    public final MediaFormat getFormat() {
+        return mFormat;
+    }
+
+    private long mNextScheduledTimeMs = -1;
+
+    /**
+     * Called when there is input data for the subtitle track.
+     */
+    public void onData(SubtitleData data) {
+        long runID = data.getStartTimeUs() + 1;
+        onData(data.getData(), true /* eos */, runID);
+        setRunDiscardTimeMs(
+                runID,
+                (data.getStartTimeUs() + data.getDurationUs()) / 1000);
+    }
+
+    /**
+     * Called when there is input data for the subtitle track.  The
+     * complete subtitle for a track can include multiple whole units
+     * (runs).  Each of these units can have multiple sections.  The
+     * contents of a run are submitted in sequential order, with eos
+     * indicating the last section of the run.  Calls from different
+     * runs must not be intermixed.
+     *
+     * @param data subtitle data byte buffer
+     * @param eos true if this is the last section of the run.
+     * @param runID mostly-unique ID for this run of data.  Subtitle cues
+     *              with runID of 0 are discarded immediately after
+     *              display.  Cues with runID of ~0 are discarded
+     *              only at the deletion of the track object.  Cues
+     *              with other runID-s are discarded at the end of the
+     *              run, which defaults to the latest timestamp of
+     *              any of its cues (with this runID).
+     */
+    protected abstract void onData(byte[] data, boolean eos, long runID);
+
+    /**
+     * Called when adding the subtitle rendering widget to the view hierarchy,
+     * as well as when showing or hiding the subtitle track, or when the video
+     * surface position has changed.
+     *
+     * @return the widget that renders this subtitle track. For most renderers
+     *         there should be a single shared instance that is used for all
+     *         tracks supported by that renderer, as at most one subtitle track
+     *         is visible at one time.
+     */
+    public abstract RenderingWidget getRenderingWidget();
+
+    /**
+     * Called when the active cues have changed, and the contents of the subtitle
+     * view should be updated.
+     */
+    public abstract void updateView(ArrayList<Cue> activeCues);
+
+    protected synchronized void updateActiveCues(boolean rebuild, long timeMs) {
+        // out-of-order times mean seeking or new active cues being added
+        // (during their own timespan)
+        if (rebuild || mLastUpdateTimeMs > timeMs) {
+            clearActiveCues();
+        }
+
+        for (Iterator<Pair<Long, Cue>> it =
+                mCues.entriesBetween(mLastUpdateTimeMs, timeMs).iterator(); it.hasNext(); ) {
+            Pair<Long, Cue> event = it.next();
+            Cue cue = event.second;
+
+            if (cue.mEndTimeMs == event.first) {
+                // remove past cues
+                if (DEBUG) Log.v(TAG, "Removing " + cue);
+                mActiveCues.remove(cue);
+                if (cue.mRunID == 0) {
+                    it.remove();
+                }
+            } else if (cue.mStartTimeMs == event.first) {
+                // add new cues
+                // TRICKY: this will happen in start order
+                if (DEBUG) Log.v(TAG, "Adding " + cue);
+                if (cue.mInnerTimesMs != null) {
+                    cue.onTime(timeMs);
+                }
+                mActiveCues.add(cue);
+            } else if (cue.mInnerTimesMs != null) {
+                // cue is modified
+                cue.onTime(timeMs);
+            }
+        }
+
+        /* complete any runs */
+        while (mRunsByEndTime.size() > 0 && mRunsByEndTime.keyAt(0) <= timeMs) {
+            removeRunsByEndTimeIndex(0); // removes element
+        }
+        mLastUpdateTimeMs = timeMs;
+    }
+
+    private void removeRunsByEndTimeIndex(int ix) {
+        Run run = mRunsByEndTime.valueAt(ix);
+        while (run != null) {
+            Cue cue = run.mFirstCue;
+            while (cue != null) {
+                mCues.remove(cue);
+                Cue nextCue = cue.mNextInRun;
+                cue.mNextInRun = null;
+                cue = nextCue;
+            }
+            mRunsByID.remove(run.mRunID);
+            Run nextRun = run.mNextRunAtEndTimeMs;
+            run.mPrevRunAtEndTimeMs = null;
+            run.mNextRunAtEndTimeMs = null;
+            run = nextRun;
+        }
+        mRunsByEndTime.removeAt(ix);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        /* remove all cues (untangle all cross-links) */
+        int size = mRunsByEndTime.size();
+        for (int ix = size - 1; ix >= 0; ix--) {
+            removeRunsByEndTimeIndex(ix);
+        }
+
+        super.finalize();
+    }
+
+    private synchronized void takeTime(long timeMs) {
+        mLastTimeMs = timeMs;
+    }
+
+    protected synchronized void clearActiveCues() {
+        if (DEBUG) Log.v(TAG, "Clearing " + mActiveCues.size() + " active cues");
+        mActiveCues.clear();
+        mLastUpdateTimeMs = -1;
+    }
+
+    protected void scheduleTimedEvents() {
+        /* get times for the next event */
+        if (mTimeProvider != null) {
+            mNextScheduledTimeMs = mCues.nextTimeAfter(mLastTimeMs);
+            if (DEBUG) Log.d(TAG, "sched @" + mNextScheduledTimeMs + " after " + mLastTimeMs);
+            mTimeProvider.notifyAt(mNextScheduledTimeMs >= 0
+                    ? (mNextScheduledTimeMs * 1000) : MediaTimeProvider.NO_TIME, this);
+        }
+    }
+
+    @Override
+    public void onTimedEvent(long timeUs) {
+        if (DEBUG) Log.d(TAG, "onTimedEvent " + timeUs);
+        synchronized (this) {
+            long timeMs = timeUs / 1000;
+            updateActiveCues(false, timeMs);
+            takeTime(timeMs);
+        }
+        updateView(mActiveCues);
+        scheduleTimedEvents();
+    }
+
+    @Override
+    public void onSeek(long timeUs) {
+        if (DEBUG) Log.d(TAG, "onSeek " + timeUs);
+        synchronized (this) {
+            long timeMs = timeUs / 1000;
+            updateActiveCues(true, timeMs);
+            takeTime(timeMs);
+        }
+        updateView(mActiveCues);
+        scheduleTimedEvents();
+    }
+
+    @Override
+    public void onStop() {
+        synchronized (this) {
+            if (DEBUG) Log.d(TAG, "onStop");
+            clearActiveCues();
+            mLastTimeMs = -1;
+        }
+        updateView(mActiveCues);
+        mNextScheduledTimeMs = -1;
+        mTimeProvider.notifyAt(MediaTimeProvider.NO_TIME, this);
+    }
+
+    protected MediaTimeProvider mTimeProvider;
+
+    /**
+     * Shows subtitle rendering widget
+     */
+    public void show() {
+        if (mVisible) {
+            return;
+        }
+
+        mVisible = true;
+        RenderingWidget renderingWidget = getRenderingWidget();
+        if (renderingWidget != null) {
+            renderingWidget.setVisible(true);
+        }
+        if (mTimeProvider != null) {
+            mTimeProvider.scheduleUpdate(this);
+        }
+    }
+
+    /**
+     * Hides subtitle rendering widget
+     */
+    public void hide() {
+        if (!mVisible) {
+            return;
+        }
+
+        if (mTimeProvider != null) {
+            mTimeProvider.cancelNotifications(this);
+        }
+        RenderingWidget renderingWidget = getRenderingWidget();
+        if (renderingWidget != null) {
+            renderingWidget.setVisible(false);
+        }
+        mVisible = false;
+    }
+
+    protected synchronized boolean addCue(Cue cue) {
+        mCues.add(cue);
+
+        if (cue.mRunID != 0) {
+            Run run = mRunsByID.get(cue.mRunID);
+            if (run == null) {
+                run = new Run();
+                mRunsByID.put(cue.mRunID, run);
+                run.mEndTimeMs = cue.mEndTimeMs;
+            } else if (run.mEndTimeMs < cue.mEndTimeMs) {
+                run.mEndTimeMs = cue.mEndTimeMs;
+            }
+
+            // link-up cues in the same run
+            cue.mNextInRun = run.mFirstCue;
+            run.mFirstCue = cue;
+        }
+
+        // if a cue is added that should be visible, need to refresh view
+        long nowMs = -1;
+        if (mTimeProvider != null) {
+            try {
+                nowMs = mTimeProvider.getCurrentTimeUs(
+                        false /* precise */, true /* monotonic */) / 1000;
+            } catch (IllegalStateException e) {
+                // handle as it we are not playing
+            }
+        }
+
+        if (DEBUG) {
+            Log.v(TAG, "mVisible=" + mVisible + ", "
+                    + cue.mStartTimeMs + " <= " + nowMs + ", "
+                    + cue.mEndTimeMs + " >= " + mLastTimeMs);
+        }
+
+        if (mVisible && cue.mStartTimeMs <= nowMs
+                // we don't trust nowMs, so check any cue since last callback
+                && cue.mEndTimeMs >= mLastTimeMs) {
+            if (mRunnable != null) {
+                mHandler.removeCallbacks(mRunnable);
+            }
+            final SubtitleTrack track = this;
+            final long thenMs = nowMs;
+            mRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    // even with synchronized, it is possible that we are going
+                    // to do multiple updates as the runnable could be already
+                    // running.
+                    synchronized (track) {
+                        mRunnable = null;
+                        updateActiveCues(true, thenMs);
+                        updateView(mActiveCues);
+                    }
+                }
+            };
+            // delay update so we don't update view on every cue.  TODO why 10?
+            if (mHandler.postDelayed(mRunnable, 10 /* delay */)) {
+                if (DEBUG) Log.v(TAG, "scheduling update");
+            } else {
+                if (DEBUG) Log.w(TAG, "failed to schedule subtitle view update");
+            }
+            return true;
+        }
+
+        if (mVisible && cue.mEndTimeMs >= mLastTimeMs
+                && (cue.mStartTimeMs < mNextScheduledTimeMs || mNextScheduledTimeMs < 0)) {
+            scheduleTimedEvents();
+        }
+
+        return false;
+    }
+
+    /**
+     * Sets MediaTimeProvider
+     */
+    public synchronized void setTimeProvider(MediaTimeProvider timeProvider) {
+        if (mTimeProvider == timeProvider) {
+            return;
+        }
+        if (mTimeProvider != null) {
+            mTimeProvider.cancelNotifications(this);
+        }
+        mTimeProvider = timeProvider;
+        if (mTimeProvider != null) {
+            mTimeProvider.scheduleUpdate(this);
+        }
+    }
+
+
+    static class CueList {
+        private static final String TAG = "CueList";
+        // simplistic, inefficient implementation
+        private SortedMap<Long, ArrayList<Cue>> mCues;
+        public boolean DEBUG = false;
+
+        private boolean addEvent(Cue cue, long timeMs) {
+            ArrayList<Cue> cues = mCues.get(timeMs);
+            if (cues == null) {
+                cues = new ArrayList<Cue>(2);
+                mCues.put(timeMs, cues);
+            } else if (cues.contains(cue)) {
+                // do not duplicate cues
+                return false;
+            }
+
+            cues.add(cue);
+            return true;
+        }
+
+        private void removeEvent(Cue cue, long timeMs) {
+            ArrayList<Cue> cues = mCues.get(timeMs);
+            if (cues != null) {
+                cues.remove(cue);
+                if (cues.size() == 0) {
+                    mCues.remove(timeMs);
+                }
+            }
+        }
+
+        public void add(Cue cue) {
+            // ignore non-positive-duration cues
+            if (cue.mStartTimeMs >= cue.mEndTimeMs) return;
+
+            if (!addEvent(cue, cue.mStartTimeMs)) {
+                return;
+            }
+
+            long lastTimeMs = cue.mStartTimeMs;
+            if (cue.mInnerTimesMs != null) {
+                for (long timeMs: cue.mInnerTimesMs) {
+                    if (timeMs > lastTimeMs && timeMs < cue.mEndTimeMs) {
+                        addEvent(cue, timeMs);
+                        lastTimeMs = timeMs;
+                    }
+                }
+            }
+
+            addEvent(cue, cue.mEndTimeMs);
+        }
+
+        public void remove(Cue cue) {
+            removeEvent(cue, cue.mStartTimeMs);
+            if (cue.mInnerTimesMs != null) {
+                for (long timeMs: cue.mInnerTimesMs) {
+                    removeEvent(cue, timeMs);
+                }
+            }
+            removeEvent(cue, cue.mEndTimeMs);
+        }
+
+        public Iterable<Pair<Long, Cue>> entriesBetween(
+                final long lastTimeMs, final long timeMs) {
+            return new Iterable<Pair<Long, Cue>>() {
+                @Override
+                public Iterator<Pair<Long, Cue>> iterator() {
+                    if (DEBUG) Log.d(TAG, "slice (" + lastTimeMs + ", " + timeMs + "]=");
+                    try {
+                        return new EntryIterator(
+                                mCues.subMap(lastTimeMs + 1, timeMs + 1));
+                    } catch (IllegalArgumentException e) {
+                        return new EntryIterator(null);
+                    }
+                }
+            };
+        }
+
+        public long nextTimeAfter(long timeMs) {
+            SortedMap<Long, ArrayList<Cue>> tail = null;
+            try {
+                tail = mCues.tailMap(timeMs + 1);
+                if (tail != null) {
+                    return tail.firstKey();
+                } else {
+                    return -1;
+                }
+            } catch (IllegalArgumentException e) {
+                return -1;
+            } catch (NoSuchElementException e) {
+                return -1;
+            }
+        }
+
+        class EntryIterator implements Iterator<Pair<Long, Cue>> {
+            @Override
+            public boolean hasNext() {
+                return !mDone;
+            }
+
+            @Override
+            public Pair<Long, Cue> next() {
+                if (mDone) {
+                    throw new NoSuchElementException("");
+                }
+                mLastEntry = new Pair<Long, Cue>(
+                        mCurrentTimeMs, mListIterator.next());
+                mLastListIterator = mListIterator;
+                if (!mListIterator.hasNext()) {
+                    nextKey();
+                }
+                return mLastEntry;
+            }
+
+            @Override
+            public void remove() {
+                // only allow removing end tags
+                if (mLastListIterator == null
+                        || mLastEntry.second.mEndTimeMs != mLastEntry.first) {
+                    throw new IllegalStateException("");
+                }
+
+                // remove end-cue
+                mLastListIterator.remove();
+                mLastListIterator = null;
+                if (mCues.get(mLastEntry.first).size() == 0) {
+                    mCues.remove(mLastEntry.first);
+                }
+
+                // remove rest of the cues
+                Cue cue = mLastEntry.second;
+                removeEvent(cue, cue.mStartTimeMs);
+                if (cue.mInnerTimesMs != null) {
+                    for (long timeMs: cue.mInnerTimesMs) {
+                        removeEvent(cue, timeMs);
+                    }
+                }
+            }
+
+            EntryIterator(SortedMap<Long, ArrayList<Cue>> cues) {
+                if (DEBUG) Log.v(TAG, cues + "");
+                mRemainingCues = cues;
+                mLastListIterator = null;
+                nextKey();
+            }
+
+            private void nextKey() {
+                do {
+                    try {
+                        if (mRemainingCues == null) {
+                            throw new NoSuchElementException("");
+                        }
+                        mCurrentTimeMs = mRemainingCues.firstKey();
+                        mListIterator =
+                            mRemainingCues.get(mCurrentTimeMs).iterator();
+                        try {
+                            mRemainingCues =
+                                mRemainingCues.tailMap(mCurrentTimeMs + 1);
+                        } catch (IllegalArgumentException e) {
+                            mRemainingCues = null;
+                        }
+                        mDone = false;
+                    } catch (NoSuchElementException e) {
+                        mDone = true;
+                        mRemainingCues = null;
+                        mListIterator = null;
+                        return;
+                    }
+                } while (!mListIterator.hasNext());
+            }
+
+            private long mCurrentTimeMs;
+            private Iterator<Cue> mListIterator;
+            private boolean mDone;
+            private SortedMap<Long, ArrayList<Cue>> mRemainingCues;
+            private Iterator<Cue> mLastListIterator;
+            private Pair<Long, Cue> mLastEntry;
+        }
+
+        CueList() {
+            mCues = new TreeMap<Long, ArrayList<Cue>>();
+        }
+    }
+
+    static class Cue {
+        public long mStartTimeMs;
+        public long mEndTimeMs;
+        public long[] mInnerTimesMs;
+        public long mRunID;
+
+        public Cue mNextInRun;
+
+        /**
+         * Called to inform current timeMs to the cue
+         */
+        public void onTime(long timeMs) { }
+    }
+
+    /** update mRunsByEndTime (with default end time) */
+    protected void finishedRun(long runID) {
+        if (runID != 0 && runID != ~0) {
+            Run run = mRunsByID.get(runID);
+            if (run != null) {
+                run.storeByEndTimeMs(mRunsByEndTime);
+            }
+        }
+    }
+
+    /** update mRunsByEndTime with given end time */
+    public void setRunDiscardTimeMs(long runID, long timeMs) {
+        if (runID != 0 && runID != ~0) {
+            Run run = mRunsByID.get(runID);
+            if (run != null) {
+                run.mEndTimeMs = timeMs;
+                run.storeByEndTimeMs(mRunsByEndTime);
+            }
+        }
+    }
+
+    /** whether this is a text track who fires events instead getting rendered */
+    public int getTrackType() {
+        return getRenderingWidget() == null
+                ? TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT
+                : TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE;
+    }
+
+
+    private static class Run {
+        public Cue mFirstCue;
+        public Run mNextRunAtEndTimeMs;
+        public Run mPrevRunAtEndTimeMs;
+        public long mEndTimeMs = -1;
+        public long mRunID = 0;
+        private long mStoredEndTimeMs = -1;
+
+        public void storeByEndTimeMs(LongSparseArray<Run> runsByEndTime) {
+            // remove old value if any
+            int ix = runsByEndTime.indexOfKey(mStoredEndTimeMs);
+            if (ix >= 0) {
+                if (mPrevRunAtEndTimeMs == null) {
+                    assert (this == runsByEndTime.valueAt(ix));
+                    if (mNextRunAtEndTimeMs == null) {
+                        runsByEndTime.removeAt(ix);
+                    } else {
+                        runsByEndTime.setValueAt(ix, mNextRunAtEndTimeMs);
+                    }
+                }
+                removeAtEndTimeMs();
+            }
+
+            // add new value
+            if (mEndTimeMs >= 0) {
+                mPrevRunAtEndTimeMs = null;
+                mNextRunAtEndTimeMs = runsByEndTime.get(mEndTimeMs);
+                if (mNextRunAtEndTimeMs != null) {
+                    mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = this;
+                }
+                runsByEndTime.put(mEndTimeMs, this);
+                mStoredEndTimeMs = mEndTimeMs;
+            }
+        }
+
+        public void removeAtEndTimeMs() {
+            Run prev = mPrevRunAtEndTimeMs;
+
+            if (mPrevRunAtEndTimeMs != null) {
+                mPrevRunAtEndTimeMs.mNextRunAtEndTimeMs = mNextRunAtEndTimeMs;
+                mPrevRunAtEndTimeMs = null;
+            }
+            if (mNextRunAtEndTimeMs != null) {
+                mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = prev;
+                mNextRunAtEndTimeMs = null;
+            }
+        }
+    }
+
+    /**
+     * Interface for rendering subtitles onto a Canvas.
+     */
+    public interface RenderingWidget {
+        /**
+         * Sets the widget's callback, which is used to send updates when the
+         * rendered data has changed.
+         *
+         * @param callback update callback
+         */
+        void setOnChangedListener(OnChangedListener callback);
+
+        /**
+         * Sets the widget's size.
+         *
+         * @param width width in pixels
+         * @param height height in pixels
+         */
+        void setSize(int width, int height);
+
+        /**
+         * Sets whether the widget should draw subtitles.
+         *
+         * @param visible true if subtitles should be drawn, false otherwise
+         */
+        void setVisible(boolean visible);
+
+        /**
+         * Renders subtitles onto a {@link Canvas}.
+         *
+         * @param c canvas on which to render subtitles
+         */
+        void draw(Canvas c);
+
+        /**
+         * Called when the widget is attached to a window.
+         */
+        void onAttachedToWindow();
+
+        /**
+         * Called when the widget is detached from a window.
+         */
+        void onDetachedFromWindow();
+
+        /**
+         * Callback used to send updates about changes to rendering data.
+         */
+        public interface OnChangedListener {
+            /**
+             * Called when the rendering data has changed.
+             *
+             * @param renderingWidget the widget whose data has changed
+             */
+            void onChanged(RenderingWidget renderingWidget);
+        }
+    }
+}
diff --git a/media/src/main/res/values/dimens.xml b/media/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..be50378
--- /dev/null
+++ b/media/src/main/res/values/dimens.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.
+-->
+<resources>
+    <!-- Shadow radius for video subtitles. -->
+    <dimen name="subtitle_shadow_radius">2dp</dimen>
+
+    <!-- Shadow offset for video subtitles. -->
+    <dimen name="subtitle_shadow_offset">2dp</dimen>
+
+    <!-- Outline width for video subtitles. -->
+    <dimen name="subtitle_outline_width">2dp</dimen>
+</resources>
diff --git a/media/version-compat-tests/current/service/src/androidTest/java/android/support/mediacompat/service/MediaSessionCompatCallbackTest.java b/media/version-compat-tests/current/service/src/androidTest/java/android/support/mediacompat/service/MediaSessionCompatCallbackTest.java
index 3519f2f..8e5b944 100644
--- a/media/version-compat-tests/current/service/src/androidTest/java/android/support/mediacompat/service/MediaSessionCompatCallbackTest.java
+++ b/media/version-compat-tests/current/service/src/androidTest/java/android/support/mediacompat/service/MediaSessionCompatCallbackTest.java
@@ -55,6 +55,7 @@
 import static android.support.mediacompat.testlib.MediaSessionConstants.TEST_SESSION_TAG;
 import static android.support.mediacompat.testlib.MediaSessionConstants.TEST_VALUE;
 import static android.support.mediacompat.testlib.VersionConstants.KEY_CLIENT_VERSION;
+import static android.support.mediacompat.testlib.util.IntentUtil.CLIENT_RECEIVER_COMPONENT_NAME;
 import static android.support.mediacompat.testlib.util.IntentUtil.callMediaControllerMethod;
 import static android.support.mediacompat.testlib.util.IntentUtil.callTransportControlsMethod;
 import static android.support.mediacompat.testlib.util.TestUtil.assertBundleEquals;
@@ -96,6 +97,7 @@
 import android.util.Log;
 import android.view.KeyEvent;
 
+import androidx.media.MediaSessionManager;
 import androidx.media.VolumeProviderCompat;
 
 import org.junit.After;
@@ -323,6 +325,12 @@
 
     @Test
     @SmallTest
+    public void testGetCurrentControllerInfo() {
+        assertNull(mSession.getCurrentControllerInfo());
+    }
+
+    @Test
+    @SmallTest
     public void testSendCommand() throws Exception {
         mCallback.reset(1);
 
@@ -339,6 +347,8 @@
         assertNotNull(mCallback.mCommandCallback);
         assertEquals(TEST_COMMAND, mCallback.mCommand);
         assertBundleEquals(extras, mCallback.mExtras);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
     }
 
     @Test
@@ -361,6 +371,8 @@
         assertEquals(-1, mCallback.mQueueIndex);
         assertEquals(TEST_MEDIA_ID_1, mCallback.mQueueDescription.getMediaId());
         assertEquals(TEST_MEDIA_TITLE_1, mCallback.mQueueDescription.getTitle());
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         Bundle arguments = new Bundle();
@@ -374,6 +386,8 @@
         assertEquals(0, mCallback.mQueueIndex);
         assertEquals(TEST_MEDIA_ID_2, mCallback.mQueueDescription.getMediaId());
         assertEquals(TEST_MEDIA_TITLE_2, mCallback.mQueueDescription.getTitle());
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         callMediaControllerMethod(
@@ -382,6 +396,8 @@
         assertTrue(mCallback.mOnRemoveQueueItemCalled);
         assertEquals(TEST_MEDIA_ID_1, mCallback.mQueueDescription.getMediaId());
         assertEquals(TEST_MEDIA_TITLE_1, mCallback.mQueueDescription.getTitle());
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
     }
 
     @Test
@@ -391,39 +407,53 @@
         callTransportControlsMethod(PLAY, null, getContext(), mSession.getSessionToken());
         mCallback.await(TIME_OUT_MS);
         assertEquals(1, mCallback.mOnPlayCalledCount);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         callTransportControlsMethod(PAUSE, null, getContext(), mSession.getSessionToken());
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnPauseCalled);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         callTransportControlsMethod(STOP, null, getContext(), mSession.getSessionToken());
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnStopCalled);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         callTransportControlsMethod(
                 FAST_FORWARD, null, getContext(), mSession.getSessionToken());
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnFastForwardCalled);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         callTransportControlsMethod(REWIND, null, getContext(), mSession.getSessionToken());
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnRewindCalled);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         callTransportControlsMethod(
                 SKIP_TO_PREVIOUS, null, getContext(), mSession.getSessionToken());
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnSkipToPreviousCalled);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         callTransportControlsMethod(
                 SKIP_TO_NEXT, null, getContext(), mSession.getSessionToken());
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnSkipToNextCalled);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         final long seekPosition = 1000;
@@ -432,6 +462,8 @@
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnSeekToCalled);
         assertEquals(seekPosition, mCallback.mSeekPosition);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         final RatingCompat rating =
@@ -442,6 +474,8 @@
         assertTrue(mCallback.mOnSetRatingCalled);
         assertEquals(rating.getRatingStyle(), mCallback.mRating.getRatingStyle());
         assertEquals(rating.getStarRating(), mCallback.mRating.getStarRating(), DELTA);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         final Bundle extras = new Bundle();
@@ -455,6 +489,8 @@
         assertTrue(mCallback.mOnPlayFromMediaIdCalled);
         assertEquals(TEST_MEDIA_ID_1, mCallback.mMediaId);
         assertBundleEquals(extras, mCallback.mExtras);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         final String query = "test-query";
@@ -467,6 +503,8 @@
         assertTrue(mCallback.mOnPlayFromSearchCalled);
         assertEquals(query, mCallback.mQuery);
         assertBundleEquals(extras, mCallback.mExtras);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         final Uri uri = Uri.parse("content://test/popcorn.mod");
@@ -479,6 +517,8 @@
         assertTrue(mCallback.mOnPlayFromUriCalled);
         assertEquals(uri, mCallback.mUri);
         assertBundleEquals(extras, mCallback.mExtras);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         final String action = "test-action";
@@ -491,6 +531,8 @@
         assertTrue(mCallback.mOnCustomActionCalled);
         assertEquals(action, mCallback.mAction);
         assertBundleEquals(extras, mCallback.mExtras);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         mCallback.mOnCustomActionCalled = false;
@@ -510,6 +552,8 @@
         assertTrue(mCallback.mOnCustomActionCalled);
         assertEquals(action, mCallback.mAction);
         assertBundleEquals(extras, mCallback.mExtras);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         final long queueItemId = 1000;
@@ -518,12 +562,16 @@
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnSkipToQueueItemCalled);
         assertEquals(queueItemId, mCallback.mQueueItemId);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         callTransportControlsMethod(
                 PREPARE, null, getContext(), mSession.getSessionToken());
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnPrepareCalled);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         arguments = new Bundle();
@@ -535,6 +583,8 @@
         assertTrue(mCallback.mOnPrepareFromMediaIdCalled);
         assertEquals(TEST_MEDIA_ID_2, mCallback.mMediaId);
         assertBundleEquals(extras, mCallback.mExtras);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         arguments = new Bundle();
@@ -546,6 +596,8 @@
         assertTrue(mCallback.mOnPrepareFromSearchCalled);
         assertEquals(query, mCallback.mQuery);
         assertBundleEquals(extras, mCallback.mExtras);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         arguments = new Bundle();
@@ -557,6 +609,8 @@
         assertTrue(mCallback.mOnPrepareFromUriCalled);
         assertEquals(uri, mCallback.mUri);
         assertBundleEquals(extras, mCallback.mExtras);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         callTransportControlsMethod(
@@ -564,6 +618,8 @@
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnSetCaptioningEnabledCalled);
         assertEquals(ENABLED, mCallback.mCaptioningEnabled);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         final int repeatMode = PlaybackStateCompat.REPEAT_MODE_ALL;
@@ -572,6 +628,8 @@
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnSetRepeatModeCalled);
         assertEquals(repeatMode, mCallback.mRepeatMode);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         final int shuffleMode = PlaybackStateCompat.SHUFFLE_MODE_ALL;
@@ -580,6 +638,8 @@
         mCallback.await(TIME_OUT_MS);
         assertTrue(mCallback.mOnSetShuffleModeCalled);
         assertEquals(shuffleMode, mCallback.mShuffleMode);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
     }
 
     /**
@@ -605,6 +665,8 @@
         sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_PLAY);
         assertTrue(mCallback.await(TIME_OUT_MS));
         assertEquals(1, mCallback.mOnPlayCalledCount);
+        assertEquals(CLIENT_RECEIVER_COMPONENT_NAME.getPackageName(),
+                mCallback.mControllerInfo.getPackageName());
 
         mCallback.reset(1);
         sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_PAUSE);
@@ -825,6 +887,7 @@
         private int mQueueIndex;
         private MediaDescriptionCompat mQueueDescription;
         private List<MediaSessionCompat.QueueItem> mQueue = new ArrayList<>();
+        private MediaSessionManager.RemoteUserInfo mControllerInfo;
 
         private int mOnPlayCalledCount;
         private boolean mOnPauseCalled;
@@ -869,6 +932,7 @@
             mShuffleMode = PlaybackStateCompat.SHUFFLE_MODE_NONE;
             mQueueIndex = -1;
             mQueueDescription = null;
+            mControllerInfo = null;
 
             mOnPlayCalledCount = 0;
             mOnPauseCalled = false;
@@ -908,6 +972,7 @@
         @Override
         public void onPlay() {
             mOnPlayCalledCount++;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             setPlaybackState(PlaybackStateCompat.STATE_PLAYING);
             mLatch.countDown();
         }
@@ -915,6 +980,7 @@
         @Override
         public void onPause() {
             mOnPauseCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             setPlaybackState(PlaybackStateCompat.STATE_PAUSED);
             mLatch.countDown();
         }
@@ -922,6 +988,7 @@
         @Override
         public void onStop() {
             mOnStopCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             setPlaybackState(PlaybackStateCompat.STATE_STOPPED);
             mLatch.countDown();
         }
@@ -929,30 +996,35 @@
         @Override
         public void onFastForward() {
             mOnFastForwardCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mLatch.countDown();
         }
 
         @Override
         public void onRewind() {
             mOnRewindCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mLatch.countDown();
         }
 
         @Override
         public void onSkipToPrevious() {
             mOnSkipToPreviousCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mLatch.countDown();
         }
 
         @Override
         public void onSkipToNext() {
             mOnSkipToNextCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mLatch.countDown();
         }
 
         @Override
         public void onSeekTo(long pos) {
             mOnSeekToCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mSeekPosition = pos;
             mLatch.countDown();
         }
@@ -960,6 +1032,7 @@
         @Override
         public void onSetRating(RatingCompat rating) {
             mOnSetRatingCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mRating = rating;
             mLatch.countDown();
         }
@@ -967,6 +1040,7 @@
         @Override
         public void onPlayFromMediaId(String mediaId, Bundle extras) {
             mOnPlayFromMediaIdCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mMediaId = mediaId;
             mExtras = extras;
             mLatch.countDown();
@@ -975,6 +1049,7 @@
         @Override
         public void onPlayFromSearch(String query, Bundle extras) {
             mOnPlayFromSearchCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mQuery = query;
             mExtras = extras;
             mLatch.countDown();
@@ -983,6 +1058,7 @@
         @Override
         public void onPlayFromUri(Uri uri, Bundle extras) {
             mOnPlayFromUriCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mUri = uri;
             mExtras = extras;
             mLatch.countDown();
@@ -991,6 +1067,7 @@
         @Override
         public void onCustomAction(String action, Bundle extras) {
             mOnCustomActionCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mAction = action;
             mExtras = extras;
             mLatch.countDown();
@@ -999,6 +1076,7 @@
         @Override
         public void onSkipToQueueItem(long id) {
             mOnSkipToQueueItemCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mQueueItemId = id;
             mLatch.countDown();
         }
@@ -1006,6 +1084,7 @@
         @Override
         public void onCommand(String command, Bundle extras, ResultReceiver cb) {
             mOnCommandCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mCommand = command;
             mExtras = extras;
             mCommandCallback = cb;
@@ -1015,12 +1094,14 @@
         @Override
         public void onPrepare() {
             mOnPrepareCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mLatch.countDown();
         }
 
         @Override
         public void onPrepareFromMediaId(String mediaId, Bundle extras) {
             mOnPrepareFromMediaIdCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mMediaId = mediaId;
             mExtras = extras;
             mLatch.countDown();
@@ -1029,6 +1110,7 @@
         @Override
         public void onPrepareFromSearch(String query, Bundle extras) {
             mOnPrepareFromSearchCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mQuery = query;
             mExtras = extras;
             mLatch.countDown();
@@ -1037,6 +1119,7 @@
         @Override
         public void onPrepareFromUri(Uri uri, Bundle extras) {
             mOnPrepareFromUriCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mUri = uri;
             mExtras = extras;
             mLatch.countDown();
@@ -1045,6 +1128,7 @@
         @Override
         public void onSetRepeatMode(int repeatMode) {
             mOnSetRepeatModeCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mRepeatMode = repeatMode;
             mLatch.countDown();
         }
@@ -1052,6 +1136,7 @@
         @Override
         public void onAddQueueItem(MediaDescriptionCompat description) {
             mOnAddQueueItemCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mQueueDescription = description;
             mQueue.add(new MediaSessionCompat.QueueItem(description, mQueue.size()));
             mSession.setQueue(mQueue);
@@ -1061,6 +1146,7 @@
         @Override
         public void onAddQueueItem(MediaDescriptionCompat description, int index) {
             mOnAddQueueItemAtCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mQueueIndex = index;
             mQueueDescription = description;
             mQueue.add(index, new MediaSessionCompat.QueueItem(description, mQueue.size()));
@@ -1071,6 +1157,7 @@
         @Override
         public void onRemoveQueueItem(MediaDescriptionCompat description) {
             mOnRemoveQueueItemCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             String mediaId = description.getMediaId();
             for (int i = mQueue.size() - 1; i >= 0; --i) {
                 if (mediaId.equals(mQueue.get(i).getDescription().getMediaId())) {
@@ -1085,6 +1172,7 @@
         @Override
         public void onSetCaptioningEnabled(boolean enabled) {
             mOnSetCaptioningEnabledCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mCaptioningEnabled = enabled;
             mLatch.countDown();
         }
@@ -1092,6 +1180,7 @@
         @Override
         public void onSetShuffleMode(int shuffleMode) {
             mOnSetShuffleModeCalled = true;
+            mControllerInfo = mSession.getCurrentControllerInfo();
             mShuffleMode = shuffleMode;
             mLatch.countDown();
         }
diff --git a/mediarouter/build.gradle b/mediarouter/build.gradle
index a2463a4..2044242 100644
--- a/mediarouter/build.gradle
+++ b/mediarouter/build.gradle
@@ -34,4 +34,6 @@
     mavenGroup = LibraryGroups.MEDIAROUTER
     inceptionYear = "2013"
     description = "Android MediaRouter Support Library"
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/mediarouter/src/main/res/values-af/strings.xml b/mediarouter/src/main/res/values-af/strings.xml
new file mode 100644
index 0000000..1968699
--- /dev/null
+++ b/mediarouter/src/main/res/values-af/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Stelsel"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Toestelle"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Uitsaai-knoppie"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Uitsaai-knoppie. Ontkoppel"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Uitsaai-knoppie. Koppel tans"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Uitsaai-knoppie. Gekoppel"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Saai uit na"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Soek tans toestelle"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Ontkoppel"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Hou op uitsaai"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Maak toe"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Speel"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Onderbreek"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stop"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Vou uit"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Vou in"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albumkunswerk"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Volumeglyer"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Geen media is gekies nie"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Geen inligting is beskikbaar nie"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Saai tans skerm uit"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-am/strings.xml b/mediarouter/src/main/res/values-am/strings.xml
new file mode 100644
index 0000000..5e4eb42
--- /dev/null
+++ b/mediarouter/src/main/res/values-am/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"ሥርዓት"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"መሣሪያዎች"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"የCast አዝራር"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast አዝራር። ግንኙነት ተቋርጧል"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast አዝራር። በመገናኘት ላይ"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"የCast አዝራር። ተገናኝቷል"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Cast አድርግ ወደ"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"መሣሪያዎችን በማግኘት ላይ"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ግንኙነት አቋርጥ"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Cast ማድረግ አቁም"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"ዝጋ"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"አጫውት"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"ለአፍታ አቁም"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"አቁም"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"ዘርጋ"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"ሰብስብ"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"የአልበም ስነ-ጥበብ"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"ተንሸራታች የድምፅ መቆጣጠሪያ"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"ምንም ማህደረ መረጃ አልተመረጠም"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"ምንም መረጃ አይገኝም"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"ማያ ገጽን Cast በማድረግ ላይ"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ar/strings.xml b/mediarouter/src/main/res/values-ar/strings.xml
new file mode 100644
index 0000000..12a6df3
--- /dev/null
+++ b/mediarouter/src/main/res/values-ar/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"النظام"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"الأجهزة"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"زر الإرسال"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"زر الإرسال. تم قطع الاتصال"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"زر الإرسال. جارٍ الاتصال"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"زر الإرسال. تم الاتصال"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"إرسال إلى"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"جارٍ البحث عن أجهزة"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"قطع الاتصال"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"إيقاف الإرسال"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"إغلاق"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"تشغيل"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"إيقاف مؤقت"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"إيقاف"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"توسيع"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"تصغير"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"صورة الألبوم"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"شريط تمرير مستوى الصوت"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"لم يتم اختيار أي وسائط"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"لا تتوفر أي معلومات"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"جارٍ إرسال الشاشة"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-az/strings.xml b/mediarouter/src/main/res/values-az/strings.xml
index 8f3b518..651c84c 100644
--- a/mediarouter/src/main/res/values-az/strings.xml
+++ b/mediarouter/src/main/res/values-az/strings.xml
@@ -16,25 +16,25 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="3117964881088969586">"Sistem"</string>
-    <string name="mr_user_route_category_name" msgid="8236416097133080726">"Cihazlar"</string>
-    <string name="mr_button_content_description" msgid="1685185767093348095">"Yayım düyməsi"</string>
-    <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Yayım düyməsi. Bağlantı kəsildi"</string>
-    <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Yayım düyməsi. Qoşulur"</string>
-    <string name="mr_cast_button_connected" msgid="1350095112462806159">"Yayım düyməsi. Qoşuldu"</string>
-    <string name="mr_chooser_title" msgid="7548226170787476564">"Bura yayımlayın"</string>
-    <string name="mr_chooser_searching" msgid="5504553798429329689">"Cihazlar axtarılır"</string>
-    <string name="mr_controller_disconnect" msgid="1370654436555555647">"Əlaqəni silin"</string>
-    <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Yayımı dayandırın"</string>
-    <string name="mr_controller_close_description" msgid="5468775621814500662">"Bağlayın"</string>
-    <string name="mr_controller_play" msgid="4443315438268112801">"Oyun"</string>
-    <string name="mr_controller_pause" msgid="4701315813294065305">"Pauza"</string>
-    <string name="mr_controller_stop" msgid="5106056093749454009">"Dayandırın"</string>
-    <string name="mr_controller_expand_group" msgid="2422682304043876468">"Genişləndirin"</string>
-    <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Yığcamlaşdırın"</string>
-    <string name="mr_controller_album_art" msgid="5813284753012893250">"Albom incəsənəti"</string>
-    <string name="mr_controller_volume_slider" msgid="691656961160498512">"Səs ayarlayıcısı"</string>
-    <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Media seçilməyib"</string>
-    <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Əlçatan məlumat yoxdur"</string>
-    <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Ekran yayımlanır"</string>
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Cihazlar"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Yayım düyməsi"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Yayım düyməsi. Bağlantı kəsildi"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Yayım düyməsi. Qoşulur"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Yayım düyməsi. Qoşuldu"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Bura yayımlayın"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Cihazlar axtarılır"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Ayırın"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Yayımı dayandırın"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Bağlayın"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Fasilə verin"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Dayandırın"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Dayandırın"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Genişləndirin"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Yığcamlaşdırın"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albom incəsənəti"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Səs ayarlayıcısı"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Media seçilməyib"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Əlçatan məlumat yoxdur"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Ekran yayımlanır"</string>
 </resources>
diff --git a/mediarouter/src/main/res/values-b+sr+Latn/strings.xml b/mediarouter/src/main/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..805709b
--- /dev/null
+++ b/mediarouter/src/main/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Uređaji"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Dugme Prebaci"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Dugme Prebaci. Veza je prekinuta"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Dugme Prebaci. Povezuje se"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Dugme Prebaci. Povezan je"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Prebacite na"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Traže se uređaji"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Prekini vezu"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Zaustavi prebacivanje"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Zatvori"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Pusti"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pauziraj"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Zaustavi"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Proširi"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Skupi"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Omot albuma"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Klizač za jačinu zvuka"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nema izabranih medija"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nema dostupnih informacija"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Prebacuje se ekran"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-be/strings.xml b/mediarouter/src/main/res/values-be/strings.xml
new file mode 100644
index 0000000..b0ae4d5
--- /dev/null
+++ b/mediarouter/src/main/res/values-be/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Сістэма"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Прылады"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Кнопка трансляцыі"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Кнопка трансляцыі. Прылада адключана"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Кнопка трансляцыі. Прылада падключаецца"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Кнопка трансляцыі. Прылада падключана"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Трансліраваць на прыладу"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Пошук прылад"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Адключыць"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Спыніць трансляцыю"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Закрыць"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Прайграць"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Паўза"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Спыніць"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Разгарнуць"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Згарнуць"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Вокладка альбома"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Рэгулятар гучнасці"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Медыяфайл не выбраны"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Інфармацыя адсутнічае"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Экран трансліруецца"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-bg/strings.xml b/mediarouter/src/main/res/values-bg/strings.xml
new file mode 100644
index 0000000..7491533
--- /dev/null
+++ b/mediarouter/src/main/res/values-bg/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Система"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Устройства"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Бутон за предаване"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Бутон за предаване. Връзката е прекратена"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Бутон за предаване. Установява се връзка"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Бутон за предаване. Установена е връзка"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Предаване към"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Търсят се устройства"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Прекратяване на връзката"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Спиране на предаването"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Затваряне"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Възпроизвеждане"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Поставяне на пауза"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Спиране"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Разгъване"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Свиване"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Обложка на албума"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Плъзгач за силата на звука"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Няма избрана мултимедия"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Няма налична информация"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Екранът се предава"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-bn/strings.xml b/mediarouter/src/main/res/values-bn/strings.xml
new file mode 100644
index 0000000..b3ed757
--- /dev/null
+++ b/mediarouter/src/main/res/values-bn/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"সিস্টেম"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"ডিভাইস"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"কাস্ট করার বোতাম"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"কাস্ট করার বোতাম। কানেক্ট করা নেই"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"কাস্ট করার বোতাম। কানেক্ট করা হচ্ছে"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"কাস্ট করার বোতাম। কানেক্ট হয়েছে"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"এখানে কাস্ট করুন"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"ডিভাইস খোঁজা হচ্ছে"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ডিসকানেক্ট"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"কাস্ট করা বন্ধ করুন"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"বন্ধ করুন"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"চালান"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"পজ করুন"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"থামান"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"বড় করে দেখুন"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"আড়াল করুন"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"অ্যালবাম আর্ট"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"ভলিউম স্লাইডার"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"কোনও মিডিয়া বেছে নেওয়া হয়নি"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"কোনও তথ্য উপলভ্য নেই"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"স্ক্রিন কাস্ট করা হচ্ছে"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-bs/strings.xml b/mediarouter/src/main/res/values-bs/strings.xml
new file mode 100644
index 0000000..553efdf
--- /dev/null
+++ b/mediarouter/src/main/res/values-bs/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Uređaji"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Dugme za emitiranje"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Dugme za emitiranje. Veza je prekinuta"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Dugme za emitiranje. Povezivanje"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Dugme za emitiranje. Povezano"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Emitiranje na"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Traženje uređaja"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Prekini vezu"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Zaustavi emitiranje"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Zatvori"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Reproduciraj"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pauza"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Zaustavi"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Proširi"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Skupi"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Omot albuma"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Klizač za jačinu zvuka"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nije odabran nijedan medij"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nema dostupnih informacija"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Emitiranje ekrana"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ca/strings.xml b/mediarouter/src/main/res/values-ca/strings.xml
new file mode 100644
index 0000000..e6a2f71
--- /dev/null
+++ b/mediarouter/src/main/res/values-ca/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Dispositius"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Botó d\'emetre"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Botó d\'emetre. Desconnectat."</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Botó d\'emetre. S\'està connectant."</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Botó d\'emetre. Connectat."</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Emet contingut a"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"S\'estan cercant dispositius"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Desconnecta"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Atura l\'emissió"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Tanca"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Reprodueix"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Posa en pausa"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Atura"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Desplega"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Replega"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Imatge de l\'àlbum"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Control lliscant de volum"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"No hi ha contingut multimèdia seleccionat"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"No hi ha informació disponible"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"S\'està emetent la pantalla"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-cs/strings.xml b/mediarouter/src/main/res/values-cs/strings.xml
new file mode 100644
index 0000000..a914d34
--- /dev/null
+++ b/mediarouter/src/main/res/values-cs/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Systém"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Zařízení"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Tlačítko odesílání"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Tlačítko odesílání. Odpojeno"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Tlačítko odesílání. Připojování"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Tlačítko odesílání. Připojeno"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Odeslat do zařízení"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Hledání zařízení"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Odpojit"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Zastavit odesílání"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Zavřít"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Přehrát"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pozastavit"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Ukončit"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Rozbalit"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Sbalit"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Obal alba"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Posuvník hlasitosti"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Není vybrán žádný mediální obsah"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nejsou k dispozici žádné informace"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Odesílání obsahu obrazovky"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-da/strings.xml b/mediarouter/src/main/res/values-da/strings.xml
new file mode 100644
index 0000000..5736cb5
--- /dev/null
+++ b/mediarouter/src/main/res/values-da/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Enheder"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast-knap"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast-knap. Forbindelsen er afbrudt"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast-knap. Opretter forbindelse"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast-knap. Tilsluttet"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Cast til"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Finder enheder"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Afbryd"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Stop med at caste"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Luk"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Afspil"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Sæt på pause"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stop"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Udvid"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Skjul"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albumgrafik"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Lydstyrkeskyder"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Ingen medier er markeret"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Der er ingen tilgængelige oplysninger"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Skærmen castes"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-de/strings.xml b/mediarouter/src/main/res/values-de/strings.xml
new file mode 100644
index 0000000..bfab0be
--- /dev/null
+++ b/mediarouter/src/main/res/values-de/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Geräte"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast-Symbol"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast-Symbol. Nicht verbunden"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast-Symbol. Verbindung wird hergestellt"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast-Symbol. Verbunden"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Streamen auf"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Keine Geräte gefunden"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Trennen"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Streaming beenden"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Schließen"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Wiedergeben"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pausieren"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Beenden"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Maximieren"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Minimieren"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albumcover"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Schieberegler für die Lautstärke"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Keine Medien ausgewählt"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Keine Informationen verfügbar"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Bildschirm wird übertragen"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-el/strings.xml b/mediarouter/src/main/res/values-el/strings.xml
new file mode 100644
index 0000000..6290c3d
--- /dev/null
+++ b/mediarouter/src/main/res/values-el/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Σύστημα"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Συσκευές"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Κουμπί μετάδοσης"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Κουμπί μετάδοσης. Αποσυνδέθηκε."</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Κουμπί μετάδοση. Σύνδεση."</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Κουμπί μετάδοσης. Συνδέθηκε."</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Μετάδοση σε"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Εύρεση συσκευών"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Αποσύνδεση"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Διακοπή μετάδοσης"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Κλείσιμο"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Αναπαραγωγή"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Παύση"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Διακοπή"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Ανάπτυξη"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Σύμπτυξη"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Εξώφυλλο άλμπουμ"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Ρυθμιστικό έντασης ήχου"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Δεν επιλέχθηκαν μέσα"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Δεν υπάρχουν διαθέσιμες πληροφορίες"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Μετάδοση οθόνης"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-en-rAU/strings.xml b/mediarouter/src/main/res/values-en-rAU/strings.xml
index df5801c..420d536 100644
--- a/mediarouter/src/main/res/values-en-rAU/strings.xml
+++ b/mediarouter/src/main/res/values-en-rAU/strings.xml
@@ -16,25 +16,25 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="3117964881088969586">"System"</string>
-    <string name="mr_user_route_category_name" msgid="8236416097133080726">"Devices"</string>
-    <string name="mr_button_content_description" msgid="1685185767093348095">"Cast button"</string>
-    <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast button. Disconnected"</string>
-    <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast button. Connecting"</string>
-    <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast button. Connected"</string>
-    <string name="mr_chooser_title" msgid="7548226170787476564">"Cast to"</string>
-    <string name="mr_chooser_searching" msgid="5504553798429329689">"Finding devices"</string>
-    <string name="mr_controller_disconnect" msgid="1370654436555555647">"Disconnect"</string>
-    <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Stop casting"</string>
-    <string name="mr_controller_close_description" msgid="5468775621814500662">"Close"</string>
-    <string name="mr_controller_play" msgid="4443315438268112801">"Play"</string>
-    <string name="mr_controller_pause" msgid="4701315813294065305">"Pause"</string>
-    <string name="mr_controller_stop" msgid="5106056093749454009">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="2422682304043876468">"Expand"</string>
-    <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Collapse"</string>
-    <string name="mr_controller_album_art" msgid="5813284753012893250">"Album art"</string>
-    <string name="mr_controller_volume_slider" msgid="691656961160498512">"Volume slider"</string>
-    <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"No media selected"</string>
-    <string name="mr_controller_no_info_available" msgid="7299368841849988218">"No info available"</string>
-    <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Casting screen"</string>
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Devices"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast button"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast button. Disconnected"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast button. Connecting"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast button. Connected"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Cast to"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Finding devices"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Disconnect"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Stop casting"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Close"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Play"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pause"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stop"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Expand"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Collapse"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Album art"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Volume slider"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"No media selected"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"No info available"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Casting screen"</string>
 </resources>
diff --git a/mediarouter/src/main/res/values-en-rCA/strings.xml b/mediarouter/src/main/res/values-en-rCA/strings.xml
index df5801c..420d536 100644
--- a/mediarouter/src/main/res/values-en-rCA/strings.xml
+++ b/mediarouter/src/main/res/values-en-rCA/strings.xml
@@ -16,25 +16,25 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="3117964881088969586">"System"</string>
-    <string name="mr_user_route_category_name" msgid="8236416097133080726">"Devices"</string>
-    <string name="mr_button_content_description" msgid="1685185767093348095">"Cast button"</string>
-    <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast button. Disconnected"</string>
-    <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast button. Connecting"</string>
-    <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast button. Connected"</string>
-    <string name="mr_chooser_title" msgid="7548226170787476564">"Cast to"</string>
-    <string name="mr_chooser_searching" msgid="5504553798429329689">"Finding devices"</string>
-    <string name="mr_controller_disconnect" msgid="1370654436555555647">"Disconnect"</string>
-    <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Stop casting"</string>
-    <string name="mr_controller_close_description" msgid="5468775621814500662">"Close"</string>
-    <string name="mr_controller_play" msgid="4443315438268112801">"Play"</string>
-    <string name="mr_controller_pause" msgid="4701315813294065305">"Pause"</string>
-    <string name="mr_controller_stop" msgid="5106056093749454009">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="2422682304043876468">"Expand"</string>
-    <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Collapse"</string>
-    <string name="mr_controller_album_art" msgid="5813284753012893250">"Album art"</string>
-    <string name="mr_controller_volume_slider" msgid="691656961160498512">"Volume slider"</string>
-    <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"No media selected"</string>
-    <string name="mr_controller_no_info_available" msgid="7299368841849988218">"No info available"</string>
-    <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Casting screen"</string>
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Devices"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast button"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast button. Disconnected"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast button. Connecting"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast button. Connected"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Cast to"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Finding devices"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Disconnect"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Stop casting"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Close"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Play"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pause"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stop"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Expand"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Collapse"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Album art"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Volume slider"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"No media selected"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"No info available"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Casting screen"</string>
 </resources>
diff --git a/mediarouter/src/main/res/values-en-rGB/strings.xml b/mediarouter/src/main/res/values-en-rGB/strings.xml
index df5801c..420d536 100644
--- a/mediarouter/src/main/res/values-en-rGB/strings.xml
+++ b/mediarouter/src/main/res/values-en-rGB/strings.xml
@@ -16,25 +16,25 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="3117964881088969586">"System"</string>
-    <string name="mr_user_route_category_name" msgid="8236416097133080726">"Devices"</string>
-    <string name="mr_button_content_description" msgid="1685185767093348095">"Cast button"</string>
-    <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast button. Disconnected"</string>
-    <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast button. Connecting"</string>
-    <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast button. Connected"</string>
-    <string name="mr_chooser_title" msgid="7548226170787476564">"Cast to"</string>
-    <string name="mr_chooser_searching" msgid="5504553798429329689">"Finding devices"</string>
-    <string name="mr_controller_disconnect" msgid="1370654436555555647">"Disconnect"</string>
-    <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Stop casting"</string>
-    <string name="mr_controller_close_description" msgid="5468775621814500662">"Close"</string>
-    <string name="mr_controller_play" msgid="4443315438268112801">"Play"</string>
-    <string name="mr_controller_pause" msgid="4701315813294065305">"Pause"</string>
-    <string name="mr_controller_stop" msgid="5106056093749454009">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="2422682304043876468">"Expand"</string>
-    <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Collapse"</string>
-    <string name="mr_controller_album_art" msgid="5813284753012893250">"Album art"</string>
-    <string name="mr_controller_volume_slider" msgid="691656961160498512">"Volume slider"</string>
-    <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"No media selected"</string>
-    <string name="mr_controller_no_info_available" msgid="7299368841849988218">"No info available"</string>
-    <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Casting screen"</string>
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Devices"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast button"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast button. Disconnected"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast button. Connecting"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast button. Connected"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Cast to"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Finding devices"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Disconnect"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Stop casting"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Close"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Play"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pause"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stop"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Expand"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Collapse"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Album art"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Volume slider"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"No media selected"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"No info available"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Casting screen"</string>
 </resources>
diff --git a/mediarouter/src/main/res/values-en-rIN/strings.xml b/mediarouter/src/main/res/values-en-rIN/strings.xml
index df5801c..420d536 100644
--- a/mediarouter/src/main/res/values-en-rIN/strings.xml
+++ b/mediarouter/src/main/res/values-en-rIN/strings.xml
@@ -16,25 +16,25 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="3117964881088969586">"System"</string>
-    <string name="mr_user_route_category_name" msgid="8236416097133080726">"Devices"</string>
-    <string name="mr_button_content_description" msgid="1685185767093348095">"Cast button"</string>
-    <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast button. Disconnected"</string>
-    <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast button. Connecting"</string>
-    <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast button. Connected"</string>
-    <string name="mr_chooser_title" msgid="7548226170787476564">"Cast to"</string>
-    <string name="mr_chooser_searching" msgid="5504553798429329689">"Finding devices"</string>
-    <string name="mr_controller_disconnect" msgid="1370654436555555647">"Disconnect"</string>
-    <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Stop casting"</string>
-    <string name="mr_controller_close_description" msgid="5468775621814500662">"Close"</string>
-    <string name="mr_controller_play" msgid="4443315438268112801">"Play"</string>
-    <string name="mr_controller_pause" msgid="4701315813294065305">"Pause"</string>
-    <string name="mr_controller_stop" msgid="5106056093749454009">"Stop"</string>
-    <string name="mr_controller_expand_group" msgid="2422682304043876468">"Expand"</string>
-    <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Collapse"</string>
-    <string name="mr_controller_album_art" msgid="5813284753012893250">"Album art"</string>
-    <string name="mr_controller_volume_slider" msgid="691656961160498512">"Volume slider"</string>
-    <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"No media selected"</string>
-    <string name="mr_controller_no_info_available" msgid="7299368841849988218">"No info available"</string>
-    <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Casting screen"</string>
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Devices"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast button"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast button. Disconnected"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast button. Connecting"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast button. Connected"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Cast to"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Finding devices"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Disconnect"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Stop casting"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Close"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Play"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pause"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stop"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Expand"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Collapse"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Album art"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Volume slider"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"No media selected"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"No info available"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Casting screen"</string>
 </resources>
diff --git a/mediarouter/src/main/res/values-en-rXC/strings.xml b/mediarouter/src/main/res/values-en-rXC/strings.xml
index 993d212..03083ad 100644
--- a/mediarouter/src/main/res/values-en-rXC/strings.xml
+++ b/mediarouter/src/main/res/values-en-rXC/strings.xml
@@ -16,25 +16,25 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="3117964881088969586">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎System‎‏‎‎‏‎"</string>
-    <string name="mr_user_route_category_name" msgid="8236416097133080726">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎Devices‎‏‎‎‏‎"</string>
-    <string name="mr_button_content_description" msgid="1685185767093348095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎Cast button‎‏‎‎‏‎"</string>
-    <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎Cast button. Disconnected‎‏‎‎‏‎"</string>
-    <string name="mr_cast_button_connecting" msgid="8959304318293841992">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎Cast button. Connecting‎‏‎‎‏‎"</string>
-    <string name="mr_cast_button_connected" msgid="1350095112462806159">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‎Cast button. Connected‎‏‎‎‏‎"</string>
-    <string name="mr_chooser_title" msgid="7548226170787476564">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎Cast to‎‏‎‎‏‎"</string>
-    <string name="mr_chooser_searching" msgid="5504553798429329689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎Finding devices‎‏‎‎‏‎"</string>
-    <string name="mr_controller_disconnect" msgid="1370654436555555647">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎Disconnect‎‏‎‎‏‎"</string>
-    <string name="mr_controller_stop_casting" msgid="7617024847862349259">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎Stop casting‎‏‎‎‏‎"</string>
-    <string name="mr_controller_close_description" msgid="5468775621814500662">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎Close‎‏‎‎‏‎"</string>
-    <string name="mr_controller_play" msgid="4443315438268112801">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎Play‎‏‎‎‏‎"</string>
-    <string name="mr_controller_pause" msgid="4701315813294065305">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‏‏‎‎‏‎Pause‎‏‎‎‏‎"</string>
-    <string name="mr_controller_stop" msgid="5106056093749454009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‎Stop‎‏‎‎‏‎"</string>
-    <string name="mr_controller_expand_group" msgid="2422682304043876468">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‎‎Expand‎‏‎‎‏‎"</string>
-    <string name="mr_controller_collapse_group" msgid="5518911192681928413">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‎Collapse‎‏‎‎‏‎"</string>
-    <string name="mr_controller_album_art" msgid="5813284753012893250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎Album art‎‏‎‎‏‎"</string>
-    <string name="mr_controller_volume_slider" msgid="691656961160498512">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎Volume slider‎‏‎‎‏‎"</string>
-    <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎No media selected‎‏‎‎‏‎"</string>
-    <string name="mr_controller_no_info_available" msgid="7299368841849988218">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎No info available‎‏‎‎‏‎"</string>
-    <string name="mr_controller_casting_screen" msgid="5286734709674025661">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎Casting screen‎‏‎‎‏‎"</string>
+    <string name="mr_system_route_name" msgid="6445173646164603280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎System‎‏‎‎‏‎"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‎‏‎‏‎Devices‎‏‎‎‏‎"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎Cast button‎‏‎‎‏‎"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‏‏‎‎Cast button. Disconnected‎‏‎‎‏‎"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎Cast button. Connecting‎‏‎‎‏‎"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎Cast button. Connected‎‏‎‎‏‎"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎Cast to‎‏‎‎‏‎"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎Finding devices‎‏‎‎‏‎"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‎Disconnect‎‏‎‎‏‎"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎Stop casting‎‏‎‎‏‎"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎Close‎‏‎‎‏‎"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‎Play‎‏‎‎‏‎"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‎Pause‎‏‎‎‏‎"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎Stop‎‏‎‎‏‎"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‎Expand‎‏‎‎‏‎"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎Collapse‎‏‎‎‏‎"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎‎‎‎‎Album art‎‏‎‎‏‎"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‎Volume slider‎‏‎‎‏‎"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎No media selected‎‏‎‎‏‎"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‏‎‎‎‏‏‎‎‎‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎No info available‎‏‎‎‏‎"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎Casting screen‎‏‎‎‏‎"</string>
 </resources>
diff --git a/mediarouter/src/main/res/values-es-rUS/strings.xml b/mediarouter/src/main/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..51a2955
--- /dev/null
+++ b/mediarouter/src/main/res/values-es-rUS/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Dispositivos"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Botón para transmitir"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Botón para transmitir (desconectado)"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Botón para transmitir (conectando)"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Botón para transmitir (conectado)"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Transmitir a"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Buscando dispositivos"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Desconectar"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Detener transmisión"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Cerrar"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Reproducir"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pausar"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Detener"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Expandir"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Contraer"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Imagen del álbum"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Control deslizante del volumen"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"No se seleccionó ningún contenido multimedia"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Sin información disponible"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Transmitiendo pantalla"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-es/strings.xml b/mediarouter/src/main/res/values-es/strings.xml
new file mode 100644
index 0000000..e07a751
--- /dev/null
+++ b/mediarouter/src/main/res/values-es/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Dispositivos"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Botón de enviar"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Botón de enviar. Desconectado"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Botón de enviar. Conectando"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Botón de enviar. Conectado"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Enviar a"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Buscando dispositivos"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Desconectar"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Detener envío"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Cerrar"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Reproducir"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pausar"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Detener"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Mostrar"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Ocultar"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Carátula del álbum"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Control deslizante de volumen"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"No se ha seleccionado contenido multimedia"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"No hay información disponible"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Enviando pantalla"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-et/strings.xml b/mediarouter/src/main/res/values-et/strings.xml
new file mode 100644
index 0000000..4ff3f62
--- /dev/null
+++ b/mediarouter/src/main/res/values-et/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Süsteem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Seadmed"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Ülekandenupp"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Ülekandenupp. Ühendus on katkestatud"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Ülekandenupp. Ühendamine"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Ülekandenupp. Ühendatud"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Ülekandmine seadmesse"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Seadmete otsimine"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Katkesta ühendus"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Peata ülekandmine"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Sulgemine"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Esitamine"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Peatamine"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Peatamine"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Laiendamine"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Ahendamine"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albumi kujundus"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Helitugevuse liugur"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Meediat pole valitud"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Teave pole saadaval"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Ekraanikuva ülekandmine"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-eu/strings.xml b/mediarouter/src/main/res/values-eu/strings.xml
new file mode 100644
index 0000000..18aeed3
--- /dev/null
+++ b/mediarouter/src/main/res/values-eu/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Gailuak"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Igorri botoia"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Igortzeko botoia. Deskonektatuta"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Igortzeko botoia. Konektatzen"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Igortzeko botoia. Konektatuta"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Igorri hona"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Gailuak bilatzen"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Deskonektatu"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Utzi igortzeari"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Itxi"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Erreproduzitu"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pausatu"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Gelditu"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Zabaldu"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Tolestu"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albumaren azala"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Bolumenaren graduatzailea"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Ez da ezer hautatu"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Ez dago informaziorik"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Pantaila igortzen"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-fa/strings.xml b/mediarouter/src/main/res/values-fa/strings.xml
new file mode 100644
index 0000000..eb0ea6c
--- /dev/null
+++ b/mediarouter/src/main/res/values-fa/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"سیستم"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"دستگاه‌ها"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"دکمه ارسال محتوا"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"دکمه فرستادن. اتصال قطع شد"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"دکمه فرستادن. درحال اتصال"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"دکمه فرستادن. متصل"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"ارسال محتوا به"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"پیدا کردن دستگاه‌ها"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"قطع اتصال"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"توقف ارسال محتوا"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"بستن"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"پخش"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"مکث"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"توقف"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"بزرگ کردن"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"کوچک کردن"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"عکس روی جلد آلبوم"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"لغزنده میزان صدا"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"رسانه‌ای انتخاب نشده است"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"اطلاعات دردسترس نیست"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"صفحه ارسال محتوا"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-fi/strings.xml b/mediarouter/src/main/res/values-fi/strings.xml
new file mode 100644
index 0000000..a365147
--- /dev/null
+++ b/mediarouter/src/main/res/values-fi/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Järjestelmä"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Laitteet"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast-painike"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast-painike. Yhteys katkaistu"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast-painike. Yhdistetään"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast-painike. Yhdistetty"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Suoratoiston kohde"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Etsitään laitteita"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Katkaise yhteys"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Lopeta suoratoisto"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Sulje"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Toista"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Keskeytä"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Lopeta"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Laajenna"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Tiivistä"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albumin kansikuva"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Äänenvoimakkuuden liukusäädin"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Ei valittua mediaa"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Ei tietoja saatavilla"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Suoratoistetaan näyttöä"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-fr-rCA/strings.xml b/mediarouter/src/main/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..8df9031
--- /dev/null
+++ b/mediarouter/src/main/res/values-fr-rCA/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Système"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Appareils"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Bouton Diffuser"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Bouton Diffuser. Déconnecté"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Bouton Diffuser. Connexion en cours…"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Bouton Diffuser. Connecté"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Diffuser vers"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Recherche d\'appareils"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Dissocier"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Arrêter la diffusion"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Fermer"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Lire"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pause"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Arrêter"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Développer"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Réduire"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Image de l\'album"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Curseur de réglage du volume"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Aucun média sélectionné"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Aucune donnée trouvée"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Diffusion de l\'écran en cours"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-fr/strings.xml b/mediarouter/src/main/res/values-fr/strings.xml
new file mode 100644
index 0000000..cfce49b
--- /dev/null
+++ b/mediarouter/src/main/res/values-fr/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Système"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Appareils"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Icône Cast"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Icône Cast. Déconnecté"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Icône Cast. Connexion…"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Icône Cast. Connecté"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Caster sur"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Recherche d\'appareils…"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Déconnecter"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Arrêter la diffusion"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Fermer"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Lecture"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pause"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Arrêt"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Développer"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Réduire"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Image de l\'album"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Curseur de volume"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Aucun contenu multimédia sélectionné"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Aucune information disponible"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Diffusion de l\'écran"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-gl/strings.xml b/mediarouter/src/main/res/values-gl/strings.xml
new file mode 100644
index 0000000..2eb5e04
--- /dev/null
+++ b/mediarouter/src/main/res/values-gl/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Dispositivos"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Botón de emitir"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Botón de emitir. Desconectado"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Botón de emitir. Conectando"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Botón de emitir. Conectado"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Emitir en"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Buscando dispositivos"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Desconectar"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Deter emisión"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Pechar"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Reproducir"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pausar"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Deter"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Despregar"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Contraer"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Portada do álbum"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Control desprazable do volume"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Non se seleccionou ningún recurso multimedia"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Non hai información dispoñible"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Emitindo a pantalla"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-gu/strings.xml b/mediarouter/src/main/res/values-gu/strings.xml
new file mode 100644
index 0000000..8459bcd
--- /dev/null
+++ b/mediarouter/src/main/res/values-gu/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"સિસ્ટમ"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"ઉપકરણો"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"કાસ્ટ બટન"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"કાસ્ટ બટન. ડિસ્કનેક્ટેડ"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"કાસ્ટ બટન. કનેક્ટ કરી રહ્યાં છીએ"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"કાસ્ટ બટન. કનેક્ટેડ"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"આના પર કાસ્ટ કરો"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"ઉપકરણો શોધી રહ્યાં છીએ"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ડિસ્કનેક્ટ કરો"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"કાસ્ટ કરવાનું રોકો"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"બંધ કરો"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"ચલાવો"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"થોભાવો"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"રોકો"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"વિસ્તાર કરો"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"સંકુચિત કરો"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"આલ્બમ આર્ટ"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"વૉલ્યુમ સ્લાઇડર"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"કોઈ મીડિયા પસંદ કરેલ નથી"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"કોઈ માહિતી ઉપલબ્ધ નથી"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"સ્ક્રીનને કાસ્ટ કરી રહ્યાં છીએ"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-hi/strings.xml b/mediarouter/src/main/res/values-hi/strings.xml
new file mode 100644
index 0000000..891d765
--- /dev/null
+++ b/mediarouter/src/main/res/values-hi/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"सिस्‍टम"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"डिवाइस"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"कास्ट करें बटन"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"कास्ट करें बटन. नहीं जुड़ा है"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"कास्ट करें बटन. जुड़ रहा है"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"कास्ट करें बटन. जुड़ा है"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"इस पर कास्‍ट करें"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"डिवाइस ढूंढे जा रहे हैं"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"कनेक्शन हटाएं"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"कास्ट करना रोकें"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"बंद करें"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"चलाएं"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"रोकें"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"रुकें"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"सदस्याें की सूची को बड़ा करके देखें"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"सदस्याें की सूची छोटी करें"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"एल्बम आर्ट"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"आवाज़ बढ़ाने या घटाने वाला स्लाइडर"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"कोई मीडिया चुना नहीं गया"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"कोई जानकारी मौजूद नहीं है"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"स्क्रीन कास्ट की जा रही है"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-hr/strings.xml b/mediarouter/src/main/res/values-hr/strings.xml
new file mode 100644
index 0000000..e17a0e7
--- /dev/null
+++ b/mediarouter/src/main/res/values-hr/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sustav"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Uređaji"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Gumb za emitiranje"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Gumb za emitiranje. Veza prekinuta"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Gumb za emitiranje. Povezivanje"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Gumb za emitiranje. Povezan"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Emitiranje na"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Traženje uređaja"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Prekini"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Zaustavi emitiranje"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Zatvori"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Pokreni"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pauza"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Zaustavi"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Proširi"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Sažmi"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Naslovnica albuma"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Klizač za glasnoću"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nije odabran nijedan medij"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Informacije nisu dostupne"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Emitiranje zaslona"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-hu/strings.xml b/mediarouter/src/main/res/values-hu/strings.xml
new file mode 100644
index 0000000..a9f80f4
--- /dev/null
+++ b/mediarouter/src/main/res/values-hu/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Rendszer"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Eszközök"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Átküldés gomb"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Átküldés gomb. Kapcsolat bontva"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Átküldés gomb. Csatlakozás"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Átküldés gomb. Csatlakoztatva"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Átküldés ide:"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Eszközök keresése"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Leválasztás"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Átküldés leállítása"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Bezárás"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Lejátszás"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Szünet"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Leállítás"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Kibontás"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Összecsukás"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Lemezborító"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Hangerőszabályzó"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nincs médiatartalom kiválasztva"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nincs információ"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Képernyőtartalom átküldése…"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-hy/strings.xml b/mediarouter/src/main/res/values-hy/strings.xml
new file mode 100644
index 0000000..e48fac5
--- /dev/null
+++ b/mediarouter/src/main/res/values-hy/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Համակարգ"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Սարքեր"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Հեռարձակման կոճակ"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Հեռարձակման կոճակ: Սարքն անջատած է:"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Հեռարձակման կոճակ: Սարքը միանում է:"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Հեռարձակման կոճակ: Սարքը միացված է:"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Ընտրեք սարք"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Սարքերի որոնում"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Անջատել"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Դադարեցնել հեռարձակումը"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Փակել"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Նվագարկել"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Ընդհատել"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Դադարեցնել"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Ընդարձակել"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Կոծկել"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Ալբոմի շապիկ"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Ձայնի ուժգնության կարգավորիչ"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Մեդիա ֆայլ չի ընտրվել"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Հասանելի տեղեկություններ չկան"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Էկրանի հեռարձակում"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-in/strings.xml b/mediarouter/src/main/res/values-in/strings.xml
new file mode 100644
index 0000000..5a19254
--- /dev/null
+++ b/mediarouter/src/main/res/values-in/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Perangkat"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Tombol Cast"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Tombol Cast. Terputus"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Tombol Cast. Menghubungkan"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Tombol Cast. Terhubung"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Cast ke"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Mencari perangkat"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Putuskan hubungan"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Hentikan cast"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Tutup"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Putar"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Jeda"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Berhenti"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Luaskan"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Ciutkan"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Sampul album"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Penggeser volume"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Tidak ada media yang dipilih"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Tidak ada info yang tersedia"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Melakukan cast layar"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-is/strings.xml b/mediarouter/src/main/res/values-is/strings.xml
new file mode 100644
index 0000000..bc3c36d
--- /dev/null
+++ b/mediarouter/src/main/res/values-is/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Kerfi"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Tæki"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Útsendingarhnappur"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Útsendingarhnappur. Aftengt"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Útsendingarhnappur. Tengist"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Útsendingarhnappur. Tengt"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Senda út í"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Leitað að tækj"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Aftengja"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Stöðva útsendingu"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Loka"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Spila"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Hlé"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stöðva"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Stækka"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Minnka"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Plötuumslag"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Hljóðstyrkssleði"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Ekkert efni valið"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Engar upplýsingar í boði"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Skjár sendur út"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-it/strings.xml b/mediarouter/src/main/res/values-it/strings.xml
new file mode 100644
index 0000000..3bbfecd
--- /dev/null
+++ b/mediarouter/src/main/res/values-it/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Dispositivi"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Pulsante Trasmetti"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Pulsante Trasmetti. Disconnesso"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Pulsante Trasmetti. Connessione in corso"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Pulsante Trasmetti. Connesso"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Trasmetti a"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Ricerca di dispositivi"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Disconnetti"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Interrompi trasmissione"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Chiudi"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Riproduci"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Metti in pausa"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Interrompi"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Espandi"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Comprimi"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Copertina"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Dispositivo di scorrimento del volume"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nessun contenuto multimediale selezionato"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nessuna informazione disponibile"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Trasmissione dello schermo"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-iw/strings.xml b/mediarouter/src/main/res/values-iw/strings.xml
new file mode 100644
index 0000000..72ebc9c
--- /dev/null
+++ b/mediarouter/src/main/res/values-iw/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"מערכת"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"מכשירים"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"‏לחצן הפעלת Cast"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"‏לחצן הפעלת Cast. מנותק"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"‏לחצן הפעלת Cast. מתחבר"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"‏לחצן הפעלת Cast. מחובר"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"העברה אל"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"מחפש מכשירים"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ניתוק"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"עצירת העברה"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"סגירה"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"הפעלה"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"השהיה"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"הפסקה"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"הרחבה"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"כיווץ"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"עטיפת אלבום"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"מחוון עוצמה"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"לא נבחרה מדיה"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"אין מידע זמין"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"העברת מסך מתבצעת"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ja/strings.xml b/mediarouter/src/main/res/values-ja/strings.xml
new file mode 100644
index 0000000..b33ffb9
--- /dev/null
+++ b/mediarouter/src/main/res/values-ja/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"システム"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"端末"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"キャスト アイコン"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"キャスト アイコン。接続解除済み"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"キャスト アイコン。接続中"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"キャスト アイコン。接続済み"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"キャスト先"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"端末を検索しています"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"接続を解除"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"キャストを停止"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"閉じる"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"再生"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"一時停止"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"停止"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"展開"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"折りたたむ"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"アルバムアート"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"音量スライダー"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"メディアを選択していません"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"情報がありません"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"画面をキャストしています"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ka/strings.xml b/mediarouter/src/main/res/values-ka/strings.xml
new file mode 100644
index 0000000..446a9e0
--- /dev/null
+++ b/mediarouter/src/main/res/values-ka/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"სისტემა"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"მოწყობილობები"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"ტრანსლირების ღილაკი"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"ტრანსლირების ღილაკი. გათიშული"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"ტრანსლირების ღილაკი. მიმდინარეობს დაკავშირება"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"ტრანსლირების ღილაკი. დაკავშირებული"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"ტრანსლირება:"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"მოწყობილობების მოძიება..."</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"გათიშვა"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"ტრანსლირების შეწყვეტა"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"დახურვა"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"დაკვრა"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"პაუზა"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"შეწყვეტა"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"გაშლა"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"ჩაკეცვა"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"ალბომის გარეკანი"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"ხმის სლაიდერი"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"მედია არჩეული არ არის"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"ინფორმაცია არ არის ხელმისაწვდომი"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"მიმდინარეობს ეკრანის ტრანსლირება"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-kk/strings.xml b/mediarouter/src/main/res/values-kk/strings.xml
new file mode 100644
index 0000000..d512ff9
--- /dev/null
+++ b/mediarouter/src/main/res/values-kk/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Жүйе"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Құрылғылар"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Трансляциялау түймесі"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Трансляциялау түймесі. Ажыратылды"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Трансляциялау түймесі. Қосылуда"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Трансляциялау түймесі. Қосылды"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Трансляция:"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Құрылғылар ізделуде"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Ажырату"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Трансляцияны тоқтату"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Жабу"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Ойнату"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Кідірту"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Тоқтату"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Жаю"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Жию"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Альбомның мұқабасы"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Дыбыс деңгейінің жүгірткісі"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Ешқандай медиафайл таңдалмаған"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Қолжетімді ақпарат жоқ"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Экранды трансляциялау"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-km/strings.xml b/mediarouter/src/main/res/values-km/strings.xml
new file mode 100644
index 0000000..9303a1b
--- /dev/null
+++ b/mediarouter/src/main/res/values-km/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"ប្រព័ន្ធ"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"ឧបករណ៍"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"ប៊ូតុង​បញ្ជូន"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"ប៊ូតុង​បញ្ជូន។ បាន​ផ្តាច់"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"ប៊ូតុង​បញ្ជូន។ កំពុង​ភ្ជាប់"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"ប៊ូតុង​បញ្ជូន។ បាន​ភ្ជាប់​ហើយ"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"បញ្ជូន​ទៅ"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"កំពុង​ស្វែងរក​ឧបករណ៍"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ផ្ដាច់"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"បញ្ឈប់​ការបញ្ជូន"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"បិទ"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"ចាក់"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"ផ្អាក"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"បញ្ឈប់"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"ពង្រីក"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"បង្រួម"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"រូបភាព​សិល្បៈ​ក្រប​អាល់ប៊ុម"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"របារកម្រិតសំឡេង"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"មិនបាន​ជ្រើសរើស​មេឌៀ​ទេ"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"មិនមានព័ត៌មានទេ"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"កំពុង​បញ្ជូន​អេក្រង់"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-kn/strings.xml b/mediarouter/src/main/res/values-kn/strings.xml
new file mode 100644
index 0000000..f495017
--- /dev/null
+++ b/mediarouter/src/main/res/values-kn/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"ಸಿಸ್ಟಂ"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"ಸಾಧನಗಳು"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"ಬಿತ್ತರಿಸು ಬಟನ್‌"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"ಬಿತ್ತರಿಸು ಬಟನ್‌. ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"ಬಿತ್ತರಿಸು ಬಟನ್‌. ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"ಬಿತ್ತರಿಸು ಬಟನ್‌. ಸಂಪರ್ಕಿತಗೊಂಡಿದೆ"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"ಇದಕ್ಕೆ ಬಿತ್ತರಿಸಿ"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"ಸಾಧನಗಳನ್ನು ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿ"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"ಮುಚ್ಚಿ"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"ಪ್ಲೇ"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"ವಿರಾಮ"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"ನಿಲ್ಲಿಸಿ"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"ಹಿಗ್ಗಿಸಿ"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"ಕುಗ್ಗಿಸಿ"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"ಆಲ್ಬಮ್ ಕಲೆ"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"ವಾಲ್ಯೂಮ್ ಸ್ಲೈಡರ್"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"ಯಾವುದೇ ಮಾಧ್ಯಮ ಆಯ್ಕೆ ಮಾಡಿಲ್ಲ"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"ಯಾವುದೇ ಮಾಹಿತಿ ಲಭ್ಯವಿಲ್ಲ"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"ಪರದೆಯನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ko/strings.xml b/mediarouter/src/main/res/values-ko/strings.xml
new file mode 100644
index 0000000..178fab0
--- /dev/null
+++ b/mediarouter/src/main/res/values-ko/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"시스템"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"기기"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"전송 버튼"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"전송 버튼. 연결 해제됨"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"전송 버튼. 연결 중"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"전송 버튼. 연결됨"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"전송 대상"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"기기를 찾는 중"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"연결 끊기"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"전송 중지"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"닫기"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"재생"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"일시중지"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"중지"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"확대"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"접기"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"앨범아트"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"볼륨 슬라이더"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"선택된 미디어 없음"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"사용할 수 있는 정보 없음"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"화면 전송 중"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ky/strings.xml b/mediarouter/src/main/res/values-ky/strings.xml
new file mode 100644
index 0000000..100e5a5
--- /dev/null
+++ b/mediarouter/src/main/res/values-ky/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Тутум"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Түзмөктөр"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Тышкы экранга чыгаруу баскычы"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Тышкы экранга чыгаруу баскычы. Түзмөк ажырап турат."</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Тышкы экранга чыгаруу баскычы. Түзмөк туташууда"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Тышкы экранга чыгаруу баскычы. Түзмөк туташып турат"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Түзмөккө чыгаруу"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Түзмөктөр изделүүдө"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Ажыратуу"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Тышкы экранга чыгарууну токтотуу"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Жабуу"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Угуу"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Тыным"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Токтотуу"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Жайып көрсөтүү"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Жыйыштыруу"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Альбом мукабасы"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Үндү катуулатуучу сыдырма"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Эч нерсе тандалган жок"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Эч маалымат жок"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Тышкы экранга чыгарылууда"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-lo/strings.xml b/mediarouter/src/main/res/values-lo/strings.xml
new file mode 100644
index 0000000..79bd210
--- /dev/null
+++ b/mediarouter/src/main/res/values-lo/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"ລະບົບ"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"ອຸປະກອນ"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"ປຸ່ມສົ່ງສັນຍານ"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"ປຸ່ມສົ່ງສັນຍານ. ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"ປຸ່ມສົ່ງສັນຍານ. ກຳລັງເຊື່ອມຕໍ່"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"ປຸ່ມສົ່ງສັນຍານ. ເຊື່ອມຕໍ່ແລ້ວ"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"ສົ່ງສັນຍານໄປທີ່"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"ກຳລັງຊອກຫາອຸປະກອນ"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ຕັດການເຊື່ອມຕໍ່"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"ຢຸດການສົ່ງສັນຍານ"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"ປິດ"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"ຫຼິ້ນ"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"ຢຸດຊົ່ວຄາວ"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"ຢຸດ"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"ຂະຫຍາຍ"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"ຫຍໍ້ລົງ"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"ໜ້າປົກອະລະບໍ້າ"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"ຕົວປັບລະດັບສຽງ"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"ບໍ່ໄດ້ເລືອກສື່ໃດ"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"ບໍ່ມີຂໍ້ມູນ"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"ກຳລັງສົ່ງສັນຍານພາບ"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-lt/strings.xml b/mediarouter/src/main/res/values-lt/strings.xml
new file mode 100644
index 0000000..6f1ce9f
--- /dev/null
+++ b/mediarouter/src/main/res/values-lt/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Įrenginiai"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Perdavimo mygtukas"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Perdavimo mygtukas. Atsijungta"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Perdavimo mygtukas. Prisijungiama"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Perdavimo mygtukas. Prisijungta"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Perduoti į"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Randami įrenginiai"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Atsijungti"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Sustabdyti perdavimą"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Uždaryti"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Leisti"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pristabdyti"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Sustabdyti"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Išskleisti"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Sutraukti"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albumo viršelis"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Garsumo šliaužiklis"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nepasirinkta jokios medijos"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Informacija nepasiekiama"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Perduodamas ekranas"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-lv/strings.xml b/mediarouter/src/main/res/values-lv/strings.xml
new file mode 100644
index 0000000..56432f8
--- /dev/null
+++ b/mediarouter/src/main/res/values-lv/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistēma"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Ierīces"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Apraides poga"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Apraides poga. Savienojums pārtraukts."</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Apraides poga. Notiek savienojuma izveide."</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Apraides poga. Savienojums izveidots."</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Apraides veikšana uz ierīci"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Ierīču meklēšana"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Atvienot"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Apturēt apraidi"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Aizvērt"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Atskaņot"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pauzēt"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Apturēt"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Izvērst"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Sakļaut"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albuma vāciņš"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Skaļuma slīdnis"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nav atlasīts multivides saturs"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nav informācijas"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Notiek ekrāna apraide"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-mk/strings.xml b/mediarouter/src/main/res/values-mk/strings.xml
new file mode 100644
index 0000000..e4572c5
--- /dev/null
+++ b/mediarouter/src/main/res/values-mk/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Систем"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Уреди"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Копче за Cast"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Копче за Cast. Исклучено"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Копче за Cast. Се поврзува"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Копче за Cast. Поврзано"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Емитување на"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Се бараат уреди"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Исклучи"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Сопри со емитување"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Затвори"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Пушти"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Паузирај"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Сопри"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Прошири"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Собери"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Корица на албум"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Лизгач за јачина на звук"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Не се избрани аудиовизуелни датотеки"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Нема достапни информации"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Се емитува екран"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ml/strings.xml b/mediarouter/src/main/res/values-ml/strings.xml
new file mode 100644
index 0000000..d7c987b
--- /dev/null
+++ b/mediarouter/src/main/res/values-ml/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"സിസ്റ്റം"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"ഉപകരണങ്ങൾ"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"കാസ്റ്റ് ബട്ടൺ"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"കാസ്റ്റ് ബട്ടൺ. വിച്ഛേദിച്ചു"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"കാസ്‌റ്റ് ബട്ടൺ. കണക്‌റ്റ് ചെയ്യുന്നു"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"കാസ്റ്റ് ബട്ടൺ. കണക്‌റ്റ് ചെയ്തു"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"ഇതിലേക്ക് കാസ്‌റ്റ് ചെയ്യുക"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"ഉപകരണങ്ങൾ കണ്ടെത്തുന്നു"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"വിച്ഛേദിക്കുക"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"കാസ്റ്റ് ചെയ്യുന്നത് നിർത്തുക"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"അവസാനിപ്പിക്കുക"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"പ്ലേ ചെയ്യുക"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"താൽക്കാലികമായി നിർത്തുക"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"നിര്‍ത്തുക"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"വികസിപ്പിക്കുക"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"ചുരുക്കുക"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"ആൽബം ആർട്ട്"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"ശബ്‌ദ സ്ലൈഡർ"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"മീഡിയയൊന്നും തിരഞ്ഞെടുത്തിട്ടില്ല"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"വിവരങ്ങളൊന്നും ലഭ്യമല്ല"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"സ്‌ക്രീൻ കാസ്‌റ്റ് ചെയ്യുന്നു"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-mn/strings.xml b/mediarouter/src/main/res/values-mn/strings.xml
new file mode 100644
index 0000000..9f03518
--- /dev/null
+++ b/mediarouter/src/main/res/values-mn/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Систем"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Төхөөрөмж"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Дамжуулах товч"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Дамжуулах товч. Салсан"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Дамжуулах товч. Холбогдож байна"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Дамжуулах товч. Холбогдсон"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Дамжуулах"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Төхөөрөмжийг хайж байна"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Салгах"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Дамжуулахыг зогсоох"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Хаах"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Тоглуулах"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Түр зогсоох"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Зогсоох"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Дэлгэх"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Хумих"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Цомгийн зураг"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Дууны түвшин тааруулагч"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Ямар ч медиа сонгоогүй байна"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Мэдээлэл байхгүй байна"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Дэлгэцийг дамжуулж байна"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-mr/strings.xml b/mediarouter/src/main/res/values-mr/strings.xml
new file mode 100644
index 0000000..f3ccbb9
--- /dev/null
+++ b/mediarouter/src/main/res/values-mr/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"सिस्टम"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"डिव्हाइस"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"कास्ट बटण"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"कास्ट बटण. डिस्कनेक्ट केले"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"कास्ट बटण. कनेक्ट करत आहे"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"कास्ट बटण. कनेक्ट केले"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"यावर कास्ट करा"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"डिव्हाइस शोधत आहे"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"‍डिस्कनेक्ट करा"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"कास्ट करणे थांबवा"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"बंद"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"खेळा"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"विराम द्या"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"थांबा"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"विस्तार करा"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"कोलॅप्स"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"अल्बम कला"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"व्हॉल्यूम स्लायडर"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"मीडिया निवडला नाही"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"कोणतीही माहिती उपलब्ध नाही"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"स्क्रीन कास्‍ट करत आहे"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ms/strings.xml b/mediarouter/src/main/res/values-ms/strings.xml
new file mode 100644
index 0000000..5096704
--- /dev/null
+++ b/mediarouter/src/main/res/values-ms/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Peranti"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Butang hantar"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Butang hantar. Sambungan diputuskan"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Butang hantar. Menyambung"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Butang hantar. Disambungkan"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Hantar ke"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Mencari peranti"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Putuskan sambungan"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Berhenti menghantar"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Tutup"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Main"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Jeda"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Berhenti"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Kembangkan"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Runtuhkan"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Seni album"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Peluncur kelantangan"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Tiada media yang dipilih"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Maklumat tidak tersedia"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Menghantar skrin"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-my/strings.xml b/mediarouter/src/main/res/values-my/strings.xml
new file mode 100644
index 0000000..5e843a0
--- /dev/null
+++ b/mediarouter/src/main/res/values-my/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"စနစ်"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"စက်များ"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"ကာစ်ခလုတ်"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"ကာစ်ခလုတ်။ ချိတ်ဆက်မထားပါ"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"ကာစ်ခလုတ်။ ချိတ်ဆက်နေသည်"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"ကာစ်ခလုတ်။ ချိတ်ဆက်ထားသည်"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"ဤစက်သို့ ကာစ်လုပ်ရန်"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"စက်များ ရှာနေသည်"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ချိတ်ဆက်မှု ဖြုတ်ရန်"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"ကာစ်လုပ်ခြင်းကို ရပ်ရန်"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"ပိတ်ရန်"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"ဖွင့်ရန်"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"ခဏရပ်ရန်"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"ရပ်ရန်"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"ချဲ့ရန်"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"လျှော့ပြရန်"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"အယ်လ်ဘမ်ပုံ"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"အသံအတိုးအကျယ်ချိန်သည့် ဆလိုက်ဒါ"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"မီဒီယာ ရွေးမထားပါ"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"အချက်အလက် မရရှိနိုင်ပါ"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"ကာစ်တ်လုပ်သည့် မျက်နှာပြင်"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-nb/strings.xml b/mediarouter/src/main/res/values-nb/strings.xml
new file mode 100644
index 0000000..487b9d5
--- /dev/null
+++ b/mediarouter/src/main/res/values-nb/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Enheter"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast-ikonet"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast-ikonet. Frakoblet"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast-ikonet. Kobler til"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast-ikonet. Tilkoblet"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Cast til"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Finner enheter"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Koble fra"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Stopp castingen"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Lukk"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Spill av"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Sett på pause"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stopp"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Vis"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Skjul"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albumgrafikk"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Glidebryter for volum"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Ingen medier er valgt"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Ingen informasjon er tilgjengelig"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Caster skjermen"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ne/strings.xml b/mediarouter/src/main/res/values-ne/strings.xml
new file mode 100644
index 0000000..8a13ac7
--- /dev/null
+++ b/mediarouter/src/main/res/values-ne/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"प्रणाली"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"यन्त्रहरू"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast बटन"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast बटन। जडान विच्छेद गरियो"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast बटन। जडान गरिँदै छ"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast बटन। जडान गरियो"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"यसमा Cast गर्नुहोस्"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"यन्त्रहरू पत्ता लगाइँदै छ"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"विच्छेद गर्नुहोस्"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Cast गर्न छाड्नुहोस्"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"बन्द गर्नुहोस्"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"प्ले गर्नुहोस्"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"पज गर्नुहोस्"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"रोक्नुहोस्"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"विस्तृत गर्नुहोस्"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"संक्षिप्त गर्नुहोस्"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"एल्बम आर्ट"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"भोल्युमको स्लाइडर"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"कुनै पनि मिडिया चयन गरिएन"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"कुनै पनि जानकारी उपलब्ध छैन"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"स्क्रिन Cast गरिँदै छ"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-nl/strings.xml b/mediarouter/src/main/res/values-nl/strings.xml
new file mode 100644
index 0000000..eb19187
--- /dev/null
+++ b/mediarouter/src/main/res/values-nl/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Systeem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Apparaten"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast-knop"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast-icoon. Verbinding verbroken"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast-icoon. Verbinding maken"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast-icoon. Verbonden"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Casten naar"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Apparaten zoeken"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Loskoppelen"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Casten stoppen"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Sluiten"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Afspelen"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pauzeren"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stoppen"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Uitvouwen"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Samenvouwen"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albumhoes"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Volumeschuifregelaar"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Geen media geselecteerd"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Geen informatie beschikbaar"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Scherm casten"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-pa/strings.xml b/mediarouter/src/main/res/values-pa/strings.xml
new file mode 100644
index 0000000..5092ae0
--- /dev/null
+++ b/mediarouter/src/main/res/values-pa/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"ਸਿਸਟਮ"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"ਡੀਵਾਈਸ"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"\'ਕਾਸਟ ਕਰੋ\' ਬਟਨ"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"\'ਕਾਸਟ ਕਰੋ\' ਬਟਨ। ਡਿਸਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"\'ਕਾਸਟ ਕਰੋ\' ਬਟਨ। ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"\'ਕਾਸਟ ਕਰੋ\' ਬਟਨ। ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"ਏਥੇ ਕਾਸਟ ਕਰੋ"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"ਡੀਵਾਈਸ ਲੱਭੇ ਜਾ ਰਹੇ ਹਨ"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"ਬੰਦ ਕਰੋ"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"ਚਲਾਓ"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"ਰੋਕੋ"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"ਬੰਦ ਕਰੋ"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"ਵਿਸਤਾਰ ਕਰੋ"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"ਸਮੇਟੋ"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"ਐਲਬਮ ਕਲਾ"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"ਵੌਲਯੂਮ ਸਲਾਈਡਰ"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ ਚੁਣਿਆ ਗਿਆ"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"ਕੋਈ ਜਾਣਕਾਰੀ ਉਪਲਬਧ ਨਹੀਂ"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"ਸਕ੍ਰੀਨ \'ਤੇ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-pl/strings.xml b/mediarouter/src/main/res/values-pl/strings.xml
new file mode 100644
index 0000000..6f52faf
--- /dev/null
+++ b/mediarouter/src/main/res/values-pl/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Urządzenia"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Przycisk Cast"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Przycisk Cast. Rozłączono"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Przycisk Cast. Łączę"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Przycisk Cast. Połączono"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Przesyłaj na"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Znajdowanie urządzeń"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Odłącz"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Zatrzymaj przesyłanie"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Zamknij"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Odtwórz"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Wstrzymaj"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Zatrzymaj"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Rozwiń"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Zwiń"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Okładka albumu"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Suwak głośności"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nie wybrano multimediów"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Brak informacji"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Przesyłanie ekranu"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-pt-rBR/strings.xml b/mediarouter/src/main/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..213424a
--- /dev/null
+++ b/mediarouter/src/main/res/values-pt-rBR/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Dispositivos"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Botão \"Transmitir\""</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Botão \"Transmitir\". Desconectado"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Botão \"Transmitir\". Conectando"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Botão \"Transmitir\". Conectado"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Transmitir para"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Localizando dispositivos"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Desconectar"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Parar transmissão"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Fechar"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Reproduzir"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pausar"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Parar"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Expandir"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Recolher"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Arte do álbum"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Controle deslizante de volume"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nenhuma mídia selecionada"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nenhuma informação disponível"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Transmitindo tela"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-pt-rPT/strings.xml b/mediarouter/src/main/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..4780144
--- /dev/null
+++ b/mediarouter/src/main/res/values-pt-rPT/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Dispositivos"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Botão Transmitir"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Botão Transmitir. Desligado."</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Botão Transmitir. A ligar..."</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Botão Transmitir. Ligado"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Transmitir para"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"A localizar dispositivos..."</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Desligar"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Parar transmissão"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Fechar"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Reproduzir"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Interromper"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Parar"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Expandir"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Reduzir"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Imagem do álbum"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Controlo de deslize do volume"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nenhum conteúdo multimédia selecionado."</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nenhuma informação disponível."</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"A transmitir o ecrã..."</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-pt/strings.xml b/mediarouter/src/main/res/values-pt/strings.xml
new file mode 100644
index 0000000..213424a
--- /dev/null
+++ b/mediarouter/src/main/res/values-pt/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistema"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Dispositivos"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Botão \"Transmitir\""</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Botão \"Transmitir\". Desconectado"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Botão \"Transmitir\". Conectando"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Botão \"Transmitir\". Conectado"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Transmitir para"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Localizando dispositivos"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Desconectar"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Parar transmissão"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Fechar"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Reproduzir"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pausar"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Parar"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Expandir"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Recolher"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Arte do álbum"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Controle deslizante de volume"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nenhuma mídia selecionada"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nenhuma informação disponível"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Transmitindo tela"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ro/strings.xml b/mediarouter/src/main/res/values-ro/strings.xml
new file mode 100644
index 0000000..82660fc
--- /dev/null
+++ b/mediarouter/src/main/res/values-ro/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Dispozitive"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Butonul de proiecție"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Butonul de proiecție. Deconectat"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Butonul de proiecție. Se conectează"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Butonul de proiecție. Conectat"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Proiectați pe"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Se caută dispozitive"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Deconectați"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Nu mai proiectați"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Închideți"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Redați"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Întrerupeți"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Opriți"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Extindeți"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Restrângeți"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Grafica albumului"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Glisor pentru volum"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Niciun conținut media selectat"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nu sunt disponibile informații"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Se proiectează ecranul"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ru/strings.xml b/mediarouter/src/main/res/values-ru/strings.xml
new file mode 100644
index 0000000..b3e5e16
--- /dev/null
+++ b/mediarouter/src/main/res/values-ru/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Система"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Устройства"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Кнопка Google Cast"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Кнопка трансляции. Устройство отключено."</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Кнопка трансляции. Устройство подключается."</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Кнопка трансляции. Устройство подключено."</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Транслировать на устройство"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Поиск устройств…"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Отключить"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Прекратить трансляцию"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Закрыть"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Воспроизвести"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Пауза"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Остановить"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Развернуть"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Скрыть"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Обложка"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Регулятор громкости"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Контент не выбран"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Данных нет"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Подключение к удаленному монитору"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-si/strings.xml b/mediarouter/src/main/res/values-si/strings.xml
new file mode 100644
index 0000000..044f1a3
--- /dev/null
+++ b/mediarouter/src/main/res/values-si/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"පද්ධතිය"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"උපාංග"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"විකාශ බොත්තම"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"විකාශ බොත්තම. විසන්ධි කරන ලදී"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"විකාශ බොත්තම සම්බන්ධ කරමින්"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"විකාශ බොත්තම සම්බන්ධ කරන ලදී"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"විකාශය"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"උපාංග සෙවීම"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"විසන්ධි කරන්න"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"විකාශය නවතන්න"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"වසන්න"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"ධාවනය කරන්න"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"විරාම කරන්න"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"නවත්වන්න"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"දිග හරින්න"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"හකුළන්න"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"ඇල්බම කලාව"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"හඬ පරිමා ස්ලයිඩරය"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"මාධ්‍ය තෝරා නැත"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"ලබා ගත හැකි තොරතුරු නොමැත"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"විකාශ තිරය"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-sk/strings.xml b/mediarouter/src/main/res/values-sk/strings.xml
new file mode 100644
index 0000000..bb81d01
--- /dev/null
+++ b/mediarouter/src/main/res/values-sk/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Systém"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Zariadenia"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Tlačidlo prenosu"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Tlačidlo prenosu. Odpojené"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Tlačidlo prenosu. Pripája sa"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Tlačidlo prenosu. Pripojené"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Prenos do zariadenia"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Hľadajú sa zariadenia"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Odpojiť"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Zastaviť prenos"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Zavrieť"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Prehrať"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pozastaviť"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Ukončiť"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Rozbaliť"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Zbaliť"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Obrázok albumu"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Posúvač hlasitosti"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nie sú vybrané žiadne médiá"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nie sú k dispozícii žiadne informácie"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Prenáša sa obrazovka"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-sl/strings.xml b/mediarouter/src/main/res/values-sl/strings.xml
new file mode 100644
index 0000000..2b0eeb8
--- /dev/null
+++ b/mediarouter/src/main/res/values-sl/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Naprave"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Gumb za predvajanje"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Gumb za predvajanje. Povezava je prekinjena."</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Gumb za predvajanje. Vzpostavljanje povezave."</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Gumb za predvajanje. Povezava je vzpostavljena."</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Predvajanje prek:"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Iskanje naprav"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Prekini povezavo"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Ustavi predvajanje"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Zapri"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Predvajaj"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Začasno ustavi"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Ustavi"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Razširi"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Strni"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Naslovnica albuma"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Drsnik za glasnost"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Predstavnost ni izbrana"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Ni podatkov"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Predvajanje vsebine zaslona"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-sq/strings.xml b/mediarouter/src/main/res/values-sq/strings.xml
new file mode 100644
index 0000000..f172212
--- /dev/null
+++ b/mediarouter/src/main/res/values-sq/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistemi"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Pajisjet"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Butoni i transmetimit"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Butoni i transmetimit. Je i shkëputur"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Butoni i transmetimit. Po lidhet"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Butoni i transmetimit. Je i lidhur"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Transmeto te"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Po kërkon pajisje"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Shkëput"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Ndalo transmetimin"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Mbyll"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Luaj"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pauzë"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Ndalo"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Zgjero"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Palos"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Kopertina e albumit"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Rrëshqitësi i volumit"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Nuk është zgjedhur asnjë media"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Nuk jepet asnjë informacion"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Po transmeton ekranin"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-sr/strings.xml b/mediarouter/src/main/res/values-sr/strings.xml
new file mode 100644
index 0000000..e5d3577
--- /dev/null
+++ b/mediarouter/src/main/res/values-sr/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Систем"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Уређаји"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Дугме Пребаци"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Дугме Пребаци. Веза је прекинута"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Дугме Пребаци. Повезује се"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Дугме Пребаци. Повезан је"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Пребаците на"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Траже се уређаји"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Прекини везу"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Заустави пребацивање"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Затвори"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Пусти"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Паузирај"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Заустави"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Прошири"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Скупи"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Омот албума"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Клизач за јачину звука"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Нема изабраних медија"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Нема доступних информација"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Пребацује се екран"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-sv/strings.xml b/mediarouter/src/main/res/values-sv/strings.xml
new file mode 100644
index 0000000..3ed8212
--- /dev/null
+++ b/mediarouter/src/main/res/values-sv/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Enheter"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast-knappen"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast-knappen. Frånkopplad"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast-knappen. Ansluter"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast-knappen. Ansluten"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Casta till"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Letar efter enheter"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Koppla från"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Sluta casta"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Stäng"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Spela upp"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pausa"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Stoppa"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Utöka"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Komprimera"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Skivomslag"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Volymreglage"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Ingen media har valts"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Det finns ingen information"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Skärmen castas"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-sw/strings.xml b/mediarouter/src/main/res/values-sw/strings.xml
new file mode 100644
index 0000000..2a7af85
--- /dev/null
+++ b/mediarouter/src/main/res/values-sw/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Mfumo"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Vifaa"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Kitufe cha kutuma"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Kitufe cha kutuma. Kimeondolewa"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Kitufe cha kutuma. Kinaunganishwa"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Kitufe cha kutuma. Kimeunganishwa"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Tuma kwenye"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Inatafuta vifaa"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Ondoa"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Acha kutuma"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Funga"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Cheza"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Sitisha"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Simamisha"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Panua"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Kunja"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Sanaa ya albamu"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Kidhibiti cha sauti"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Hakuna maudhui yaliyochaguliwa"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Hakuna maelezo yaliyopatikana"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Inatuma skrini"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ta/strings.xml b/mediarouter/src/main/res/values-ta/strings.xml
new file mode 100644
index 0000000..6b4f896
--- /dev/null
+++ b/mediarouter/src/main/res/values-ta/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"சிஸ்டம்"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"சாதனங்கள்"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"அலைபரப்பும் பட்டன்"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"அலைபரப்பும் பட்டன். துண்டிக்கப்பட்டது"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"அலைபரப்பும் பட்டன். இணைக்கிறது"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"அலைபரப்பும் பட்டன். இணைக்கப்பட்டது"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"இதற்கு அலைபரப்பு:"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"சாதனங்களைத் தேடுகிறது"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"துண்டி"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"அலைபரப்புவதை நிறுத்து"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"மூடுவதற்கான பட்டன்"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"இயக்குவதற்கான பட்டன்"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"இடைநிறுத்துவதற்கான பட்டன்"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"நிறுத்துவதற்கான பட்டன்"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"விரிவாக்குவதற்கான பட்டன்"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"சுருக்குவதற்கான பட்டன்"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"ஆல்பம் ஆர்ட்"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"ஒலியளவு ஸ்லைடர்"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"மீடியா எதுவும் தேர்ந்தெடுக்கப்படவில்லை"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"தகவல் எதுவுமில்லை"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"திரையை அலைபரப்புகிறது"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-te/strings.xml b/mediarouter/src/main/res/values-te/strings.xml
new file mode 100644
index 0000000..0d4168f
--- /dev/null
+++ b/mediarouter/src/main/res/values-te/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"సిస్టమ్"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"పరికరాలు"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Cast బటన్"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Cast బటన్. డిస్‌కనెక్ట్ చేయబడింది"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Cast బటన్. కనెక్ట్ చేస్తోంది"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Cast బటన్. కనెక్ట్ చేయబడింది"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"దీనికి ప్రసారం చేయండి"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"పరికరాలను కనుగొంటోంది"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"డిస్‌కనెక్ట్ చేయి"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"ప్రసారాన్ని ఆపివేయి"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"మూసివేయి"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"ప్లే చేయి"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"పాజ్ చేయి"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"ఆపివేయి"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"విస్తరించు"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"కుదించు"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"ఆల్బమ్ ఆర్ట్"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"వాల్యూమ్ స్లయిడర్"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"మీడియా ఏదీ ఎంచుకోలేదు"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"సమాచారం అందుబాటులో లేదు"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"స్క్రీన్‌ను ప్రసారం చేస్తోంది"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-th/strings.xml b/mediarouter/src/main/res/values-th/strings.xml
new file mode 100644
index 0000000..b360779
--- /dev/null
+++ b/mediarouter/src/main/res/values-th/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"ระบบ"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"อุปกรณ์"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"ปุ่ม \"แคสต์\""</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"ปุ่ม \"แคสต์\" ยกเลิกการเชื่อมต่อแล้ว"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"ปุ่ม \"แคสต์\" กำลังเชื่อมต่อ"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"ปุ่ม \"แคสต์\" เชื่อมต่อแล้ว"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"แคสต์ไปยัง"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"กำลังค้นหาอุปกรณ์"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"ยกเลิกการเชื่อมต่อ"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"หยุดแคสต์"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"ปิด"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"เล่น"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"หยุดชั่วคราว"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"หยุด"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"ขยาย"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"ยุบ"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"ปกอัลบั้ม"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"แถบเลื่อนปรับระดับเสียง"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"ไม่ได้เลือกสื่อไว้"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"ไม่มีข้อมูล"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"กำลังแคสต์หน้าจอ"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-tl/strings.xml b/mediarouter/src/main/res/values-tl/strings.xml
new file mode 100644
index 0000000..4d21125
--- /dev/null
+++ b/mediarouter/src/main/res/values-tl/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"System"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Mga Device"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Button na I-cast"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Button na I-cast. Nadiskonekta"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Button na I-cast. Kumokonekta"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Button na I-cast. Nakakonekta"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"I-cast sa"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Naghahanap ng mga device"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Idiskonekta"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Ihinto ang pag-cast"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Isara"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"I-play"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"I-pause"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Ihinto"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"I-expand"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"I-collapse"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Album art"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Slider ng volume"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Walang napiling media"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Walang available na impormasyon"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Ikina-cast ang screen"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-tr/strings.xml b/mediarouter/src/main/res/values-tr/strings.xml
new file mode 100644
index 0000000..e44f443
--- /dev/null
+++ b/mediarouter/src/main/res/values-tr/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Sistem"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Cihazlar"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Yayınla düğmesi"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Yayınla düğmesi. Bağlantı kesildi"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Yayınla düğmesi. Bağlanıyor"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Yayınla düğmesi. Bağlandı"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Şuraya yayınla:"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Cihazlar bulunuyor"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Bağlantıyı kes"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Yayını durdur"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Kapat"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Oynat"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Duraklat"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Durdur"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Genişlet"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Daralt"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albüm kapağı"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Ses düzeyi kaydırma çubuğu"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Medya seçilmedi"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Bilgi yok"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Ekran yayınlanıyor"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-uk/strings.xml b/mediarouter/src/main/res/values-uk/strings.xml
new file mode 100644
index 0000000..28e09bd
--- /dev/null
+++ b/mediarouter/src/main/res/values-uk/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Система"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Пристрої"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Кнопка трансляції"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Кнопка трансляції. Від’єднано"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Кнопка трансляції. Під’єднання"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Кнопка трансляції. Під’єднано"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Транслювати на"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Пошук пристроїв"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Від’єднати"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Припинити трансляцію"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Закрити"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Відтворити"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Призупинити"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Припинити"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Розгорнути"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Згорнути"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Обкладинка альбому"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Повзунок гучності"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Не вибрано медіа"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Немає даних"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Трансляція екрана"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-ur/strings.xml b/mediarouter/src/main/res/values-ur/strings.xml
new file mode 100644
index 0000000..8c09830
--- /dev/null
+++ b/mediarouter/src/main/res/values-ur/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"سسٹم"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"آلات"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"کاسٹ کرنے کا بٹن"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"کاسٹ کرنے کا بٹن۔ غیر منسلک ہے"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"کاسٹ کرنے کا بٹن۔ منسلک ہو رہا ہے"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"کاسٹ کرنے کا بٹن۔ منسلک ہے"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"اس میں کاسٹ کریں"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"آلات تلاش کئے جا رہے ہیں"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"غیر منسلک کریں"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"کاسٹ کرنا بند کریں"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"بند کریں"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"چلائیں"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"موقوف کریں"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"روکیں"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"پھیلائیں"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"سکیڑیں"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"البم آرٹ"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"والیوم سلائیڈر"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"کوئی میڈیا منتخب نہیں ہے"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"کوئی معلومات دستیاب نہیں"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"اسکرین کاسٹ ہو رہی ہے"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-uz/strings.xml b/mediarouter/src/main/res/values-uz/strings.xml
index 0c6fbf1..2eadc9b 100644
--- a/mediarouter/src/main/res/values-uz/strings.xml
+++ b/mediarouter/src/main/res/values-uz/strings.xml
@@ -16,25 +16,25 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mr_system_route_name" msgid="3117964881088969586">"Tizim"</string>
-    <string name="mr_user_route_category_name" msgid="8236416097133080726">"Qurilmalar"</string>
-    <string name="mr_button_content_description" msgid="1685185767093348095">"Translatsiya tugmasi"</string>
-    <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Translatsiya tugmasi. Uzildi"</string>
-    <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Translatsiya tugmasi. Ulanmoqda"</string>
-    <string name="mr_cast_button_connected" msgid="1350095112462806159">"Translatsiya tugmasi. Ulandi"</string>
-    <string name="mr_chooser_title" msgid="7548226170787476564">"Bunga translatsiya qilish:"</string>
-    <string name="mr_chooser_searching" msgid="5504553798429329689">"Qurilmalarni topish"</string>
-    <string name="mr_controller_disconnect" msgid="1370654436555555647">"Uzish"</string>
-    <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Translatsiyani to‘xtatish"</string>
-    <string name="mr_controller_close_description" msgid="5468775621814500662">"Yopish"</string>
-    <string name="mr_controller_play" msgid="4443315438268112801">"Ijro"</string>
-    <string name="mr_controller_pause" msgid="4701315813294065305">"Pauza"</string>
-    <string name="mr_controller_stop" msgid="5106056093749454009">"To‘xtatish"</string>
-    <string name="mr_controller_expand_group" msgid="2422682304043876468">"Yoyish"</string>
-    <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Yig‘ish"</string>
-    <string name="mr_controller_album_art" msgid="5813284753012893250">"Albom muqovasi"</string>
-    <string name="mr_controller_volume_slider" msgid="691656961160498512">"Tovush balandligi slayderi"</string>
-    <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Multimedia tanlamagan"</string>
-    <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Ma’lumot yo‘q"</string>
-    <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Ekran namoyish qilinmoqda"</string>
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Tizim"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Qurilmalar"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Translatsiya qilish tugmasi"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Translatsiya tugmasi. Uzildi"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Translatsiya tugmasi. Ulanmoqda"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Translatsiya tugmasi. Ulandi"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Bunga translatsiya qilish:"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Qurilmalarni topish"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Uzish"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Translatsiyani to‘xtatish"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Yopish"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Ijro"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Pauza"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"To‘xtatish"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Yoyish"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Yig‘ish"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Albom muqovasi"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Tovush balandligi slayderi"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Multimedia tanlamagan"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Ma’lumot yo‘q"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Ekran namoyish qilinmoqda"</string>
 </resources>
diff --git a/mediarouter/src/main/res/values-vi/strings.xml b/mediarouter/src/main/res/values-vi/strings.xml
new file mode 100644
index 0000000..d0f7311
--- /dev/null
+++ b/mediarouter/src/main/res/values-vi/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Hệ thống"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Thiết bị"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Nút truyền"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Nút truyền. Đã ngắt kết nối"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Nút truyền. Đang kết nối"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Nút truyền. Đã kết nối"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Truyền tới"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Đang tìm thiết bị"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Ngắt kết nối"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Dừng truyền"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Đóng"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Phát"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Tạm dừng"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Dừng"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Mở rộng"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Thu gọn"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Ảnh bìa album"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Thanh trượt âm lượng"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Không có phương tiện nào được chọn"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Không có thông tin nào"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Đang truyền màn hình"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-zh-rCN/strings.xml b/mediarouter/src/main/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..140c817
--- /dev/null
+++ b/mediarouter/src/main/res/values-zh-rCN/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"系统"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"设备"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"投射按钮"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"投射按钮。已断开连接"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"投射按钮。正在连接"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"投射按钮。已连接"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"投射到"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"正在查找设备"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"断开连接"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"停止投射"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"关闭"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"播放"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"暂停"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"停止"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"展开"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"收起"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"专辑封面"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"音量滑块"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"未选择任何媒体内容"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"没有任何相关信息"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"正在投射屏幕"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-zh-rHK/strings.xml b/mediarouter/src/main/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..9318093
--- /dev/null
+++ b/mediarouter/src/main/res/values-zh-rHK/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"系統"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"裝置"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"投放按鈕"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"投放按鈕。解除咗連線"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"投放按鈕。連緊線"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"投放按鈕。連咗線"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"投放至"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"正在尋找裝置"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"解除連線"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"停止投放"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"閂"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"播放"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"暫停"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"停"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"展開"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"收合"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"專輯封面"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"音量滑桿"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"未選取任何媒體"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"沒有資料可以提供"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"正在投放畫面"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-zh-rTW/strings.xml b/mediarouter/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..bd2f9ad
--- /dev/null
+++ b/mediarouter/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"系統"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"裝置"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"投放按鈕"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"投放按鈕;已中斷連線"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"投放按鈕;連線中"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"投放按鈕;已連線"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"投放到"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"正在尋找裝置"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"中斷連線"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"停止投放"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"關閉"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"播放"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"暫停"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"停止"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"展開"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"收合"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"專輯封面"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"音量滑桿"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"未選取任何媒體"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"沒有可用的資訊"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"正在投放畫面"</string>
+</resources>
diff --git a/mediarouter/src/main/res/values-zu/strings.xml b/mediarouter/src/main/res/values-zu/strings.xml
new file mode 100644
index 0000000..e91293f
--- /dev/null
+++ b/mediarouter/src/main/res/values-zu/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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">
+    <string name="mr_system_route_name" msgid="6445173646164603280">"Isistimu"</string>
+    <string name="mr_user_route_category_name" msgid="8951247913519682277">"Amadivayisi"</string>
+    <string name="mr_button_content_description" msgid="6209940985205889239">"Inkinobho yokusakaza"</string>
+    <string name="mr_cast_button_disconnected" msgid="1214396433859225686">"Inkinobho yokusakaza. Kunqanyuliwe"</string>
+    <string name="mr_cast_button_connecting" msgid="7767160474954808770">"Inkinobho yokusakaza. Kuyaxhunywa"</string>
+    <string name="mr_cast_button_connected" msgid="7205934955575650355">"Inkinobho yokusakaza. Kuxhunyiwe"</string>
+    <string name="mr_chooser_title" msgid="1469819231928206099">"Sakaza ku-"</string>
+    <string name="mr_chooser_searching" msgid="7883700464756247478">"Ithola amadivayisi"</string>
+    <string name="mr_controller_disconnect" msgid="1224563715954797152">"Nqamula"</string>
+    <string name="mr_controller_stop_casting" msgid="6043110833085090960">"Misa ukusakaza"</string>
+    <string name="mr_controller_close_description" msgid="1404151965680505956">"Vala"</string>
+    <string name="mr_controller_play" msgid="2233159395781515552">"Dlala"</string>
+    <string name="mr_controller_pause" msgid="5465089322498973309">"Misa isikhashana"</string>
+    <string name="mr_controller_stop" msgid="6970507798830838731">"Misa"</string>
+    <string name="mr_controller_expand_group" msgid="6561849209271950311">"Nweba"</string>
+    <string name="mr_controller_collapse_group" msgid="5621264648958127139">"Goqa"</string>
+    <string name="mr_controller_album_art" msgid="8313236767081989488">"Ubuciko be-albhamu"</string>
+    <string name="mr_controller_volume_slider" msgid="390328956880221771">"Isilayida sevolumu"</string>
+    <string name="mr_controller_no_media_selected" msgid="5388112032574870059">"Ayikho imidiya ekhethiwe"</string>
+    <string name="mr_controller_no_info_available" msgid="942251150039480236">"Alukho ulwazi olutholakalayo"</string>
+    <string name="mr_controller_casting_screen" msgid="2406876321200529148">"Isikrini sokusakaza"</string>
+</resources>
diff --git a/paging/runtime/build.gradle b/paging/runtime/build.gradle
index dd9189c..8329c05 100644
--- a/paging/runtime/build.gradle
+++ b/paging/runtime/build.gradle
@@ -48,4 +48,5 @@
     inceptionYear = "2017"
     description = "Android Paging-Runtime"
     url = SupportLibraryExtension.ARCHITECTURE_URL
+    failOnUncheckedWarnings = false
 }
diff --git a/paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.java b/paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.java
index f30163d..0033665 100644
--- a/paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.java
+++ b/paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.java
@@ -150,7 +150,7 @@
     public AsyncPagedListDiffer(@NonNull RecyclerView.Adapter adapter,
             @NonNull DiffUtil.ItemCallback<T> diffCallback) {
         mUpdateCallback = new AdapterListUpdateCallback(adapter);
-        mConfig = new AsyncDifferConfig.Builder<T>(diffCallback).build();
+        mConfig = new AsyncDifferConfig.Builder<>(diffCallback).build();
     }
 
     @SuppressWarnings("WeakerAccess")
@@ -227,6 +227,7 @@
      *
      * @param pagedList The new PagedList.
      */
+    @SuppressWarnings("ReferenceEquality")
     public void submitList(final PagedList<T> pagedList) {
         if (pagedList != null) {
             if (mPagedList == null && mSnapshot == null) {
diff --git a/paging/rxjava2/build.gradle b/paging/rxjava2/build.gradle
index f4c5308..2fd8caf 100644
--- a/paging/rxjava2/build.gradle
+++ b/paging/rxjava2/build.gradle
@@ -45,4 +45,5 @@
     inceptionYear = "2018"
     description = "Android Paging RXJava2"
     url = SupportLibraryExtension.ARCHITECTURE_URL
+    failOnUncheckedWarnings = false
 }
diff --git a/preference/build.gradle b/preference/build.gradle
index b7c6872..8518300 100644
--- a/preference/build.gradle
+++ b/preference/build.gradle
@@ -55,4 +55,6 @@
     mavenGroup = LibraryGroups.PREFERENCE
     inceptionYear = "2015"
     description = "Android Support Preference v7"
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/preference/res/values-af/strings.xml b/preference/res/values-af/strings.xml
new file mode 100644
index 0000000..17c2037
--- /dev/null
+++ b/preference/res/values-af/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"AAN"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"AF"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Gevorderd"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-am/strings.xml b/preference/res/values-am/strings.xml
new file mode 100644
index 0000000..052425c
--- /dev/null
+++ b/preference/res/values-am/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"በርቷል"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ቅናሽ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"የላቀ"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>፣ <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ar/strings.xml b/preference/res/values-ar/strings.xml
new file mode 100644
index 0000000..1e5515d
--- /dev/null
+++ b/preference/res/values-ar/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"تفعيل"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"إيقاف"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"إعدادات متقدمة"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>، <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-az/strings.xml b/preference/res/values-az/strings.xml
index 1b208c8..978b862 100644
--- a/preference/res/values-az/strings.xml
+++ b/preference/res/values-az/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="v7_preference_on" msgid="27351710992731591">"AKTİV"</string>
-    <string name="v7_preference_off" msgid="5138405918326871307">"DEAKTİV"</string>
-    <string name="expand_button_title" msgid="1234962710353108940">"Qabaqcıl"</string>
-    <string name="summary_collapsed_preference_list" msgid="5190123168583152844">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+    <string name="v7_preference_on" msgid="7922757586228621900">"AKTİV"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DEAKTİV"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Qabaqcıl"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
 </resources>
diff --git a/preference/res/values-b+sr+Latn/strings.xml b/preference/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..61c784a
--- /dev/null
+++ b/preference/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"UKLJUČENO"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ISKLJUČENO"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Napredno"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-be/strings.xml b/preference/res/values-be/strings.xml
new file mode 100644
index 0000000..8ebdeaf
--- /dev/null
+++ b/preference/res/values-be/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"УКЛ."</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ВЫКЛ."</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Высокая"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-bg/strings.xml b/preference/res/values-bg/strings.xml
new file mode 100644
index 0000000..e2e9544
--- /dev/null
+++ b/preference/res/values-bg/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ВКЛ."</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ИЗКЛ."</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Разширени"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-bn/strings.xml b/preference/res/values-bn/strings.xml
new file mode 100644
index 0000000..a17e22a
--- /dev/null
+++ b/preference/res/values-bn/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"চালু"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"বন্ধ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"উন্নত"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-bs/strings.xml b/preference/res/values-bs/strings.xml
new file mode 100644
index 0000000..61c784a
--- /dev/null
+++ b/preference/res/values-bs/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"UKLJUČENO"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ISKLJUČENO"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Napredno"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ca/strings.xml b/preference/res/values-ca/strings.xml
new file mode 100644
index 0000000..56e5c66
--- /dev/null
+++ b/preference/res/values-ca/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ACTIVAT"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DESACTIVAT"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Opcions avançades"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-cs/strings.xml b/preference/res/values-cs/strings.xml
new file mode 100644
index 0000000..5865c0b
--- /dev/null
+++ b/preference/res/values-cs/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ZAP"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"VYP"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Rozšířené"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-da/strings.xml b/preference/res/values-da/strings.xml
new file mode 100644
index 0000000..da2532f
--- /dev/null
+++ b/preference/res/values-da/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"TIL"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"FRA"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avanceret"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-de/strings.xml b/preference/res/values-de/strings.xml
new file mode 100644
index 0000000..5b0be51
--- /dev/null
+++ b/preference/res/values-de/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"AN"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"AUS"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Erweitert"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-el/strings.xml b/preference/res/values-el/strings.xml
new file mode 100644
index 0000000..59ba395
--- /dev/null
+++ b/preference/res/values-el/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ΕΝΕΡΓΟΠΟΙΗΣΗ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ΑΠΕΝΕΡΓΟΠΟΙΗΣΗ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Σύνθετες"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-en-rAU/strings.xml b/preference/res/values-en-rAU/strings.xml
index c8d1681..dd3e15f 100644
--- a/preference/res/values-en-rAU/strings.xml
+++ b/preference/res/values-en-rAU/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="v7_preference_on" msgid="27351710992731591">"ON"</string>
-    <string name="v7_preference_off" msgid="5138405918326871307">"OFF"</string>
-    <string name="expand_button_title" msgid="1234962710353108940">"Advanced"</string>
-    <string name="summary_collapsed_preference_list" msgid="5190123168583152844">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+    <string name="v7_preference_on" msgid="7922757586228621900">"ON"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"OFF"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Advanced"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
 </resources>
diff --git a/preference/res/values-en-rCA/strings.xml b/preference/res/values-en-rCA/strings.xml
index c8d1681..dd3e15f 100644
--- a/preference/res/values-en-rCA/strings.xml
+++ b/preference/res/values-en-rCA/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="v7_preference_on" msgid="27351710992731591">"ON"</string>
-    <string name="v7_preference_off" msgid="5138405918326871307">"OFF"</string>
-    <string name="expand_button_title" msgid="1234962710353108940">"Advanced"</string>
-    <string name="summary_collapsed_preference_list" msgid="5190123168583152844">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+    <string name="v7_preference_on" msgid="7922757586228621900">"ON"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"OFF"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Advanced"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
 </resources>
diff --git a/preference/res/values-en-rGB/strings.xml b/preference/res/values-en-rGB/strings.xml
index c8d1681..dd3e15f 100644
--- a/preference/res/values-en-rGB/strings.xml
+++ b/preference/res/values-en-rGB/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="v7_preference_on" msgid="27351710992731591">"ON"</string>
-    <string name="v7_preference_off" msgid="5138405918326871307">"OFF"</string>
-    <string name="expand_button_title" msgid="1234962710353108940">"Advanced"</string>
-    <string name="summary_collapsed_preference_list" msgid="5190123168583152844">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+    <string name="v7_preference_on" msgid="7922757586228621900">"ON"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"OFF"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Advanced"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
 </resources>
diff --git a/preference/res/values-en-rIN/strings.xml b/preference/res/values-en-rIN/strings.xml
index c8d1681..dd3e15f 100644
--- a/preference/res/values-en-rIN/strings.xml
+++ b/preference/res/values-en-rIN/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="v7_preference_on" msgid="27351710992731591">"ON"</string>
-    <string name="v7_preference_off" msgid="5138405918326871307">"OFF"</string>
-    <string name="expand_button_title" msgid="1234962710353108940">"Advanced"</string>
-    <string name="summary_collapsed_preference_list" msgid="5190123168583152844">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+    <string name="v7_preference_on" msgid="7922757586228621900">"ON"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"OFF"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Advanced"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
 </resources>
diff --git a/preference/res/values-en-rXC/strings.xml b/preference/res/values-en-rXC/strings.xml
index 96219e7..3f4c7a0 100644
--- a/preference/res/values-en-rXC/strings.xml
+++ b/preference/res/values-en-rXC/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="v7_preference_on" msgid="27351710992731591">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‎‎‎‏‏‏‎ON‎‏‎‎‏‎"</string>
-    <string name="v7_preference_off" msgid="5138405918326871307">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎OFF‎‏‎‎‏‎"</string>
-    <string name="expand_button_title" msgid="1234962710353108940">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎Advanced‎‏‎‎‏‎"</string>
-    <string name="summary_collapsed_preference_list" msgid="5190123168583152844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="ADDED_ITEMS">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="v7_preference_on" msgid="7922757586228621900">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‎ON‎‏‎‎‏‎"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎OFF‎‏‎‎‏‎"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎Advanced‎‏‎‎‏‎"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="ADDED_ITEMS">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
 </resources>
diff --git a/preference/res/values-es-rUS/strings.xml b/preference/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..3911ab9
--- /dev/null
+++ b/preference/res/values-es-rUS/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ACTIVADO"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DESACTIVADO"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avanzado"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-es/strings.xml b/preference/res/values-es/strings.xml
new file mode 100644
index 0000000..3911ab9
--- /dev/null
+++ b/preference/res/values-es/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ACTIVADO"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DESACTIVADO"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avanzado"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-et/strings.xml b/preference/res/values-et/strings.xml
new file mode 100644
index 0000000..9fa4f4f
--- /dev/null
+++ b/preference/res/values-et/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"SEES"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"VÄLJAS"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Täpsemad"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-eu/strings.xml b/preference/res/values-eu/strings.xml
new file mode 100644
index 0000000..6718992
--- /dev/null
+++ b/preference/res/values-eu/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"AKTIBATUTA"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DESAKTIBATUTA"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Aurreratua"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-fa/strings.xml b/preference/res/values-fa/strings.xml
new file mode 100644
index 0000000..86e9f30
--- /dev/null
+++ b/preference/res/values-fa/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"روشن"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"خاموش"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"پیشرفته"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>، <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-fi/strings.xml b/preference/res/values-fi/strings.xml
new file mode 100644
index 0000000..cec0857
--- /dev/null
+++ b/preference/res/values-fi/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"PÄÄLLÄ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"POIS PÄÄLTÄ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Lisätiedot"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-fr-rCA/strings.xml b/preference/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..db4c2b5
--- /dev/null
+++ b/preference/res/values-fr-rCA/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ACTIVÉ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DÉSACTIVÉ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avancé"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-fr/strings.xml b/preference/res/values-fr/strings.xml
new file mode 100644
index 0000000..b5cca98
--- /dev/null
+++ b/preference/res/values-fr/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ACTIVÉ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DÉSACTIVÉ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Options avancées"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-gl/strings.xml b/preference/res/values-gl/strings.xml
new file mode 100644
index 0000000..3911ab9
--- /dev/null
+++ b/preference/res/values-gl/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ACTIVADO"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DESACTIVADO"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avanzado"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-gu/strings.xml b/preference/res/values-gu/strings.xml
new file mode 100644
index 0000000..468fd2c
--- /dev/null
+++ b/preference/res/values-gu/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ચાલુ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"બંધ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"વિગતવાર"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-hi/strings.xml b/preference/res/values-hi/strings.xml
new file mode 100644
index 0000000..dcfb766
--- /dev/null
+++ b/preference/res/values-hi/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"चालू"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"बंद"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"बेहतर विकल्प"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-hr/strings.xml b/preference/res/values-hr/strings.xml
new file mode 100644
index 0000000..61c784a
--- /dev/null
+++ b/preference/res/values-hr/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"UKLJUČENO"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ISKLJUČENO"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Napredno"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-hu/strings.xml b/preference/res/values-hu/strings.xml
new file mode 100644
index 0000000..85f80aa
--- /dev/null
+++ b/preference/res/values-hu/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"BE"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"KI"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Speciális"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-hy/strings.xml b/preference/res/values-hy/strings.xml
new file mode 100644
index 0000000..06f9d22
--- /dev/null
+++ b/preference/res/values-hy/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ՄԻԱՑՎԱԾ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ԱՆՋԱՏԱԾ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Լրացուցիչ"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-in/strings.xml b/preference/res/values-in/strings.xml
new file mode 100644
index 0000000..e17c251
--- /dev/null
+++ b/preference/res/values-in/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"AKTIF"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"NONAKTIF"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Lanjutan"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-is/strings.xml b/preference/res/values-is/strings.xml
new file mode 100644
index 0000000..361d1c3
--- /dev/null
+++ b/preference/res/values-is/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"KVEIKT"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"SLÖKKT"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Ítarlegt"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-it/strings.xml b/preference/res/values-it/strings.xml
new file mode 100644
index 0000000..2514600
--- /dev/null
+++ b/preference/res/values-it/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ON"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"OFF"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avanzate"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-iw/strings.xml b/preference/res/values-iw/strings.xml
new file mode 100644
index 0000000..6ca15e5
--- /dev/null
+++ b/preference/res/values-iw/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"מופעל"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"כבוי"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"מתקדם"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ja/strings.xml b/preference/res/values-ja/strings.xml
new file mode 100644
index 0000000..2d599d3
--- /dev/null
+++ b/preference/res/values-ja/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ON"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"OFF"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"詳細設定"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>、<xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ka/strings.xml b/preference/res/values-ka/strings.xml
new file mode 100644
index 0000000..21b8246
--- /dev/null
+++ b/preference/res/values-ka/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ჩართული"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"გამორთული"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"დამატებით"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-kk/strings.xml b/preference/res/values-kk/strings.xml
new file mode 100644
index 0000000..ebbba78
--- /dev/null
+++ b/preference/res/values-kk/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ҚОСУЛЫ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ӨШІРУЛІ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Қосымша"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-km/strings.xml b/preference/res/values-km/strings.xml
new file mode 100644
index 0000000..d7cb942
--- /dev/null
+++ b/preference/res/values-km/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"បើក"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"បិទ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"កម្រិតខ្ពស់"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-kn/strings.xml b/preference/res/values-kn/strings.xml
new file mode 100644
index 0000000..9ce1917
--- /dev/null
+++ b/preference/res/values-kn/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ಆನ್"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ಆಫ್"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"ಸುಧಾರಿತ"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ko/strings.xml b/preference/res/values-ko/strings.xml
new file mode 100644
index 0000000..ab1f380
--- /dev/null
+++ b/preference/res/values-ko/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"사용"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"사용 안함"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"고급"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ky/strings.xml b/preference/res/values-ky/strings.xml
new file mode 100644
index 0000000..257c6d5
--- /dev/null
+++ b/preference/res/values-ky/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"КҮЙҮК"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ӨЧҮК"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Өркүндөтүлгөн"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-lo/strings.xml b/preference/res/values-lo/strings.xml
new file mode 100644
index 0000000..f4c1e2d
--- /dev/null
+++ b/preference/res/values-lo/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ເປີດ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ປິດ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"ຂັ້ນສູງ"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-lt/strings.xml b/preference/res/values-lt/strings.xml
new file mode 100644
index 0000000..ef1bfd6
--- /dev/null
+++ b/preference/res/values-lt/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"Įjungta"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"Išjungta"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Išplėstinės"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-lv/strings.xml b/preference/res/values-lv/strings.xml
new file mode 100644
index 0000000..e4890b1
--- /dev/null
+++ b/preference/res/values-lv/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"IESLĒGTS"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"IZSLĒGTS"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Papildu"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-mk/strings.xml b/preference/res/values-mk/strings.xml
new file mode 100644
index 0000000..f276876
--- /dev/null
+++ b/preference/res/values-mk/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ВКЛУЧЕНО"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ИСКЛУЧЕНО"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Напредно"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ml/strings.xml b/preference/res/values-ml/strings.xml
new file mode 100644
index 0000000..83d1125
--- /dev/null
+++ b/preference/res/values-ml/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ഓൺ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ഓഫ്"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"വിപുലമായത്"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-mn/strings.xml b/preference/res/values-mn/strings.xml
new file mode 100644
index 0000000..2d20950
--- /dev/null
+++ b/preference/res/values-mn/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"АСААЛТТАЙ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"УНТРААТАЙ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Нарийвчилсан"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-mr/strings.xml b/preference/res/values-mr/strings.xml
new file mode 100644
index 0000000..1e492dd
--- /dev/null
+++ b/preference/res/values-mr/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"चालू"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"बंद"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"प्रगत"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ms/strings.xml b/preference/res/values-ms/strings.xml
new file mode 100644
index 0000000..1601d8a
--- /dev/null
+++ b/preference/res/values-ms/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"HIDUP"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"MATI"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Lanjutan"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-my/strings.xml b/preference/res/values-my/strings.xml
new file mode 100644
index 0000000..77237bc
--- /dev/null
+++ b/preference/res/values-my/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ဖွင့်ရန်"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ပိတ်ရန်"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"အဆင့်မြင့်"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>၊ <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-nb/strings.xml b/preference/res/values-nb/strings.xml
new file mode 100644
index 0000000..d5c814b
--- /dev/null
+++ b/preference/res/values-nb/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"PÅ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"AV"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avansert"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ne/strings.xml b/preference/res/values-ne/strings.xml
new file mode 100644
index 0000000..1da1f25
--- /dev/null
+++ b/preference/res/values-ne/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"सक्रिय छ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"निष्क्रिय छ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"उन्नत"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-nl/strings.xml b/preference/res/values-nl/strings.xml
new file mode 100644
index 0000000..dc84ab8
--- /dev/null
+++ b/preference/res/values-nl/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"AAN"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"UIT"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Geavanceerd"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-pa/strings.xml b/preference/res/values-pa/strings.xml
new file mode 100644
index 0000000..29471c3
--- /dev/null
+++ b/preference/res/values-pa/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ਚਾਲੂ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ਬੰਦ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"ਉੱਨਤ"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-pl/strings.xml b/preference/res/values-pl/strings.xml
new file mode 100644
index 0000000..ef7bbf8
--- /dev/null
+++ b/preference/res/values-pl/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"WŁ."</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"WYŁ."</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Zaawansowane"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-pt-rBR/strings.xml b/preference/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..433e8e3
--- /dev/null
+++ b/preference/res/values-pt-rBR/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ATIVADO"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DESATIVADO"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avançado"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-pt-rPT/strings.xml b/preference/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..4f296f6
--- /dev/null
+++ b/preference/res/values-pt-rPT/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ATIVADA"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DESATIVADA"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avançadas"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-pt/strings.xml b/preference/res/values-pt/strings.xml
new file mode 100644
index 0000000..433e8e3
--- /dev/null
+++ b/preference/res/values-pt/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ATIVADO"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DESATIVADO"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avançado"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ro/strings.xml b/preference/res/values-ro/strings.xml
new file mode 100644
index 0000000..1353a6f
--- /dev/null
+++ b/preference/res/values-ro/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ACTIVAT"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"DEZACTIVAT"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avansat"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ru/strings.xml b/preference/res/values-ru/strings.xml
new file mode 100644
index 0000000..8449700
--- /dev/null
+++ b/preference/res/values-ru/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ВКЛ."</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ВЫКЛ."</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Дополнительно"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-si/strings.xml b/preference/res/values-si/strings.xml
new file mode 100644
index 0000000..27bf118
--- /dev/null
+++ b/preference/res/values-si/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ක්‍රියාත්මකයි"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ක්‍රියාවිරහිතයි"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"උසස්"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-sk/strings.xml b/preference/res/values-sk/strings.xml
new file mode 100644
index 0000000..a087a8b
--- /dev/null
+++ b/preference/res/values-sk/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ZAP."</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"VYP."</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Rozšírené"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-sl/strings.xml b/preference/res/values-sl/strings.xml
new file mode 100644
index 0000000..887c1b1
--- /dev/null
+++ b/preference/res/values-sl/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"VKLOPLJENO"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"IZKLOPLJENO"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Dodatno"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-sq/strings.xml b/preference/res/values-sq/strings.xml
new file mode 100644
index 0000000..f2f5b77
--- /dev/null
+++ b/preference/res/values-sq/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"AKTIV"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"JOAKTIV"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Të përparuara"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-sr/strings.xml b/preference/res/values-sr/strings.xml
new file mode 100644
index 0000000..322ace5
--- /dev/null
+++ b/preference/res/values-sr/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"УКЉУЧЕНО"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ИСКЉУЧЕНО"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Напредно"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-sv/strings.xml b/preference/res/values-sv/strings.xml
new file mode 100644
index 0000000..c689ea1
--- /dev/null
+++ b/preference/res/values-sv/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"PÅ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"AV"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Avancerat"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-sw/strings.xml b/preference/res/values-sw/strings.xml
new file mode 100644
index 0000000..9010663
--- /dev/null
+++ b/preference/res/values-sw/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"IMEWASHWA"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"IMEZIMWA"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Mipangilio ya Kina"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ta/strings.xml b/preference/res/values-ta/strings.xml
new file mode 100644
index 0000000..9fc536d
--- /dev/null
+++ b/preference/res/values-ta/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ஆன் செய்"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ஆஃப் செய்"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"மேம்பட்டது"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-te/strings.xml b/preference/res/values-te/strings.xml
new file mode 100644
index 0000000..7277c76
--- /dev/null
+++ b/preference/res/values-te/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"ఆన్"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ఆఫ్"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"అధునాతనం"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-th/strings.xml b/preference/res/values-th/strings.xml
new file mode 100644
index 0000000..90a5433
--- /dev/null
+++ b/preference/res/values-th/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"เปิด"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ปิด"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"ขั้นสูง"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g> <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-tl/strings.xml b/preference/res/values-tl/strings.xml
new file mode 100644
index 0000000..5b6885b
--- /dev/null
+++ b/preference/res/values-tl/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"NAKA-ON"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"NAKA-OFF"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Advanced"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-tr/strings.xml b/preference/res/values-tr/strings.xml
new file mode 100644
index 0000000..fa66179
--- /dev/null
+++ b/preference/res/values-tr/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"AÇIK"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"KAPALI"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Gelişmiş"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-uk/strings.xml b/preference/res/values-uk/strings.xml
new file mode 100644
index 0000000..47280c3
--- /dev/null
+++ b/preference/res/values-uk/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"УВІМКНЕНО"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"ВИМКНЕНО"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Додатково"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-ur/strings.xml b/preference/res/values-ur/strings.xml
new file mode 100644
index 0000000..c304b12
--- /dev/null
+++ b/preference/res/values-ur/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"آن"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"آف"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"جدید ترین"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>، <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-uz/strings.xml b/preference/res/values-uz/strings.xml
index cdf990b..6730b74 100644
--- a/preference/res/values-uz/strings.xml
+++ b/preference/res/values-uz/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="v7_preference_on" msgid="27351710992731591">"YONIQ"</string>
-    <string name="v7_preference_off" msgid="5138405918326871307">"O‘CHIQ"</string>
-    <string name="expand_button_title" msgid="1234962710353108940">"Kengaytirilgan"</string>
-    <string name="summary_collapsed_preference_list" msgid="5190123168583152844">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+    <string name="v7_preference_on" msgid="7922757586228621900">"YONIQ"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"O‘CHIQ"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Ekspert"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
 </resources>
diff --git a/preference/res/values-vi/strings.xml b/preference/res/values-vi/strings.xml
new file mode 100644
index 0000000..d8ea12b
--- /dev/null
+++ b/preference/res/values-vi/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"BẬT"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"TẮT"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Nâng cao"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-zh-rCN/strings.xml b/preference/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..3f91ed6
--- /dev/null
+++ b/preference/res/values-zh-rCN/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"开启"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"关闭"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"高级"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"当前显示了 <xliff:g id="CURRENT_ITEMS">%1$s</xliff:g> 项(已添加 <xliff:g id="ADDED_ITEMS">%2$s</xliff:g> 项)"</string>
+</resources>
diff --git a/preference/res/values-zh-rHK/strings.xml b/preference/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..fe64c50
--- /dev/null
+++ b/preference/res/values-zh-rHK/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"開啟"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"關閉"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"進階"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>,<xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-zh-rTW/strings.xml b/preference/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..fe64c50
--- /dev/null
+++ b/preference/res/values-zh-rTW/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"開啟"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"關閉"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"進階"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>,<xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/preference/res/values-zu/strings.xml b/preference/res/values-zu/strings.xml
new file mode 100644
index 0000000..dab4cba
--- /dev/null
+++ b/preference/res/values-zu/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="v7_preference_on" msgid="7922757586228621900">"VULA"</string>
+    <string name="v7_preference_off" msgid="2082379519172883894">"VALA"</string>
+    <string name="expand_button_title" msgid="3265458434114353660">"Okuthuthukisiwe"</string>
+    <string name="summary_collapsed_preference_list" msgid="5255557321652385027">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+</resources>
diff --git a/print/build.gradle b/print/build.gradle
index 7901514..05919df 100644
--- a/print/build.gradle
+++ b/print/build.gradle
@@ -16,4 +16,5 @@
     mavenGroup = LibraryGroups.PRINT
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnDeprecationWarnings = false
 }
diff --git a/recommendation/build.gradle b/recommendation/build.gradle
index 84d0445..684726e 100644
--- a/recommendation/build.gradle
+++ b/recommendation/build.gradle
@@ -17,4 +17,5 @@
     inceptionYear = "2015"
     description = "Android Support Recommendation"
     minSdkVersion = 21
+    failOnDeprecationWarnings = false
 }
diff --git a/recyclerview-selection/build.gradle b/recyclerview-selection/build.gradle
index b467e48..dcda345 100644
--- a/recyclerview-selection/build.gradle
+++ b/recyclerview-selection/build.gradle
@@ -41,4 +41,6 @@
     mavenGroup = LibraryGroups.RECYCLERVIEW
     inceptionYear = "2017"
     description = "Library providing item selection framework for RecyclerView. Support for touch based and band selection is provided."
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/samples/SupportMediaDemos/build.gradle b/samples/SupportMediaDemos/build.gradle
index bf23177..fecf2a5 100644
--- a/samples/SupportMediaDemos/build.gradle
+++ b/samples/SupportMediaDemos/build.gradle
@@ -25,7 +25,7 @@
 
 android {
     defaultConfig {
-        minSdkVersion 19
-        targetSdkVersion 26
+        minSdkVersion = 19
+        targetSdkVersion = 26
     }
 }
diff --git a/samples/SupportMediaDemos/src/main/AndroidManifest.xml b/samples/SupportMediaDemos/src/main/AndroidManifest.xml
index 267eafd..5348161 100644
--- a/samples/SupportMediaDemos/src/main/AndroidManifest.xml
+++ b/samples/SupportMediaDemos/src/main/AndroidManifest.xml
@@ -15,7 +15,11 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     package="com.example.androidx.media">
+
+    <uses-sdk tools:overrideLibrary="androidx.media.widget" />
+
     <application android:label="Video View Test">
 
         <!-- Video Selection Activity -->
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
index d640303..0c10b01 100644
--- a/samples/SupportMediaDemos/src/main/java/com/example/androidx/media/VideoViewTest.java
+++ b/samples/SupportMediaDemos/src/main/java/com/example/androidx/media/VideoViewTest.java
@@ -29,6 +29,7 @@
 import android.support.v4.media.session.PlaybackStateCompat;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -71,6 +72,7 @@
         setContentView(R.layout.video_activity);
 
         mVideoView = findViewById(R.id.video_view);
+        mVideoView.setActivity(this);
 
         String errorString = null;
         Intent intent = getIntent();
@@ -82,12 +84,11 @@
             if (mUseTextureView) {
                 mVideoView.setViewType(VideoView2.VIEW_TYPE_TEXTUREVIEW);
             }
-
-            mVideoView.setFullScreenRequestListener(new FullScreenRequestListener());
             mVideoView.setVideoUri(contentUri);
 
             mMediaControlView = new MediaControlView2(this);
             mVideoView.setMediaControlView2(mMediaControlView, 2000);
+            mMediaControlView.setFullScreenRequestListener(new FullScreenRequestListener());
         }
         if (errorString != null) {
             showErrorDialog(errorString);
@@ -179,7 +180,8 @@
         }
     };
 
-    private class FullScreenRequestListener implements VideoView2.OnFullScreenRequestListener {
+    private class FullScreenRequestListener
+            implements MediaControlView2.OnFullScreenRequestListener {
         @Override
         public void onFullScreenRequest(View view, boolean fullScreen) {
             // TODO: Remove bottom controls after adding back button functionality.
@@ -223,6 +225,7 @@
     public static class MyVideoView extends VideoView2 {
         private float mDX;
         private float mDY;
+        private Activity mActivity;
 
         public MyVideoView(Context context) {
             super(context);
@@ -255,6 +258,18 @@
             }
             return super.onTouchEvent(ev);
         }
+
+        @Override
+        public boolean onKeyDown(int keyCode, KeyEvent event)  {
+            if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
+                mActivity.finish();
+            }
+            return true;
+        }
+
+        public void setActivity(Activity activity) {
+            mActivity = activity;
+        }
     }
 
     @Override
diff --git a/samples/SupportSliceDemos/src/main/AndroidManifest.xml b/samples/SupportSliceDemos/src/main/AndroidManifest.xml
index 355a77a..4d43211 100644
--- a/samples/SupportSliceDemos/src/main/AndroidManifest.xml
+++ b/samples/SupportSliceDemos/src/main/AndroidManifest.xml
@@ -48,6 +48,7 @@
 
         <provider android:authorities="com.example.androidx.slice.demos"
                   android:name=".SampleSliceProvider"
+                  android:exported="true"
                   android:grantUriPermissions="true">
             <intent-filter>
                 <action android:name="androidx.intent.SLICE_ACTION"/>
diff --git a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java
index 4facfb3..622f047 100644
--- a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java
+++ b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java
@@ -16,13 +16,14 @@
 
 package com.example.androidx.slice.demos;
 
+import static androidx.slice.core.SliceHints.INFINITY;
+
 import static com.example.androidx.slice.demos.SampleSliceProvider.URI_PATHS;
 import static com.example.androidx.slice.demos.SampleSliceProvider.getUri;
 
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
@@ -48,6 +49,7 @@
 import androidx.lifecycle.LiveData;
 import androidx.slice.Slice;
 import androidx.slice.SliceItem;
+import androidx.slice.SliceMetadata;
 import androidx.slice.widget.EventInfo;
 import androidx.slice.widget.SliceLiveData;
 import androidx.slice.widget.SliceView;
@@ -130,7 +132,6 @@
             mSearchView.setQuery(savedInstanceState.getString("SELECTED_QUERY"), true);
         }
 
-        grantPackage(getPackageName());
         // TODO: Listen for changes.
         updateAvailableSlices();
         if (TEST_INTENT) {
@@ -146,7 +147,6 @@
         mTypeMenu.add("Shortcut");
         mTypeMenu.add("Small");
         mTypeMenu.add("Large");
-        menu.add("Auth");
         super.onCreateOptionsMenu(menu);
         return true;
     }
@@ -154,9 +154,6 @@
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getTitle().toString()) {
-            case "Auth":
-                authAllSlices();
-                return true;
             case "Shortcut":
                 mTypeMenu.setIcon(R.drawable.ic_shortcut);
                 mSelectedMode = SliceView.MODE_SHORTCUT;
@@ -183,21 +180,6 @@
         outState.putString("SELECTED_QUERY", mSearchView.getQuery().toString());
     }
 
-    private void authAllSlices() {
-        List<ApplicationInfo> packages = getPackageManager().getInstalledApplications(0);
-        for (ApplicationInfo info : packages) {
-            grantPackage(info.packageName);
-        }
-    }
-
-    private void grantPackage(String packageName) {
-        for (int i = 0; i < URI_PATHS.length; i++) {
-            grantUriPermission(packageName, getUri(URI_PATHS[i], getApplicationContext()),
-                    Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
-                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
-        }
-    }
-
     private void updateAvailableSlices() {
         mSliceUris.clear();
         List<PackageInfo> packageInfos = getPackageManager()
@@ -239,7 +221,17 @@
             mContainer.addView(v);
             mSliceLiveData = SliceLiveData.fromUri(this, uri);
             v.setMode(mSelectedMode);
-            mSliceLiveData.observe(this, v);
+            mSliceLiveData.observe(this, slice -> {
+                v.setSlice(slice);
+                SliceMetadata metadata = SliceMetadata.from(this, slice);
+                long expiry = metadata.getExpiry();
+                if (expiry != INFINITY) {
+                    // Shows the updated text after the TTL expires.
+                    v.postDelayed(() -> v.setSlice(slice),
+                            expiry - System.currentTimeMillis() + 15);
+                }
+            });
+            mSliceLiveData.observe(this, slice -> Log.d(TAG, "Slice: " + slice));
         } else {
             Log.w(TAG, "Invalid uri, skipping slice: " + uri);
         }
diff --git a/slices/builders/build.gradle b/slices/builders/build.gradle
index 73d0568..91c7599 100644
--- a/slices/builders/build.gradle
+++ b/slices/builders/build.gradle
@@ -36,4 +36,6 @@
     inceptionYear = "2017"
     description = "A set of builders to create templates using SliceProvider APIs"
     minSdkVersion = 19
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/slices/core/build.gradle b/slices/core/build.gradle
index cb17394..0530edd 100644
--- a/slices/core/build.gradle
+++ b/slices/core/build.gradle
@@ -40,4 +40,6 @@
     inceptionYear = "2017"
     description = "The slices core library provides utilities for the slices view and provider libraries"
     minSdkVersion = 19
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/slices/core/src/androidTest/java/androidx/slice/SliceTest.java b/slices/core/src/androidTest/java/androidx/slice/SliceTest.java
index 041c8fe..e092c97 100644
--- a/slices/core/src/androidTest/java/androidx/slice/SliceTest.java
+++ b/slices/core/src/androidTest/java/androidx/slice/SliceTest.java
@@ -23,9 +23,9 @@
 import static android.app.slice.SliceItem.FORMAT_ACTION;
 import static android.app.slice.SliceItem.FORMAT_IMAGE;
 import static android.app.slice.SliceItem.FORMAT_INT;
+import static android.app.slice.SliceItem.FORMAT_LONG;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
-import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
 import static android.app.slice.SliceProvider.SLICE_TYPE;
 
 import static org.junit.Assert.assertEquals;
@@ -184,7 +184,7 @@
         assertEquals(1, s.getItems().size());
 
         SliceItem item = s.getItems().get(0);
-        assertEquals(FORMAT_TIMESTAMP, item.getFormat());
+        assertEquals(FORMAT_LONG, item.getFormat());
         assertEquals(43, item.getTimestamp());
     }
 
diff --git a/slices/core/src/main/java/androidx/slice/Slice.java b/slices/core/src/main/java/androidx/slice/Slice.java
index d18ef23..aa077cb 100644
--- a/slices/core/src/main/java/androidx/slice/Slice.java
+++ b/slices/core/src/main/java/androidx/slice/Slice.java
@@ -35,7 +35,6 @@
 import static android.app.slice.SliceItem.FORMAT_REMOTE_INPUT;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
-import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
 
 import static androidx.slice.SliceConvert.unwrap;
 import static androidx.slice.core.SliceHints.HINT_KEYWORDS;
@@ -388,7 +387,7 @@
         }
 
         /**
-         * Add a timestamp to the slice being constructed
+         * Add a long to the slice being constructed
          * @param subType Optional template-specific type information
          * @see {@link SliceItem#getSubType()}
          */
@@ -399,6 +398,16 @@
         }
 
         /**
+         * Add a long to the slice being constructed
+         * @param subType Optional template-specific type information
+         * @see {@link SliceItem#getSubType()}
+         */
+        public Slice.Builder addLong(long time, @Nullable String subType,
+                @SliceHint List<String> hints) {
+            return addLong(time, subType, hints.toArray(new String[hints.size()]));
+        }
+
+        /**
          * Add a timestamp to the slice being constructed
          * @param subType Optional template-specific type information
          * @see {@link SliceItem#getSubType()}
@@ -407,7 +416,7 @@
         @Deprecated
         public Slice.Builder addTimestamp(long time, @Nullable String subType,
                 @SliceHint String... hints) {
-            mItems.add(new SliceItem(time, FORMAT_TIMESTAMP, subType, hints));
+            mItems.add(new SliceItem(time, FORMAT_LONG, subType, hints));
             return this;
         }
 
@@ -455,20 +464,37 @@
     public String toString(String indent) {
         StringBuilder sb = new StringBuilder();
         sb.append(indent);
-        sb.append("slice: ");
-        sb.append("\n");
-        indent += "   ";
+        sb.append("slice ");
+        addHints(sb, mHints);
+        sb.append("{\n");
+        String nextIndent = indent + "  ";
         for (int i = 0; i < mItems.length; i++) {
             SliceItem item = mItems[i];
-            sb.append(item.toString(indent));
-            if (!FORMAT_SLICE.equals(item.getFormat())) {
-                sb.append("\n");
-            }
+            sb.append(item.toString(nextIndent));
         }
+        sb.append(indent);
+        sb.append("}");
         return sb.toString();
     }
 
     /**
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY)
+    public static void addHints(StringBuilder sb, String[] hints) {
+        if (hints == null || hints.length == 0) return;
+
+        sb.append("(");
+        int end = hints.length - 1;
+        for (int i = 0; i < end; i++) {
+            sb.append(hints[i]);
+            sb.append(", ");
+        }
+        sb.append(hints[end]);
+        sb.append(") ");
+    }
+
+    /**
      * Turns a slice Uri into slice content.
      *
      * @hide
@@ -493,6 +519,6 @@
     private static Slice callBindSlice(Context context, Uri uri,
             Set<SliceSpec> supportedSpecs) {
         return SliceConvert.wrap(context.getSystemService(SliceManager.class)
-                .bindSlice(uri, new ArrayList<>(unwrap(supportedSpecs))));
+                .bindSlice(uri, unwrap(supportedSpecs)));
     }
 }
diff --git a/slices/core/src/main/java/androidx/slice/SliceConvert.java b/slices/core/src/main/java/androidx/slice/SliceConvert.java
index 73ff368..fea5b4c 100644
--- a/slices/core/src/main/java/androidx/slice/SliceConvert.java
+++ b/slices/core/src/main/java/androidx/slice/SliceConvert.java
@@ -19,17 +19,16 @@
 import static android.app.slice.SliceItem.FORMAT_ACTION;
 import static android.app.slice.SliceItem.FORMAT_IMAGE;
 import static android.app.slice.SliceItem.FORMAT_INT;
+import static android.app.slice.SliceItem.FORMAT_LONG;
 import static android.app.slice.SliceItem.FORMAT_REMOTE_INPUT;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
-import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
 
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.collection.ArraySet;
 import androidx.core.graphics.drawable.IconCompat;
 
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -43,9 +42,8 @@
      */
     public static android.app.slice.Slice unwrap(androidx.slice.Slice slice) {
         android.app.slice.Slice.Builder builder = new android.app.slice.Slice.Builder(
-                slice.getUri());
+                slice.getUri(), unwrap(slice.getSpec()));
         builder.addHints(slice.getHints());
-        builder.setSpec(unwrap(slice.getSpec()));
         for (androidx.slice.SliceItem item : slice.getItems()) {
             switch (item.getFormat()) {
                 case FORMAT_SLICE:
@@ -67,8 +65,8 @@
                 case FORMAT_INT:
                     builder.addInt(item.getInt(), item.getSubType(), item.getHints());
                     break;
-                case FORMAT_TIMESTAMP:
-                    builder.addTimestamp(item.getTimestamp(), item.getSubType(), item.getHints());
+                case FORMAT_LONG:
+                    builder.addLong(item.getLong(), item.getSubType(), item.getHints());
                     break;
             }
         }
@@ -119,8 +117,8 @@
                 case FORMAT_INT:
                     builder.addInt(item.getInt(), item.getSubType(), item.getHints());
                     break;
-                case FORMAT_TIMESTAMP:
-                    builder.addTimestamp(item.getTimestamp(), item.getSubType(), item.getHints());
+                case FORMAT_LONG:
+                    builder.addLong(item.getLong(), item.getSubType(), item.getHints());
                     break;
             }
         }
@@ -137,7 +135,7 @@
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     public static Set<androidx.slice.SliceSpec> wrap(
-            List<android.app.slice.SliceSpec> supportedSpecs) {
+            Set<android.app.slice.SliceSpec> supportedSpecs) {
         Set<androidx.slice.SliceSpec> ret = new ArraySet<>();
         for (android.app.slice.SliceSpec spec : supportedSpecs) {
             ret.add(wrap(spec));
diff --git a/slices/core/src/main/java/androidx/slice/SliceItem.java b/slices/core/src/main/java/androidx/slice/SliceItem.java
index 004e51d..f6ae848 100644
--- a/slices/core/src/main/java/androidx/slice/SliceItem.java
+++ b/slices/core/src/main/java/androidx/slice/SliceItem.java
@@ -23,7 +23,8 @@
 import static android.app.slice.SliceItem.FORMAT_REMOTE_INPUT;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
-import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
+
+import static androidx.slice.Slice.addHints;
 
 import android.app.PendingIntent;
 import android.app.RemoteInput;
@@ -57,7 +58,7 @@
  * <li>{@link android.app.slice.SliceItem#FORMAT_IMAGE}</li>
  * <li>{@link android.app.slice.SliceItem#FORMAT_ACTION}</li>
  * <li>{@link android.app.slice.SliceItem#FORMAT_INT}</li>
- * <li>{@link android.app.slice.SliceItem#FORMAT_TIMESTAMP}</li>
+ * <li>{@link android.app.slice.SliceItem#FORMAT_LONG}</li>
  * <p>
  * The hints that a {@link SliceItem} are a set of strings which annotate
  * the content. The hints that are guaranteed to be understood by the system
@@ -76,7 +77,7 @@
      */
     @RestrictTo(Scope.LIBRARY)
     @StringDef({FORMAT_SLICE, FORMAT_TEXT, FORMAT_IMAGE, FORMAT_ACTION, FORMAT_INT,
-            FORMAT_TIMESTAMP, FORMAT_REMOTE_INPUT, FORMAT_LONG})
+            FORMAT_LONG, FORMAT_REMOTE_INPUT, FORMAT_LONG})
     public @interface SliceType {
     }
 
@@ -162,7 +163,7 @@
      * <li>{@link android.app.slice.SliceItem#FORMAT_IMAGE}</li>
      * <li>{@link android.app.slice.SliceItem#FORMAT_ACTION}</li>
      * <li>{@link android.app.slice.SliceItem#FORMAT_INT}</li>
-     * <li>{@link android.app.slice.SliceItem#FORMAT_TIMESTAMP}</li>
+     * <li>{@link android.app.slice.SliceItem#FORMAT_LONG}</li>
      * <li>{@link android.app.slice.SliceItem#FORMAT_REMOTE_INPUT}</li>
      * @see #getSubType() ()
      */
@@ -345,7 +346,7 @@
             case FORMAT_INT:
                 dest.putInt(OBJ, (Integer) mObj);
                 break;
-            case FORMAT_TIMESTAMP:
+            case FORMAT_LONG:
                 dest.putLong(OBJ, (Long) mObj);
                 break;
         }
@@ -367,7 +368,7 @@
                         new Slice(in.getBundle(OBJ_2)));
             case FORMAT_INT:
                 return in.getInt(OBJ);
-            case FORMAT_TIMESTAMP:
+            case FORMAT_LONG:
                 return in.getLong(OBJ);
         }
         throw new RuntimeException("Unsupported type " + type);
@@ -389,8 +390,8 @@
                 return "Action";
             case FORMAT_INT:
                 return "Int";
-            case FORMAT_TIMESTAMP:
-                return "Timestamp";
+            case FORMAT_LONG:
+                return "Long";
             case FORMAT_REMOTE_INPUT:
                 return "RemoteInput";
         }
@@ -412,36 +413,35 @@
     @RestrictTo(Scope.LIBRARY)
     public String toString(String indent) {
         StringBuilder sb = new StringBuilder();
-        if (!FORMAT_SLICE.equals(getFormat())) {
-            sb.append(indent);
-            sb.append(getFormat());
-            sb.append(": ");
-        }
         switch (getFormat()) {
             case FORMAT_SLICE:
                 sb.append(getSlice().toString(indent));
                 break;
             case FORMAT_ACTION:
-                sb.append(getAction());
-                sb.append("\n");
+                sb.append(indent).append(getAction()).append(",\n");
                 sb.append(getSlice().toString(indent));
                 break;
             case FORMAT_TEXT:
-                sb.append(getText());
+                sb.append(indent).append('"').append(getText()).append('"');
                 break;
             case FORMAT_IMAGE:
-                sb.append(getIcon());
+                sb.append(indent).append(getIcon());
                 break;
             case FORMAT_INT:
-                sb.append(getInt());
+                sb.append(indent).append(getInt());
                 break;
-            case FORMAT_TIMESTAMP:
-                sb.append(getTimestamp());
+            case FORMAT_LONG:
+                sb.append(indent).append(getLong());
                 break;
             default:
-                sb.append(SliceItem.typeToString(getFormat()));
+                sb.append(indent).append(SliceItem.typeToString(getFormat()));
                 break;
         }
+        if (!FORMAT_SLICE.equals(getFormat())) {
+            sb.append(' ');
+            addHints(sb, mHints);
+        }
+        sb.append(",\n");
         return sb.toString();
     }
 }
diff --git a/slices/core/src/main/java/androidx/slice/SliceProvider.java b/slices/core/src/main/java/androidx/slice/SliceProvider.java
index 7ec9232..9061ab1 100644
--- a/slices/core/src/main/java/androidx/slice/SliceProvider.java
+++ b/slices/core/src/main/java/androidx/slice/SliceProvider.java
@@ -20,20 +20,8 @@
 import static android.app.slice.SliceProvider.SLICE_TYPE;
 
 import static androidx.slice.compat.SliceProviderCompat.EXTRA_BIND_URI;
-import static androidx.slice.compat.SliceProviderCompat.EXTRA_INTENT;
 import static androidx.slice.compat.SliceProviderCompat.EXTRA_PKG;
 import static androidx.slice.compat.SliceProviderCompat.EXTRA_PROVIDER_PKG;
-import static androidx.slice.compat.SliceProviderCompat.EXTRA_SLICE;
-import static androidx.slice.compat.SliceProviderCompat.EXTRA_SLICE_DESCENDANTS;
-import static androidx.slice.compat.SliceProviderCompat.METHOD_GET_DESCENDANTS;
-import static androidx.slice.compat.SliceProviderCompat.METHOD_GET_PINNED_SPECS;
-import static androidx.slice.compat.SliceProviderCompat.METHOD_MAP_INTENT;
-import static androidx.slice.compat.SliceProviderCompat.METHOD_MAP_ONLY_INTENT;
-import static androidx.slice.compat.SliceProviderCompat.METHOD_PIN;
-import static androidx.slice.compat.SliceProviderCompat.METHOD_SLICE;
-import static androidx.slice.compat.SliceProviderCompat.METHOD_UNPIN;
-import static androidx.slice.compat.SliceProviderCompat.addSpecs;
-import static androidx.slice.compat.SliceProviderCompat.getSpecs;
 import static androidx.slice.core.SliceHints.HINT_PERMISSION_REQUEST;
 
 import android.app.PendingIntent;
@@ -48,13 +36,8 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.CancellationSignal;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Process;
-import android.os.StrictMode;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -63,11 +46,10 @@
 import androidx.annotation.RestrictTo;
 import androidx.core.app.CoreComponentFactory;
 import androidx.core.os.BuildCompat;
-import androidx.slice.compat.CompatPinnedList;
+import androidx.slice.compat.SliceProviderCompat;
 import androidx.slice.compat.SliceProviderWrapperContainer;
 import androidx.slice.core.R;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
@@ -118,14 +100,9 @@
 
     private static final String TAG = "SliceProvider";
 
-    private static final String DATA_PREFIX = "slice_data_";
-    private static final long SLICE_BIND_ANR = 2000;
-
     private static final boolean DEBUG = false;
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
-    private CompatPinnedList mPinnedList;
 
-    private String mCallback;
+    private SliceProviderCompat mCompat;
 
     /**
      * Implement this to initialize your slice provider on startup.
@@ -154,8 +131,9 @@
 
     @Override
     public final boolean onCreate() {
-        mPinnedList = new CompatPinnedList(getContext(),
-                DATA_PREFIX + getClass().getName());
+        if (!BuildCompat.isAtLeastP()) {
+            mCompat = new SliceProviderCompat(this);
+        }
         return onCreateSliceProvider();
     }
 
@@ -167,115 +145,7 @@
 
     @Override
     public Bundle call(String method, String arg, Bundle extras) {
-        if (method.equals(METHOD_SLICE)) {
-            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
-            if (Binder.getCallingUid() != Process.myUid()) {
-                getContext().enforceUriPermission(uri, Binder.getCallingPid(),
-                        Binder.getCallingUid(),
-                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
-                        "Slice binding requires write access to the uri");
-            }
-            Set<SliceSpec> specs = getSpecs(extras);
-
-            Slice s = handleBindSlice(uri, specs, getCallingPackage());
-            Bundle b = new Bundle();
-            b.putParcelable(EXTRA_SLICE, s.toBundle());
-            return b;
-        } else if (method.equals(METHOD_MAP_INTENT)) {
-            Intent intent = extras.getParcelable(EXTRA_INTENT);
-            Uri uri = onMapIntentToUri(intent);
-            Bundle b = new Bundle();
-            if (uri != null) {
-                Set<SliceSpec> specs = getSpecs(extras);
-                Slice s = handleBindSlice(uri, specs, getCallingPackage());
-                b.putParcelable(EXTRA_SLICE, s.toBundle());
-            } else {
-                b.putParcelable(EXTRA_SLICE, null);
-            }
-            return b;
-        } else if (method.equals(METHOD_MAP_ONLY_INTENT)) {
-            Intent intent = extras.getParcelable(EXTRA_INTENT);
-            Uri uri = onMapIntentToUri(intent);
-            Bundle b = new Bundle();
-            b.putParcelable(EXTRA_SLICE, uri);
-            return b;
-        } else if (method.equals(METHOD_PIN)) {
-            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
-            Set<SliceSpec> specs = getSpecs(extras);
-            String pkg = extras.getString(EXTRA_PKG);
-            if (mPinnedList.addPin(uri, pkg, specs)) {
-                handleSlicePinned(uri);
-            }
-            return null;
-        } else if (method.equals(METHOD_UNPIN)) {
-            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
-            String pkg = extras.getString(EXTRA_PKG);
-            if (mPinnedList.removePin(uri, pkg)) {
-                handleSliceUnpinned(uri);
-            }
-            return null;
-        } else if (method.equals(METHOD_GET_PINNED_SPECS)) {
-            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
-            Bundle b = new Bundle();
-            addSpecs(b, mPinnedList.getSpecs(uri));
-            return b;
-        } else if (method.equals(METHOD_GET_DESCENDANTS)) {
-            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
-            Bundle b = new Bundle();
-            b.putParcelableArrayList(EXTRA_SLICE_DESCENDANTS,
-                    new ArrayList<>(handleGetDescendants(uri)));
-            return b;
-        }
-        return super.call(method, arg, extras);
-    }
-
-    private Collection<Uri> handleGetDescendants(Uri uri) {
-        mCallback = "onGetSliceDescendants";
-        mHandler.postDelayed(mAnr, SLICE_BIND_ANR);
-        try {
-            return onGetSliceDescendants(uri);
-        } finally {
-            mHandler.removeCallbacks(mAnr);
-        }
-    }
-
-    private void handleSlicePinned(final Uri sliceUri) {
-        mCallback = "onSlicePinned";
-        mHandler.postDelayed(mAnr, SLICE_BIND_ANR);
-        try {
-            onSlicePinned(sliceUri);
-        } finally {
-            mHandler.removeCallbacks(mAnr);
-        }
-    }
-
-    private void handleSliceUnpinned(final Uri sliceUri) {
-        mCallback = "onSliceUnpinned";
-        mHandler.postDelayed(mAnr, SLICE_BIND_ANR);
-        try {
-            onSliceUnpinned(sliceUri);
-        } finally {
-            mHandler.removeCallbacks(mAnr);
-        }
-    }
-
-    private Slice handleBindSlice(final Uri sliceUri, final Set<SliceSpec> specs,
-            final String callingPkg) {
-        // This can be removed once Slice#bindSlice is removed and everyone is using
-        // SliceManager#bindSlice.
-        String pkg = callingPkg != null ? callingPkg
-                : getContext().getPackageManager().getNameForUid(Binder.getCallingUid());
-        if (Binder.getCallingUid() != Process.myUid()) {
-            try {
-                getContext().enforceUriPermission(sliceUri,
-                        Binder.getCallingPid(), Binder.getCallingUid(),
-                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
-                        "Slice binding requires write access to Uri");
-            } catch (SecurityException e) {
-                return createPermissionSlice(getContext(), sliceUri, pkg);
-            }
-        }
-        return onBindSliceStrict(sliceUri, specs);
+        return mCompat != null ? mCompat.call(method, arg, extras) : null;
     }
 
     /**
@@ -337,35 +207,6 @@
         }
     }
 
-    private Slice onBindSliceStrict(Uri sliceUri, Set<SliceSpec> specs) {
-        StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
-        mCallback = "onBindSlice";
-        mHandler.postDelayed(mAnr, SLICE_BIND_ANR);
-        try {
-            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
-                    .detectAll()
-                    .penaltyDeath()
-                    .build());
-            SliceProvider.setSpecs(specs);
-            try {
-                return onBindSlice(sliceUri);
-            } finally {
-                SliceProvider.setSpecs(null);
-                mHandler.removeCallbacks(mAnr);
-            }
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-    }
-
-    private final Runnable mAnr = new Runnable() {
-        @Override
-        public void run() {
-            Process.sendSignal(Process.myPid(), Process.SIGNAL_QUIT);
-            Log.wtf(TAG, "Timed out while handling slice callback " + mCallback);
-        }
-    };
-
     /**
      * Implemented to create a slice.
      * <p>
diff --git a/slices/core/src/main/java/androidx/slice/compat/CompatPermissionManager.java b/slices/core/src/main/java/androidx/slice/compat/CompatPermissionManager.java
new file mode 100644
index 0000000..247a763
--- /dev/null
+++ b/slices/core/src/main/java/androidx/slice/compat/CompatPermissionManager.java
@@ -0,0 +1,198 @@
+/*
+ * 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.slice.compat;
+
+import static androidx.core.content.PermissionChecker.PERMISSION_DENIED;
+import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.collection.ArraySet;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+class CompatPermissionManager {
+
+    private static final String TAG = "CompatPermissionManager";
+    public static final String ALL_SUFFIX = "_all";
+
+    private final Context mContext;
+    private final String mPrefsName;
+
+    CompatPermissionManager(Context context, String prefsName) {
+        mContext = context;
+        mPrefsName = prefsName;
+    }
+
+    private SharedPreferences getPrefs() {
+        return mContext.getSharedPreferences(mPrefsName, Context.MODE_PRIVATE);
+    }
+
+    public int checkSlicePermission(Uri uri, int pid, int uid) {
+        for (String pkg : mContext.getPackageManager().getPackagesForUid(uid)) {
+            if (checkSlicePermission(uri, pkg) == PERMISSION_GRANTED) {
+                return PERMISSION_GRANTED;
+            }
+        }
+        // Fall back to allowing uri permissions through.
+        return mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+    }
+
+    private int checkSlicePermission(Uri uri, String pkg) {
+        PermissionState state = getPermissionState(pkg, uri.getAuthority());
+        return state.hasAccess(uri.getPathSegments()) ? PERMISSION_GRANTED : PERMISSION_DENIED;
+    }
+
+    public void grantSlicePermission(Uri uri, String toPkg) {
+        PermissionState state = getPermissionState(toPkg, uri.getAuthority());
+        if (state.addPath(uri.getPathSegments())) {
+            persist(state);
+        }
+    }
+
+    public void revokeSlicePermission(Uri uri, String toPkg) {
+        PermissionState state = getPermissionState(toPkg, uri.getAuthority());
+        if (state.removePath(uri.getPathSegments())) {
+            persist(state);
+        }
+    }
+
+    private synchronized void persist(PermissionState state) {
+        if (!getPrefs().edit()
+                .putStringSet(state.getKey(), state.toPersistable())
+                .putBoolean(state.getKey() + ALL_SUFFIX, state.hasAllPermissions())
+                .commit()) {
+            Log.e(TAG, "Unable to persist permissions");
+        }
+    }
+
+    private PermissionState getPermissionState(String pkg, String authority) {
+        String key = pkg + "_" + authority;
+        Set<String> grant = getPrefs().getStringSet(key, Collections.<String>emptySet());
+        boolean hasAllPermissions = getPrefs().getBoolean(key + ALL_SUFFIX, false);
+        return new PermissionState(grant, key, hasAllPermissions);
+    }
+
+    public static class PermissionState {
+
+        private final ArraySet<String[]> mPaths = new ArraySet<>();
+        private final String mKey;
+
+        PermissionState(Set<String> grant, String key, boolean hasAllPermissions) {
+            if (hasAllPermissions) {
+                mPaths.add(new String[0]);
+            } else {
+                for (String g : grant) {
+                    mPaths.add(decodeSegments(g));
+                }
+            }
+            mKey = key;
+        }
+
+        public boolean hasAllPermissions() {
+            return hasAccess(Collections.<String>emptyList());
+        }
+
+        public String getKey() {
+            return mKey;
+        }
+
+        public Set<String> toPersistable() {
+            ArraySet<String> ret = new ArraySet<>();
+            for (String[] path : mPaths) {
+                ret.add(encodeSegments(path));
+            }
+            return ret;
+        }
+
+        public boolean hasAccess(List<String> path) {
+            String[] inPath = path.toArray(new String[path.size()]);
+            for (String[] p : mPaths) {
+                if (isPathPrefixMatch(p, inPath)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        boolean addPath(List<String> path) {
+            String[] pathSegs = path.toArray(new String[path.size()]);
+            for (int i = mPaths.size() - 1; i >= 0; i--) {
+                String[] existing = mPaths.valueAt(i);
+                if (isPathPrefixMatch(existing, pathSegs)) {
+                    // Nothing to add here.
+                    return false;
+                }
+                if (isPathPrefixMatch(pathSegs, existing)) {
+                    mPaths.removeAt(i);
+                }
+            }
+            mPaths.add(pathSegs);
+            return true;
+        }
+
+        boolean removePath(List<String> path) {
+            boolean changed = false;
+            String[] pathSegs = path.toArray(new String[path.size()]);
+            for (int i = mPaths.size() - 1; i >= 0; i--) {
+                String[] existing = mPaths.valueAt(i);
+                if (isPathPrefixMatch(pathSegs, existing)) {
+                    changed = true;
+                    mPaths.removeAt(i);
+                }
+            }
+            return changed;
+        }
+
+        private boolean isPathPrefixMatch(String[] prefix, String[] path) {
+            final int prefixSize = prefix.length;
+            if (path.length < prefixSize) return false;
+
+            for (int i = 0; i < prefixSize; i++) {
+                if (!Objects.equals(path[i], prefix[i])) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private String encodeSegments(String[] s) {
+            String[] out = new String[s.length];
+            for (int i = 0; i < s.length; i++) {
+                out[i] = Uri.encode(s[i]);
+            }
+            return TextUtils.join("/", out);
+        }
+
+        private String[] decodeSegments(String s) {
+            String[] sets = s.split("/", -1);
+            for (int i = 0; i < sets.length; i++) {
+                sets[i] = Uri.decode(sets[i]);
+            }
+            return sets;
+        }
+    }
+}
diff --git a/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java b/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java
index 56b8122..da602f5 100644
--- a/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java
+++ b/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java
@@ -28,6 +28,8 @@
 import androidx.core.util.ObjectsCompat;
 import androidx.slice.SliceSpec;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -70,6 +72,22 @@
         return prefs;
     }
 
+    /**
+     * Get pinned specs
+     */
+    public List<Uri> getPinnedSlices() {
+        List<Uri> pinned = new ArrayList<>();
+        for (String key : getPrefs().getAll().keySet()) {
+            if (key.startsWith(PIN_PREFIX)) {
+                Uri uri = Uri.parse(key.substring(PIN_PREFIX.length()));
+                if (!getPins(uri).isEmpty()) {
+                    pinned.add(uri);
+                }
+            }
+        }
+        return pinned;
+    }
+
     private Set<String> getPins(Uri uri) {
         return getPrefs().getStringSet(PIN_PREFIX + uri.toString(), new ArraySet<String>());
     }
@@ -85,8 +103,8 @@
         if (TextUtils.isEmpty(specNamesStr) || TextUtils.isEmpty(specRevsStr)) {
             return new ArraySet<>();
         }
-        String[] specNames = specNamesStr.split(",");
-        String[] specRevs = specRevsStr.split(",");
+        String[] specNames = specNamesStr.split(",", -1);
+        String[] specRevs = specRevsStr.split(",", -1);
         if (specNames.length != specRevs.length) {
             return new ArraySet<>();
         }
diff --git a/slices/core/src/main/java/androidx/slice/compat/SlicePermissionActivity.java b/slices/core/src/main/java/androidx/slice/compat/SlicePermissionActivity.java
index f3270f8..5fa33ae 100644
--- a/slices/core/src/main/java/androidx/slice/compat/SlicePermissionActivity.java
+++ b/slices/core/src/main/java/androidx/slice/compat/SlicePermissionActivity.java
@@ -20,16 +20,20 @@
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.content.DialogInterface.OnDismissListener;
-import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
+import android.text.Html;
+import android.text.TextPaint;
+import android.text.TextUtils;
 import android.util.Log;
 import android.widget.TextView;
 
 import androidx.annotation.RestrictTo;
 import androidx.appcompat.app.AlertDialog;
+import androidx.core.text.BidiFormatter;
 import androidx.slice.core.R;
 
 /**
@@ -40,6 +44,8 @@
 public class SlicePermissionActivity extends Activity implements OnClickListener,
         OnDismissListener {
 
+    private static final float MAX_LABEL_SIZE_PX = 500f;
+
     private static final String TAG = "SlicePermissionActivity";
 
     private Uri mUri;
@@ -56,8 +62,12 @@
 
         try {
             PackageManager pm = getPackageManager();
-            CharSequence app1 = pm.getApplicationInfo(mCallingPkg, 0).loadLabel(pm);
-            CharSequence app2 = pm.getApplicationInfo(mProviderPkg, 0).loadLabel(pm);
+            CharSequence app1 = BidiFormatter.getInstance().unicodeWrap(
+                    loadSafeLabel(pm, pm.getApplicationInfo(mCallingPkg, 0))
+                    .toString());
+            CharSequence app2 = BidiFormatter.getInstance().unicodeWrap(
+                    loadSafeLabel(pm, pm.getApplicationInfo(mProviderPkg, 0))
+                    .toString());
             AlertDialog dialog = new AlertDialog.Builder(this)
                     .setTitle(getString(R.string.abc_slice_permission_title, app1, app2))
                     .setView(R.layout.abc_slice_permission_request)
@@ -75,14 +85,50 @@
         }
     }
 
+    // Based on loadSafeLabel in PackageitemInfo
+    private CharSequence loadSafeLabel(PackageManager pm, ApplicationInfo appInfo) {
+        // loadLabel() always returns non-null
+        String label = appInfo.loadLabel(pm).toString();
+        // strip HTML tags to avoid <br> and other tags overwriting original message
+        String labelStr = Html.fromHtml(label).toString();
+
+        // If the label contains new line characters it may push the UI
+        // down to hide a part of it. Labels shouldn't have new line
+        // characters, so just truncate at the first time one is seen.
+        final int labelLength = labelStr.length();
+        int offset = 0;
+        while (offset < labelLength) {
+            final int codePoint = labelStr.codePointAt(offset);
+            final int type = Character.getType(codePoint);
+            if (type == Character.LINE_SEPARATOR
+                    || type == Character.CONTROL
+                    || type == Character.PARAGRAPH_SEPARATOR) {
+                labelStr = labelStr.substring(0, offset);
+                break;
+            }
+            // replace all non-break space to " " in order to be trimmed
+            if (type == Character.SPACE_SEPARATOR) {
+                labelStr = labelStr.substring(0, offset) + " " + labelStr.substring(offset
+                        + Character.charCount(codePoint));
+            }
+            offset += Character.charCount(codePoint);
+        }
+
+        labelStr = labelStr.trim();
+        if (labelStr.isEmpty()) {
+            return appInfo.packageName;
+        }
+        TextPaint paint = new TextPaint();
+        paint.setTextSize(42);
+
+        return TextUtils.ellipsize(labelStr, paint, MAX_LABEL_SIZE_PX, TextUtils.TruncateAt.END);
+    }
+
     @Override
     public void onClick(DialogInterface dialog, int which) {
         if (which == DialogInterface.BUTTON_POSITIVE) {
-            grantUriPermission(mCallingPkg, mUri.buildUpon().path("").build(),
-                    Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
-                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
-                            | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
-            getContentResolver().notifyChange(mUri, null);
+            SliceProviderCompat.grantSlicePermission(this, getPackageName(), mCallingPkg,
+                    mUri.buildUpon().path("").build());
         }
         finish();
     }
diff --git a/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java b/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
index 61bc65e..d62e9b5 100644
--- a/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
+++ b/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
@@ -15,19 +15,29 @@
  */
 package androidx.slice.compat;
 
+import static android.app.slice.SliceManager.CATEGORY_SLICE;
+import static android.app.slice.SliceManager.SLICE_METADATA_KEY;
 import static android.app.slice.SliceProvider.SLICE_TYPE;
 
+import static androidx.core.content.PermissionChecker.PERMISSION_DENIED;
+
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.Parcelable;
+import android.os.Process;
 import android.os.RemoteException;
+import android.os.StrictMode;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -36,8 +46,8 @@
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
 import androidx.slice.Slice;
+import androidx.slice.SliceProvider;
 import androidx.slice.SliceSpec;
-import androidx.slice.core.SliceHints;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -51,8 +61,12 @@
 @RestrictTo(Scope.LIBRARY)
 public class SliceProviderCompat {
     private static final String TAG = "SliceProviderCompat";
+    private static final String DATA_PREFIX = "slice_data_";
+    private static final String PERMS_PREFIX = "slice_perms_";
+    private static final String ALL_FILES = DATA_PREFIX + "all_slice_files";
 
-    public static final String EXTRA_BIND_URI = "slice_uri";
+    private static final long SLICE_BIND_ANR = 2000;
+
     public static final String METHOD_SLICE = "bind_slice";
     public static final String METHOD_MAP_INTENT = "map_slice";
     public static final String METHOD_PIN = "pin_slice";
@@ -60,7 +74,11 @@
     public static final String METHOD_GET_PINNED_SPECS = "get_specs";
     public static final String METHOD_MAP_ONLY_INTENT = "map_only";
     public static final String METHOD_GET_DESCENDANTS = "get_descendants";
+    public static final String METHOD_CHECK_PERMISSION = "check_perms";
+    public static final String METHOD_GRANT_PERMISSION = "grant_perms";
+    public static final String METHOD_REVOKE_PERMISSION = "revoke_perms";
 
+    public static final String EXTRA_BIND_URI = "slice_uri";
     public static final String EXTRA_INTENT = "slice_intent";
     public static final String EXTRA_SLICE = "slice";
     public static final String EXTRA_SUPPORTED_SPECS = "specs";
@@ -68,6 +86,202 @@
     public static final String EXTRA_PKG = "pkg";
     public static final String EXTRA_PROVIDER_PKG = "provider_pkg";
     public static final String EXTRA_SLICE_DESCENDANTS = "slice_descendants";
+    public static final String EXTRA_UID = "uid";
+    public static final String EXTRA_PID = "pid";
+    public static final String EXTRA_RESULT = "result";
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+    private String mCallback;
+    private final SliceProvider mProvider;
+    private CompatPinnedList mPinnedList;
+    private CompatPermissionManager mPermissionManager;
+
+    public SliceProviderCompat(SliceProvider provider) {
+        mProvider = provider;
+        String prefsFile = DATA_PREFIX + getClass().getName();
+        SharedPreferences allFiles = provider.getContext().getSharedPreferences(ALL_FILES, 0);
+        Set<String> files = allFiles.getStringSet(ALL_FILES, Collections.<String>emptySet());
+        if (!files.contains(prefsFile)) {
+            // Make sure this is editable.
+            files = new ArraySet<>(files);
+            files.add(prefsFile);
+            allFiles.edit()
+                    .putStringSet(ALL_FILES, files)
+                    .commit();
+        }
+        mPinnedList = new CompatPinnedList(provider.getContext(), prefsFile);
+        mPermissionManager = new CompatPermissionManager(provider.getContext(),
+                PERMS_PREFIX + getClass().getName());
+    }
+
+    private Context getContext() {
+        return mProvider.getContext();
+    }
+
+    private String getCallingPackage() {
+        return mProvider.getCallingPackage();
+    }
+
+    /**
+     * Called by SliceProvider when compat is needed.
+     */
+    public Bundle call(String method, String arg, Bundle extras) {
+        if (method.equals(METHOD_SLICE)) {
+            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
+            Set<SliceSpec> specs = getSpecs(extras);
+
+            Slice s = handleBindSlice(uri, specs, getCallingPackage());
+            Bundle b = new Bundle();
+            b.putParcelable(EXTRA_SLICE, s.toBundle());
+            return b;
+        } else if (method.equals(METHOD_MAP_INTENT)) {
+            Intent intent = extras.getParcelable(EXTRA_INTENT);
+            Uri uri = mProvider.onMapIntentToUri(intent);
+            Bundle b = new Bundle();
+            if (uri != null) {
+                Set<SliceSpec> specs = getSpecs(extras);
+                Slice s = handleBindSlice(uri, specs, getCallingPackage());
+                b.putParcelable(EXTRA_SLICE, s.toBundle());
+            } else {
+                b.putParcelable(EXTRA_SLICE, null);
+            }
+            return b;
+        } else if (method.equals(METHOD_MAP_ONLY_INTENT)) {
+            Intent intent = extras.getParcelable(EXTRA_INTENT);
+            Uri uri = mProvider.onMapIntentToUri(intent);
+            Bundle b = new Bundle();
+            b.putParcelable(EXTRA_SLICE, uri);
+            return b;
+        } else if (method.equals(METHOD_PIN)) {
+            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
+            Set<SliceSpec> specs = getSpecs(extras);
+            String pkg = extras.getString(EXTRA_PKG);
+            if (mPinnedList.addPin(uri, pkg, specs)) {
+                handleSlicePinned(uri);
+            }
+            return null;
+        } else if (method.equals(METHOD_UNPIN)) {
+            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
+            String pkg = extras.getString(EXTRA_PKG);
+            if (mPinnedList.removePin(uri, pkg)) {
+                handleSliceUnpinned(uri);
+            }
+            return null;
+        } else if (method.equals(METHOD_GET_PINNED_SPECS)) {
+            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
+            Bundle b = new Bundle();
+            addSpecs(b, mPinnedList.getSpecs(uri));
+            return b;
+        } else if (method.equals(METHOD_GET_DESCENDANTS)) {
+            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
+            Bundle b = new Bundle();
+            b.putParcelableArrayList(EXTRA_SLICE_DESCENDANTS,
+                    new ArrayList<>(handleGetDescendants(uri)));
+            return b;
+        } else if (method.equals(METHOD_CHECK_PERMISSION)) {
+            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
+            String pkg = extras.getString(EXTRA_PKG);
+            int pid = extras.getInt(EXTRA_PID);
+            int uid = extras.getInt(EXTRA_UID);
+            Bundle b = new Bundle();
+            b.putInt(EXTRA_RESULT, mPermissionManager.checkSlicePermission(uri, pid, uid));
+            return b;
+        } else if (method.equals(METHOD_GRANT_PERMISSION)) {
+            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
+            String toPkg = extras.getString(EXTRA_PKG);
+            if (Binder.getCallingUid() != Process.myUid()) {
+                throw new SecurityException("Only the owning process can manage slice permissions");
+            }
+            mPermissionManager.grantSlicePermission(uri, toPkg);
+        } else if (method.equals(METHOD_REVOKE_PERMISSION)) {
+            Uri uri = extras.getParcelable(EXTRA_BIND_URI);
+            String toPkg = extras.getString(EXTRA_PKG);
+            if (Binder.getCallingUid() != Process.myUid()) {
+                throw new SecurityException("Only the owning process can manage slice permissions");
+            }
+            mPermissionManager.revokeSlicePermission(uri, toPkg);
+        }
+        return null;
+    }
+
+    private Collection<Uri> handleGetDescendants(Uri uri) {
+        mCallback = "onGetSliceDescendants";
+        mHandler.postDelayed(mAnr, SLICE_BIND_ANR);
+        try {
+            return mProvider.onGetSliceDescendants(uri);
+        } finally {
+            mHandler.removeCallbacks(mAnr);
+        }
+    }
+
+    private void handleSlicePinned(final Uri sliceUri) {
+        mCallback = "onSlicePinned";
+        mHandler.postDelayed(mAnr, SLICE_BIND_ANR);
+        try {
+            mProvider.onSlicePinned(sliceUri);
+        } finally {
+            mHandler.removeCallbacks(mAnr);
+        }
+    }
+
+    private void handleSliceUnpinned(final Uri sliceUri) {
+        mCallback = "onSliceUnpinned";
+        mHandler.postDelayed(mAnr, SLICE_BIND_ANR);
+        try {
+            mProvider.onSliceUnpinned(sliceUri);
+        } finally {
+            mHandler.removeCallbacks(mAnr);
+        }
+    }
+
+    private Slice handleBindSlice(final Uri sliceUri, final Set<SliceSpec> specs,
+            final String callingPkg) {
+        // This can be removed once Slice#bindSlice is removed and everyone is using
+        // SliceManager#bindSlice.
+        String pkg = callingPkg != null ? callingPkg
+                : getContext().getPackageManager().getNameForUid(Binder.getCallingUid());
+        if (Binder.getCallingUid() != Process.myUid()) {
+            try {
+                getContext().enforceUriPermission(sliceUri,
+                        Binder.getCallingPid(), Binder.getCallingUid(),
+                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+                        "Slice binding requires write access to Uri");
+            } catch (SecurityException e) {
+                return mProvider.createPermissionSlice(getContext(), sliceUri, pkg);
+            }
+        }
+        return onBindSliceStrict(sliceUri, specs);
+    }
+
+    private Slice onBindSliceStrict(Uri sliceUri, Set<SliceSpec> specs) {
+        StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
+        mCallback = "onBindSlice";
+        mHandler.postDelayed(mAnr, SLICE_BIND_ANR);
+        try {
+            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
+                    .detectAll()
+                    .penaltyDeath()
+                    .build());
+            SliceProvider.setSpecs(specs);
+            try {
+                return mProvider.onBindSlice(sliceUri);
+            } finally {
+                SliceProvider.setSpecs(null);
+                mHandler.removeCallbacks(mAnr);
+            }
+        } finally {
+            StrictMode.setThreadPolicy(oldPolicy);
+        }
+    }
+
+    private final Runnable mAnr = new Runnable() {
+        @Override
+        public void run() {
+            Process.sendSignal(Process.myPid(), Process.SIGNAL_QUIT);
+            Log.wtf(TAG, "Timed out while handling slice callback " + mCallback);
+        }
+    };
 
     /**
      * Compat version of {@link Slice#bindSlice}.
@@ -137,6 +351,10 @@
      */
     public static Slice bindSlice(Context context, Intent intent,
             Set<SliceSpec> supportedSpecs) {
+        Preconditions.checkNotNull(intent, "intent");
+        Preconditions.checkArgument(intent.getComponent() != null || intent.getPackage() != null
+                || intent.getData() != null,
+                String.format("Slice intent must be explicit %s", intent));
         ContentResolver resolver = context.getContentResolver();
 
         // Check if the intent has data for the slice uri on it and use that
@@ -145,10 +363,24 @@
             return bindSlice(context, intentData, supportedSpecs);
         }
         // Otherwise ask the app
+        Intent queryIntent = new Intent(intent);
+        if (!queryIntent.hasCategory(CATEGORY_SLICE)) {
+            queryIntent.addCategory(CATEGORY_SLICE);
+        }
         List<ResolveInfo> providers =
-                context.getPackageManager().queryIntentContentProviders(intent, 0);
-        if (providers == null) {
-            throw new IllegalArgumentException("Unable to resolve intent " + intent);
+                context.getPackageManager().queryIntentContentProviders(queryIntent, 0);
+        if (providers == null || providers.isEmpty()) {
+            // There are no providers, see if this activity has a direct link.
+            ResolveInfo resolve = context.getPackageManager().resolveActivity(intent,
+                    PackageManager.GET_META_DATA);
+            if (resolve != null && resolve.activityInfo != null
+                    && resolve.activityInfo.metaData != null
+                    && resolve.activityInfo.metaData.containsKey(SLICE_METADATA_KEY)) {
+                return bindSlice(context, Uri.parse(
+                        resolve.activityInfo.metaData.getString(SLICE_METADATA_KEY)),
+                        supportedSpecs);
+            }
+            return null;
         }
         String authority = providers.get(0).providerInfo.authority;
         Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
@@ -258,7 +490,8 @@
      */
     public static Uri mapIntentToUri(Context context, Intent intent) {
         Preconditions.checkNotNull(intent, "intent");
-        Preconditions.checkArgument(intent.getComponent() != null || intent.getPackage() != null,
+        Preconditions.checkArgument(intent.getComponent() != null || intent.getPackage() != null
+                || intent.getData() != null,
                 String.format("Slice intent must be explicit %s", intent));
         ContentResolver resolver = context.getContentResolver();
 
@@ -268,17 +501,21 @@
             return intentData;
         }
         // Otherwise ask the app
+        Intent queryIntent = new Intent(intent);
+        if (!queryIntent.hasCategory(CATEGORY_SLICE)) {
+            queryIntent.addCategory(CATEGORY_SLICE);
+        }
         List<ResolveInfo> providers =
-                context.getPackageManager().queryIntentContentProviders(intent, 0);
+                context.getPackageManager().queryIntentContentProviders(queryIntent, 0);
         if (providers == null || providers.isEmpty()) {
             // There are no providers, see if this activity has a direct link.
             ResolveInfo resolve = context.getPackageManager().resolveActivity(intent,
                     PackageManager.GET_META_DATA);
             if (resolve != null && resolve.activityInfo != null
                     && resolve.activityInfo.metaData != null
-                    && resolve.activityInfo.metaData.containsKey(SliceHints.SLICE_METADATA_KEY)) {
+                    && resolve.activityInfo.metaData.containsKey(SLICE_METADATA_KEY)) {
                 return Uri.parse(
-                        resolve.activityInfo.metaData.getString(SliceHints.SLICE_METADATA_KEY));
+                        resolve.activityInfo.metaData.getString(SLICE_METADATA_KEY));
             }
             return null;
         }
@@ -319,6 +556,73 @@
         return Collections.emptyList();
     }
 
-    private SliceProviderCompat() {
+    /**
+     * Compat version of {@link android.app.slice.SliceManager#checkSlicePermission}.
+     */
+    public static int checkSlicePermission(Context context, String packageName, Uri uri, int pid,
+            int uid) {
+        ContentResolver resolver = context.getContentResolver();
+        try (ContentProviderClient provider = resolver.acquireContentProviderClient(uri)) {
+            Bundle extras = new Bundle();
+            extras.putParcelable(EXTRA_BIND_URI, uri);
+            extras.putString(EXTRA_PKG, packageName);
+            extras.putInt(EXTRA_PID, pid);
+            extras.putInt(EXTRA_UID, uid);
+
+            final Bundle res = provider.call(METHOD_CHECK_PERMISSION, null, extras);
+            return res.getInt(EXTRA_RESULT);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to check slice permission", e);
+        }
+        return PERMISSION_DENIED;
+    }
+
+    /**
+     * Compat version of {@link android.app.slice.SliceManager#grantSlicePermission}.
+     */
+    public static void grantSlicePermission(Context context, String packageName, String toPackage,
+            Uri uri) {
+        ContentResolver resolver = context.getContentResolver();
+        try (ContentProviderClient provider = resolver.acquireContentProviderClient(uri)) {
+            Bundle extras = new Bundle();
+            extras.putParcelable(EXTRA_BIND_URI, uri);
+            extras.putString(EXTRA_PROVIDER_PKG, packageName);
+            extras.putString(EXTRA_PKG, toPackage);
+
+            provider.call(METHOD_GRANT_PERMISSION, null, extras);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to get slice descendants", e);
+        }
+    }
+
+    /**
+     * Compat version of {@link android.app.slice.SliceManager#revokeSlicePermission}.
+     */
+    public static void revokeSlicePermission(Context context, String packageName, String toPackage,
+            Uri uri) {
+        ContentResolver resolver = context.getContentResolver();
+        try (ContentProviderClient provider = resolver.acquireContentProviderClient(uri)) {
+            Bundle extras = new Bundle();
+            extras.putParcelable(EXTRA_BIND_URI, uri);
+            extras.putString(EXTRA_PROVIDER_PKG, packageName);
+            extras.putString(EXTRA_PKG, toPackage);
+
+            provider.call(METHOD_REVOKE_PERMISSION, null, extras);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to get slice descendants", e);
+        }
+    }
+
+    /**
+     * Compat version of {@link android.app.slice.SliceManager#getPinnedSlices}.
+     */
+    public static List<Uri> getPinnedSlices(Context context) {
+        ArrayList<Uri> pinnedSlices = new ArrayList<>();
+        SharedPreferences prefs = context.getSharedPreferences(ALL_FILES, 0);
+        Set<String> prefSet = prefs.getStringSet(ALL_FILES, Collections.<String>emptySet());
+        for (String pref : prefSet) {
+            pinnedSlices.addAll(new CompatPinnedList(context, pref).getPinnedSlices());
+        }
+        return pinnedSlices;
     }
 }
diff --git a/slices/core/src/main/java/androidx/slice/compat/SliceProviderWrapperContainer.java b/slices/core/src/main/java/androidx/slice/compat/SliceProviderWrapperContainer.java
index 8641530..c35793e 100644
--- a/slices/core/src/main/java/androidx/slice/compat/SliceProviderWrapperContainer.java
+++ b/slices/core/src/main/java/androidx/slice/compat/SliceProviderWrapperContainer.java
@@ -29,11 +29,10 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
-import androidx.collection.ArraySet;
 import androidx.slice.SliceConvert;
 
 import java.util.Collection;
-import java.util.List;
+import java.util.Set;
 
 /**
  * @hide
@@ -64,8 +63,8 @@
         }
 
         @Override
-        public Slice onBindSlice(Uri sliceUri, List<SliceSpec> supportedVersions) {
-            androidx.slice.SliceProvider.setSpecs(new ArraySet<>(wrap(supportedVersions)));
+        public Slice onBindSlice(Uri sliceUri, Set<SliceSpec> supportedVersions) {
+            androidx.slice.SliceProvider.setSpecs(wrap(supportedVersions));
             try {
                 return SliceConvert.unwrap(mSliceProvider.onBindSlice(sliceUri));
             } finally {
diff --git a/slices/view/api/current.txt b/slices/view/api/current.txt
index 5a37826..aa95b81 100644
--- a/slices/view/api/current.txt
+++ b/slices/view/api/current.txt
@@ -5,6 +5,8 @@
     method public abstract androidx.slice.Slice bindSlice(android.content.Intent);
     method public abstract int checkSlicePermission(android.net.Uri, int, int);
     method public static androidx.slice.SliceManager getInstance(android.content.Context);
+    method public abstract java.util.List<android.net.Uri> getPinnedSlices();
+    method public abstract java.util.Set<androidx.slice.SliceSpec> getPinnedSpecs(android.net.Uri);
     method public abstract java.util.Collection<android.net.Uri> getSliceDescendants(android.net.Uri);
     method public abstract void grantSlicePermission(java.lang.String, android.net.Uri);
     method public abstract android.net.Uri mapIntentToUri(android.content.Intent);
diff --git a/slices/view/build.gradle b/slices/view/build.gradle
index 38576c3..d214a19 100644
--- a/slices/view/build.gradle
+++ b/slices/view/build.gradle
@@ -34,9 +34,6 @@
     androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
 }
 
-android {
-}
-
 supportLibrary {
     name = "Slice views"
     publish = true
@@ -45,4 +42,6 @@
     inceptionYear = "2017"
     description = "A library that handles rendering of slice content into supported templates"
     minSdkVersion = 19
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/slices/view/src/androidTest/AndroidManifest.xml b/slices/view/src/androidTest/AndroidManifest.xml
index 78f3ad8..7c90f90 100644
--- a/slices/view/src/androidTest/AndroidManifest.xml
+++ b/slices/view/src/androidTest/AndroidManifest.xml
@@ -27,6 +27,7 @@
                   android:exported="true">
             <intent-filter>
                 <action android:name="androidx.slice.action.TEST" />
+                <category android:name="android.app.slice.category.SLICE" />
             </intent-filter>
         </provider>
 
diff --git a/slices/view/src/androidTest/java/androidx/slice/SliceManagerTest.java b/slices/view/src/androidTest/java/androidx/slice/SliceManagerTest.java
index 5564f72..465db2b 100644
--- a/slices/view/src/androidTest/java/androidx/slice/SliceManagerTest.java
+++ b/slices/view/src/androidTest/java/androidx/slice/SliceManagerTest.java
@@ -17,6 +17,7 @@
 package androidx.slice;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
@@ -37,7 +38,6 @@
 import androidx.annotation.NonNull;
 import androidx.core.os.BuildCompat;
 import androidx.slice.render.SliceRenderActivity;
-import androidx.slice.widget.SliceLiveData;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -45,6 +45,7 @@
 
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.Executor;
 
 @RunWith(AndroidJUnit4.class)
@@ -89,6 +90,28 @@
     }
 
     @Test
+    public void testPinList() {
+        Uri uri = new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(mContext.getPackageName())
+                .build();
+        Uri longerUri = uri.buildUpon().appendPath("something").build();
+        try {
+            mManager.pinSlice(uri);
+            mManager.pinSlice(longerUri);
+            verify(mSliceProvider, timeout(2000)).onSlicePinned(eq(longerUri));
+
+            List<Uri> uris = mManager.getPinnedSlices();
+            assertEquals(2, uris.size());
+            assertTrue(uris.contains(uri));
+            assertTrue(uris.contains(longerUri));
+        } finally {
+            mManager.unpinSlice(uri);
+            mManager.unpinSlice(longerUri);
+        }
+    }
+
+    @Test
     public void testCallback() {
         if (BuildCompat.isAtLeastP()) {
             return;
@@ -124,7 +147,8 @@
         mManager.pinSlice(uri);
         verify(mSliceProvider).onSlicePinned(eq(uri));
 
-        assertEquals(SliceLiveData.SUPPORTED_SPECS, mManager.getPinnedSpecs(uri));
+        // Disabled while we update APIs.
+        //assertEquals(SliceLiveData.SUPPORTED_SPECS, mManager.getPinnedSpecs(uri));
     }
 
     @Test
@@ -145,8 +169,8 @@
         when(mSliceProvider.onMapIntentToUri(eq(intent))).thenReturn(expected);
         Uri uri = mManager.mapIntentToUri(intent);
 
-        assertEquals(expected, uri);
         verify(mSliceProvider).onMapIntentToUri(eq(intent));
+        assertEquals(expected, uri);
     }
 
     @Test
diff --git a/slices/view/src/androidTest/java/androidx/slice/SlicePermissionTest.java b/slices/view/src/androidTest/java/androidx/slice/SlicePermissionTest.java
new file mode 100644
index 0000000..ffb65e0
--- /dev/null
+++ b/slices/view/src/androidTest/java/androidx/slice/SlicePermissionTest.java
@@ -0,0 +1,185 @@
+/*
+ * 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.slice;
+
+import static androidx.core.content.PermissionChecker.PERMISSION_DENIED;
+import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.os.Process;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class SlicePermissionTest {
+
+    private static final Uri BASE_URI = Uri.parse("content://androidx.slice.view.test/");
+    private final Context mContext = InstrumentationRegistry.getContext();
+    private String mTestPkg;
+    private int mTestUid;
+    private int mTestPid;
+    private SliceManager mSliceManager;
+
+    @Before
+    public void setup() throws NameNotFoundException {
+        mSliceManager = SliceManager.getInstance(mContext);
+        mTestPkg = mContext.getPackageName();
+        mTestUid = mContext.getPackageManager().getPackageUid(mTestPkg, 0);
+        mTestPid = Process.myPid();
+    }
+
+    @After
+    public void tearDown() {
+        mSliceManager.revokeSlicePermission(mTestPkg, BASE_URI);
+    }
+
+    @Test
+    public void testGrant() {
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+
+        mSliceManager.grantSlicePermission(mTestPkg, BASE_URI);
+
+        assertEquals(PERMISSION_GRANTED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+    }
+
+    @Test
+    public void testGrantParent() {
+        Uri uri = BASE_URI.buildUpon()
+                .appendPath("something")
+                .build();
+
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(uri, mTestPid, mTestUid));
+
+        mSliceManager.grantSlicePermission(mTestPkg, BASE_URI);
+
+        assertEquals(PERMISSION_GRANTED,
+                mSliceManager.checkSlicePermission(uri, mTestPid, mTestUid));
+    }
+
+    @Test
+    public void testGrantParentExpands() {
+        Uri uri = BASE_URI.buildUpon()
+                .appendPath("something")
+                .build();
+
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(uri, mTestPid, mTestUid));
+
+        mSliceManager.grantSlicePermission(mTestPkg, uri);
+
+        // Only sub-path granted.
+        assertEquals(PERMISSION_GRANTED,
+                mSliceManager.checkSlicePermission(uri, mTestPid, mTestUid));
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+
+        mSliceManager.grantSlicePermission(mTestPkg, BASE_URI);
+
+        // Now all granted.
+        assertEquals(PERMISSION_GRANTED,
+                mSliceManager.checkSlicePermission(uri, mTestPid, mTestUid));
+        assertEquals(PERMISSION_GRANTED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+    }
+
+    @Test
+    public void testGrantChild() {
+        Uri uri = BASE_URI.buildUpon()
+                .appendPath("something")
+                .build();
+
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+
+        mSliceManager.grantSlicePermission(mTestPkg, uri);
+
+        // Still no permission because only a child was granted
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+    }
+
+    @Test
+    public void testRevoke() {
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+
+        mSliceManager.grantSlicePermission(mTestPkg, BASE_URI);
+
+        assertEquals(PERMISSION_GRANTED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+
+        mSliceManager.revokeSlicePermission(mTestPkg, BASE_URI);
+
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+    }
+
+    @Test
+    public void testRevokeParent() {
+        Uri uri = BASE_URI.buildUpon()
+                .appendPath("something")
+                .build();
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(uri, mTestPid, mTestUid));
+
+        mSliceManager.grantSlicePermission(mTestPkg, uri);
+
+        assertEquals(PERMISSION_GRANTED,
+                mSliceManager.checkSlicePermission(uri, mTestPid, mTestUid));
+
+        mSliceManager.revokeSlicePermission(mTestPkg, BASE_URI);
+
+        // Revoked because parent was revoked
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(uri, mTestPid, mTestUid));
+    }
+
+    @Test
+    public void testRevokeChild() {
+        Uri uri = BASE_URI.buildUpon()
+                .appendPath("something")
+                .build();
+        assertEquals(PERMISSION_DENIED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+
+        mSliceManager.grantSlicePermission(mTestPkg, BASE_URI);
+
+        assertEquals(PERMISSION_GRANTED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+
+        mSliceManager.revokeSlicePermission(mTestPkg, uri);
+
+        // Not revoked because child was revoked.
+        assertEquals(PERMISSION_GRANTED,
+                mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
+    }
+
+}
diff --git a/slices/view/src/main/java/androidx/slice/SliceManager.java b/slices/view/src/main/java/androidx/slice/SliceManager.java
index 63c56e8..83febcc 100644
--- a/slices/view/src/main/java/androidx/slice/SliceManager.java
+++ b/slices/view/src/main/java/androidx/slice/SliceManager.java
@@ -28,6 +28,7 @@
 import androidx.core.os.BuildCompat;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Executor;
 
@@ -125,10 +126,8 @@
      * <p>
      * This is the set of specs supported for a specific pinned slice. It will take
      * into account all clients and returns only specs supported by all.
-     * @hide
      * @see SliceSpec
      */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public abstract @NonNull Set<SliceSpec> getPinnedSpecs(@NonNull Uri uri);
 
     /**
@@ -141,9 +140,8 @@
     public abstract @Nullable Slice bindSlice(@NonNull Uri uri);
 
     /**
-     * Turns a slice intent into slice content. Expects an explicit intent. If there is no
-     * {@link android.content.ContentProvider} associated with the given intent this will throw
-     * {@link IllegalArgumentException}.
+     * Turns a slice intent into slice content. Is a shortcut to perform the action
+     * of both {@link #mapIntentToUri(Intent)} and {@link #bindSlice(Uri)} at once.
      *
      * @param intent The intent associated with a slice.
      * @return The Slice provided by the app or null if none is given.
@@ -154,12 +152,23 @@
     public abstract @Nullable Slice bindSlice(@NonNull Intent intent);
 
     /**
-     * Turns a slice intent into a slice uri. Expects an explicit intent. If there is no
-     * {@link android.content.ContentProvider} associated with the given intent this will throw
-     * {@link IllegalArgumentException}.
-     *
+     * Turns a slice intent into a slice uri. Expects an explicit intent.
+     * <p>
+     * This goes through a several stage resolution process to determine if any slice
+     * can represent this intent.
+     * <ol>
+     *  <li> If the intent contains data that {@link android.content.ContentResolver#getType} is
+     *  {@link android.app.slice.SliceProvider#SLICE_TYPE} then the data will be returned.</li>
+     *  <li>If the intent explicitly points at an activity, and that activity has
+     *  meta-data for key {@link android.app.slice.SliceManager#SLICE_METADATA_KEY},
+     *  then the Uri specified there will be returned.</li>
+     *  <li>Lastly, if the intent with {@link android.app.slice.SliceManager#CATEGORY_SLICE} added
+     *  resolves to a provider, then the provider will be asked to
+     *  {@link SliceProvider#onMapIntentToUri} and that result will be returned.</li>
+     *  <li>If no slice is found, then {@code null} is returned.</li>
+     * </ol>
      * @param intent The intent associated with a slice.
-     * @return The Slice Uri provided by the app or null if none is given.
+     * @return The Slice Uri provided by the app or null if none exists.
      * @see Slice
      * @see SliceProvider#onMapIntentToUri(Intent)
      * @see Intent
@@ -223,6 +232,12 @@
     public abstract @NonNull Collection<Uri> getSliceDescendants(@NonNull Uri uri);
 
     /**
+     * Get the list of currently pinned slices for this app.
+     * @see SliceProvider#onSlicePinned
+     */
+    public abstract @NonNull List<Uri> getPinnedSlices();
+
+    /**
      * Class that listens to changes in {@link Slice}s.
      */
     public interface SliceCallback {
diff --git a/slices/view/src/main/java/androidx/slice/SliceManagerBase.java b/slices/view/src/main/java/androidx/slice/SliceManagerBase.java
index fb9fccd..5192dad 100644
--- a/slices/view/src/main/java/androidx/slice/SliceManagerBase.java
+++ b/slices/view/src/main/java/androidx/slice/SliceManagerBase.java
@@ -19,11 +19,9 @@
 import static androidx.slice.widget.SliceLiveData.SUPPORTED_SPECS;
 
 import android.content.Context;
-import android.content.Intent;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.AsyncTask;
-import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.ArrayMap;
@@ -31,7 +29,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
-import androidx.core.content.PermissionChecker;
 
 import java.util.concurrent.Executor;
 
@@ -71,31 +68,6 @@
         if (impl != null) impl.stopListening();
     }
 
-    @Override
-    @PermissionChecker.PermissionResult
-    public int checkSlicePermission(@NonNull Uri uri, int pid, int uid) {
-        // TODO: Switch off Uri permissions.
-        return mContext.checkUriPermission(uri, pid, uid,
-                Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
-    }
-
-    @Override
-    public void grantSlicePermission(@NonNull String toPackage, @NonNull Uri uri) {
-        // TODO: Switch off Uri permissions.
-        mContext.grantUriPermission(toPackage, uri,
-                Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
-                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
-                        | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
-    }
-
-    @Override
-    public void revokeSlicePermission(@NonNull String toPackage, @NonNull Uri uri) {
-        // TODO: Switch off Uri permissions.
-        if (Build.VERSION.SDK_INT >= 26) {
-            mContext.revokeUriPermission(toPackage, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
-        }
-    }
-
 
     private SliceListenerImpl getListener(Uri uri, SliceCallback callback,
             SliceListenerImpl listener) {
diff --git a/slices/view/src/main/java/androidx/slice/SliceManagerCompat.java b/slices/view/src/main/java/androidx/slice/SliceManagerCompat.java
index 1badbb4..0018c13 100644
--- a/slices/view/src/main/java/androidx/slice/SliceManagerCompat.java
+++ b/slices/view/src/main/java/androidx/slice/SliceManagerCompat.java
@@ -29,6 +29,7 @@
 import androidx.slice.widget.SliceLiveData;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Set;
 
 
@@ -76,7 +77,30 @@
     }
 
     @Override
+    public int checkSlicePermission(Uri uri, int pid, int uid) {
+        return SliceProviderCompat.checkSlicePermission(mContext, mContext.getPackageName(), uri,
+                pid, uid);
+    }
+
+    @Override
+    public void grantSlicePermission(String toPackage, Uri uri) {
+        SliceProviderCompat.grantSlicePermission(mContext, mContext.getPackageName(), toPackage,
+                uri);
+    }
+
+    @Override
+    public void revokeSlicePermission(String toPackage, Uri uri) {
+        SliceProviderCompat.revokeSlicePermission(mContext, mContext.getPackageName(), toPackage,
+                uri);
+    }
+
+    @Override
     public Collection<Uri> getSliceDescendants(Uri uri) {
         return SliceProviderCompat.getSliceDescendants(mContext, uri);
     }
+
+    @Override
+    public List<Uri> getPinnedSlices() {
+        return SliceProviderCompat.getPinnedSlices(mContext);
+    }
 }
diff --git a/slices/view/src/main/java/androidx/slice/SliceManagerWrapper.java b/slices/view/src/main/java/androidx/slice/SliceManagerWrapper.java
index e0c0342..ec49fe2 100644
--- a/slices/view/src/main/java/androidx/slice/SliceManagerWrapper.java
+++ b/slices/view/src/main/java/androidx/slice/SliceManagerWrapper.java
@@ -28,9 +28,10 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
+import androidx.core.content.PermissionChecker;
 
-import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -42,7 +43,7 @@
 class SliceManagerWrapper extends SliceManagerBase {
 
     private final android.app.slice.SliceManager mManager;
-    private final List<SliceSpec> mSpecs;
+    private final Set<SliceSpec> mSpecs;
 
     SliceManagerWrapper(Context context) {
         this(context, context.getSystemService(android.app.slice.SliceManager.class));
@@ -51,7 +52,7 @@
     SliceManagerWrapper(Context context, android.app.slice.SliceManager manager) {
         super(context);
         mManager = manager;
-        mSpecs = new ArrayList<>(unwrap(SUPPORTED_SPECS));
+        mSpecs = unwrap(SUPPORTED_SPECS);
     }
 
     @Override
@@ -66,7 +67,9 @@
 
     @Override
     public @NonNull Set<androidx.slice.SliceSpec> getPinnedSpecs(@NonNull Uri uri) {
-        return SliceConvert.wrap(mManager.getPinnedSpecs(uri));
+        // Disabled while we update APIs.
+        //return SliceConvert.wrap(mManager.getPinnedSpecs(uri));
+        return Collections.EMPTY_SET;
     }
 
     @Nullable
@@ -86,9 +89,30 @@
         return mManager.getSliceDescendants(uri);
     }
 
+    @Override
+    @PermissionChecker.PermissionResult
+    public int checkSlicePermission(@NonNull Uri uri, int pid, int uid) {
+        return mManager.checkSlicePermission(uri, pid, uid);
+    }
+
+    @Override
+    public void grantSlicePermission(@NonNull String toPackage, @NonNull Uri uri) {
+        mManager.grantSlicePermission(toPackage, uri);
+    }
+
+    @Override
+    public void revokeSlicePermission(@NonNull String toPackage, @NonNull Uri uri) {
+        mManager.revokeSlicePermission(toPackage, uri);
+    }
+
     @Nullable
     @Override
     public Uri mapIntentToUri(@NonNull Intent intent) {
         return mManager.mapIntentToUri(intent);
     }
+
+    @Override
+    public List<Uri> getPinnedSlices() {
+        return mManager.getPinnedSlices();
+    }
 }
diff --git a/slices/view/src/main/java/androidx/slice/SliceMetadata.java b/slices/view/src/main/java/androidx/slice/SliceMetadata.java
index 8a4ee03..0c4f614 100644
--- a/slices/view/src/main/java/androidx/slice/SliceMetadata.java
+++ b/slices/view/src/main/java/androidx/slice/SliceMetadata.java
@@ -23,9 +23,9 @@
 import static android.app.slice.Slice.SUBTYPE_MAX;
 import static android.app.slice.Slice.SUBTYPE_VALUE;
 import static android.app.slice.SliceItem.FORMAT_INT;
+import static android.app.slice.SliceItem.FORMAT_LONG;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
-import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
 
 import static androidx.slice.core.SliceHints.HINT_KEYWORDS;
 import static androidx.slice.core.SliceHints.HINT_LAST_UPDATED;
@@ -118,11 +118,11 @@
     private SliceMetadata(@NonNull Context context, @NonNull Slice slice) {
         mSlice = slice;
         mContext = context;
-        SliceItem ttlItem = SliceQuery.find(slice, FORMAT_TIMESTAMP, HINT_TTL, null);
+        SliceItem ttlItem = SliceQuery.find(slice, FORMAT_LONG, HINT_TTL, null);
         if (ttlItem != null) {
             mExpiry = ttlItem.getTimestamp();
         }
-        SliceItem updatedItem = SliceQuery.find(slice, FORMAT_TIMESTAMP, HINT_LAST_UPDATED, null);
+        SliceItem updatedItem = SliceQuery.find(slice, FORMAT_LONG, HINT_LAST_UPDATED, null);
         if (updatedItem != null) {
             mLastUpdated = updatedItem.getTimestamp();
         }
diff --git a/slices/view/src/main/java/androidx/slice/widget/GridContent.java b/slices/view/src/main/java/androidx/slice/widget/GridContent.java
index 69d5c44..424143c 100644
--- a/slices/view/src/main/java/androidx/slice/widget/GridContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/GridContent.java
@@ -26,9 +26,9 @@
 import static android.app.slice.SliceItem.FORMAT_ACTION;
 import static android.app.slice.SliceItem.FORMAT_IMAGE;
 import static android.app.slice.SliceItem.FORMAT_INT;
+import static android.app.slice.SliceItem.FORMAT_LONG;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
-import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
 
 import static androidx.slice.core.SliceHints.HINT_KEYWORDS;
 import static androidx.slice.core.SliceHints.HINT_LAST_UPDATED;
@@ -295,7 +295,7 @@
                     if (SUBTYPE_CONTENT_DESCRIPTION.equals(item.getSubType())) {
                         mContentDescr = item;
                     } else if (mTextCount < 2 && (FORMAT_TEXT.equals(itemFormat)
-                            || FORMAT_TIMESTAMP.equals(itemFormat))) {
+                            || FORMAT_LONG.equals(itemFormat))) {
                         mTextCount++;
                         mCellItems.add(item);
                     } else if (imageCount < 1 && FORMAT_IMAGE.equals(item.getFormat())) {
@@ -340,7 +340,7 @@
                     || cellItem.hasAnyHints(HINT_KEYWORDS, HINT_TTL, HINT_LAST_UPDATED);
             return !isNonCellContent
                     && (FORMAT_TEXT.equals(format)
-                    || FORMAT_TIMESTAMP.equals(format)
+                    || FORMAT_LONG.equals(format)
                     || FORMAT_IMAGE.equals(format));
         }
 
diff --git a/slices/view/src/main/java/androidx/slice/widget/GridRowView.java b/slices/view/src/main/java/androidx/slice/widget/GridRowView.java
index 4b8078c..7423b02 100644
--- a/slices/view/src/main/java/androidx/slice/widget/GridRowView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/GridRowView.java
@@ -21,9 +21,9 @@
 import static android.app.slice.Slice.HINT_TITLE;
 import static android.app.slice.SliceItem.FORMAT_ACTION;
 import static android.app.slice.SliceItem.FORMAT_IMAGE;
+import static android.app.slice.SliceItem.FORMAT_LONG;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
-import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
@@ -258,7 +258,7 @@
             SliceItem item = cellItems.get(i);
             final String itemFormat = item.getFormat();
             if (textCount < maxCellText && (FORMAT_TEXT.equals(itemFormat)
-                    || FORMAT_TIMESTAMP.equals(itemFormat))) {
+                    || FORMAT_LONG.equals(itemFormat))) {
                 if (textItems != null && !textItems.contains(item)) {
                     continue;
                 }
@@ -305,13 +305,13 @@
     private boolean addItem(SliceItem item, int color, ViewGroup container, boolean singleItem) {
         final String format = item.getFormat();
         View addedView = null;
-        if (FORMAT_TEXT.equals(format) || FORMAT_TIMESTAMP.equals(format)) {
+        if (FORMAT_TEXT.equals(format) || FORMAT_LONG.equals(format)) {
             boolean title = SliceQuery.hasAnyHints(item, HINT_LARGE, HINT_TITLE);
             TextView tv = (TextView) LayoutInflater.from(getContext()).inflate(title
                     ? TITLE_TEXT_LAYOUT : TEXT_LAYOUT, null);
             tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, title ? mTitleSize : mSubtitleSize);
             tv.setTextColor(title ? mTitleColor : mSubtitleColor);
-            CharSequence text = FORMAT_TIMESTAMP.equals(format)
+            CharSequence text = FORMAT_LONG.equals(format)
                     ? SliceViewUtil.getRelativeTimeString(item.getTimestamp())
                     : item.getText();
             tv.setText(text);
diff --git a/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java b/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java
index e09405c..9578e21 100644
--- a/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java
+++ b/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java
@@ -191,8 +191,6 @@
                         null);
                 break;
         }
-        int mode = mParent != null ? mParent.getMode() : MODE_LARGE;
-        ((SliceChildView) v).setMode(mode);
         return v;
     }
 
@@ -248,6 +246,8 @@
             mSliceChildView.setOnTouchListener(this);
 
             final boolean isHeader = position == HEADER_INDEX;
+            int mode = mParent != null ? mParent.getMode() : MODE_LARGE;
+            mSliceChildView.setMode(mode);
             mSliceChildView.setTint(mColor);
             mSliceChildView.setStyle(mAttrs, mDefStyleAttr, mDefStyleRes);
             mSliceChildView.setSliceItem(item, isHeader, position, mSliceObserver);
diff --git a/slices/view/src/main/java/androidx/slice/widget/RowContent.java b/slices/view/src/main/java/androidx/slice/widget/RowContent.java
index bc3826f..0c8d4a6 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowContent.java
@@ -27,10 +27,10 @@
 import static android.app.slice.SliceItem.FORMAT_ACTION;
 import static android.app.slice.SliceItem.FORMAT_IMAGE;
 import static android.app.slice.SliceItem.FORMAT_INT;
+import static android.app.slice.SliceItem.FORMAT_LONG;
 import static android.app.slice.SliceItem.FORMAT_REMOTE_INPUT;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
-import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
 
 import static androidx.slice.core.SliceHints.HINT_KEYWORDS;
 import static androidx.slice.core.SliceHints.HINT_LAST_UPDATED;
@@ -157,11 +157,11 @@
             }
             // Special rules for end items: only one timestamp
             boolean hasTimestamp = mStartItem != null
-                    && FORMAT_TIMESTAMP.equals(mStartItem.getFormat());
+                    && FORMAT_LONG.equals(mStartItem.getFormat());
             for (int i = 0; i < endItems.size(); i++) {
                 final SliceItem item = endItems.get(i);
                 boolean isAction = SliceQuery.find(item, FORMAT_ACTION) != null;
-                if (FORMAT_TIMESTAMP.equals(item.getFormat())) {
+                if (FORMAT_LONG.equals(item.getFormat())) {
                     if (!hasTimestamp) {
                         hasTimestamp = true;
                         mEndItems.add(item);
@@ -382,7 +382,7 @@
         return (FORMAT_TEXT.equals(itemFormat)
                 && !SUBTYPE_CONTENT_DESCRIPTION.equals(item.getSubType()))
                 || FORMAT_IMAGE.equals(itemFormat)
-                || FORMAT_TIMESTAMP.equals(itemFormat)
+                || FORMAT_LONG.equals(itemFormat)
                 || FORMAT_REMOTE_INPUT.equals(itemFormat)
                 || (FORMAT_SLICE.equals(itemFormat) && item.hasHint(HINT_TITLE)
                 && !item.hasHint(HINT_SHORTCUT))
@@ -400,7 +400,7 @@
         final String type = item.getFormat();
         return (FORMAT_ACTION.equals(type) && (SliceQuery.find(item, FORMAT_IMAGE) != null))
                     || FORMAT_IMAGE.equals(type)
-                    || (FORMAT_TIMESTAMP.equals(type)
+                    || (FORMAT_LONG.equals(type)
                 && !item.hasAnyHints(HINT_TTL, HINT_LAST_UPDATED));
     }
 }
diff --git a/slices/view/src/main/java/androidx/slice/widget/RowView.java b/slices/view/src/main/java/androidx/slice/widget/RowView.java
index a7101fe..2840db9 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowView.java
@@ -26,8 +26,8 @@
 import static android.app.slice.SliceItem.FORMAT_ACTION;
 import static android.app.slice.SliceItem.FORMAT_IMAGE;
 import static android.app.slice.SliceItem.FORMAT_INT;
+import static android.app.slice.SliceItem.FORMAT_LONG;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
-import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
 
 import static androidx.slice.core.SliceHints.ICON_IMAGE;
 import static androidx.slice.core.SliceHints.SMALL_IMAGE;
@@ -278,7 +278,7 @@
 
         // If we're here we can can show end items; check for top level actions first
         List<SliceItem> endItems = mRowContent.getEndItems();
-        if (mIsHeader && mHeaderActions != null && mHeaderActions.size() > 0) {
+        if (mHeaderActions != null && mHeaderActions.size() > 0) {
             // Use these if we have them instead
             endItems = mHeaderActions;
         }
@@ -460,7 +460,7 @@
         if (FORMAT_IMAGE.equals(sliceItem.getFormat())) {
             icon = sliceItem.getIcon();
             imageMode = sliceItem.hasHint(HINT_NO_TINT) ? SMALL_IMAGE : ICON_IMAGE;
-        } else if (FORMAT_TIMESTAMP.equals(sliceItem.getFormat())) {
+        } else if (FORMAT_LONG.equals(sliceItem.getFormat())) {
             timeStamp = sliceItem;
         }
         View addedView = null;
diff --git a/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java b/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java
index 37ef17b..3afda5d 100644
--- a/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java
@@ -195,7 +195,7 @@
                 if (mActionItem == null) {
                     mActionItem = new SliceItem(PendingIntent.getActivity(context, 0,
                             pm.getLaunchIntentForPackage(appInfo.packageName), 0),
-                            new Slice.Builder(slice.getUri()).build(), FORMAT_SLICE,
+                            new Slice.Builder(slice.getUri()).build(), FORMAT_ACTION,
                             null /* subtype */, null);
                 }
             }
diff --git a/slices/view/src/main/res/values-as/strings.xml b/slices/view/src/main/res/values-as/strings.xml
index dbc598f..77f9af6 100644
--- a/slices/view/src/main/res/values-as/strings.xml
+++ b/slices/view/src/main/res/values-as/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"অধিক"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"অধিক দেখুৱাওক"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> আপডেট কৰা হৈছিল"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> মিনিট আগেয়ে</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> মিনিট আগেয়ে</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> বছৰ আগেয়ে</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> বছৰ আগেয়ে</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> দিন আগেয়ে</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g>দিন আগেয়ে</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"সংযোগ কৰিব পৰা নগ\'ল"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-be/strings.xml b/slices/view/src/main/res/values-be/strings.xml
index b03f283..f1ae045 100644
--- a/slices/view/src/main/res/values-be/strings.xml
+++ b/slices/view/src/main/res/values-be/strings.xml
@@ -21,23 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Яшчэ"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Яшчэ"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Абноўлена <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> хвіліну таму</item>
-      <item quantity="few"><xliff:g id="ID_2">%d</xliff:g> хвіліны таму</item>
-      <item quantity="many"><xliff:g id="ID_2">%d</xliff:g> хвілін таму</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> хвіліны таму</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> год таму</item>
-      <item quantity="few"><xliff:g id="ID_2">%d</xliff:g> гады таму</item>
-      <item quantity="many"><xliff:g id="ID_2">%d</xliff:g> гадоў таму</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> года таму</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> дзень таму</item>
-      <item quantity="few"><xliff:g id="ID_2">%d</xliff:g> дні таму</item>
-      <item quantity="many"><xliff:g id="ID_2">%d</xliff:g> дзён таму</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> дня таму</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Не атрымалася падключыцца"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-bn/strings.xml b/slices/view/src/main/res/values-bn/strings.xml
index bc5c45b..3b8acdf 100644
--- a/slices/view/src/main/res/values-bn/strings.xml
+++ b/slices/view/src/main/res/values-bn/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"আরও"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"আরও দেখুন"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> আপডেট করা হয়েছে"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> মিনিট আগে</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> মিনিট আগে</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> বছর আগে</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> বছর আগে</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> দিন আগে</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> দিন আগে</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"কানেক্ট করা যায়নি"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-ca/strings.xml b/slices/view/src/main/res/values-ca/strings.xml
index cc5dde0..52e1988 100644
--- a/slices/view/src/main/res/values-ca/strings.xml
+++ b/slices/view/src/main/res/values-ca/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Més"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Mostra\'n més"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"S\'ha actualitzat <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other">Fa <xliff:g id="ID_2">%d</xliff:g> min</item>
-      <item quantity="one">Fa <xliff:g id="ID_1">%d</xliff:g> min</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other">Fa <xliff:g id="ID_2">%d</xliff:g> anys</item>
-      <item quantity="one">Fa <xliff:g id="ID_1">%d</xliff:g> any</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other">Fa <xliff:g id="ID_2">%d</xliff:g> dies</item>
-      <item quantity="one">Fa <xliff:g id="ID_1">%d</xliff:g> dia</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"No s\'ha pogut connectar"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-da/strings.xml b/slices/view/src/main/res/values-da/strings.xml
index c7c2850..33d9c9d 100644
--- a/slices/view/src/main/res/values-da/strings.xml
+++ b/slices/view/src/main/res/values-da/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Mere"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Se mere"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Opdateret <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one">for <xliff:g id="ID_2">%d</xliff:g> min. siden</item>
-      <item quantity="other">for <xliff:g id="ID_2">%d</xliff:g> min. siden</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one">for <xliff:g id="ID_2">%d</xliff:g> år siden</item>
-      <item quantity="other">for <xliff:g id="ID_2">%d</xliff:g> år siden</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one">for <xliff:g id="ID_2">%d</xliff:g> dag siden</item>
-      <item quantity="other">for <xliff:g id="ID_2">%d</xliff:g> dage siden</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Der kunne ikke oprettes forbindelse"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-de/strings.xml b/slices/view/src/main/res/values-de/strings.xml
index 25dff37..96da7eb 100644
--- a/slices/view/src/main/res/values-de/strings.xml
+++ b/slices/view/src/main/res/values-de/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Mehr"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Mehr anzeigen"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Aktualisiert: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other">vor <xliff:g id="ID_2">%d</xliff:g> Min.</item>
-      <item quantity="one">vor <xliff:g id="ID_1">%d</xliff:g> Min.</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other">vor <xliff:g id="ID_2">%d</xliff:g> Jahren</item>
-      <item quantity="one">vor <xliff:g id="ID_1">%d</xliff:g> Jahr</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other">vor <xliff:g id="ID_2">%d</xliff:g> Tagen</item>
-      <item quantity="one">vor <xliff:g id="ID_1">%d</xliff:g> Tag</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Verbindung nicht möglich"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-es-rUS/strings.xml b/slices/view/src/main/res/values-es-rUS/strings.xml
index 3125104..124c40c 100644
--- a/slices/view/src/main/res/values-es-rUS/strings.xml
+++ b/slices/view/src/main/res/values-es-rUS/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Más"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Mostrar más"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Última actualización: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other">Hace <xliff:g id="ID_2">%d</xliff:g> min</item>
-      <item quantity="one">Hace <xliff:g id="ID_1">%d</xliff:g> min</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other">Hace <xliff:g id="ID_2">%d</xliff:g> años</item>
-      <item quantity="one">Hace <xliff:g id="ID_1">%d</xliff:g> año</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other">Hace <xliff:g id="ID_2">%d</xliff:g> días</item>
-      <item quantity="one">Hace <xliff:g id="ID_1">%d</xliff:g> día</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"No se pudo establecer conexión"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-es/strings.xml b/slices/view/src/main/res/values-es/strings.xml
index f6e42fc..57685ba 100644
--- a/slices/view/src/main/res/values-es/strings.xml
+++ b/slices/view/src/main/res/values-es/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Más"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Ver más"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Última actualización: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other">hace <xliff:g id="ID_2">%d</xliff:g> minutos</item>
-      <item quantity="one">hace <xliff:g id="ID_1">%d</xliff:g> minuto</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other">hace <xliff:g id="ID_2">%d</xliff:g> años</item>
-      <item quantity="one">hace <xliff:g id="ID_1">%d</xliff:g> año</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other">hace <xliff:g id="ID_2">%d</xliff:g> días</item>
-      <item quantity="one">hace <xliff:g id="ID_1">%d</xliff:g> día</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"No se ha podido establecer la conexión"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-et/strings.xml b/slices/view/src/main/res/values-et/strings.xml
index 7e053e9..4bd8a92 100644
--- a/slices/view/src/main/res/values-et/strings.xml
+++ b/slices/view/src/main/res/values-et/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Rohkem"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Kuva rohkem"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Värskendatud kell <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> min tagasi</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min tagasi</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> a tagasi</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> a tagasi</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> päeva tagasi</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> päev tagasi</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Ühendamine ebaõnnestus"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-eu/strings.xml b/slices/view/src/main/res/values-eu/strings.xml
index 5e0642c..e689ada 100644
--- a/slices/view/src/main/res/values-eu/strings.xml
+++ b/slices/view/src/main/res/values-eu/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Gehiago"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Erakutsi gehiago"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Azken eguneratzea: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other">Duela <xliff:g id="ID_2">%d</xliff:g> minutu</item>
-      <item quantity="one">Duela <xliff:g id="ID_1">%d</xliff:g> minutu</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other">Duela <xliff:g id="ID_2">%d</xliff:g> urte</item>
-      <item quantity="one">Duela <xliff:g id="ID_1">%d</xliff:g> urte</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other">Duela <xliff:g id="ID_2">%d</xliff:g> egun</item>
-      <item quantity="one">Duela <xliff:g id="ID_1">%d</xliff:g> egun</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Ezin izan da konektatu"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-fa/strings.xml b/slices/view/src/main/res/values-fa/strings.xml
index 7832e8a..cb94e5d 100644
--- a/slices/view/src/main/res/values-fa/strings.xml
+++ b/slices/view/src/main/res/values-fa/strings.xml
@@ -19,7 +19,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="abc_slice_more_content" msgid="6405516388971241142">"‎+ <xliff:g id="NUMBER">%1$d</xliff:g>‎"</string>
     <string name="abc_slice_more" msgid="1983560225998630901">"بیشتر"</string>
-    <string name="abc_slice_show_more" msgid="1567717014004692768">"بیشتر ببینید"</string>
+    <string name="abc_slice_show_more" msgid="1567717014004692768">"نمایش موارد بیشتر"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"زمان به‌روزرسانی <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
       <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> دقیقه قبل</item>
diff --git a/slices/view/src/main/res/values-fi/strings.xml b/slices/view/src/main/res/values-fi/strings.xml
index dbbe0cd..bc37611 100644
--- a/slices/view/src/main/res/values-fi/strings.xml
+++ b/slices/view/src/main/res/values-fi/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Lisää"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Näytä lisää"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Päivitetty <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> min sitten</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min sitten</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> vuotta sitten</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> vuosi sitten</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> päivää sitten</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> päivä sitten</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Ei yhteyttä"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-fr-rCA/strings.xml b/slices/view/src/main/res/values-fr-rCA/strings.xml
index 63c7fcd..1563136 100644
--- a/slices/view/src/main/res/values-fr-rCA/strings.xml
+++ b/slices/view/src/main/res/values-fr-rCA/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Plus"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Plus"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Mise à jour : <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one">Il y a <xliff:g id="ID_2">%d</xliff:g> minute</item>
-      <item quantity="other">Il y a <xliff:g id="ID_2">%d</xliff:g> minutes</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one">Il y a <xliff:g id="ID_2">%d</xliff:g> an</item>
-      <item quantity="other">Il y a <xliff:g id="ID_2">%d</xliff:g> ans</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one">Il y a <xliff:g id="ID_2">%d</xliff:g> jour</item>
-      <item quantity="other">Il y a <xliff:g id="ID_2">%d</xliff:g> jours</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Impossible de se connecter"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-fr/strings.xml b/slices/view/src/main/res/values-fr/strings.xml
index 47ff242..6762544 100644
--- a/slices/view/src/main/res/values-fr/strings.xml
+++ b/slices/view/src/main/res/values-fr/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Plus"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Afficher plus"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Dernière mise à jour : <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one">Il y a <xliff:g id="ID_2">%d</xliff:g> minute</item>
-      <item quantity="other">Il y a <xliff:g id="ID_2">%d</xliff:g> minutes</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one">Il y a <xliff:g id="ID_2">%d</xliff:g> an</item>
-      <item quantity="other">Il y a <xliff:g id="ID_2">%d</xliff:g> ans</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one">Il y a <xliff:g id="ID_2">%d</xliff:g> jour</item>
-      <item quantity="other">Il y a <xliff:g id="ID_2">%d</xliff:g> jours</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Impossible de se connecter"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-gl/strings.xml b/slices/view/src/main/res/values-gl/strings.xml
index fb3d1c2..70b31bb 100644
--- a/slices/view/src/main/res/values-gl/strings.xml
+++ b/slices/view/src/main/res/values-gl/strings.xml
@@ -22,16 +22,16 @@
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Amosar máis"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Contido actualizado (<xliff:g id="TIME">%1$s</xliff:g>)"</string>
     <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other">hai <xliff:g id="ID_2">%d</xliff:g> min</item>
-      <item quantity="one">hai <xliff:g id="ID_1">%d</xliff:g> min</item>
+      <item quantity="other">Hai <xliff:g id="ID_2">%d</xliff:g> min</item>
+      <item quantity="one">Hai <xliff:g id="ID_1">%d</xliff:g> min</item>
     </plurals>
     <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other">hai <xliff:g id="ID_2">%d</xliff:g> anos</item>
-      <item quantity="one">hai <xliff:g id="ID_1">%d</xliff:g> ano</item>
+      <item quantity="other">Hai <xliff:g id="ID_2">%d</xliff:g> anos</item>
+      <item quantity="one">Hai <xliff:g id="ID_1">%d</xliff:g> ano</item>
     </plurals>
     <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other">hai <xliff:g id="ID_2">%d</xliff:g> días</item>
-      <item quantity="one">hai <xliff:g id="ID_1">%d</xliff:g> día</item>
+      <item quantity="other">Hai <xliff:g id="ID_2">%d</xliff:g> días</item>
+      <item quantity="one">Hai <xliff:g id="ID_1">%d</xliff:g> día</item>
     </plurals>
     <string name="abc_slice_error" msgid="4188371422904147368">"Non se puido establecer conexión"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-gu/strings.xml b/slices/view/src/main/res/values-gu/strings.xml
index 4951f8c..d6a7ee8 100644
--- a/slices/view/src/main/res/values-gu/strings.xml
+++ b/slices/view/src/main/res/values-gu/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"વધુ"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"વધુ બતાવો"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> અપડેટ થયું"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> મિનિટ પહેલાં</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> મિનિટ પહેલાં</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> વર્ષ પહેલાં</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> વર્ષ પહેલાં</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> દિવસ પહેલાં</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> દિવસ પહેલાં</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"કનેક્ટ કરી શકાયું નથી"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-hi/strings.xml b/slices/view/src/main/res/values-hi/strings.xml
index 79a64bb..380025e 100644
--- a/slices/view/src/main/res/values-hi/strings.xml
+++ b/slices/view/src/main/res/values-hi/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"ज़्यादा देखें"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"ज़्यादा देखें"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> बजे अपडेट किया गया"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> मिनट पहले</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> मिनट पहले</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> साल पहले</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> साल पहले</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> दिन पहले</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> दिन पहले</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"कनेक्‍ट नहीं हो पाया"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-hu/strings.xml b/slices/view/src/main/res/values-hu/strings.xml
index cf5ebdc..c56143b 100644
--- a/slices/view/src/main/res/values-hu/strings.xml
+++ b/slices/view/src/main/res/values-hu/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Több"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Több megjelenítése"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Frissítve: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> perce</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> perce</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> éve</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> éve</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> napja</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> napja</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Nem sikerült kapcsolódni"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-hy/strings.xml b/slices/view/src/main/res/values-hy/strings.xml
index fcf96af..bb6b812 100644
--- a/slices/view/src/main/res/values-hy/strings.xml
+++ b/slices/view/src/main/res/values-hy/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Ավելին"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Ցուցադրել ավելի շատ"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Թարմացվել է <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> րոպե առաջ</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> րոպե առաջ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> տարի առաջ</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> տարի առաջ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> օր առաջ</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> օր առաջ</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Չհաջողվեց միանալ"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-is/strings.xml b/slices/view/src/main/res/values-is/strings.xml
index 855a858..c059c03 100644
--- a/slices/view/src/main/res/values-is/strings.xml
+++ b/slices/view/src/main/res/values-is/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Meira"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Sýna meira"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Uppfært <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one">Fyrir <xliff:g id="ID_2">%d</xliff:g> mín.</item>
-      <item quantity="other">Fyrir <xliff:g id="ID_2">%d</xliff:g> mín.</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one">Fyrir <xliff:g id="ID_2">%d</xliff:g> ári</item>
-      <item quantity="other">Fyrir <xliff:g id="ID_2">%d</xliff:g> árum</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one">Fyrir <xliff:g id="ID_2">%d</xliff:g> degi</item>
-      <item quantity="other">Fyrir <xliff:g id="ID_2">%d</xliff:g> dögum</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Tenging mistókst"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-it/strings.xml b/slices/view/src/main/res/values-it/strings.xml
index d2f7a39..05410e8 100644
--- a/slices/view/src/main/res/values-it/strings.xml
+++ b/slices/view/src/main/res/values-it/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Altro"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Mostra altro"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Aggiornamento: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> min fa</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min fa</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> anni fa</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> anno fa</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> gg fa</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> g fa</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Impossibile collegarsi"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-iw/strings.xml b/slices/view/src/main/res/values-iw/strings.xml
index db052e3..5c55fe2 100644
--- a/slices/view/src/main/res/values-iw/strings.xml
+++ b/slices/view/src/main/res/values-iw/strings.xml
@@ -21,23 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"עוד"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"הצג יותר"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"עודכן ב-<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="two">לפני <xliff:g id="ID_2">%d</xliff:g> דק’</item>
-      <item quantity="many">לפני <xliff:g id="ID_2">%d</xliff:g> דק’</item>
-      <item quantity="other">לפני <xliff:g id="ID_2">%d</xliff:g> דק’</item>
-      <item quantity="one">לפני <xliff:g id="ID_1">%d</xliff:g> דק’</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="two">לפני <xliff:g id="ID_2">%d</xliff:g> שנים</item>
-      <item quantity="many">לפני <xliff:g id="ID_2">%d</xliff:g> שנים</item>
-      <item quantity="other">לפני <xliff:g id="ID_2">%d</xliff:g> שנים</item>
-      <item quantity="one">לפני שנה (<xliff:g id="ID_1">%d</xliff:g>)</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="two">לפני <xliff:g id="ID_2">%d</xliff:g> ימים</item>
-      <item quantity="many">לפני <xliff:g id="ID_2">%d</xliff:g> ימים</item>
-      <item quantity="other">לפני <xliff:g id="ID_2">%d</xliff:g> ימים</item>
-      <item quantity="one">לפני יום אחד (<xliff:g id="ID_1">%d</xliff:g>)</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"לא ניתן היה להתחבר"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-ja/strings.xml b/slices/view/src/main/res/values-ja/strings.xml
index 4d21cdf..286949f 100644
--- a/slices/view/src/main/res/values-ja/strings.xml
+++ b/slices/view/src/main/res/values-ja/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"もっと見る"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"もっと見る"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"更新時刻: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> 分前</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> 分前</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> 年前</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> 年前</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> 日前</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> 日前</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"接続できませんでした"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-ka/strings.xml b/slices/view/src/main/res/values-ka/strings.xml
index 9b8558c..542c6cc 100644
--- a/slices/view/src/main/res/values-ka/strings.xml
+++ b/slices/view/src/main/res/values-ka/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"მეტი"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"მეტის ჩვენება"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"განახლების დრო: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> წუთის წინ</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> წუთის წინ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> წლის წინ</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> წლის წინ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> დღის წინ</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> დღის წინ</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"დაკავშირება ვერ მოხერხდა"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-kk/strings.xml b/slices/view/src/main/res/values-kk/strings.xml
index 72b0303..231a499 100644
--- a/slices/view/src/main/res/values-kk/strings.xml
+++ b/slices/view/src/main/res/values-kk/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Тағы"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Толығырақ көрсету"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Жаңартылған уақыты: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> минут бұрын</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> минут бұрын</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> жыл бұрын</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> жыл бұрын</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> күн бұрын</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> күн бұрын</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Байланыс орнатылмады"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-ko/strings.xml b/slices/view/src/main/res/values-ko/strings.xml
index 4dab983..1ec58f0 100644
--- a/slices/view/src/main/res/values-ko/strings.xml
+++ b/slices/view/src/main/res/values-ko/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"더보기"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"더보기"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g>에 업데이트됨"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g>분 전</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g>분 전</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g>년 전</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g>년 전</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g>일 전</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g>일 전</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"연결할 수 없음"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-ky/strings.xml b/slices/view/src/main/res/values-ky/strings.xml
index 63c7d13..06244ab 100644
--- a/slices/view/src/main/res/values-ky/strings.xml
+++ b/slices/view/src/main/res/values-ky/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Дагы"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Дагы көрсөтүү"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> жаңыртылды"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> мүн. мурун</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> мүн. мурун</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> жыл мурун</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> жыл мурун</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> күн мурун</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> күн мурун</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Туташпай койду"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-lo/strings.xml b/slices/view/src/main/res/values-lo/strings.xml
index 89c4291..44111ea 100644
--- a/slices/view/src/main/res/values-lo/strings.xml
+++ b/slices/view/src/main/res/values-lo/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"ເພີ່ມເຕີມ"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"ສະແດງເພີ່ມເຕີມ"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"ອັບເດດເມື່ອ <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ນທ ກ່ອນ</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> ນທ ກ່ອນ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ປີກ່ອນ</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> ປີກ່ອນ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ມື້ກ່ອນ</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> ມື້ກ່ອນ</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"ບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-mn/strings.xml b/slices/view/src/main/res/values-mn/strings.xml
index 52a5d1a..beaa1a3 100644
--- a/slices/view/src/main/res/values-mn/strings.xml
+++ b/slices/view/src/main/res/values-mn/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Бусад"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Дэлгэрэнгүй үзэх"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> шинэчилсэн"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> минутын өмнө</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> минутын өмнө</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> жилийн өмнө</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> жилийн өмнө</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> өдрийн өмнө</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> өдрийн өмнө</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Холбогдож чадсангүй"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-mr/strings.xml b/slices/view/src/main/res/values-mr/strings.xml
index 80aa0a7..693c821 100644
--- a/slices/view/src/main/res/values-mr/strings.xml
+++ b/slices/view/src/main/res/values-mr/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"आणखी"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"आणखी दाखवा"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> ला अपडेट केले"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> मिनिटापूर्वी</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> मिनिटांपूर्वी</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> वर्षापूर्वी</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> वर्षांपूर्वी</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> दिवसापूर्वी</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> दिवसांपूर्वी</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"कनेक्ट करता आले नाही"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-ms/strings.xml b/slices/view/src/main/res/values-ms/strings.xml
index 576b8df..eced3de 100644
--- a/slices/view/src/main/res/values-ms/strings.xml
+++ b/slices/view/src/main/res/values-ms/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Lagi"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Tunjukkan lagi"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Dikemas kini pada <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> min yang lalu</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min yang lalu</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> thn yang lalu</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> thn yang lalu</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> hari yang lalu</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> hari yang lalu</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Tidak dapat menyambung"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-nb/strings.xml b/slices/view/src/main/res/values-nb/strings.xml
index 3fad9c4..6576626 100644
--- a/slices/view/src/main/res/values-nb/strings.xml
+++ b/slices/view/src/main/res/values-nb/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Mer"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Vis mer"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Oppdatert <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other">For <xliff:g id="ID_2">%d</xliff:g> min. siden</item>
-      <item quantity="one">For <xliff:g id="ID_1">%d</xliff:g> min. siden</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other">For <xliff:g id="ID_2">%d</xliff:g> år siden</item>
-      <item quantity="one">For <xliff:g id="ID_1">%d</xliff:g> år siden</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other">For <xliff:g id="ID_2">%d</xliff:g> dager siden</item>
-      <item quantity="one">For <xliff:g id="ID_1">%d</xliff:g> dag siden</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Kunne ikke koble til"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-nl/strings.xml b/slices/view/src/main/res/values-nl/strings.xml
index b5d2edc..1ba58e9 100644
--- a/slices/view/src/main/res/values-nl/strings.xml
+++ b/slices/view/src/main/res/values-nl/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Meer"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Meer weergeven"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Geüpdatet: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> min geleden</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min geleden</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> jaar geleden</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> jaar geleden</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> dagen geleden</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> dag geleden</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Kan geen verbinding maken"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-or/strings.xml b/slices/view/src/main/res/values-or/strings.xml
index 6bf6019..1099e80 100644
--- a/slices/view/src/main/res/values-or/strings.xml
+++ b/slices/view/src/main/res/values-or/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"ଅଧିକ"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"ଅଧିକ ଦେଖାନ୍ତୁ"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g>ରେ ଅପଡେଟ୍ ହୋଇଥିଲା"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ମିନିଟ୍ ପୂର୍ବେ</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> ମିନିଟ୍ ପୂର୍ବେ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ବର୍ଷ ପୂର୍ବେ</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> ବର୍ଷ ପୂର୍ବେ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ଦିନ ପୂର୍ବେ</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> ଦିନ ପୂର୍ବେ</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"କନେକ୍ଟ ହେଲାନାହିଁ"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-pa/strings.xml b/slices/view/src/main/res/values-pa/strings.xml
index e588aac..8926d0f 100644
--- a/slices/view/src/main/res/values-pa/strings.xml
+++ b/slices/view/src/main/res/values-pa/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"ਹੋਰ"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"ਹੋਰ ਦਿਖਾਓ"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> ਅੱਪਡੇਟ ਕੀਤੀ ਗਈ"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> ਮਿੰਟ ਪਹਿਲਾਂ</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ਮਿੰਟ ਪਹਿਲਾਂ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> ਸਾਲ ਪਹਿਲਾਂ</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ਸਾਲ ਪਹਿਲਾਂ</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> ਦਿਨ ਪਹਿਲਾਂ</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ਦਿਨ ਪਹਿਲਾਂ</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-pl/strings.xml b/slices/view/src/main/res/values-pl/strings.xml
index c5300ca..fa565f3 100644
--- a/slices/view/src/main/res/values-pl/strings.xml
+++ b/slices/view/src/main/res/values-pl/strings.xml
@@ -21,23 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Więcej"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Pokaż więcej"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Aktualizacja: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="few"><xliff:g id="ID_2">%d</xliff:g> min temu</item>
-      <item quantity="many"><xliff:g id="ID_2">%d</xliff:g> min temu</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> min temu</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min temu</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="few"><xliff:g id="ID_2">%d</xliff:g> lata temu</item>
-      <item quantity="many"><xliff:g id="ID_2">%d</xliff:g> lat temu</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> roku temu</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> rok temu</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="few"><xliff:g id="ID_2">%d</xliff:g> dni temu</item>
-      <item quantity="many"><xliff:g id="ID_2">%d</xliff:g> dni temu</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> dnia temu</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> dzień temu</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Nie udało się połączyć"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-ro/strings.xml b/slices/view/src/main/res/values-ro/strings.xml
index 9ff89d0..a3f9ff2 100644
--- a/slices/view/src/main/res/values-ro/strings.xml
+++ b/slices/view/src/main/res/values-ro/strings.xml
@@ -22,19 +22,19 @@
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Vedeți mai multe"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Actualizat la <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="few">acum <xliff:g id="ID_2">%d</xliff:g> min.</item>
-      <item quantity="other">acum <xliff:g id="ID_2">%d</xliff:g> de min.</item>
-      <item quantity="one">acum <xliff:g id="ID_1">%d</xliff:g> min.</item>
+      <item quantity="few">Acum <xliff:g id="ID_2">%d</xliff:g> min.</item>
+      <item quantity="other">Acum <xliff:g id="ID_2">%d</xliff:g> de min.</item>
+      <item quantity="one">Acum <xliff:g id="ID_1">%d</xliff:g> min.</item>
     </plurals>
     <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="few">acum <xliff:g id="ID_2">%d</xliff:g> ani</item>
-      <item quantity="other">acum <xliff:g id="ID_2">%d</xliff:g> de ani</item>
-      <item quantity="one">acum <xliff:g id="ID_1">%d</xliff:g> an</item>
+      <item quantity="few">Acum <xliff:g id="ID_2">%d</xliff:g> ani</item>
+      <item quantity="other">Acum <xliff:g id="ID_2">%d</xliff:g> de ani</item>
+      <item quantity="one">Acum <xliff:g id="ID_1">%d</xliff:g> an</item>
     </plurals>
     <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="few">acum <xliff:g id="ID_2">%d</xliff:g> zile</item>
-      <item quantity="other">acum <xliff:g id="ID_2">%d</xliff:g> de zile</item>
-      <item quantity="one">acum <xliff:g id="ID_1">%d</xliff:g> zi</item>
+      <item quantity="few">Acum <xliff:g id="ID_2">%d</xliff:g> zile</item>
+      <item quantity="other">Acum <xliff:g id="ID_2">%d</xliff:g> de zile</item>
+      <item quantity="one">Acum <xliff:g id="ID_1">%d</xliff:g> zi</item>
     </plurals>
     <string name="abc_slice_error" msgid="4188371422904147368">"Nu s-a putut conecta"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-si/strings.xml b/slices/view/src/main/res/values-si/strings.xml
index cfd7685..be85112 100644
--- a/slices/view/src/main/res/values-si/strings.xml
+++ b/slices/view/src/main/res/values-si/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"තව"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"තව පෙන්වන්න"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> යාවත්කාලීන කරන ලදී"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one">මිනි <xliff:g id="ID_2">%d</xliff:g>කට පෙර</item>
-      <item quantity="other">මිනි <xliff:g id="ID_2">%d</xliff:g>කට පෙර</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="one">වසර <xliff:g id="ID_2">%d</xliff:g>කට පෙර</item>
-      <item quantity="other">වසර <xliff:g id="ID_2">%d</xliff:g>කට පෙර</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="one">දින <xliff:g id="ID_2">%d</xliff:g>කට පෙර</item>
-      <item quantity="other">දින <xliff:g id="ID_2">%d</xliff:g>කට පෙර</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"සම්බන්ධ වීමට නොහැකි විය"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-sk/strings.xml b/slices/view/src/main/res/values-sk/strings.xml
index 76bed58..a153760 100644
--- a/slices/view/src/main/res/values-sk/strings.xml
+++ b/slices/view/src/main/res/values-sk/strings.xml
@@ -22,22 +22,22 @@
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Zobraziť viac"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Aktualizované <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="few">pred <xliff:g id="ID_2">%d</xliff:g> min</item>
-      <item quantity="many">pred <xliff:g id="ID_2">%d</xliff:g> min</item>
-      <item quantity="other">pred <xliff:g id="ID_2">%d</xliff:g> min</item>
-      <item quantity="one">pred <xliff:g id="ID_1">%d</xliff:g> min</item>
+      <item quantity="few">Pred <xliff:g id="ID_2">%d</xliff:g> min</item>
+      <item quantity="many">Pred <xliff:g id="ID_2">%d</xliff:g> min</item>
+      <item quantity="other">Pred <xliff:g id="ID_2">%d</xliff:g> min</item>
+      <item quantity="one">Pred <xliff:g id="ID_1">%d</xliff:g> min</item>
     </plurals>
     <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="few">pred <xliff:g id="ID_2">%d</xliff:g> rokmi</item>
-      <item quantity="many">pred <xliff:g id="ID_2">%d</xliff:g> roka</item>
-      <item quantity="other">pred <xliff:g id="ID_2">%d</xliff:g> rokmi</item>
-      <item quantity="one">pred <xliff:g id="ID_1">%d</xliff:g> rokom</item>
+      <item quantity="few">Pred <xliff:g id="ID_2">%d</xliff:g> rokmi</item>
+      <item quantity="many">Pred <xliff:g id="ID_2">%d</xliff:g> rokom</item>
+      <item quantity="other">Pred <xliff:g id="ID_2">%d</xliff:g> rokmi</item>
+      <item quantity="one">Pred <xliff:g id="ID_1">%d</xliff:g> rokom</item>
     </plurals>
     <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="few">pred <xliff:g id="ID_2">%d</xliff:g> dňami</item>
-      <item quantity="many">pred <xliff:g id="ID_2">%d</xliff:g> dňa</item>
-      <item quantity="other">pred <xliff:g id="ID_2">%d</xliff:g> dňami</item>
-      <item quantity="one">pred <xliff:g id="ID_1">%d</xliff:g> dňom</item>
+      <item quantity="few">Pred <xliff:g id="ID_2">%d</xliff:g> dňami</item>
+      <item quantity="many">Pred <xliff:g id="ID_2">%d</xliff:g> dňami</item>
+      <item quantity="other">Pred <xliff:g id="ID_2">%d</xliff:g> dňami</item>
+      <item quantity="one">Pred <xliff:g id="ID_1">%d</xliff:g> dňom</item>
     </plurals>
     <string name="abc_slice_error" msgid="4188371422904147368">"Nepodarilo sa pripojiť"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-sv/strings.xml b/slices/view/src/main/res/values-sv/strings.xml
index 90caa1a..bc6947d 100644
--- a/slices/view/src/main/res/values-sv/strings.xml
+++ b/slices/view/src/main/res/values-sv/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Mer"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Visa mer"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Uppdaterades <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> minuter sedan</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> minut sedan</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> år sedan</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> år sedan</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> dagar sedan</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> dag sedan</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Det gick inte att ansluta"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-ta/strings.xml b/slices/view/src/main/res/values-ta/strings.xml
index 778218e..5b36b79 100644
--- a/slices/view/src/main/res/values-ta/strings.xml
+++ b/slices/view/src/main/res/values-ta/strings.xml
@@ -20,18 +20,11 @@
     <string name="abc_slice_more_content" msgid="6405516388971241142">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="abc_slice_more" msgid="1983560225998630901">"மேலும்"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"மேலும் காட்டு"</string>
-    <string name="abc_slice_updated" msgid="8155085405396453848">"புதுப்பித்தது: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> நிமி. முன்</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> நிமி. முன்</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ஆண்டிற்கு முன்</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> ஆண்டிற்கு முன்</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> நாளுக்கு முன்</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> நாளுக்கு முன்</item>
-    </plurals>
-    <string name="abc_slice_error" msgid="4188371422904147368">"இணைக்க முடியவில்லை"</string>
+    <!-- no translation found for abc_slice_updated (8155085405396453848) -->
+    <skip />
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
+    <!-- no translation found for abc_slice_error (4188371422904147368) -->
+    <skip />
 </resources>
diff --git a/slices/view/src/main/res/values-tl/strings.xml b/slices/view/src/main/res/values-tl/strings.xml
index 2e76a1a..d2d5526 100644
--- a/slices/view/src/main/res/values-tl/strings.xml
+++ b/slices/view/src/main/res/values-tl/strings.xml
@@ -22,8 +22,8 @@
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Magpakita pa"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Na-update noong <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> min ang nakalipas</item>
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> na min ang nakalipas</item>
+      <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> minuto ang nakalipas</item>
+      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> na minuto ang nakalipas</item>
     </plurals>
     <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
       <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> taon ang nakalipas</item>
diff --git a/slices/view/src/main/res/values-ur/strings.xml b/slices/view/src/main/res/values-ur/strings.xml
index 1fff81c..4f51700 100644
--- a/slices/view/src/main/res/values-ur/strings.xml
+++ b/slices/view/src/main/res/values-ur/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"مزید"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"مزید دکھائیں"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> اپ ڈیٹ کیا گیا"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> منٹ پہلے</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> منٹ پہلے</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> سال پہلے</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> سال پہلے</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> دن پہلے</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> دن پہلے</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"منسلک نہیں ہو سکا"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-uz/strings.xml b/slices/view/src/main/res/values-uz/strings.xml
index 0a973cd..2250c91 100644
--- a/slices/view/src/main/res/values-uz/strings.xml
+++ b/slices/view/src/main/res/values-uz/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Yana"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Yana"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Yangilandi: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> daqiqa oldin</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> daqiqa oldin</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> yil oldin</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> yil oldin</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> kun oldin</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> kun oldin</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Ulanib bo‘lmadi"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-vi/strings.xml b/slices/view/src/main/res/values-vi/strings.xml
index 1e71db6..c9129be 100644
--- a/slices/view/src/main/res/values-vi/strings.xml
+++ b/slices/view/src/main/res/values-vi/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"Thêm"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Hiển thị thêm"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Đã cập nhật lúc <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> phút trước</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> phút trước</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> năm trước</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> năm trước</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ngày trước</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> ngày trước</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"Không thể kết nối"</string>
 </resources>
diff --git a/slices/view/src/main/res/values-zh-rCN/strings.xml b/slices/view/src/main/res/values-zh-rCN/strings.xml
index c018343..2ecb835 100644
--- a/slices/view/src/main/res/values-zh-rCN/strings.xml
+++ b/slices/view/src/main/res/values-zh-rCN/strings.xml
@@ -21,17 +21,8 @@
     <string name="abc_slice_more" msgid="1983560225998630901">"更多"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"显示更多"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"更新时间:<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> 分钟前</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> 分钟前</item>
-    </plurals>
-    <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> 年前</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> 年前</item>
-    </plurals>
-    <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
-      <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> 天前</item>
-      <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> 天前</item>
-    </plurals>
+    <!-- no translation found for abc_slice_duration_min (6996334305156847955) -->
+    <!-- no translation found for abc_slice_duration_years (6212691832333991589) -->
+    <!-- no translation found for abc_slice_duration_days (6241698511167107334) -->
     <string name="abc_slice_error" msgid="4188371422904147368">"无法连接"</string>
 </resources>
diff --git a/testutils/build.gradle b/testutils/build.gradle
index e0c4139..f39248e 100644
--- a/testutils/build.gradle
+++ b/testutils/build.gradle
@@ -36,3 +36,7 @@
         disable 'InvalidPackage' // Lint is unhappy about junit package
     }
 }
+
+supportLibrary {
+    failOnUncheckedWarnings = false
+}
\ No newline at end of file
diff --git a/textclassifier/build.gradle b/textclassifier/build.gradle
index fd654ee..fcaa89d 100644
--- a/textclassifier/build.gradle
+++ b/textclassifier/build.gradle
@@ -24,4 +24,5 @@
     inceptionYear = "2018"
     description = "The TextClassifier Support Library can be added to an Android application in order to use the TextClassifier API introduced in Android O on all devices with API level 14 or later."
     minSdkVersion = 14
+    failOnUncheckedWarnings = false
 }
diff --git a/transition/build.gradle b/transition/build.gradle
index 3e4e7d1..61c690f 100644
--- a/transition/build.gradle
+++ b/transition/build.gradle
@@ -36,4 +36,5 @@
     mavenGroup = LibraryGroups.TRANSITION
     inceptionYear = "2016"
     description = "Android Transition Support Library"
+    failOnDeprecationWarnings = false
 }
diff --git a/tv-provider/build.gradle b/tv-provider/build.gradle
index 9fe5f93..469f06d 100644
--- a/tv-provider/build.gradle
+++ b/tv-provider/build.gradle
@@ -23,4 +23,6 @@
     inceptionYear = "2017"
     description = "Android Support Library for TV Provider"
     minSdkVersion = 21
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
\ No newline at end of file
diff --git a/tv-provider/src/main/java/androidx/tvprovider/media/tv/TvContractUtils.java b/tv-provider/src/main/java/androidx/tvprovider/media/tv/TvContractUtils.java
index 3483d0f..99383c0 100644
--- a/tv-provider/src/main/java/androidx/tvprovider/media/tv/TvContractUtils.java
+++ b/tv-provider/src/main/java/androidx/tvprovider/media/tv/TvContractUtils.java
@@ -50,7 +50,7 @@
         if (TextUtils.isEmpty(commaSeparatedRatings)) {
             return EMPTY;
         }
-        String[] ratings = commaSeparatedRatings.split("\\s*,\\s*");
+        String[] ratings = commaSeparatedRatings.split("\\s*,\\s*", -1);
         List<TvContentRating> contentRatings = new ArrayList<>(ratings.length);
         for (String rating : ratings) {
             try {
diff --git a/v7/appcompat/build.gradle b/v7/appcompat/build.gradle
index a2ca59a..b04bee6 100644
--- a/v7/appcompat/build.gradle
+++ b/v7/appcompat/build.gradle
@@ -53,4 +53,6 @@
     mavenGroup = LibraryGroups.APPCOMPAT
     inceptionYear = "2011"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/v7/appcompat/res/values-bs/strings.xml b/v7/appcompat/res/values-bs/strings.xml
index 5100cbf..91281fc 100644
--- a/v7/appcompat/res/values-bs/strings.xml
+++ b/v7/appcompat/res/values-bs/strings.xml
@@ -20,7 +20,7 @@
     <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Vrati se na početnu stranicu"</string>
     <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigiraj prema gore"</string>
     <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Više opcija"</string>
-    <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Suzi"</string>
+    <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Skupi"</string>
     <string name="abc_searchview_description_search" msgid="8264924765203268293">"Traži"</string>
     <string name="abc_search_hint" msgid="7723749260725869598">"Pretraži..."</string>
     <string name="abc_searchview_description_query" msgid="2550479030709304392">"Pretraži upit"</string>
diff --git a/v7/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java b/v7/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
index b66dec3..404df41 100644
--- a/v7/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
+++ b/v7/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
@@ -39,6 +39,7 @@
 import androidx.annotation.RestrictTo;
 import androidx.appcompat.view.ActionMode;
 import androidx.appcompat.widget.Toolbar;
+import androidx.appcompat.widget.VectorEnabledTintResources;
 import androidx.core.view.WindowCompat;
 import androidx.fragment.app.FragmentActivity;
 
@@ -129,8 +130,6 @@
     @NightMode
     private static int sDefaultNightMode = MODE_NIGHT_FOLLOW_SYSTEM;
 
-    private static boolean sCompatVectorFromResourcesEnabled = false;
-
     /** @hide */
     @RestrictTo(LIBRARY_GROUP)
     @IntDef({MODE_NIGHT_NO, MODE_NIGHT_YES, MODE_NIGHT_AUTO, MODE_NIGHT_FOLLOW_SYSTEM,
@@ -522,7 +521,7 @@
      * <p>Please note: this only takes effect in Activities created after this call.</p>
      */
     public static void setCompatVectorFromResourcesEnabled(boolean enabled) {
-        sCompatVectorFromResourcesEnabled = enabled;
+        VectorEnabledTintResources.setCompatVectorFromResourcesEnabled(enabled);
     }
 
     /**
@@ -532,6 +531,6 @@
      * @see #setCompatVectorFromResourcesEnabled(boolean)
      */
     public static boolean isCompatVectorFromResourcesEnabled() {
-        return sCompatVectorFromResourcesEnabled;
+        return VectorEnabledTintResources.isCompatVectorFromResourcesEnabled();
     }
 }
diff --git a/v7/appcompat/src/main/java/androidx/appcompat/widget/VectorEnabledTintResources.java b/v7/appcompat/src/main/java/androidx/appcompat/widget/VectorEnabledTintResources.java
index 15fcf88..af61860 100644
--- a/v7/appcompat/src/main/java/androidx/appcompat/widget/VectorEnabledTintResources.java
+++ b/v7/appcompat/src/main/java/androidx/appcompat/widget/VectorEnabledTintResources.java
@@ -25,7 +25,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
-import androidx.appcompat.app.AppCompatDelegate;
 
 import java.lang.ref.WeakReference;
 
@@ -37,9 +36,10 @@
  */
 @RestrictTo(LIBRARY_GROUP)
 public class VectorEnabledTintResources extends Resources {
+    private static boolean sCompatVectorFromResourcesEnabled = false;
 
     public static boolean shouldBeUsed() {
-        return AppCompatDelegate.isCompatVectorFromResourcesEnabled()
+        return isCompatVectorFromResourcesEnabled()
                 && Build.VERSION.SDK_INT <= MAX_SDK_WHERE_REQUIRED;
     }
 
@@ -74,4 +74,22 @@
     final Drawable superGetDrawable(int id) {
         return super.getDrawable(id);
     }
+
+    /**
+     * Sets whether vector drawables on older platforms (< API 21) can be used within
+     * {@link android.graphics.drawable.DrawableContainer} resources.
+     */
+    public static void setCompatVectorFromResourcesEnabled(boolean enabled) {
+        sCompatVectorFromResourcesEnabled = enabled;
+    }
+
+    /**
+     * Returns whether vector drawables on older platforms (< API 21) can be accessed from within
+     * resources.
+     *
+     * @see #setCompatVectorFromResourcesEnabled(boolean)
+     */
+    public static boolean isCompatVectorFromResourcesEnabled() {
+        return sCompatVectorFromResourcesEnabled;
+    }
 }
\ No newline at end of file
diff --git a/v7/recyclerview/build.gradle b/v7/recyclerview/build.gradle
index 3e93b4e..ab5b778 100644
--- a/v7/recyclerview/build.gradle
+++ b/v7/recyclerview/build.gradle
@@ -42,4 +42,6 @@
     mavenGroup = LibraryGroups.RECYCLERVIEW
     inceptionYear = "2014"
     description = "Android Support RecyclerView v7"
+    failOnUncheckedWarnings = false
+    failOnDeprecationWarnings = false
 }
diff --git a/viewpager/build.gradle b/viewpager/build.gradle
index 02b45ba..6ba1d4d 100644
--- a/viewpager/build.gradle
+++ b/viewpager/build.gradle
@@ -24,4 +24,5 @@
     mavenGroup = LibraryGroups.VIEWPAGER
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
+    failOnDeprecationWarnings = false
 }
diff --git a/wear/build.gradle b/wear/build.gradle
index c70ebef..0f606f1 100644
--- a/wear/build.gradle
+++ b/wear/build.gradle
@@ -42,4 +42,5 @@
     inceptionYear = "2016"
     description = "Android Wear Support UI"
     minSdkVersion = 23
+    failOnDeprecationWarnings = false
 }
diff --git a/webkit/api/current.txt b/webkit/api/current.txt
index 08c6a55..60dbb9c 100644
--- a/webkit/api/current.txt
+++ b/webkit/api/current.txt
@@ -1,5 +1,11 @@
 package androidx.webkit {
 
+  public abstract class SafeBrowsingResponseCompat {
+    method public abstract void backToSafety(boolean);
+    method public abstract void proceed(boolean);
+    method public abstract void showInterstitial(boolean);
+  }
+
   public abstract class ServiceWorkerClientCompat {
     ctor public ServiceWorkerClientCompat();
     method public abstract android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest);
@@ -22,6 +28,15 @@
     method public abstract void setCacheMode(int);
   }
 
+  public abstract class WebResourceErrorCompat {
+    method public abstract java.lang.CharSequence getDescription();
+    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);
@@ -33,6 +48,10 @@
 
   public class WebViewClientCompat extends android.webkit.WebViewClient {
     ctor public WebViewClientCompat();
+    method public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
+    method public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
+    method public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
+    method public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
   }
 
   public class WebViewCompat {
@@ -49,7 +68,24 @@
 
   public class WebViewFeature {
     method public static boolean isFeatureSupported(java.lang.String);
+    field public static final java.lang.String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
+    field public static final java.lang.String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
+    field public static final java.lang.String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
+    field public static final java.lang.String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
+    field public static final java.lang.String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
+    field public static final java.lang.String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
+    field public static final java.lang.String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
+    field public static final java.lang.String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
+    field public static final java.lang.String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
+    field public static final java.lang.String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
+    field public static final java.lang.String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
+    field public static final java.lang.String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
+    field public static final java.lang.String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
+    field public static final java.lang.String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
+    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/build.gradle b/webkit/build.gradle
index d610dad..baed9cb 100644
--- a/webkit/build.gradle
+++ b/webkit/build.gradle
@@ -40,7 +40,7 @@
     }
 
     buildTypes.all {
-        consumerProguardFiles new File(webviewBoundaryInterfacesDir, "proguard.flags")
+        consumerProguardFiles new File(webviewBoundaryInterfacesDir, "proguard.flags") , 'proguard-rules.pro'
     }
 }
 
diff --git a/webkit/proguard-rules.pro b/webkit/proguard-rules.pro
new file mode 100644
index 0000000..86756ab
--- /dev/null
+++ b/webkit/proguard-rules.pro
@@ -0,0 +1,16 @@
+# 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.
+
+# Prevent WebViewClientCompat from being renamed, since chromium depends on this name.
+-keep public class androidx.webkit.WebViewClientCompat { public *; }
diff --git a/webkit/src/androidTest/java/androidx/webkit/IncompatibilityTest.java b/webkit/src/androidTest/java/androidx/webkit/IncompatibilityTest.java
new file mode 100644
index 0000000..09424c6
--- /dev/null
+++ b/webkit/src/androidTest/java/androidx/webkit/IncompatibilityTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.support.test.filters.MediumTest;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.runner.AndroidJUnit4;
+
+import androidx.webkit.internal.WebViewFeatureInternal;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests ensuring that Android versions/setups that are incompatible with the WebView Support
+ * Library are handled gracefully.
+ *
+ * Only L+ Android versions are compatible with the WebView Support Library, so any tests in this
+ * class that guarantee certain behaviour for incompatible Android versions will only be run on
+ * pre-L devices.
+ */
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class IncompatibilityTest {
+    @Test
+    @SdkSuppress(maxSdkVersion = 20)
+    public void testPreLDeviceHasNoWebViewFeatures() {
+        assertEquals(0, WebViewFeatureInternal.getWebViewApkFeaturesForTesting().length);
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = 20)
+    public void testPreLDeviceDoesNotSupportVisualStateCallback() {
+        assertFalse(WebViewFeature.isFeatureSupported(WebViewFeature.VISUAL_STATE_CALLBACK));
+    }
+}
diff --git a/webkit/src/androidTest/java/androidx/webkit/WebViewCompatTest.java b/webkit/src/androidTest/java/androidx/webkit/WebViewCompatTest.java
index bd77fdb..893b6df 100644
--- a/webkit/src/androidTest/java/androidx/webkit/WebViewCompatTest.java
+++ b/webkit/src/androidTest/java/androidx/webkit/WebViewCompatTest.java
@@ -29,7 +29,6 @@
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
-import android.support.test.filters.Suppress;
 import android.support.test.runner.AndroidJUnit4;
 import android.webkit.SafeBrowsingResponse;
 import android.webkit.ValueCallback;
@@ -85,9 +84,12 @@
         assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
     }
 
-    @Suppress // TODO(gsennton) remove @Suppress when b/76202025 has been resolved
     @Test
     public void testCheckThread() {
+        if (!WebViewFeature.isFeatureSupported(WebViewFeature.VISUAL_STATE_CALLBACK)) {
+            // Skip this test if VisualStateCallback is not supported.
+            return;
+        }
         try {
             WebViewCompat.postVisualStateCallback(mWebViewOnUiThread.getWebViewOnCurrentThread(), 5,
                     new WebViewCompat.VisualStateCallback() {
diff --git a/webkit/src/main/java/androidx/webkit/SafeBrowsingResponseCompat.java b/webkit/src/main/java/androidx/webkit/SafeBrowsingResponseCompat.java
new file mode 100644
index 0000000..67e046a
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/SafeBrowsingResponseCompat.java
@@ -0,0 +1,120 @@
+/*
+ * 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.webkit.SafeBrowsingResponse;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+import org.chromium.support_lib_boundary.SafeBrowsingResponseBoundaryInterface;
+import org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil;
+
+import java.lang.reflect.InvocationHandler;
+
+/**
+ * Compatibility version of {@link SafeBrowsingResponse}.
+ */
+public abstract class SafeBrowsingResponseCompat {
+    /**
+     * Display the default interstitial.
+     *
+     * @param allowReporting {@code true} if the interstitial should show a reporting checkbox.
+     */
+    public abstract void showInterstitial(boolean allowReporting);
+
+    /**
+     * Act as if the user clicked "visit this unsafe site."
+     *
+     * @param report {@code true} to enable Safe Browsing reporting.
+     */
+    public abstract void proceed(boolean report);
+
+    /**
+     * Act as if the user clicked "back to safety."
+     *
+     * @param report {@code true} to enable Safe Browsing reporting.
+     */
+    public abstract void backToSafety(boolean report);
+
+    /**
+     * This class cannot be created by applications. The support library should instantiate this
+     * with {@link #fromInvocationHandler} or {@link #fromSafeBrowsingResponse}.
+     */
+    private SafeBrowsingResponseCompat() {
+    }
+
+    /**
+     * Conversion helper to create a SafeBrowsingResponseCompat which delegates calls to {@param
+     * handler}. The InvocationHandler must be created by {@link
+     * BoundaryInterfaceReflectionUtil#createInvocationHandlerFor} using {@link
+     * SafeBrowsingResponseBoundaryInterface}.
+     *
+     * @param handler The InvocationHandler that chromium passed in the callback.
+     */
+    @NonNull
+    /* package */ static SafeBrowsingResponseCompat fromInvocationHandler(
+            @NonNull InvocationHandler handler) {
+        final SafeBrowsingResponseBoundaryInterface responseDelegate =
+                BoundaryInterfaceReflectionUtil.castToSuppLibClass(
+                        SafeBrowsingResponseBoundaryInterface.class, handler);
+        return new SafeBrowsingResponseCompat() {
+            @Override
+            public void showInterstitial(boolean allowReporting) {
+                responseDelegate.showInterstitial(allowReporting);
+            }
+
+            @Override
+            public void proceed(boolean report) {
+                responseDelegate.proceed(report);
+            }
+
+            @Override
+            public void backToSafety(boolean report) {
+                responseDelegate.backToSafety(report);
+            }
+        };
+    }
+
+    /**
+     * Conversion helper to create a SafeBrowsingResponseCompat which delegates calls to {@param
+     * response}.
+     *
+     * @param response The SafeBrowsingResponse that chromium passed in the callback.
+     */
+    @NonNull
+    @RequiresApi(27)
+    /* package */ static SafeBrowsingResponseCompat fromSafeBrowsingResponse(
+            @NonNull final SafeBrowsingResponse response) {
+        return new SafeBrowsingResponseCompat() {
+            @Override
+            public void showInterstitial(boolean allowReporting) {
+                response.showInterstitial(allowReporting);
+            }
+
+            @Override
+            public void proceed(boolean report) {
+                response.proceed(report);
+            }
+
+            @Override
+            public void backToSafety(boolean report) {
+                response.backToSafety(report);
+            }
+        };
+    }
+}
diff --git a/webkit/src/main/java/androidx/webkit/ServiceWorkerClientCompat.java b/webkit/src/main/java/androidx/webkit/ServiceWorkerClientCompat.java
index 19aab8c..5c3c5ff 100644
--- a/webkit/src/main/java/androidx/webkit/ServiceWorkerClientCompat.java
+++ b/webkit/src/main/java/androidx/webkit/ServiceWorkerClientCompat.java
@@ -43,6 +43,10 @@
      * @see android.webkit.WebViewClient#shouldInterceptRequest(android.webkit.WebView,
      * WebResourceRequest)
      *
+     * This method is called only if
+     * {@link WebViewFeature#SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST} is supported. You can check
+     * whether that flag is supported using {@link WebViewFeature#isFeatureSupported(String)}.
+     *
      */
     public abstract WebResourceResponse shouldInterceptRequest(@NonNull WebResourceRequest request);
 }
diff --git a/webkit/src/main/java/androidx/webkit/ServiceWorkerControllerCompat.java b/webkit/src/main/java/androidx/webkit/ServiceWorkerControllerCompat.java
index 3eb55d2..79b714a 100644
--- a/webkit/src/main/java/androidx/webkit/ServiceWorkerControllerCompat.java
+++ b/webkit/src/main/java/androidx/webkit/ServiceWorkerControllerCompat.java
@@ -16,18 +16,11 @@
 
 package androidx.webkit;
 
-import android.os.Build;
-import android.webkit.ServiceWorkerController;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
+import androidx.annotation.RequiresFeature;
 import androidx.annotation.RestrictTo;
-import androidx.webkit.internal.FrameworkServiceWorkerController;
-import androidx.webkit.internal.ServiceWorkerControllerAdapter;
-import androidx.webkit.internal.WebViewGlueCommunicator;
-
-// TODO(gsennton) guard APIs with isFeatureSupported(String)
+import androidx.webkit.internal.ServiceWorkerControllerImpl;
 
 /**
  * Manages Service Workers used by WebView.
@@ -61,28 +54,14 @@
      * @return the default ServiceWorkerController instance
      */
     @NonNull
+    @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_BASIC_USAGE,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static ServiceWorkerControllerCompat getInstance() {
         return LAZY_HOLDER.INSTANCE;
     }
 
     private static class LAZY_HOLDER {
-        static final ServiceWorkerControllerCompat INSTANCE =
-                Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
-                        ? getFrameworkControllerCompat() : getSupportLibraryControllerCompat();
-    }
-
-    /**
-     * Return a version of {@link ServiceWorkerControllerCompat} that only uses framework APIs.
-     */
-    @RequiresApi(Build.VERSION_CODES.N)
-    private static ServiceWorkerControllerCompat getFrameworkControllerCompat() {
-        return new FrameworkServiceWorkerController(
-                ServiceWorkerController.getInstance());
-    }
-
-    private static ServiceWorkerControllerCompat getSupportLibraryControllerCompat() {
-        return new ServiceWorkerControllerAdapter(
-                WebViewGlueCommunicator.getFactory().getServiceWorkerController());
+        static final ServiceWorkerControllerCompat INSTANCE = new ServiceWorkerControllerImpl();
     }
 
     /**
diff --git a/webkit/src/main/java/androidx/webkit/ServiceWorkerWebSettingsCompat.java b/webkit/src/main/java/androidx/webkit/ServiceWorkerWebSettingsCompat.java
index 61c46c3..6763db4 100644
--- a/webkit/src/main/java/androidx/webkit/ServiceWorkerWebSettingsCompat.java
+++ b/webkit/src/main/java/androidx/webkit/ServiceWorkerWebSettingsCompat.java
@@ -19,6 +19,7 @@
 import android.webkit.WebSettings;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.RequiresFeature;
 import androidx.annotation.RestrictTo;
 
 import java.lang.annotation.Retention;
@@ -58,6 +59,8 @@
      * {@link WebSettings#LOAD_DEFAULT}.
      *
      */
+    @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_CACHE_MODE,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public abstract void setCacheMode(@CacheMode int mode);
 
     /**
@@ -68,6 +71,8 @@
      * @see #setCacheMode
      *
      */
+    @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_CACHE_MODE,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public abstract @CacheMode int getCacheMode();
 
     /**
@@ -76,6 +81,8 @@
      * {@link WebSettings#setAllowContentAccess}.
      *
      */
+    @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public abstract void setAllowContentAccess(boolean allow);
 
     /**
@@ -85,6 +92,8 @@
      * @see #setAllowContentAccess
      *
      */
+    @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public abstract boolean getAllowContentAccess();
 
     /**
@@ -93,6 +102,8 @@
      * {@link WebSettings#setAllowFileAccess}.
      *
      */
+    @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_FILE_ACCESS,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public abstract void setAllowFileAccess(boolean allow);
 
     /**
@@ -102,6 +113,8 @@
      * @see #setAllowFileAccess
      *
      */
+    @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_FILE_ACCESS,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public abstract boolean getAllowFileAccess();
 
     /**
@@ -112,6 +125,8 @@
      * @param flag {@code true} means block network loads by the Service Workers
      *
      */
+    @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public abstract void setBlockNetworkLoads(boolean flag);
 
     /**
@@ -123,5 +138,7 @@
      * @see #setBlockNetworkLoads
      *
      */
+    @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public abstract boolean getBlockNetworkLoads();
 }
diff --git a/webkit/src/main/java/androidx/webkit/WebResourceErrorCompat.java b/webkit/src/main/java/androidx/webkit/WebResourceErrorCompat.java
new file mode 100644
index 0000000..24e2f94
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/WebResourceErrorCompat.java
@@ -0,0 +1,135 @@
+/*
+ * 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.webkit.WebResourceError;
+import android.webkit.WebViewClient;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+
+import org.chromium.support_lib_boundary.WebResourceErrorBoundaryInterface;
+import org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationHandler;
+
+/**
+ * Compatibility version of {@link WebResourceError}.
+ */
+public abstract class WebResourceErrorCompat {
+    /** @hide */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @IntDef(value = {
+            WebViewClient.ERROR_UNKNOWN,
+            WebViewClient.ERROR_HOST_LOOKUP,
+            WebViewClient.ERROR_UNSUPPORTED_AUTH_SCHEME,
+            WebViewClient.ERROR_AUTHENTICATION,
+            WebViewClient.ERROR_PROXY_AUTHENTICATION,
+            WebViewClient.ERROR_CONNECT,
+            WebViewClient.ERROR_IO,
+            WebViewClient.ERROR_TIMEOUT,
+            WebViewClient.ERROR_REDIRECT_LOOP,
+            WebViewClient.ERROR_UNSUPPORTED_SCHEME,
+            WebViewClient.ERROR_FAILED_SSL_HANDSHAKE,
+            WebViewClient.ERROR_BAD_URL,
+            WebViewClient.ERROR_FILE,
+            WebViewClient.ERROR_FILE_NOT_FOUND,
+            WebViewClient.ERROR_TOO_MANY_REQUESTS,
+            WebViewClient.ERROR_UNSAFE_RESOURCE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NetErrorCode {}
+
+    /**
+     * Gets the error code of the error. The code corresponds to one
+     * of the {@code ERROR_*} constants in {@link WebViewClient}.
+     *
+     * @return The error code of the error
+     */
+    public abstract @NetErrorCode int getErrorCode();
+
+    /**
+     * Gets the string describing the error. Descriptions are localized,
+     * and thus can be used for communicating the problem to the user.
+     *
+     * @return The description of the error
+     */
+    @NonNull
+    public abstract CharSequence getDescription();
+
+    /**
+     * This class cannot be created by applications. The support library should instantiate this
+     * with {@link #fromInvocationHandler} or {@link #fromWebResourceError}.
+     */
+    private WebResourceErrorCompat() {
+    }
+
+    /**
+     * Conversion helper to create a WebResourceErrorCompat which delegates calls to {@param
+     * handler}. The InvocationHandler must be created by {@link
+     * BoundaryInterfaceReflectionUtil#createInvocationHandlerFor} using {@link
+     * WebResourceErrorBoundaryInterface}.
+     *
+     * @param handler The InvocationHandler that chromium passed in the callback.
+     */
+    @NonNull
+    /* package */ static WebResourceErrorCompat fromInvocationHandler(
+            @NonNull InvocationHandler handler) {
+        final WebResourceErrorBoundaryInterface errorDelegate =
+                BoundaryInterfaceReflectionUtil.castToSuppLibClass(
+                        WebResourceErrorBoundaryInterface.class, handler);
+        return new WebResourceErrorCompat() {
+            @Override
+            public @NetErrorCode int getErrorCode() {
+                return errorDelegate.getErrorCode();
+            }
+
+            @Override
+            @NonNull
+            public CharSequence getDescription() {
+                return errorDelegate.getDescription();
+            }
+        };
+    }
+
+    /**
+     * Conversion helper to create a WebResourceErrorCompat which delegates calls to {@param error}.
+     *
+     * @param error The WebResourceError that chromium passed in the callback.
+     */
+    @NonNull
+    @RequiresApi(23)
+    /* package */ static WebResourceErrorCompat fromWebResourceError(
+            @NonNull final WebResourceError error) {
+        return new WebResourceErrorCompat() {
+            @Override
+            public @NetErrorCode int getErrorCode() {
+                return error.getErrorCode();
+            }
+
+            @Override
+            @NonNull
+            public CharSequence getDescription() {
+                return error.getDescription();
+            }
+        };
+    }
+}
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/WebSettingsCompat.java b/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
index 12d7e63..bff6170 100644
--- a/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
+++ b/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
@@ -16,27 +16,27 @@
 
 package androidx.webkit;
 
-import android.os.Build;
+import android.annotation.SuppressLint;
 import android.webkit.WebSettings;
 
+import androidx.annotation.IntDef;
+import androidx.annotation.RequiresFeature;
+import androidx.annotation.RestrictTo;
+import androidx.webkit.internal.WebSettingsAdapter;
+import androidx.webkit.internal.WebViewFeatureInternal;
+import androidx.webkit.internal.WebViewGlueCommunicator;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-import androidx.annotation.IntDef;
-import androidx.annotation.RestrictTo;
-import androidx.webkit.internal.WebSettingsAdapter;
-import androidx.webkit.internal.WebViewGlueCommunicator;
-
 /**
  * Compatibility version of {@link android.webkit.WebSettings}
  */
 public class WebSettingsCompat {
     private WebSettingsCompat() {}
 
-    // TODO(gsennton): add feature detection
-
     /**
      * Sets whether this WebView should raster tiles when it is
      * offscreen but attached to a window. Turning this on can avoid
@@ -50,11 +50,18 @@
      *   visible WebViews and WebViews about to be animated to visible.
      * </ul>
      */
+    @SuppressLint("NewApi")
+    @RequiresFeature(name = WebViewFeature.OFF_SCREEN_PRERASTER,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static void setOffscreenPreRaster(WebSettings webSettings, boolean enabled) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+        WebViewFeatureInternal webviewFeature =
+                WebViewFeatureInternal.getFeature(WebViewFeature.OFF_SCREEN_PRERASTER);
+        if (webviewFeature.isSupportedByFramework()) {
             webSettings.setOffscreenPreRaster(enabled);
-        } else {
+        } else if (webviewFeature.isSupportedByWebView()) {
             getAdapter(webSettings).setOffscreenPreRaster(enabled);
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
@@ -64,11 +71,18 @@
      * @return {@code true} if this WebView will raster tiles when it is
      * offscreen but attached to a window.
      */
+    @SuppressLint("NewApi")
+    @RequiresFeature(name = WebViewFeature.OFF_SCREEN_PRERASTER,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static boolean getOffscreenPreRaster(WebSettings webSettings) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+        WebViewFeatureInternal webviewFeature =
+                WebViewFeatureInternal.getFeature(WebViewFeature.OFF_SCREEN_PRERASTER);
+        if (webviewFeature.isSupportedByFramework()) {
             return webSettings.getOffscreenPreRaster();
-        } else {
+        } else if (webviewFeature.isSupportedByWebView()) {
             return getAdapter(webSettings).getOffscreenPreRaster();
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
@@ -86,11 +100,18 @@
      *
      * @param enabled Whether Safe Browsing is enabled.
      */
+    @SuppressLint("NewApi")
+    @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_ENABLE,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static void setSafeBrowsingEnabled(WebSettings webSettings, boolean enabled) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+        WebViewFeatureInternal webviewFeature =
+                WebViewFeatureInternal.getFeature(WebViewFeature.SAFE_BROWSING_ENABLE);
+        if (webviewFeature.isSupportedByFramework()) {
             webSettings.setSafeBrowsingEnabled(enabled);
-        } else {
+        } else if (webviewFeature.isSupportedByWebView()) {
             getAdapter(webSettings).setSafeBrowsingEnabled(enabled);
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
@@ -100,11 +121,18 @@
      *
      * @return {@code true} if Safe Browsing is enabled and {@code false} otherwise.
      */
+    @SuppressLint("NewApi")
+    @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_ENABLE,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static boolean getSafeBrowsingEnabled(WebSettings webSettings) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+        WebViewFeatureInternal webviewFeature =
+                WebViewFeatureInternal.getFeature(WebViewFeature.SAFE_BROWSING_ENABLE);
+        if (webviewFeature.isSupportedByFramework()) {
             return webSettings.getSafeBrowsingEnabled();
-        } else {
+        } else if (webviewFeature.isSupportedByWebView()) {
             return getAdapter(webSettings).getSafeBrowsingEnabled();
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
@@ -126,12 +154,19 @@
      * Disables the action mode menu items according to {@code menuItems} flag.
      * @param menuItems an integer field flag for the menu items to be disabled.
      */
+    @SuppressLint("NewApi")
+    @RequiresFeature(name = WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static void setDisabledActionModeMenuItems(WebSettings webSettings,
             @MenuItemFlags int menuItems) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+        WebViewFeatureInternal webviewFeature =
+                WebViewFeatureInternal.getFeature(WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS);
+        if (webviewFeature.isSupportedByFramework()) {
             webSettings.setDisabledActionModeMenuItems(menuItems);
-        } else {
+        } else if (webviewFeature.isSupportedByWebView()) {
             getAdapter(webSettings).setDisabledActionModeMenuItems(menuItems);
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
@@ -141,11 +176,18 @@
      *
      * @return all the disabled menu item flags combined with bitwise OR.
      */
+    @SuppressLint("NewApi")
+    @RequiresFeature(name = WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static @MenuItemFlags int getDisabledActionModeMenuItems(WebSettings webSettings) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+        WebViewFeatureInternal webviewFeature =
+                WebViewFeatureInternal.getFeature(WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS);
+        if (webviewFeature.isSupportedByFramework()) {
             return webSettings.getDisabledActionModeMenuItems();
-        } else {
+        } else if (webviewFeature.isSupportedByWebView()) {
             return getAdapter(webSettings).getDisabledActionModeMenuItems();
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
diff --git a/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java b/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java
index 8c690f9..d354fbf 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java
@@ -17,6 +17,8 @@
 package androidx.webkit;
 
 import android.os.Build;
+import android.webkit.SafeBrowsingResponse;
+import android.webkit.WebResourceError;
 import android.webkit.WebResourceRequest;
 import android.webkit.WebResourceResponse;
 import android.webkit.WebView;
@@ -28,6 +30,7 @@
 import androidx.annotation.RestrictTo;
 
 import org.chromium.support_lib_boundary.WebViewClientBoundaryInterface;
+import org.chromium.support_lib_boundary.util.Features;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -41,6 +44,14 @@
 // still construct a WebViewClientCompat on a pre-Lollipop devices, and explicitly invoke these
 // methods, so each of these methods must also handle this case.
 public class WebViewClientCompat extends WebViewClient implements WebViewClientBoundaryInterface {
+    private static final String[] sSupportedFeatures = new String[] {
+        Features.VISUAL_STATE_CALLBACK,
+        Features.RECEIVE_WEB_RESOURCE_ERROR,
+        Features.RECEIVE_HTTP_ERROR,
+        Features.SHOULD_OVERRIDE_WITH_REDIRECTS,
+        Features.SAFE_BROWSING_HIT,
+    };
+
     /** @hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @IntDef(value = {
@@ -52,33 +63,135 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface SafeBrowsingThreat {}
 
+    /**
+     * Returns the list of features this client supports. This feature list should always be a
+     * subset of the Features declared in WebViewFeature.
+     *
+     * @hide
+     */
+    @Override
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public final String[] getSupportedFeatures() {
+        return sSupportedFeatures;
+    }
+
+    /**
+     * Notify the host application that {@link android.webkit.WebView} content left over from
+     * previous page navigations will no longer be drawn.
+     *
+     * <p>This callback can be used to determine the point at which it is safe to make a recycled
+     * {@link android.webkit.WebView} visible, ensuring that no stale content is shown. It is called
+     * at the earliest point at which it can be guaranteed that {@link WebView#onDraw} will no
+     * longer draw any content from previous navigations. The next draw will display either the
+     * {@link WebView#setBackgroundColor background color} of the {@link WebView}, or some of the
+     * contents of the newly loaded page.
+     *
+     * <p>This method is called when the body of the HTTP response has started loading, is reflected
+     * in the DOM, and will be visible in subsequent draws. This callback occurs early in the
+     * document loading process, and as such you should expect that linked resources (for example,
+     * CSS and images) may not be available.
+     *
+     * <p>For more fine-grained notification of visual state updates, see {@link
+     * WebViewCompat#postVisualStateCallback}.
+     *
+     * <p>Please note that all the conditions and recommendations applicable to
+     * {@link WebViewCompat#postVisualStateCallback} also apply to this API.
+     *
+     * <p>This callback is only called for main frame navigations.
+     *
+     * <p>This method is called only if {@link WebViewFeature#VISUAL_STATE_CALLBACK} is supported.
+     * You can check whether that flag is supported using {@link
+     * WebViewFeature#isFeatureSupported(String)}.
+     *
+     * @param view The {@link android.webkit.WebView} for which the navigation occurred.
+     * @param url  The URL corresponding to the page navigation that triggered this callback.
+     */
     @Override
     public void onPageCommitVisible(@NonNull WebView view, @NonNull String url) {
     }
 
     /**
-     * Invoked by chromium for the {@code onReceivedError} event. Applications are not meant to
-     * override this, and should instead override the non-final {@code onReceivedError} method.
-     * TODO(ntfschr): link to that method once it's implemented.
+     * Invoked by chromium (for WebView APks 67+) for the {@code onReceivedError} event.
+     * Applications are not meant to override this, and should instead override the non-final {@link
+     * onReceivedError(WebView, WebResourceRequest, WebResourceErrorCompat)} method.
      *
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @Override
+    @RequiresApi(21)
     public final void onReceivedError(@NonNull WebView view, @NonNull WebResourceRequest request,
-            /* WebResourceError */ @NonNull InvocationHandler error) {
-        // TODO(ntfschr): implement this (b/73151460).
+            /* WebResourceError */ @NonNull InvocationHandler handler) {
+        onReceivedError(view, request, WebResourceErrorCompat.fromInvocationHandler(handler));
     }
 
+    /**
+     * Invoked by chromium (in legacy WebView APKs) for the {@code onReceivedError} event on {@link
+     * Build.VERSION_CODES.M} and above. Applications are not meant to override this, and should
+     * instead override the non-final {@link onReceivedError(WebView, WebResourceRequest,
+     * WebResourceErrorCompat)} method.
+     *
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @Override
+    @RequiresApi(23)
+    public final void onReceivedError(@NonNull WebView view, @NonNull WebResourceRequest request,
+            @NonNull WebResourceError error) {
+        if (Build.VERSION.SDK_INT < 23) return;
+        onReceivedError(view, request, WebResourceErrorCompat.fromWebResourceError(error));
+    }
+
+    /**
+     * Report web resource loading error to the host application. These errors usually indicate
+     * inability to connect to the server. Note that unlike the deprecated version of the callback,
+     * the new version will be called for any resource (iframe, image, etc.), not just for the main
+     * page. Thus, it is recommended to perform minimum required work in this callback.
+     *
+     * <p>This method is called only if {@link WebViewFeature#RECEIVE_WEB_RESOURCE_ERROR} is
+     * supported. You can check whether that flag is supported using {@link
+     * WebViewFeature#isFeatureSupported(String)}.
+     *
+     * @param view The WebView that is initiating the callback.
+     * @param request The originating request.
+     * @param error Information about the error occurred.
+     */
+    @SuppressWarnings("deprecation") // for invoking the old onReceivedError.
+    @RequiresApi(21)
+    public void onReceivedError(@NonNull WebView view, @NonNull WebResourceRequest request,
+            @NonNull WebResourceErrorCompat error) {
+        if (Build.VERSION.SDK_INT < 21) return;
+        if (request.isForMainFrame()) {
+            onReceivedError(view,
+                    error.getErrorCode(), error.getDescription().toString(),
+                    request.getUrl().toString());
+        }
+    }
+
+    /**
+     * Notify the host application that an HTTP error has been received from the server while
+     * loading a resource.  HTTP errors have status codes &gt;= 400.  This callback will be called
+     * for any resource (iframe, image, etc.), not just for the main page. Thus, it is recommended
+     * to perform minimum required work in this callback. Note that the content of the server
+     * response may not be provided within the {@code errorResponse} parameter.
+     *
+     * <p>This method is called only if {@link WebViewFeature#RECEIVE_HTTP_ERROR} is supported. You
+     * can check whether that flag is supported using {@link
+     * WebViewFeature#isFeatureSupported(String)}.
+     *
+     * @param view The WebView that is initiating the callback.
+     * @param request The originating request.
+     * @param errorResponse Information about the error occurred.
+     */
     @Override
     public void onReceivedHttpError(@NonNull WebView view, @NonNull WebResourceRequest request,
             @NonNull WebResourceResponse errorResponse) {
     }
 
     /**
-     * Invoked by chromium for the {@code onSafeBrowsingHit} event. Applications are not meant to
-     * override this, and should instead override the non-final {@code onSafeBrowsingHit} method.
-     * TODO(ntfschr): link to that method once it's implemented.
+     * Invoked by chromium (for WebView APks 67+) for the {@code onSafeBrowsingHit} event.
+     * Applications are not meant to override this, and should instead override the non-final {@link
+     * onSafeBrowsingHit(WebView, WebResourceRequest, int, SafeBrowsingResponseCompat)} method.
      *
      * @hide
      */
@@ -86,14 +199,77 @@
     @Override
     public final void onSafeBrowsingHit(@NonNull WebView view, @NonNull WebResourceRequest request,
             @SafeBrowsingThreat int threatType,
-            /* SafeBrowsingResponse */ @NonNull InvocationHandler callback) {
-        // TODO(ntfschr): implement this (b/73151460).
+            /* SafeBrowsingResponse */ @NonNull InvocationHandler handler) {
+        onSafeBrowsingHit(view, request, threatType,
+                SafeBrowsingResponseCompat.fromInvocationHandler(handler));
     }
 
-    // Default behavior in WebViewClient is to invoke the other (deprecated)
-    // shouldOverrideUrlLoading method.
+    /**
+     * Invoked by chromium (in legacy WebView APKs) for the {@code onSafeBrowsingHit} event on
+     * {@link Build.VERSION_CODES.O_MR1} and above. Applications are not meant to override this, and
+     * should instead override the non-final {@link onSafeBrowsingHit(WebView, WebResourceRequest,
+     * int, SafeBrowsingResponseCompat)} method.
+     *
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @Override
-    @SuppressWarnings("deprecation")
+    @RequiresApi(27)
+    public final void onSafeBrowsingHit(@NonNull WebView view, @NonNull WebResourceRequest request,
+            @SafeBrowsingThreat int threatType, @NonNull SafeBrowsingResponse response) {
+        onSafeBrowsingHit(view, request, threatType,
+                SafeBrowsingResponseCompat.fromSafeBrowsingResponse(response));
+    }
+
+    /**
+     * Notify the host application that a loading URL has been flagged by Safe Browsing.
+     *
+     * The application must invoke the callback to indicate the preferred response. The default
+     * behavior is to show an interstitial to the user, with the reporting checkbox visible.
+     *
+     * If the application needs to show its own custom interstitial UI, the callback can be invoked
+     * asynchronously with {@link SafeBrowsingResponseCompat#backToSafety} or {@link
+     * SafeBrowsingResponseCompat#proceed}, depending on user response.
+     *
+     * @param view The WebView that hit the malicious resource.
+     * @param request Object containing the details of the request.
+     * @param threatType The reason the resource was caught by Safe Browsing, corresponding to a
+     *                   {@code SAFE_BROWSING_THREAT_*} value.
+     * @param callback Applications must invoke one of the callback methods.
+     */
+    public void onSafeBrowsingHit(@NonNull WebView view, @NonNull WebResourceRequest request,
+            @SafeBrowsingThreat int threatType, @NonNull SafeBrowsingResponseCompat callback) {
+        callback.showInterstitial(true);
+    }
+
+    /**
+     * Give the host application a chance to take over the control when a new
+     * url is about to be loaded in the current WebView. If WebViewClient is not
+     * provided, by default WebView will ask Activity Manager to choose the
+     * proper handler for the url. If WebViewClient is provided, return {@code true}
+     * means the host application handles the url, while return {@code false} means the
+     * current WebView handles the url.
+     *
+     * <p>Notes:
+     * <ul>
+     * <li>This method is not called for requests using the POST &quot;method&quot;.</li>
+     * <li>This method is also called for subframes with non-http schemes, thus it is
+     * strongly disadvised to unconditionally call {@link WebView#loadUrl(String)}
+     * with the request's url from inside the method and then return {@code true},
+     * as this will make WebView to attempt loading a non-http url, and thus fail.</li>
+     * </ul>
+     *
+     * <p>This method is called only if {@link WebViewFeature#SHOULD_OVERRIDE_WITH_REDIRECTS} is
+     * supported. You can check whether that flag is supported using {@link
+     * WebViewFeature#isFeatureSupported(String)}.
+     *
+     * @param view The WebView that is initiating the callback.
+     * @param request Object containing the details of the request.
+     * @return {@code true} if the host application wants to leave the current WebView
+     *         and handle the url itself, otherwise return {@code false}.
+     */
+    @Override
+    @SuppressWarnings("deprecation") // for invoking the old shouldOverrideUrlLoading.
     @RequiresApi(21)
     public boolean shouldOverrideUrlLoading(@NonNull WebView view,
             @NonNull WebResourceRequest request) {
diff --git a/webkit/src/main/java/androidx/webkit/WebViewCompat.java b/webkit/src/main/java/androidx/webkit/WebViewCompat.java
index 88de335..bb1c4fc 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewCompat.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewCompat.java
@@ -16,6 +16,7 @@
 
 package androidx.webkit;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -32,7 +33,7 @@
 import androidx.webkit.internal.WebViewFeatureInternal;
 import androidx.webkit.internal.WebViewGlueCommunicator;
 import androidx.webkit.internal.WebViewProviderAdapter;
-import androidx.webkit.internal.WebViewProviderFactoryAdapter;
+import androidx.webkit.internal.WebViewProviderFactory;
 
 import org.chromium.support_lib_boundary.WebViewProviderBoundaryInterface;
 
@@ -135,7 +136,7 @@
             checkThread(webview);
             getProvider(webview).insertVisualStateCallback(requestId, callback);
         } else {
-            WebViewFeatureInternal.throwUnsupportedOperationException("postVisualStateCallback");
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
@@ -157,12 +158,19 @@
      * @param callback will be called on the UI thread with {@code true} if initialization is
      * successful, {@code false} otherwise.
      */
+    @SuppressLint("NewApi")
+    @RequiresFeature(name = WebViewFeature.START_SAFE_BROWSING,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static void startSafeBrowsing(@NonNull Context context,
             @Nullable ValueCallback<Boolean> callback) {
-        if (Build.VERSION.SDK_INT >= 27) {
+        WebViewFeatureInternal webviewFeature =
+                WebViewFeatureInternal.getFeature(WebViewFeature.START_SAFE_BROWSING);
+        if (webviewFeature.isSupportedByFramework()) {
             WebView.startSafeBrowsing(context, callback);
-        } else { // TODO(gsennton): guard with WebViewApk.hasFeature(SafeBrowsing)
+        } else if (webviewFeature.isSupportedByWebView()) {
             getFactory().getStatics().initSafeBrowsing(context, callback);
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
@@ -189,12 +197,19 @@
      * whitelist. It will be called with {@code false} if any hosts are malformed. The callback
      * will be run on the UI thread
      */
+    @SuppressLint("NewApi")
+    @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_WHITELIST,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static void setSafeBrowsingWhitelist(@NonNull List<String> hosts,
             @Nullable ValueCallback<Boolean> callback) {
-        if (Build.VERSION.SDK_INT >= 27) {
+        WebViewFeatureInternal webviewFeature =
+                WebViewFeatureInternal.getFeature(WebViewFeature.SAFE_BROWSING_WHITELIST);
+        if (webviewFeature.isSupportedByFramework()) {
             WebView.setSafeBrowsingWhitelist(hosts, callback);
-        } else { // TODO(gsennton): guard with WebViewApk.hasFeature(SafeBrowsing)
+        } else if (webviewFeature.isSupportedByWebView()) {
             getFactory().getStatics().setSafeBrowsingWhitelist(hosts, callback);
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
@@ -203,12 +218,19 @@
      *
      * @return the url pointing to a privacy policy document which can be displayed to users.
      */
+    @SuppressLint("NewApi")
     @NonNull
+    @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL,
+            enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
     public static Uri getSafeBrowsingPrivacyPolicyUrl() {
-        if (Build.VERSION.SDK_INT >= 27) {
+        WebViewFeatureInternal webviewFeature =
+                WebViewFeatureInternal.getFeature(WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL);
+        if (webviewFeature.isSupportedByFramework()) {
             return WebView.getSafeBrowsingPrivacyPolicyUrl();
-        } else { // TODO(gsennton): guard with WebViewApk.hasFeature(SafeBrowsing)
+        } else if (webviewFeature.isSupportedByWebView()) {
             return getFactory().getStatics().getSafeBrowsingPrivacyPolicyUrl();
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
         }
     }
 
@@ -258,7 +280,7 @@
     private static PackageInfo getLoadedWebViewPackageInfo()
             throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
             IllegalAccessException {
-        Class webViewFactoryClass = Class.forName("android.webkit.WebViewFactory");
+        Class<?> webViewFactoryClass = Class.forName("android.webkit.WebViewFactory");
         PackageInfo webviewPackageInfo =
                 (PackageInfo) webViewFactoryClass.getMethod(
                         "getLoadedPackageInfo").invoke(null);
@@ -274,13 +296,13 @@
         try {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
                     && Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
-                Class webViewFactoryClass = null;
+                Class<?> webViewFactoryClass = null;
                 webViewFactoryClass = Class.forName("android.webkit.WebViewFactory");
 
                 webviewPackageName = (String) webViewFactoryClass.getMethod(
                         "getWebViewPackageName").invoke(null);
             } else {
-                Class webviewUpdateServiceClass =
+                Class<?> webviewUpdateServiceClass =
                         Class.forName("android.webkit.WebViewUpdateService");
                 webviewPackageName = (String) webviewUpdateServiceClass.getMethod(
                         "getCurrentWebViewPackageName").invoke(null);
@@ -307,7 +329,7 @@
         return new WebViewProviderAdapter(createProvider(webview));
     }
 
-    private static WebViewProviderFactoryAdapter getFactory() {
+    private static WebViewProviderFactory getFactory() {
         return WebViewGlueCommunicator.getFactory();
     }
 
@@ -322,7 +344,7 @@
                 throw new RuntimeException("A WebView method was called on thread '"
                         + Thread.currentThread().getName() + "'. "
                         + "All WebView methods must be called on the same thread. "
-                        + "(Expected Looper " + webview.getLooper() + " called on "
+                        + "(Expected Looper " + webview.getWebViewLooper() + " called on "
                         + Looper.myLooper() + ", FYI main Looper is " + Looper.getMainLooper()
                         + ")");
             }
diff --git a/webkit/src/main/java/androidx/webkit/WebViewFeature.java b/webkit/src/main/java/androidx/webkit/WebViewFeature.java
index d514477..5ee4c2c 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewFeature.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewFeature.java
@@ -16,6 +16,11 @@
 
 package androidx.webkit;
 
+import android.content.Context;
+import android.webkit.ValueCallback;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebSettings;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.StringDef;
@@ -27,6 +32,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import java.util.List;
 
 /**
  * Utility class for checking which WebView Support Library features are supported on the device.
@@ -41,6 +47,23 @@
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @StringDef(value = {
             VISUAL_STATE_CALLBACK,
+            OFF_SCREEN_PRERASTER,
+            SAFE_BROWSING_ENABLE,
+            DISABLED_ACTION_MODE_MENU_ITEMS,
+            START_SAFE_BROWSING,
+            SAFE_BROWSING_WHITELIST,
+            SAFE_BROWSING_PRIVACY_POLICY_URL,
+            SERVICE_WORKER_BASIC_USAGE,
+            SERVICE_WORKER_CACHE_MODE,
+            SERVICE_WORKER_CONTENT_ACCESS,
+            SERVICE_WORKER_FILE_ACCESS,
+            SERVICE_WORKER_BLOCK_NETWORK_LOADS,
+            SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST,
+            RECEIVE_WEB_RESOURCE_ERROR,
+            RECEIVE_HTTP_ERROR,
+            SHOULD_OVERRIDE_WITH_REDIRECTS,
+            SAFE_BROWSING_HIT,
+            WEB_RESOURCE_REQUEST_IS_REDIRECT
     })
     @Retention(RetentionPolicy.SOURCE)
     @Target({ElementType.PARAMETER, ElementType.METHOD})
@@ -50,11 +73,150 @@
      * Feature for {@link #isFeatureSupported(String)}.
      * This feature covers
      * {@link androidx.webkit.WebViewCompat#postVisualStateCallback(android.webkit.WebView, long,
-     * WebViewCompat.VisualStateCallback)}.
+     * WebViewCompat.VisualStateCallback)}, and {@link
+     * WebViewClientCompat#onPageCommitVisible(
+     * android.webkit.WebView, String)}.
      */
     public static final String VISUAL_STATE_CALLBACK = Features.VISUAL_STATE_CALLBACK;
 
     /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link androidx.webkit.WebSettingsCompat#getOffscreenPreRaster(WebSettings)}, and
+     * {@link androidx.webkit.WebSettingsCompat#setOffscreenPreRaster(WebSettings, boolean)}.
+     */
+    public static final String OFF_SCREEN_PRERASTER = Features.OFF_SCREEN_PRERASTER;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link androidx.webkit.WebSettingsCompat#getSafeBrowsingEnabled(WebSettings)}, and
+     * {@link androidx.webkit.WebSettingsCompat#setSafeBrowsingEnabled(WebSettings, boolean)}.
+     */
+    public static final String SAFE_BROWSING_ENABLE = Features.SAFE_BROWSING_ENABLE;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link androidx.webkit.WebSettingsCompat#getDisabledActionModeMenuItems(WebSettings)}, and
+     * {@link androidx.webkit.WebSettingsCompat#setDisabledActionModeMenuItems(WebSettings, int)}.
+     */
+    public static final String DISABLED_ACTION_MODE_MENU_ITEMS =
+            Features.DISABLED_ACTION_MODE_MENU_ITEMS;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link androidx.webkit.WebViewCompat#startSafeBrowsing(Context, ValueCallback)}.
+     */
+    public static final String START_SAFE_BROWSING = Features.START_SAFE_BROWSING;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link androidx.webkit.WebViewCompat#setSafeBrowsingWhitelist(List, ValueCallback)}.
+     */
+    public static final String SAFE_BROWSING_WHITELIST = Features.SAFE_BROWSING_WHITELIST;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link WebViewCompat#getSafeBrowsingPrivacyPolicyUrl()}.
+     */
+    public static final String SAFE_BROWSING_PRIVACY_POLICY_URL =
+            Features.SAFE_BROWSING_PRIVACY_POLICY_URL;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link ServiceWorkerControllerCompat#getInstance()}.
+     */
+    public static final String SERVICE_WORKER_BASIC_USAGE = Features.SERVICE_WORKER_BASIC_USAGE;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link ServiceWorkerWebSettingsCompat#getCacheMode()}, and
+     * {@link ServiceWorkerWebSettingsCompat#setCacheMode(int)}.
+     */
+    public static final String SERVICE_WORKER_CACHE_MODE = Features.SERVICE_WORKER_CACHE_MODE;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link ServiceWorkerWebSettingsCompat#getAllowContentAccess()}, and
+     * {@link ServiceWorkerWebSettingsCompat#setAllowContentAccess(boolean)}.
+     */
+    public static final String SERVICE_WORKER_CONTENT_ACCESS =
+            Features.SERVICE_WORKER_CONTENT_ACCESS;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link ServiceWorkerWebSettingsCompat#getAllowFileAccess()}, and
+     * {@link ServiceWorkerWebSettingsCompat#setAllowFileAccess(boolean)}.
+     */
+    public static final String SERVICE_WORKER_FILE_ACCESS = Features.SERVICE_WORKER_FILE_ACCESS;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link ServiceWorkerWebSettingsCompat#getBlockNetworkLoads()}, and
+     * {@link ServiceWorkerWebSettingsCompat#setBlockNetworkLoads(boolean)}.
+     */
+    public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS =
+            Features.SERVICE_WORKER_BLOCK_NETWORK_LOADS;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link ServiceWorkerClientCompat#shouldInterceptRequest(WebResourceRequest)}.
+     */
+    public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST =
+            Features.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link WebViewClientCompat#onReceivedError(android.webkit.WebView, WebResourceRequest,
+     * WebResourceErrorCompat)}.
+     */
+    public static final String RECEIVE_WEB_RESOURCE_ERROR = Features.RECEIVE_WEB_RESOURCE_ERROR;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link WebViewClientCompat#onReceivedHttpError(android.webkit.WebView, WebResourceRequest,
+     * WebResourceResponse)}.
+     */
+    public static final String RECEIVE_HTTP_ERROR = Features.RECEIVE_HTTP_ERROR;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link WebViewClientCompat#shouldOverrideUrlLoading(android.webkit.WebView,
+     * WebResourceRequest)}.
+     */
+    public static final String SHOULD_OVERRIDE_WITH_REDIRECTS =
+            Features.SHOULD_OVERRIDE_WITH_REDIRECTS;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link WebViewClientCompat#onSafeBrowsingHit(android.webkit.WebView,
+     * WebResourceRequest, int, SafeBrowsingResponseCompat)}.
+     */
+    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/FrameworkServiceWorkerController.java b/webkit/src/main/java/androidx/webkit/internal/FrameworkServiceWorkerController.java
deleted file mode 100644
index 2e02777..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/FrameworkServiceWorkerController.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.os.Build;
-import android.webkit.ServiceWorkerController;
-
-import androidx.annotation.RequiresApi;
-import androidx.webkit.ServiceWorkerClientCompat;
-import androidx.webkit.ServiceWorkerControllerCompat;
-import androidx.webkit.ServiceWorkerWebSettingsCompat;
-
-/**
- * Implementation of {@link ServiceWorkerControllerCompat} meant for use on up-to-date platforms.
- * This class does not use reflection to bypass framework APIs - instead it uses android.webkit
- * APIs.
- */
-@RequiresApi(Build.VERSION_CODES.N)
-public class FrameworkServiceWorkerController extends ServiceWorkerControllerCompat {
-    private final ServiceWorkerController mImpl;
-    private ServiceWorkerWebSettingsCompat mSettings;
-
-    public FrameworkServiceWorkerController(ServiceWorkerController impl) {
-        mImpl = impl;
-    }
-
-    @Override
-    public ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings() {
-        if (mSettings == null) {
-            mSettings = new FrameworksServiceWorkerWebSettings(mImpl.getServiceWorkerWebSettings());
-        }
-        return mSettings;
-    }
-
-    @Override
-    public void setServiceWorkerClient(ServiceWorkerClientCompat client) {
-        mImpl.setServiceWorkerClient(new FrameworkServiceWorkerClient(client));
-    }
-}
diff --git a/webkit/src/main/java/androidx/webkit/internal/FrameworksServiceWorkerWebSettings.java b/webkit/src/main/java/androidx/webkit/internal/FrameworksServiceWorkerWebSettings.java
deleted file mode 100644
index 4373756..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/FrameworksServiceWorkerWebSettings.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.os.Build;
-import android.webkit.ServiceWorkerWebSettings;
-
-import androidx.annotation.RequiresApi;
-import androidx.webkit.ServiceWorkerWebSettingsCompat;
-
-/**
- * Implementation of {@link ServiceWorkerWebSettingsCompat} meant for use on up-to-date platforms.
- * This class does not use reflection to bypass framework APIs - instead it uses android.webkit
- * APIs.
- */
-@RequiresApi(Build.VERSION_CODES.N)
-public class FrameworksServiceWorkerWebSettings extends ServiceWorkerWebSettingsCompat {
-    private final ServiceWorkerWebSettings mImpl;
-
-    public FrameworksServiceWorkerWebSettings(ServiceWorkerWebSettings impl) {
-        mImpl = impl;
-    }
-
-    @Override
-    public void setCacheMode(int mode) {
-        mImpl.setCacheMode(mode);
-    }
-
-    @Override
-    public int getCacheMode() {
-        return mImpl.getCacheMode();
-    }
-
-    @Override
-    public void setAllowContentAccess(boolean allow) {
-        mImpl.setAllowContentAccess(allow);
-    }
-
-    @Override
-    public boolean getAllowContentAccess() {
-        return mImpl.getAllowContentAccess();
-    }
-
-    @Override
-    public void setAllowFileAccess(boolean allow) {
-        mImpl.setAllowContentAccess(allow);
-    }
-
-    @Override
-    public boolean getAllowFileAccess() {
-        return mImpl.getAllowFileAccess();
-    }
-
-    @Override
-    public void setBlockNetworkLoads(boolean flag) {
-        mImpl.setAllowContentAccess(flag);
-    }
-
-    @Override
-    public boolean getBlockNetworkLoads() {
-        return mImpl.getBlockNetworkLoads();
-    }
-}
diff --git a/webkit/src/main/java/androidx/webkit/internal/IncompatibleApkWebViewProviderFactory.java b/webkit/src/main/java/androidx/webkit/internal/IncompatibleApkWebViewProviderFactory.java
new file mode 100644
index 0000000..71d5768
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/IncompatibleApkWebViewProviderFactory.java
@@ -0,0 +1,62 @@
+/*
+ * 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.WebView;
+
+import org.chromium.support_lib_boundary.ServiceWorkerControllerBoundaryInterface;
+import org.chromium.support_lib_boundary.StaticsBoundaryInterface;
+import org.chromium.support_lib_boundary.WebViewProviderBoundaryInterface;
+import org.chromium.support_lib_boundary.WebkitToCompatConverterBoundaryInterface;
+
+/**
+ * This is a stub class used when the WebView Support Library is invoked on a device incompatible
+ * with the library (either a pre-L device or a device without a compatible WebView APK).
+ * The only method in this class that should be called is {@link #getWebViewFeatures()}.
+ */
+public class IncompatibleApkWebViewProviderFactory implements WebViewProviderFactory {
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+    private static final String UNSUPPORTED_EXCEPTION_EXPLANATION =
+            "This should never happen, if this method was called it means we're trying to reach "
+            + "into WebView APK code on an incompatible device. This most likely means the current "
+            + "method is being called too early, or is being called on start-up rather than lazily";
+
+    @Override
+    public WebViewProviderBoundaryInterface createWebView(WebView webview) {
+        throw new UnsupportedOperationException(UNSUPPORTED_EXCEPTION_EXPLANATION);
+    }
+
+    @Override
+    public WebkitToCompatConverterBoundaryInterface getWebkitToCompatConverter() {
+        throw new UnsupportedOperationException(UNSUPPORTED_EXCEPTION_EXPLANATION);
+    }
+
+    @Override
+    public StaticsBoundaryInterface getStatics() {
+        throw new UnsupportedOperationException(UNSUPPORTED_EXCEPTION_EXPLANATION);
+    }
+
+    @Override
+    public String[] getWebViewFeatures() {
+        return EMPTY_STRING_ARRAY;
+    }
+
+    @Override
+    public ServiceWorkerControllerBoundaryInterface getServiceWorkerController() {
+        throw new UnsupportedOperationException(UNSUPPORTED_EXCEPTION_EXPLANATION);
+    }
+}
diff --git a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerClientAdapter.java b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerClientAdapter.java
index 3ffeb83..f96bbd1 100644
--- a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerClientAdapter.java
+++ b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerClientAdapter.java
@@ -22,6 +22,7 @@
 import androidx.webkit.ServiceWorkerClientCompat;
 
 import org.chromium.support_lib_boundary.ServiceWorkerClientBoundaryInterface;
+import org.chromium.support_lib_boundary.util.Features;
 
 /**
  * Adapter between {@link ServiceWorkerClientCompat} and
@@ -39,4 +40,9 @@
     public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
         return mClient.shouldInterceptRequest(request);
     }
+
+    @Override
+    public String[] getSupportedFeatures() {
+        return new String[] { Features.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST };
+    }
 }
diff --git a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerControllerAdapter.java b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerControllerAdapter.java
deleted file mode 100644
index 4baa3ea..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerControllerAdapter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 androidx.webkit.ServiceWorkerClientCompat;
-import androidx.webkit.ServiceWorkerControllerCompat;
-import androidx.webkit.ServiceWorkerWebSettingsCompat;
-
-import org.chromium.support_lib_boundary.ServiceWorkerControllerBoundaryInterface;
-import org.chromium.support_lib_boundary.ServiceWorkerWebSettingsBoundaryInterface;
-import org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil;
-
-/**
- * Adapter between {@link ServiceWorkerControllerCompat} and
- * {@link ServiceWorkerControllerBoundaryInterface} (the corresponding interface shared with the
- * support library glue in the WebView APK).
- */
-public class ServiceWorkerControllerAdapter extends ServiceWorkerControllerCompat {
-    private final ServiceWorkerControllerBoundaryInterface mImpl;
-    private final ServiceWorkerWebSettingsCompat mWebSettings;
-
-    public ServiceWorkerControllerAdapter(ServiceWorkerControllerBoundaryInterface impl) {
-        mImpl = impl;
-        mWebSettings = new ServiceWorkerWebSettingsAdapter(
-                BoundaryInterfaceReflectionUtil.castToSuppLibClass(
-                        ServiceWorkerWebSettingsBoundaryInterface.class,
-                        mImpl.getServiceWorkerWebSettings()));
-    }
-
-    @Override
-    public ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings() {
-        return mWebSettings;
-    }
-
-    @Override
-    public void setServiceWorkerClient(ServiceWorkerClientCompat client) {
-        mImpl.setServiceWorkerClient(BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
-                new ServiceWorkerClientAdapter(client)));
-    }
-}
diff --git a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerControllerImpl.java b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerControllerImpl.java
new file mode 100644
index 0000000..17e0a7d
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerControllerImpl.java
@@ -0,0 +1,90 @@
+/*
+ * 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.annotation.SuppressLint;
+import android.webkit.ServiceWorkerController;
+
+import androidx.webkit.ServiceWorkerClientCompat;
+import androidx.webkit.ServiceWorkerControllerCompat;
+import androidx.webkit.ServiceWorkerWebSettingsCompat;
+
+import org.chromium.support_lib_boundary.ServiceWorkerControllerBoundaryInterface;
+import org.chromium.support_lib_boundary.ServiceWorkerWebSettingsBoundaryInterface;
+import org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil;
+
+/**
+ * Implementation of {@link ServiceWorkerControllerCompat}.
+ * This class uses either the framework, the WebView APK, or both, to implement
+ * {@link ServiceWorkerControllerCompat} functionality.
+ */
+public class ServiceWorkerControllerImpl extends ServiceWorkerControllerCompat {
+    private final ServiceWorkerController mFrameworksImpl;
+    private ServiceWorkerControllerBoundaryInterface mBoundaryInterface;
+    private final ServiceWorkerWebSettingsCompat mWebSettings;
+
+    @SuppressLint("NewApi")
+    public ServiceWorkerControllerImpl() {
+        final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_BASIC_USAGE;
+        if (feature.isSupportedByFramework()) {
+            mFrameworksImpl = ServiceWorkerController.getInstance();
+            // The current WebView APK might not be compatible with the support library, so set the
+            // boundary interface to null for now.
+            mBoundaryInterface = null;
+            mWebSettings = new ServiceWorkerWebSettingsImpl(
+                    mFrameworksImpl.getServiceWorkerWebSettings(), null);
+        } else if (feature.isSupportedByWebView()) {
+            mFrameworksImpl = null;
+            mBoundaryInterface = WebViewGlueCommunicator.getFactory().getServiceWorkerController();
+            mWebSettings = new ServiceWorkerWebSettingsImpl(null,
+                    BoundaryInterfaceReflectionUtil.castToSuppLibClass(
+                            ServiceWorkerWebSettingsBoundaryInterface.class,
+                            mBoundaryInterface.getServiceWorkerWebSettings()));
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+
+    private ServiceWorkerControllerBoundaryInterface getBoundaryInterface() {
+        if (mBoundaryInterface != null) return mBoundaryInterface;
+
+        // If the boundary interface is null we must have a working frameworks implementation to
+        // convert into a boundary interface.
+        mBoundaryInterface = WebViewGlueCommunicator.getFactory().getServiceWorkerController();
+        return mBoundaryInterface;
+    }
+
+    @Override
+    public ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings() {
+        return mWebSettings;
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public void setServiceWorkerClient(ServiceWorkerClientCompat client)  {
+        final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_BASIC_USAGE;
+        if (feature.isSupportedByFramework()) {
+            mFrameworksImpl.setServiceWorkerClient(new FrameworkServiceWorkerClient(client));
+        } else if (feature.isSupportedByWebView()) {
+            getBoundaryInterface().setServiceWorkerClient(
+                    BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
+                            new ServiceWorkerClientAdapter(client)));
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+}
diff --git a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerWebSettingsAdapter.java b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerWebSettingsAdapter.java
deleted file mode 100644
index fd49396..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerWebSettingsAdapter.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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 androidx.webkit.ServiceWorkerWebSettingsCompat;
-
-import org.chromium.support_lib_boundary.ServiceWorkerWebSettingsBoundaryInterface;
-
-/**
- * Adapter between {@link ServiceWorkerWebSettingsCompat} and
- * {@link ServiceWorkerWebSettingsBoundaryInterface} (the corresponding interface shared with the
- * support library glue in the WebView APK).
- */
-public class ServiceWorkerWebSettingsAdapter extends ServiceWorkerWebSettingsCompat {
-    private final ServiceWorkerWebSettingsBoundaryInterface mImpl;
-
-    public ServiceWorkerWebSettingsAdapter(ServiceWorkerWebSettingsBoundaryInterface impl) {
-        mImpl = impl;
-    }
-
-    @Override
-    public void setCacheMode(int mode) {
-        mImpl.setCacheMode(mode);
-    }
-
-    @Override
-    public int getCacheMode() {
-        return mImpl.getCacheMode();
-    }
-
-    @Override
-    public void setAllowContentAccess(boolean allow) {
-        mImpl.setAllowContentAccess(allow);
-    }
-
-    @Override
-    public boolean getAllowContentAccess() {
-        return mImpl.getAllowContentAccess();
-    }
-
-    @Override
-    public void setAllowFileAccess(boolean allow) {
-        mImpl.setAllowFileAccess(allow);
-    }
-
-    @Override
-    public boolean getAllowFileAccess() {
-        return mImpl.getAllowFileAccess();
-    }
-
-    @Override
-    public void setBlockNetworkLoads(boolean flag) {
-        mImpl.setBlockNetworkLoads(flag);
-    }
-
-    @Override
-    public boolean getBlockNetworkLoads() {
-        return mImpl.getBlockNetworkLoads();
-    }
-}
diff --git a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerWebSettingsImpl.java b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerWebSettingsImpl.java
new file mode 100644
index 0000000..9ac4450
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerWebSettingsImpl.java
@@ -0,0 +1,172 @@
+/*
+ * 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.annotation.SuppressLint;
+import android.webkit.ServiceWorkerWebSettings;
+
+import androidx.webkit.ServiceWorkerWebSettingsCompat;
+
+import org.chromium.support_lib_boundary.ServiceWorkerWebSettingsBoundaryInterface;
+
+/**
+ * Implementation of {@link ServiceWorkerWebSettingsCompat}.
+ * This class uses either the framework, the WebView APK, or both, to implement
+ * {@link ServiceWorkerWebSettingsCompat} functionality.
+ */
+public class ServiceWorkerWebSettingsImpl extends ServiceWorkerWebSettingsCompat {
+    private final ServiceWorkerWebSettings mFrameworksImpl;
+    private ServiceWorkerWebSettingsBoundaryInterface mBoundaryInterface;
+
+    /**
+     * This class handles three different scenarios:
+     * 1. The Android version on the device is high enough to support all APIs used.
+     * 2. The Android version on the device is too low to support any ServiceWorkerWebSettings APIs
+     * so we use the support library glue instead through
+     * {@link ServiceWorkerWebSettingsBoundaryInterface}.
+     * 3. The Android version on the device is high enough to support some ServiceWorkerWebSettings
+     * APIs, so we call into them using {@link android.webkit.ServiceWorkerWebSettings}, but the
+     * rest of the APIs are only supported by the support library glue, so whenever we call such an
+     * API we fetch a {@link ServiceWorkerWebSettingsBoundaryInterface} corresponding to our
+     * {@link android.webkit.ServiceWorkerWebSettings}.
+     */
+    public ServiceWorkerWebSettingsImpl(ServiceWorkerWebSettings frameworksImpl,
+            ServiceWorkerWebSettingsBoundaryInterface boundaryInterface) {
+        if (frameworksImpl == null && boundaryInterface == null) {
+            throw new IllegalArgumentException(
+                    "Both of the possible implementations cannot be null!");
+        }
+        mFrameworksImpl = frameworksImpl;
+        mBoundaryInterface = boundaryInterface;
+    }
+
+    private ServiceWorkerWebSettingsBoundaryInterface getBoundaryInterface() {
+        if (mBoundaryInterface != null) return mBoundaryInterface;
+        // If the boundary interface is null we must have a working frameworks implementation to
+        // convert into a boundary interface.
+        mBoundaryInterface =
+                WebViewGlueCommunicator.getCompatConverter().convertServiceWorkerSettings(
+                        mFrameworksImpl);
+        return mBoundaryInterface;
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public void setCacheMode(int mode) {
+        final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_CACHE_MODE;
+        if (feature.isSupportedByFramework()) {
+            mFrameworksImpl.setCacheMode(mode);
+        } else if (feature.isSupportedByWebView()) {
+            getBoundaryInterface().setCacheMode(mode);
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public int getCacheMode() {
+        final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_CACHE_MODE;
+        if (feature.isSupportedByFramework()) {
+            return mFrameworksImpl.getCacheMode();
+        } else if (feature.isSupportedByWebView()) {
+            return getBoundaryInterface().getCacheMode();
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public void setAllowContentAccess(boolean allow) {
+        final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_CONTENT_ACCESS;
+        if (feature.isSupportedByFramework()) {
+            mFrameworksImpl.setAllowContentAccess(allow);
+        } else if (feature.isSupportedByWebView()) {
+            getBoundaryInterface().setAllowContentAccess(allow);
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public boolean getAllowContentAccess() {
+        final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_CONTENT_ACCESS;
+        if (feature.isSupportedByFramework()) {
+            return mFrameworksImpl.getAllowContentAccess();
+        } else if (feature.isSupportedByWebView()) {
+            return getBoundaryInterface().getAllowContentAccess();
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public void setAllowFileAccess(boolean allow) {
+        final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_FILE_ACCESS;
+        if (feature.isSupportedByFramework()) {
+            mFrameworksImpl.setAllowFileAccess(allow);
+        } else if (feature.isSupportedByWebView()) {
+            getBoundaryInterface().setAllowFileAccess(allow);
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public boolean getAllowFileAccess() {
+        final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_FILE_ACCESS;
+        if (feature.isSupportedByFramework()) {
+            return mFrameworksImpl.getAllowFileAccess();
+        } else if (feature.isSupportedByWebView()) {
+            return getBoundaryInterface().getAllowFileAccess();
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public void setBlockNetworkLoads(boolean flag) {
+        final WebViewFeatureInternal feature =
+                WebViewFeatureInternal.SERVICE_WORKER_BLOCK_NETWORK_LOADS;
+        if (feature.isSupportedByFramework()) {
+            mFrameworksImpl.setBlockNetworkLoads(flag);
+        } else if (feature.isSupportedByWebView()) {
+            getBoundaryInterface().setBlockNetworkLoads(flag);
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public boolean getBlockNetworkLoads() {
+        final WebViewFeatureInternal feature =
+                WebViewFeatureInternal.SERVICE_WORKER_BLOCK_NETWORK_LOADS;
+        if (feature.isSupportedByFramework()) {
+            return mFrameworksImpl.getBlockNetworkLoads();
+        } else if (feature.isSupportedByWebView()) {
+            return getBoundaryInterface().getBlockNetworkLoads();
+        } else {
+            throw WebViewFeatureInternal.getUnsupportedOperationException();
+        }
+    }
+}
diff --git a/webkit/src/main/java/androidx/webkit/internal/SupportLibraryInfo.java b/webkit/src/main/java/androidx/webkit/internal/SupportLibraryInfo.java
deleted file mode 100644
index da8a02c..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/SupportLibraryInfo.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 org.chromium.support_lib_boundary.SupportLibraryInfoBoundaryInterface;
-import org.chromium.support_lib_boundary.util.Features;
-
-/**
- * Contains information about the Android Support Library part of the WebView Support Library - this
- * information is passed to the WebView APK code with the first WebView Support Library call.
- */
-public class SupportLibraryInfo implements SupportLibraryInfoBoundaryInterface {
-    // Features supported by the support library itself (regardless of what the WebView APK
-    // supports).
-    private static final String[] SUPPORTED_FEATURES =
-            new String[] {
-                    Features.VISUAL_STATE_CALLBACK
-            };
-
-    @Override
-    public String[] getSupportedFeatures() {
-        return SUPPORTED_FEATURES;
-    }
-}
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 d16713c..07c6b5f 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
@@ -16,11 +16,21 @@
 
 package androidx.webkit.internal;
 
+import android.content.Context;
 import android.os.Build;
+import android.webkit.ValueCallback;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebSettings;
 
+import androidx.webkit.ServiceWorkerClientCompat;
+import androidx.webkit.WebResourceRequestCompat;
+import androidx.webkit.WebViewClientCompat;
+import androidx.webkit.WebViewCompat;
 import androidx.webkit.WebViewFeature;
 import androidx.webkit.WebViewFeature.WebViewSupportFeature;
 
+import java.util.List;
+
 /**
  * Enum representing a WebView feature, this provides functionality for determining whether a
  * feature is supported by the current framework and/or WebView APK.
@@ -29,9 +39,130 @@
     /**
      * This feature covers
      * {@link androidx.webkit.WebViewCompat#postVisualStateCallback(android.webkit.WebView, long,
-     * androidx.webkit.WebViewCompat.VisualStateCallback)}.
+     * androidx.webkit.WebViewCompat.VisualStateCallback)}, and
+     * {@link WebViewClientCompat#onPageCommitVisible(android.webkit.WebView, String)}.
      */
-    VISUAL_STATE_CALLBACK_FEATURE(WebViewFeature.VISUAL_STATE_CALLBACK, Build.VERSION_CODES.M);
+    VISUAL_STATE_CALLBACK_FEATURE(WebViewFeature.VISUAL_STATE_CALLBACK, Build.VERSION_CODES.M),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.WebSettingsCompat#getOffscreenPreRaster(WebSettings)}, and
+     * {@link androidx.webkit.WebSettingsCompat#setOffscreenPreRaster(WebSettings, boolean)}.
+     */
+    OFF_SCREEN_PRERASTER(WebViewFeature.OFF_SCREEN_PRERASTER, Build.VERSION_CODES.M),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.WebSettingsCompat#getSafeBrowsingEnabled(WebSettings)}, and
+     * {@link androidx.webkit.WebSettingsCompat#setSafeBrowsingEnabled(WebSettings, boolean)}.
+     */
+    SAFE_BROWSING_ENABLE(WebViewFeature.SAFE_BROWSING_ENABLE, Build.VERSION_CODES.O),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.WebSettingsCompat#getDisabledActionModeMenuItems(WebSettings)}, and
+     * {@link androidx.webkit.WebSettingsCompat#setDisabledActionModeMenuItems(WebSettings, int)}.
+     */
+    DISABLED_ACTION_MODE_MENU_ITEMS(WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS,
+                                    Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.WebViewCompat#startSafeBrowsing(Context, ValueCallback)}.
+     */
+    START_SAFE_BROWSING(WebViewFeature.START_SAFE_BROWSING, Build.VERSION_CODES.O_MR1),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.WebViewCompat#setSafeBrowsingWhitelist(List, ValueCallback)}.
+     */
+    SAFE_BROWSING_WHITELIST(WebViewFeature.SAFE_BROWSING_WHITELIST, Build.VERSION_CODES.O_MR1),
+
+    /**
+     * This feature covers
+     * {@link WebViewCompat#getSafeBrowsingPrivacyPolicyUrl()}.
+     */
+    SAFE_BROWSING_PRIVACY_POLICY_URL(WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL,
+            Build.VERSION_CODES.O_MR1),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.ServiceWorkerControllerCompat#getInstance()}.
+     */
+    SERVICE_WORKER_BASIC_USAGE(WebViewFeature.SERVICE_WORKER_BASIC_USAGE, Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#getCacheMode()}, and
+     * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#setCacheMode(int)}.
+     */
+    SERVICE_WORKER_CACHE_MODE(WebViewFeature.SERVICE_WORKER_CACHE_MODE, Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#getAllowContentAccess()}, and
+     * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#setAllowContentAccess(boolean)}.
+     */
+    SERVICE_WORKER_CONTENT_ACCESS(WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS,
+            Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#getAllowFileAccess()}, and
+     * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#setAllowFileAccess(boolean)}.
+     */
+    SERVICE_WORKER_FILE_ACCESS(WebViewFeature.SERVICE_WORKER_FILE_ACCESS, Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#getBlockNetworkLoads()}, and
+     * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#setBlockNetworkLoads(boolean)}.
+     */
+    SERVICE_WORKER_BLOCK_NETWORK_LOADS(WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS,
+            Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * {@link ServiceWorkerClientCompat#shouldInterceptRequest(WebResourceRequest)}.
+     */
+    SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST(WebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST,
+            Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * {@link WebViewClientCompat#onReceivedError(android.webkit.WebView, WebResourceRequest,
+     * WebResourceErrorCompat)}.
+     */
+    RECEIVE_WEB_RESOURCE_ERROR(WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR, Build.VERSION_CODES.M),
+
+    /**
+     * This feature covers
+     * {@link WebViewClientCompat#onReceivedHttpError(android.webkit.WebView, WebResourceRequest,
+     * WebResourceResponse)}.
+     */
+    RECEIVE_HTTP_ERROR(WebViewFeature.RECEIVE_HTTP_ERROR, Build.VERSION_CODES.M),
+
+    /**
+     * This feature covers
+     * {@link WebViewClientCompat#shouldOverrideUrlLoading(android.webkit.WebView,
+     * WebResourceRequest)}.
+     */
+    SHOULD_OVERRIDE_WITH_REDIRECTS(WebViewFeature.SHOULD_OVERRIDE_WITH_REDIRECTS,
+            Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * {@link WebViewClientCompat#onSafeBrowsingHit(android.webkit.WebView,
+     * WebResourceRequest, int, SafeBrowsingResponseCompat)}.
+     */
+    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;
@@ -45,12 +176,10 @@
      * Return the {@link WebViewFeatureInternal} corresponding to {@param feature}.
      */
     public static WebViewFeatureInternal getFeature(@WebViewSupportFeature String feature) {
-        switch (feature) {
-            case WebViewFeature.VISUAL_STATE_CALLBACK:
-                return VISUAL_STATE_CALLBACK_FEATURE;
-            default:
-                throw new RuntimeException("Unknown feature " + feature);
+        for (WebViewFeatureInternal internalFeature : WebViewFeatureInternal.values()) {
+            if (internalFeature.mFeatureValue.equals(feature)) return internalFeature;
         }
+        throw new RuntimeException("Unknown feature " + feature);
     }
 
     /**
@@ -77,12 +206,17 @@
                 WebViewGlueCommunicator.getFactory().getWebViewFeatures();
     }
 
+
+    public static String[] getWebViewApkFeaturesForTesting() {
+        return LAZY_HOLDER.WEBVIEW_APK_FEATURES;
+    }
+
     /**
      * Utility method for throwing an exception explaining that the feature the app trying to use
      * isn't supported.
      */
-    public static void throwUnsupportedOperationException(String feature) {
-        throw new UnsupportedOperationException("Feature " + feature
-                + " is not supported by the current version of the framework and WebView APK");
+    public static UnsupportedOperationException getUnsupportedOperationException() {
+        return new UnsupportedOperationException("This method is not supported by the current "
+                + "version of the framework and the current WebView APK");
     }
 }
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebViewGlueCommunicator.java b/webkit/src/main/java/androidx/webkit/internal/WebViewGlueCommunicator.java
index 33ac145..9adffe7 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebViewGlueCommunicator.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebViewGlueCommunicator.java
@@ -39,49 +39,53 @@
     /**
      * Fetch the one global support library WebViewProviderFactory from the WebView glue layer.
      */
-    public static WebViewProviderFactoryAdapter getFactory() {
+    public static WebViewProviderFactory getFactory() {
         return LAZY_FACTORY_HOLDER.INSTANCE;
     }
 
     public static WebkitToCompatConverter getCompatConverter() {
-        return LAZY_FACTORY_HOLDER.COMPAT_CONVERTER;
+        return LAZY_COMPAT_CONVERTER_HOLDER.INSTANCE;
     }
 
     private static class LAZY_FACTORY_HOLDER {
-        static final WebViewProviderFactoryAdapter INSTANCE =
-                new WebViewProviderFactoryAdapter(
-                        WebViewGlueCommunicator.createGlueProviderFactory());
-        static final WebkitToCompatConverter COMPAT_CONVERTER =
-                new WebkitToCompatConverter(
-                        INSTANCE.getWebkitToCompatConverter());
+        private static final WebViewProviderFactory INSTANCE =
+                        WebViewGlueCommunicator.createGlueProviderFactory();
     }
 
-    private static InvocationHandler fetchGlueProviderFactoryImpl() {
+    private static class LAZY_COMPAT_CONVERTER_HOLDER {
+        static final WebkitToCompatConverter INSTANCE = new WebkitToCompatConverter(
+                WebViewGlueCommunicator.getFactory().getWebkitToCompatConverter());
+    }
+
+    private static InvocationHandler fetchGlueProviderFactoryImpl() throws IllegalAccessException,
+            InvocationTargetException, ClassNotFoundException, NoSuchMethodException {
+        Class<?> glueFactoryProviderFetcherClass = Class.forName(
+                GLUE_FACTORY_PROVIDER_FETCHER_CLASS, false, getWebViewClassLoader());
+        Method createProviderFactoryMethod = glueFactoryProviderFetcherClass.getDeclaredMethod(
+                GLUE_FACTORY_PROVIDER_FETCHER_METHOD);
+        return (InvocationHandler) createProviderFactoryMethod.invoke(null);
+    }
+
+    private static WebViewProviderFactory createGlueProviderFactory() {
+        InvocationHandler invocationHandler;
         try {
-            Class<?> glueFactoryProviderFetcherClass = Class.forName(
-                    GLUE_FACTORY_PROVIDER_FETCHER_CLASS, false, getWebViewClassLoader());
-            Method createProviderFactoryMethod = glueFactoryProviderFetcherClass.getDeclaredMethod(
-                    GLUE_FACTORY_PROVIDER_FETCHER_METHOD, InvocationHandler.class);
-            return (InvocationHandler) createProviderFactoryMethod.invoke(null,
-                    BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
-                            new SupportLibraryInfo()));
+            invocationHandler = fetchGlueProviderFactoryImpl();
+            // The only way we should fail to fetch the provider-factory is if the class we are
+            // calling into doesn't exist - any other kind of failure is unexpected and should cause
+            // a run-time exception.
         } catch (IllegalAccessException e) {
             throw new RuntimeException(e);
         } catch (InvocationTargetException e) {
             throw new RuntimeException(e);
         } catch (ClassNotFoundException e) {
-            throw new RuntimeException(e);
+            // If WebView APK support library glue entry point doesn't exist then return a Provider
+            // factory that declares that there are no features available.
+            return new IncompatibleApkWebViewProviderFactory();
         } catch (NoSuchMethodException e) {
             throw new RuntimeException(e);
         }
-        // TODO(gsennton) if the above happens we should avoid throwing an exception! And probably
-        // declare that the list of features supported by the WebView APK is empty.
-    }
-
-    private static WebViewProviderFactoryBoundaryInterface createGlueProviderFactory() {
-        InvocationHandler invocationHandler = fetchGlueProviderFactoryImpl();
-        return BoundaryInterfaceReflectionUtil.castToSuppLibClass(
-                WebViewProviderFactoryBoundaryInterface.class, invocationHandler);
+        return new WebViewProviderFactoryAdapter(BoundaryInterfaceReflectionUtil.castToSuppLibClass(
+                WebViewProviderFactoryBoundaryInterface.class, invocationHandler));
     }
 
     /**
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactory.java b/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactory.java
new file mode 100644
index 0000000..5e4669a
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactory.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.internal;
+
+import android.webkit.WebView;
+
+import org.chromium.support_lib_boundary.ServiceWorkerControllerBoundaryInterface;
+import org.chromium.support_lib_boundary.StaticsBoundaryInterface;
+import org.chromium.support_lib_boundary.WebViewProviderBoundaryInterface;
+import org.chromium.support_lib_boundary.WebkitToCompatConverterBoundaryInterface;
+
+/**
+ * Interface representing {@link android.webkit.WebViewProviderFactory}.
+ * On device with a compatible WebView APK this interface is implemented by a class defined in the
+ * WebView APK itself.
+ * On devices without a compatible WebView APK this interface is implemented by a stub class
+ * {@link androidx.webkit.internal.IncompatibleWebViewProviderFactory}.
+ */
+public interface WebViewProviderFactory {
+    /**
+     * Create a support library version of {@link android.webkit.WebViewProvider}.
+     */
+    WebViewProviderBoundaryInterface createWebView(WebView webview);
+
+    /**
+     * Create the boundary interface for {@link androidx.webkit.internal.WebkitToCompatConverter}
+     * which converts android.webkit classes into their corresponding support library classes.
+     */
+    WebkitToCompatConverterBoundaryInterface getWebkitToCompatConverter();
+
+    /**
+     * Fetch the boundary interface representing
+     * {@link android.webkit.WebViewFactoryProvider#Statics}.
+     */
+    StaticsBoundaryInterface getStatics();
+
+    /**
+     * Fetch the features supported by the current WebView APK.
+     */
+    String[] getWebViewFeatures();
+
+    /**
+     * Fetch the boundary interface representing {@link android.webkit.ServiceWorkerController}.
+     */
+    ServiceWorkerControllerBoundaryInterface getServiceWorkerController();
+}
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactoryAdapter.java b/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactoryAdapter.java
index efe0e64..43e5eae 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactoryAdapter.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactoryAdapter.java
@@ -29,7 +29,7 @@
  * Adapter for WebViewProviderFactoryBoundaryInterface providing static WebView functionality
  * similar to that provided by {@link android.webkit.WebViewFactoryProvider}.
  */
-public class WebViewProviderFactoryAdapter {
+public class WebViewProviderFactoryAdapter implements WebViewProviderFactory {
     WebViewProviderFactoryBoundaryInterface mImpl;
 
     public WebViewProviderFactoryAdapter(WebViewProviderFactoryBoundaryInterface impl) {
@@ -41,6 +41,7 @@
      * {@link android.webkit.WebViewProvider} - the class used to implement
      * {@link androidx.webkit.WebViewCompat}.
      */
+    @Override
     public WebViewProviderBoundaryInterface createWebView(WebView webview) {
         return BoundaryInterfaceReflectionUtil.castToSuppLibClass(
                 WebViewProviderBoundaryInterface.class, mImpl.createWebView(webview));
@@ -51,6 +52,7 @@
      * {@link androidx.webkit.internal.WebkitToCompatConverter}, which converts android.webkit
      * classes into their corresponding support library classes.
      */
+    @Override
     public WebkitToCompatConverterBoundaryInterface getWebkitToCompatConverter() {
         return BoundaryInterfaceReflectionUtil.castToSuppLibClass(
                 WebkitToCompatConverterBoundaryInterface.class, mImpl.getWebkitToCompatConverter());
@@ -60,6 +62,7 @@
      * Adapter method for fetching the support library class representing
      * {@link android.webkit.WebViewFactoryProvider#Statics}.
      */
+    @Override
     public StaticsBoundaryInterface getStatics() {
         return BoundaryInterfaceReflectionUtil.castToSuppLibClass(
                 StaticsBoundaryInterface.class, mImpl.getStatics());
@@ -68,6 +71,7 @@
     /**
      * Adapter method for fetching the features supported by the current WebView APK.
      */
+    @Override
     public String[] getWebViewFeatures() {
         return mImpl.getSupportedFeatures();
     }
@@ -76,6 +80,7 @@
      * Adapter method for fetching the support library class representing
      * {@link android.webkit.ServiceWorkerController}.
      */
+    @Override
     public ServiceWorkerControllerBoundaryInterface getServiceWorkerController() {
         return BoundaryInterfaceReflectionUtil.castToSuppLibClass(
                 ServiceWorkerControllerBoundaryInterface.class, mImpl.getServiceWorkerController());
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java b/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java
index a07cf07..e333480 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java
@@ -16,8 +16,12 @@
 
 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;
@@ -42,4 +46,26 @@
         return new WebSettingsAdapter(BoundaryInterfaceReflectionUtil.castToSuppLibClass(
                 WebSettingsBoundaryInterface.class, mImpl.convertSettings(webSettings)));
     }
+
+    /**
+     * Return a {@link ServiceWorkerWebSettingsBoundaryInterface} linked to the given
+     * {@link ServiceWorkerWebSettings }such that calls on either of those objects affect the other
+     * object.
+     */
+    public ServiceWorkerWebSettingsBoundaryInterface convertServiceWorkerSettings(
+            ServiceWorkerWebSettings settings) {
+        return BoundaryInterfaceReflectionUtil.castToSuppLibClass(
+                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)));
+    }
 }