DO NOT MERGE
Merge pie-platform-release (PPRL.181105.017, history only) into master
Bug: 118454372
Change-Id: Iadb20e47e59fe21ca4a53e0b40f72e278284d453
diff --git a/annotations/src/main/java/androidx/annotation/AnyThread.java b/annotations/src/main/java/androidx/annotation/AnyThread.java
index e314445..c33fc3f 100644
--- a/annotations/src/main/java/androidx/annotation/AnyThread.java
+++ b/annotations/src/main/java/androidx/annotation/AnyThread.java
@@ -27,18 +27,51 @@
/**
* Denotes that the annotated method can be called from any thread (e.g. it is "thread safe".)
- * If the annotated element is a class, then all methods in the class can be called
- * from any thread.
* <p>
- * The main purpose of this method is to indicate that you believe a method can be called
+ * The main purpose of this annotation is to indicate that you believe a method can be called
* from any thread; static tools can then check that nothing you call from within this method
* or class have more strict threading requirements.
- * <p>
- * Example:
* <pre><code>
* @AnyThread
* public void deliverResult(D data) { ... }
* </code></pre>
+ *
+ * <p>If the annotated element is a class, then all methods in the class can be called
+ * from any thread. </p>
+ *
+ * <pre><code>
+ * @AnyThread
+ * public class Foo { ... }
+ * </code></pre>
+ *
+ * <p>When the class is annotated, but one of the methods has another threading annotation such as
+ * {@link MainThread}, the method annotation takes precedence. In the following example,
+ * <code>onResult()</code> should only be called on the main thread.</p>
+ *
+ * <pre><code>
+ * @AnyThread
+ * public class Foo {
+ * @MainThread
+ * void onResult(String result) { ... }
+ * }
+ * </code></pre>
+ *
+ * <p>Multiple threading annotations can be combined. Following example illustrates that,
+ * <code>saveUser()</code> can be called on a worker thread or the main thread.
+ * It's safe for <code>saveUser()</code> to invoke <code>isEmpty()</code>, whereas it's not safe
+ * for <code>isEmpty()</code> to invoke <code>saveUser()</code>.
+ * </p>
+ *
+ * <pre><code>
+ * public class Foo {
+ * @WorkerThread
+ * @MainThread
+ * void saveUser(User user) { ... }
+ *
+ * @AnyThread
+ * boolean isEmpty(String value) { ... }
+ * }
+ * </code></pre>
*/
@Documented
@Retention(CLASS)
diff --git a/annotations/src/main/java/androidx/annotation/BinderThread.java b/annotations/src/main/java/androidx/annotation/BinderThread.java
index 2f944a9..92a426b 100644
--- a/annotations/src/main/java/androidx/annotation/BinderThread.java
+++ b/annotations/src/main/java/androidx/annotation/BinderThread.java
@@ -27,14 +27,47 @@
/**
* Denotes that the annotated method should only be called on the binder thread.
- * If the annotated element is a class, then all methods in the class should be called
- * on the binder thread.
- * <p>
- * Example:
* <pre><code>
* @BinderThread
* public BeamShareData createBeamShareData() { ... }
* </code></pre>
+ *
+ * <p>If the annotated element is a class, then all methods in the class should be called
+ * on the binder thread. </p>
+ *
+ * <pre><code>
+ * @BinderThread
+ * public class Foo { ... }
+ * </code></pre>
+ *
+ * <p>When the class is annotated, but one of the methods has another threading annotation such as
+ * {@link UiThread}, the method annotation takes precedence. In the following example,
+ * <code>setText()</code> should be called on the UI thread.</p>
+ *
+ * <pre><code>
+ * @BinderThread
+ * public class Foo {
+ * @UiThread
+ * void setText(String text) { ... }
+ * }
+ * </code></pre>
+ *
+ * <p>Multiple threading annotations can be combined. Following example illustrates that,
+ * <code>isEmpty()</code> can be called on a worker thread or the binder thread.
+ * It's safe for <code>saveUser()</code> to invoke <code>isEmpty()</code>, whereas it's not safe
+ * for <code>isEmpty()</code> to invoke <code>saveUser()</code>.
+ * </p>
+ *
+ * <pre><code>
+ * public class Foo {
+ * @WorkerThread
+ * void saveUser(User user) { ... }
+ *
+ * @WorkerThread
+ * @BinderThread
+ * boolean isEmpty(String value) { ... }
+ * }
+ * </code></pre>
*/
@Documented
@Retention(CLASS)
diff --git a/annotations/src/main/java/androidx/annotation/MainThread.java b/annotations/src/main/java/androidx/annotation/MainThread.java
index fe54048..d1599d4 100644
--- a/annotations/src/main/java/androidx/annotation/MainThread.java
+++ b/annotations/src/main/java/androidx/annotation/MainThread.java
@@ -27,17 +27,51 @@
/**
* Denotes that the annotated method should only be called on the main thread.
- * If the annotated element is a class, then all methods in the class should be called
- * on the main thread.
- * <p>
- * Example:
+ *
* <pre><code>
* @MainThread
- * public void deliverResult(D data) { ... }
+ * void deliverResult(D data) { ... }
+ * </code></pre>
+ *
+ * <p>If the annotated element is a class, then all methods in the class should be called
+ * on the main thread. </p>
+ *
+ * <pre><code>
+ * @MainThread
+ * public class Foo { ... }
+ * </code></pre>
+ *
+ * <p>When the class is annotated, but one of the methods has another threading annotation such as
+ * {@link WorkerThread}, the method annotation takes precedence. In the following example,
+ * <code>getUser()</code> should be called on a worker thread.</p>
+ *
+ * <pre><code>
+ * @MainThread
+ * public class Foo {
+ * @WorkerThread
+ * User getUser() { ... }
+ * }
+ * </code></pre>
+ *
+ * <p>Multiple threading annotations can be combined. Following example illustrates that,
+ * <code>isEmpty()</code> can be called on a worker thread or the main thread.
+ * It's safe for <code>saveUser()</code> to invoke <code>isEmpty()</code>, whereas it's not safe
+ * for <code>isEmpty()</code> to invoke <code>saveUser()</code>.
+ * </p>
+ *
+ * <pre><code>
+ * public class Foo {
+ * @WorkerThread
+ * void saveUser(User user) { ... }
+ *
+ * @WorkerThread
+ * @MainThread
+ * boolean isEmpty(String value) { ... }
+ * }
* </code></pre>
*
* <p class="note"><b>Note:</b> Ordinarily, an app's main thread is also the UI
- * thread. However, However, under special circumstances, an app's main thread
+ * thread. However, under special circumstances, an app's main thread
* might not be its UI thread; for more information, see
* <a href="/studio/write/annotations.html#thread-annotations">Thread
* annotations</a>.
diff --git a/annotations/src/main/java/androidx/annotation/UiThread.java b/annotations/src/main/java/androidx/annotation/UiThread.java
index f08290f..fdf6479 100644
--- a/annotations/src/main/java/androidx/annotation/UiThread.java
+++ b/annotations/src/main/java/androidx/annotation/UiThread.java
@@ -27,18 +27,50 @@
/**
* Denotes that the annotated method or constructor should only be called on the UI thread.
- * If the annotated element is a class, then all methods in the class should be called
- * on the UI thread.
- * <p>
- * Example:
* <pre><code>
* @UiThread
+ * void setText(@NonNull String text) { ... }
+ * </code></pre>
*
- * public abstract void setText(@NonNull String text) { ... }
+ * <p>If the annotated element is a class, then all methods in the class should be called
+ * on the UI thread. </p>
+ *
+ * <pre><code>
+ * @UiThread
+ * public class Foo { ... }
+ * </code></pre>
+ *
+ * <p>When the class is annotated, but one of the methods has another threading annotation such as
+ * {@link WorkerThread}, the method annotation takes precedence. In the following example,
+ * <code>getUser()</code> should be called on a worker thread.</p>
+ *
+ * <pre><code>
+ * @UiThread
+ * public class Foo {
+ * @WorkerThread
+ * User getUser() { ... }
+ * }
+ * </code></pre>
+ *
+ * <p>Multiple threading annotations can be combined. Following example illustrates that,
+ * <code>isEmpty()</code> can be called on a worker thread or the main thread.
+ * It's safe for <code>saveUser()</code> to invoke <code>isEmpty()</code>, whereas it's not safe
+ * for <code>isEmpty()</code> to invoke <code>saveUser()</code>.
+ * </p>
+ *
+ * <pre><code>
+ * public class Foo {
+ * @WorkerThread
+ * void saveUser(User user) { ... }
+ *
+ * @WorkerThread
+ * @UiThread
+ * boolean isEmpty(String value) { ... }
+ * }
* </code></pre>
*
* <p class="note"><b>Note:</b> Ordinarily, an app's UI thread is also the main
- * thread. However, However, under special circumstances, an app's UI thread
+ * thread. However, under special circumstances, an app's UI thread
* might not be its main thread; for more information, see
* <a href="/studio/write/annotations.html#thread-annotations">Thread
* annotations</a>.
diff --git a/annotations/src/main/java/androidx/annotation/WorkerThread.java b/annotations/src/main/java/androidx/annotation/WorkerThread.java
index f102301..ac88dfb 100644
--- a/annotations/src/main/java/androidx/annotation/WorkerThread.java
+++ b/annotations/src/main/java/androidx/annotation/WorkerThread.java
@@ -27,13 +27,46 @@
/**
* Denotes that the annotated method should only be called on a worker thread.
- * If the annotated element is a class, then all methods in the class should be called
- * on a worker thread.
- * <p>
- * Example:
* <pre><code>
* @WorkerThread
- * protected abstract FilterResults performFiltering(CharSequence constraint);
+ * FilterResults performFiltering(CharSequence constraint);
+ * </code></pre>
+ *
+ * <p>If the annotated element is a class, then all methods in the class should be called
+ * on a worker thread. </p>
+ *
+ * <pre><code>
+ * @WorkerThread
+ * public class Foo { ... }
+ * </code></pre>
+ *
+ * <p>When the class is annotated, but one of the methods has another threading annotation such as
+ * {@link MainThread}, the method annotation takes precedence. In the following example,
+ * <code>onResult()</code> should be called on the main thread.</p>
+ *
+ * <pre><code>
+ * @WorkerThread
+ * public class Foo {
+ * @MainThread
+ * void onResult(String result) { ... }
+ * }
+ * </code></pre>
+ *
+ * <p>Multiple threading annotations can be combined. Following example illustrates that,
+ * <code>isEmpty()</code> can be called on the worker thread or the main thread.
+ * It's safe for <code>saveUser()</code> to invoke <code>isEmpty()</code>, whereas it's not safe
+ * for <code>isEmpty()</code> to invoke <code>saveUser()</code>.
+ * </p>
+ *
+ * <pre><code>
+ * public class Foo {
+ * @WorkerThread
+ * void saveUser(User user) { ... }
+ *
+ * @WorkerThread
+ * @UiThread
+ * boolean isEmpty(String value) { ... }
+ * }
* </code></pre>
*/
@Documented
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 8f3d7ce..bda1259 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
@@ -240,7 +240,6 @@
return mNext != null;
}
- @SuppressWarnings("ReferenceEquality")
@Override
public void supportRemove(@NonNull Entry<K, V> entry) {
if (mExpectedEnd == entry && entry == mNext) {
@@ -257,7 +256,6 @@
}
}
- @SuppressWarnings("ReferenceEquality")
private Entry<K, V> nextNode() {
if (mNext == mExpectedEnd || mExpectedEnd == null) {
return null;
@@ -314,7 +312,6 @@
private Entry<K, V> mCurrent;
private boolean mBeforeStart = true;
- @SuppressWarnings("ReferenceEquality")
@Override
public void supportRemove(@NonNull Entry<K, V> entry) {
if (entry == mCurrent) {
@@ -382,7 +379,6 @@
return mKey + "=" + mValue;
}
- @SuppressWarnings("ReferenceEquality")
@Override
public boolean equals(Object obj) {
if (obj == this) {
diff --git a/app-toolkit/settings.gradle b/app-toolkit/settings.gradle
index a85d87c..817b552 100644
--- a/app-toolkit/settings.gradle
+++ b/app-toolkit/settings.gradle
@@ -64,7 +64,6 @@
includeProject(":lifecycle:lifecycle-runtime", new File(supportRoot, "lifecycle/runtime"))
includeProject(":lifecycle:lifecycle-service", new File(supportRoot, "lifecycle/service"))
includeProject(":lifecycle:lifecycle-viewmodel", new File(supportRoot, "lifecycle/viewmodel"))
-includeProject(":lifecycle:lifecycle-viewmodel-ktx", new File(supportRoot, "lifecycle/viewmodel/ktx"))
includeProject(":paging:integration-tests:testapp", new File(supportRoot, "paging/integration-tests/testapp"))
includeProject(":paging:paging-common", new File(supportRoot, "paging/common"))
includeProject(":paging:paging-runtime", new File(supportRoot, "paging/runtime"))
diff --git a/buildSrc/dependencies.gradle b/buildSrc/dependencies.gradle
index f7928eb..2608258 100644
--- a/buildSrc/dependencies.gradle
+++ b/buildSrc/dependencies.gradle
@@ -30,18 +30,6 @@
exclude group: 'androidx.annotation'
}
-libs.exclude_for_material = {
- transitive = true
- exclude group: 'androidx.annotation'
- exclude group: 'androidx.core'
- exclude group: 'androidx.legacy'
- exclude group: 'androidx.fragment'
- exclude group: 'androidx.transition'
- exclude group: 'androidx.appcompat'
- exclude group: 'androidx.recyclerview'
- exclude group: 'androidx.cardview'
-}
-
libs.exclude_for_espresso = {
exclude group: 'androidx.annotation'
exclude group: 'androidx.appcompat'
diff --git a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
index 7b0887d..be10aa6 100644
--- a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
@@ -45,8 +45,6 @@
"-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 66a302f..aad5982 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
@@ -47,6 +47,7 @@
const val LOCALBROADCASTMANAGER = "androidx.localbroadcastmanager"
const val MEDIA = "androidx.media"
const val MEDIAROUTER = "androidx.mediarouter"
+ const val MEDIAWIDGET = "androidx.mediawidget"
const val PALETTE = "androidx.palette"
const val PERCENTLAYOUT = "androidx.percentlayout"
const val PREFERENCE = "androidx.preference"
diff --git a/buildSrc/src/main/kotlin/androidx/build/SupportJavaLibraryPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/SupportJavaLibraryPlugin.kt
index cee2955..e8bd816 100644
--- a/buildSrc/src/main/kotlin/androidx/build/SupportJavaLibraryPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/SupportJavaLibraryPlugin.kt
@@ -23,7 +23,6 @@
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
/**
@@ -48,11 +47,6 @@
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 9558f76..d2a6ddba 100644
--- a/buildSrc/src/main/kotlin/androidx/build/SupportKotlinLibraryPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/SupportKotlinLibraryPlugin.kt
@@ -20,7 +20,6 @@
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) {
@@ -39,12 +38,6 @@
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/car/api/current.txt b/car/api/current.txt
index c9daf51..47ac4ca 100644
--- a/car/api/current.txt
+++ b/car/api/current.txt
@@ -397,8 +397,6 @@
method public int getViewType();
method protected void onBind(androidx.car.widget.SeekbarListItem.ViewHolder);
method protected void resolveDirtyState();
- method public void setMax(int);
- method public void setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener);
method public void setPrimaryActionEmptyIcon();
method public void setPrimaryActionIcon(int);
method public void setPrimaryActionIcon(android.graphics.drawable.Drawable);
diff --git a/car/res/drawable/ic_nav_arrow_back.xml b/car/res/drawable/ic_nav_arrow_back.xml
deleted file mode 100644
index 574e816..0000000
--- a/car/res/drawable/ic_nav_arrow_back.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
- android:viewportWidth="48"
- android:viewportHeight="48">
-
- <path
- android:pathData="M0 0h48v48H0z" />
- <path
- android:fillColor="#000000"
- android:pathData="M40 22H15.66l11.17-11.17L24 8 8 24l16 16 2.83-2.83L15.66 26H40v-4z" />
-</vector>
-
diff --git a/car/res/layout/car_alpha_jump_button.xml b/car/res/layout/car_alpha_jump_button.xml
index 443120c..c5e90fd 100644
--- a/car/res/layout/car_alpha_jump_button.xml
+++ b/car/res/layout/car_alpha_jump_button.xml
@@ -16,7 +16,7 @@
-->
<!-- This is sized in code, so we'll set it to 0dp for now. -->
-<androidx.cardview.widget.CardView
+<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:layout_width="0dp"
@@ -32,4 +32,4 @@
android:background="@drawable/car_card_ripple_background"
android:id="@+id/button"
android:gravity="center"/>
-</androidx.cardview.widget.CardView>
+</android.support.v7.widget.CardView>
diff --git a/car/res/layout/car_drawer_activity.xml b/car/res/layout/car_drawer_activity.xml
index 21a7cf2..e506d2a 100644
--- a/car/res/layout/car_drawer_activity.xml
+++ b/car/res/layout/car_drawer_activity.xml
@@ -24,7 +24,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -38,7 +38,7 @@
android:layout_gravity="center_vertical"
android:minHeight="@dimen/car_app_bar_height"
style="?attr/toolbarStyle" />
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<!-- The main content view. Fragments will be added here. -->
<androidx.car.moderator.SpeedBumpView
diff --git a/car/res/values-af/strings.xml b/car/res/values-af/strings.xml
index 1e90b40..f307fc7 100644
--- a/car/res/values-af/strings.xml
+++ b/car/res/values-af/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Konsentreer op die pad"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Vou knoppie in/uit"</string>
</resources>
diff --git a/car/res/values-am/strings.xml b/car/res/values-am/strings.xml
index 6759ee3..30ae48e 100644
--- a/car/res/values-am/strings.xml
+++ b/car/res/values-am/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"መንገዱ ላይ ያተኩሩ"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"አዝራርን ዘርጋ/ሰብስብ"</string>
</resources>
diff --git a/car/res/values-ar/strings.xml b/car/res/values-ar/strings.xml
index 845908b..e970ed9 100644
--- a/car/res/values-ar/strings.xml
+++ b/car/res/values-ar/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"ركِّز في الطريق"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"زر التوسيع/التصغير"</string>
</resources>
diff --git a/car/res/values-as/strings.xml b/car/res/values-as/strings.xml
deleted file mode 100644
index e5a0015..0000000
--- a/car/res/values-as/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="speed_bump_lockout_message" msgid="5405697774899378511">"ৰাষ্টাত মনোযোগ দিয়ক"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"সম্প্ৰসাৰণ/সংকোচন বুটাম"</string>
-</resources>
diff --git a/car/res/values-az/strings.xml b/car/res/values-az/strings.xml
index b5e25dc..e813849 100644
--- a/car/res/values-az/strings.xml
+++ b/car/res/values-az/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Diqqətinizi yola yönəldin"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Düyməni genişləndirin/yığcamlaşdırın"</string>
</resources>
diff --git a/car/res/values-b+sr+Latn/strings.xml b/car/res/values-b+sr+Latn/strings.xml
index 43dbac24..a83a82c 100644
--- a/car/res/values-b+sr+Latn/strings.xml
+++ b/car/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Fokusirajte se na put"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Dugme Proširi/skupi"</string>
</resources>
diff --git a/car/res/values-be/strings.xml b/car/res/values-be/strings.xml
index cfef873..80912e4 100644
--- a/car/res/values-be/strings.xml
+++ b/car/res/values-be/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Увага на дарогу"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Кнопка \"Разгарнуць/згарнуць\""</string>
</resources>
diff --git a/car/res/values-bg/strings.xml b/car/res/values-bg/strings.xml
index 49e7a61..dd5811f 100644
--- a/car/res/values-bg/strings.xml
+++ b/car/res/values-bg/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Съсредоточете се върху пътя"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Бутон за разгъване/свиване"</string>
</resources>
diff --git a/car/res/values-bn/strings.xml b/car/res/values-bn/strings.xml
index 4ab2ca4..fcf0165 100644
--- a/car/res/values-bn/strings.xml
+++ b/car/res/values-bn/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"মনোযোগ দিয়ে গাড়ি চালান"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"বোতাম বড় করুন/আড়াল করুন"</string>
</resources>
diff --git a/car/res/values-bs/strings.xml b/car/res/values-bs/strings.xml
index 6ff5714..99e655e 100644
--- a/car/res/values-bs/strings.xml
+++ b/car/res/values-bs/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Fokusirajte se na cestu"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Dugme proširi/suzi"</string>
</resources>
diff --git a/car/res/values-ca/strings.xml b/car/res/values-ca/strings.xml
index 8e20fd8..758f6e7 100644
--- a/car/res/values-ca/strings.xml
+++ b/car/res/values-ca/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Concentra\'t en la carretera"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Botó per desplegar o replegar"</string>
</resources>
diff --git a/car/res/values-cs/strings.xml b/car/res/values-cs/strings.xml
index 1b4cad2..27090ef 100644
--- a/car/res/values-cs/strings.xml
+++ b/car/res/values-cs/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Soustřeďte se na silnici"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Tlačítko rozbalení/sbalení"</string>
</resources>
diff --git a/car/res/values-da/strings.xml b/car/res/values-da/strings.xml
index 4a0e180..96cc062 100644
--- a/car/res/values-da/strings.xml
+++ b/car/res/values-da/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Hold øjnene på vejen"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Knappen Udvid/skjul"</string>
</resources>
diff --git a/car/res/values-de/strings.xml b/car/res/values-de/strings.xml
index f670bd6..ee289ac 100644
--- a/car/res/values-de/strings.xml
+++ b/car/res/values-de/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Achte auf den Verkehr"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Schaltfläche zum Maximieren/Minimieren"</string>
</resources>
diff --git a/car/res/values-el/strings.xml b/car/res/values-el/strings.xml
index 4010875..cf8ab8f 100644
--- a/car/res/values-el/strings.xml
+++ b/car/res/values-el/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Επικεντρωθείτε στον δρόμο"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Κουμπί ανάπτυξης/σύμπτυξης"</string>
</resources>
diff --git a/car/res/values-en-rAU/strings.xml b/car/res/values-en-rAU/strings.xml
index a307f7e..8cc3360 100644
--- a/car/res/values-en-rAU/strings.xml
+++ b/car/res/values-en-rAU/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Focus on the road"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Expand/collapse button"</string>
</resources>
diff --git a/car/res/values-en-rCA/strings.xml b/car/res/values-en-rCA/strings.xml
index a307f7e..8cc3360 100644
--- a/car/res/values-en-rCA/strings.xml
+++ b/car/res/values-en-rCA/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Focus on the road"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Expand/collapse button"</string>
</resources>
diff --git a/car/res/values-en-rGB/strings.xml b/car/res/values-en-rGB/strings.xml
index a307f7e..8cc3360 100644
--- a/car/res/values-en-rGB/strings.xml
+++ b/car/res/values-en-rGB/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Focus on the road"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Expand/collapse button"</string>
</resources>
diff --git a/car/res/values-en-rIN/strings.xml b/car/res/values-en-rIN/strings.xml
index a307f7e..8cc3360 100644
--- a/car/res/values-en-rIN/strings.xml
+++ b/car/res/values-en-rIN/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Focus on the road"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Expand/collapse button"</string>
</resources>
diff --git a/car/res/values-en-rXC/strings.xml b/car/res/values-en-rXC/strings.xml
index 16d0daf..c11c1cb 100644
--- a/car/res/values-en-rXC/strings.xml
+++ b/car/res/values-en-rXC/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Focus on the road"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Expand/collapse button"</string>
</resources>
diff --git a/car/res/values-es-rUS/strings.xml b/car/res/values-es-rUS/strings.xml
index 46a5e11..6ac20d7 100644
--- a/car/res/values-es-rUS/strings.xml
+++ b/car/res/values-es-rUS/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Concéntrate en el camino"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Botón Expandir/contraer"</string>
</resources>
diff --git a/car/res/values-es/strings.xml b/car/res/values-es/strings.xml
index 33ed10b..09a493f 100644
--- a/car/res/values-es/strings.xml
+++ b/car/res/values-es/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Céntrate en la carretera"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Botón para mostrar u ocultar"</string>
</resources>
diff --git a/car/res/values-et/strings.xml b/car/res/values-et/strings.xml
index 7561817..66f6e48 100644
--- a/car/res/values-et/strings.xml
+++ b/car/res/values-et/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Keskenduge teele"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Nupp Laienda/Ahenda"</string>
</resources>
diff --git a/car/res/values-eu/strings.xml b/car/res/values-eu/strings.xml
index 0e92575..3773f71 100644
--- a/car/res/values-eu/strings.xml
+++ b/car/res/values-eu/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Jarri arreta errepidean"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Zabaltzeko/Tolesteko botoia"</string>
</resources>
diff --git a/car/res/values-fa/strings.xml b/car/res/values-fa/strings.xml
index 59152f0..8668d6b 100644
--- a/car/res/values-fa/strings.xml
+++ b/car/res/values-fa/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"روی جاده تمرکز داشته باشید"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"دکمه بزرگ کردن/کوچک کردن"</string>
</resources>
diff --git a/car/res/values-fi/strings.xml b/car/res/values-fi/strings.xml
index 5bbb440..e93cb9c 100644
--- a/car/res/values-fi/strings.xml
+++ b/car/res/values-fi/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Pidä katse tiessä"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Laajennus- ja tiivistyspainike"</string>
</resources>
diff --git a/car/res/values-fr-rCA/strings.xml b/car/res/values-fr-rCA/strings.xml
index e90ddf2..f32315b 100644
--- a/car/res/values-fr-rCA/strings.xml
+++ b/car/res/values-fr-rCA/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Concentrez-vous sur la route"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Bouton Développer/Réduire"</string>
</resources>
diff --git a/car/res/values-fr/strings.xml b/car/res/values-fr/strings.xml
index e90ddf2..f32315b 100644
--- a/car/res/values-fr/strings.xml
+++ b/car/res/values-fr/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Concentrez-vous sur la route"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Bouton Développer/Réduire"</string>
</resources>
diff --git a/car/res/values-gl/strings.xml b/car/res/values-gl/strings.xml
index c89cc35..42bc515 100644
--- a/car/res/values-gl/strings.xml
+++ b/car/res/values-gl/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Céntrate na estrada"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Botón despregar/contraer"</string>
</resources>
diff --git a/car/res/values-gu/strings.xml b/car/res/values-gu/strings.xml
index 4397f5d..f215ec2 100644
--- a/car/res/values-gu/strings.xml
+++ b/car/res/values-gu/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"રસ્તા પર ફોકસ કરો"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"વિસ્તાર કરો/સંકુચિત કરો બટન"</string>
</resources>
diff --git a/car/res/values-hi/strings.xml b/car/res/values-hi/strings.xml
index 08d973b..53f8a8d 100644
--- a/car/res/values-hi/strings.xml
+++ b/car/res/values-hi/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"सड़क पर ध्यान दें"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"बड़ा/छोटा करने वाला बटन"</string>
</resources>
diff --git a/car/res/values-hr/strings.xml b/car/res/values-hr/strings.xml
index 5714327c..0a08dcc 100644
--- a/car/res/values-hr/strings.xml
+++ b/car/res/values-hr/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Usredotočite se na cestu"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Gumb za proširivanje/sažimanje"</string>
</resources>
diff --git a/car/res/values-hu/strings.xml b/car/res/values-hu/strings.xml
index 88c2577..3618719 100644
--- a/car/res/values-hu/strings.xml
+++ b/car/res/values-hu/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Figyeljen az útra"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Gomb kibontása/összecsukása"</string>
</resources>
diff --git a/car/res/values-hy/strings.xml b/car/res/values-hy/strings.xml
index d97cd0a..3a85b41 100644
--- a/car/res/values-hy/strings.xml
+++ b/car/res/values-hy/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Հետևեք ճանապարհին"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"«Ծավալել/ծալել» կոճակ"</string>
</resources>
diff --git a/car/res/values-in/strings.xml b/car/res/values-in/strings.xml
index faf2f43..81daf29 100644
--- a/car/res/values-in/strings.xml
+++ b/car/res/values-in/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Konsentrasi saat mengemudi"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Tombol luaskan/ciutkan"</string>
</resources>
diff --git a/car/res/values-is/strings.xml b/car/res/values-is/strings.xml
index 7c2dd76..4b5d26d 100644
--- a/car/res/values-is/strings.xml
+++ b/car/res/values-is/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Einbeittu þér að akstrinum"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Hnappur til að stækka/minnka"</string>
</resources>
diff --git a/car/res/values-it/strings.xml b/car/res/values-it/strings.xml
index d2b3f4f..b395409 100644
--- a/car/res/values-it/strings.xml
+++ b/car/res/values-it/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Concentrati sulla strada"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Pulsante Espandi/Comprimi"</string>
</resources>
diff --git a/car/res/values-iw/strings.xml b/car/res/values-iw/strings.xml
index 79bad9c..ab92be5 100644
--- a/car/res/values-iw/strings.xml
+++ b/car/res/values-iw/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"עליך להתמקד בכביש"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"לחצן הרחבה וכיווץ"</string>
</resources>
diff --git a/car/res/values-ja/strings.xml b/car/res/values-ja/strings.xml
index 87deba0..89fce3b 100644
--- a/car/res/values-ja/strings.xml
+++ b/car/res/values-ja/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"運転に集中してください"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"展開 / 折りたたみボタン"</string>
</resources>
diff --git a/car/res/values-ka/strings.xml b/car/res/values-ka/strings.xml
index b525a9b..e3f2e07 100644
--- a/car/res/values-ka/strings.xml
+++ b/car/res/values-ka/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"კონცენტრირდით გზაზე"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"ღილაკის გაფართოება/ჩაკეცვა"</string>
</resources>
diff --git a/car/res/values-kk/strings.xml b/car/res/values-kk/strings.xml
index ff327d3..bbccd56 100644
--- a/car/res/values-kk/strings.xml
+++ b/car/res/values-kk/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Жолға назар аударыңыз"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"\"Жаю/Жию\" түймесі"</string>
</resources>
diff --git a/car/res/values-km/strings.xml b/car/res/values-km/strings.xml
index f9d9111..50fe2db 100644
--- a/car/res/values-km/strings.xml
+++ b/car/res/values-km/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"ផ្តោតលើការបើកបរ"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"ប៊ូតុងពង្រីក/បង្រួម"</string>
</resources>
diff --git a/car/res/values-kn/strings.xml b/car/res/values-kn/strings.xml
index 50ba985..6562ee2 100644
--- a/car/res/values-kn/strings.xml
+++ b/car/res/values-kn/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"ರಸ್ತೆಯ ಮೇಲೆ ಗಮನಹರಿಸಿ"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"ವಿಸ್ತರಿಸಿ/ಕುಗ್ಗಿಸಿ ಬಟನ್"</string>
</resources>
diff --git a/car/res/values-ko/strings.xml b/car/res/values-ko/strings.xml
index 0081b5c..ac5865a4 100644
--- a/car/res/values-ko/strings.xml
+++ b/car/res/values-ko/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"도로 상황에 집중하세요."</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"펼치기/접기 버튼"</string>
</resources>
diff --git a/car/res/values-ky/strings.xml b/car/res/values-ky/strings.xml
index 8a752fa..3640239 100644
--- a/car/res/values-ky/strings.xml
+++ b/car/res/values-ky/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Жолго көңүл буруңуз"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Жайып көрсөтүү/жыйыштыруу баскычы"</string>
</resources>
diff --git a/car/res/values-lo/strings.xml b/car/res/values-lo/strings.xml
index 02afe60..4af3152 100644
--- a/car/res/values-lo/strings.xml
+++ b/car/res/values-lo/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"ຕັ້ງໃຈຂັບລົດ"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"ປຸ່ມຫຍໍ້/ຂະຫຍາຍ"</string>
</resources>
diff --git a/car/res/values-lt/strings.xml b/car/res/values-lt/strings.xml
index 5281e18..685bbe5 100644
--- a/car/res/values-lt/strings.xml
+++ b/car/res/values-lt/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Sutelkite dėmesį į kelią"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Mygtukas „Išskleisti / sutraukti“"</string>
</resources>
diff --git a/car/res/values-lv/strings.xml b/car/res/values-lv/strings.xml
index 7b4372b..417d331 100644
--- a/car/res/values-lv/strings.xml
+++ b/car/res/values-lv/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Pievērsieties autovadīšanai"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Izvēršanas/sakļaušanas poga"</string>
</resources>
diff --git a/car/res/values-mk/strings.xml b/car/res/values-mk/strings.xml
index 5184503..7377299 100644
--- a/car/res/values-mk/strings.xml
+++ b/car/res/values-mk/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Фокусирајте се на патот"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Копче за проширување/собирање"</string>
</resources>
diff --git a/car/res/values-ml/strings.xml b/car/res/values-ml/strings.xml
index 8047b4c..d5ad91d 100644
--- a/car/res/values-ml/strings.xml
+++ b/car/res/values-ml/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"റോഡിൽ ശ്രദ്ധിക്കുക"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"വികസിപ്പിക്കുക/ചുരുക്കുക ബട്ടൺ"</string>
</resources>
diff --git a/car/res/values-mn/strings.xml b/car/res/values-mn/strings.xml
index a8ef13c..4b249a4 100644
--- a/car/res/values-mn/strings.xml
+++ b/car/res/values-mn/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Зам дээр төвлөрөх"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Дэлгэх/буулгах товчлуур"</string>
</resources>
diff --git a/car/res/values-mr/strings.xml b/car/res/values-mr/strings.xml
index 3032c97..c79f3f3 100644
--- a/car/res/values-mr/strings.xml
+++ b/car/res/values-mr/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"रस्त्यावर फोकस करा"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"बटण विस्तृत करा/कोलॅप्स करा"</string>
</resources>
diff --git a/car/res/values-ms/strings.xml b/car/res/values-ms/strings.xml
index 301f7eb..d209113 100644
--- a/car/res/values-ms/strings.xml
+++ b/car/res/values-ms/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Beri tumpuan pada jalan raya"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Butang kembangkan/runtuhkan"</string>
</resources>
diff --git a/car/res/values-my/strings.xml b/car/res/values-my/strings.xml
index f5317f7..438729a 100644
--- a/car/res/values-my/strings.xml
+++ b/car/res/values-my/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"လမ်းကို အာရုံစိုက်ရန်"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"ချဲ့ရန်/ခေါက်သိမ်းရန် ခလုတ်"</string>
</resources>
diff --git a/car/res/values-nb/strings.xml b/car/res/values-nb/strings.xml
index e4c4810..eb3a144 100644
--- a/car/res/values-nb/strings.xml
+++ b/car/res/values-nb/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Fokuser på veien"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Vis/skjul-knapp"</string>
</resources>
diff --git a/car/res/values-ne/strings.xml b/car/res/values-ne/strings.xml
index c4499b8..d066c0b 100644
--- a/car/res/values-ne/strings.xml
+++ b/car/res/values-ne/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"सडकमा ध्यान केन्द्रित गर्नु…"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"विस्तृत/संक्षिप्त गर्ने बटन"</string>
</resources>
diff --git a/car/res/values-nl/strings.xml b/car/res/values-nl/strings.xml
index de08f63..7fcb11e 100644
--- a/car/res/values-nl/strings.xml
+++ b/car/res/values-nl/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Houd je aandacht op de weg"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Knop voor uitvouwen/samenvouwen"</string>
</resources>
diff --git a/car/res/values-or/strings.xml b/car/res/values-or/strings.xml
deleted file mode 100644
index 3a003b8..0000000
--- a/car/res/values-or/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="speed_bump_lockout_message" msgid="5405697774899378511">"ରାସ୍ତା ଉପରେ ଧ୍ୟାନରଖନ୍ତୁ"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"ବିସ୍ତାର/ସଂକୋଚନ ବଟନ୍"</string>
-</resources>
diff --git a/car/res/values-pa/strings.xml b/car/res/values-pa/strings.xml
index 63a19f3..137bd2a 100644
--- a/car/res/values-pa/strings.xml
+++ b/car/res/values-pa/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"ਸੜਕ \'ਤੇ ਧਿਆਨ ਦਿਓ"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"ਵਿਸਤਾਰ ਕਰੋ/ਸਮੇਟੋ ਬਟਨ"</string>
</resources>
diff --git a/car/res/values-pl/strings.xml b/car/res/values-pl/strings.xml
index 133d27e..c5aa323 100644
--- a/car/res/values-pl/strings.xml
+++ b/car/res/values-pl/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Skup się na drodze"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Przycisk zwijania/rozwijania"</string>
</resources>
diff --git a/car/res/values-pt-rBR/strings.xml b/car/res/values-pt-rBR/strings.xml
index 6c6e459..a6c515a 100644
--- a/car/res/values-pt-rBR/strings.xml
+++ b/car/res/values-pt-rBR/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Foco na estrada"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Botão \"Expandir/Recolher\""</string>
</resources>
diff --git a/car/res/values-pt-rPT/strings.xml b/car/res/values-pt-rPT/strings.xml
index 911b120..2338efe 100644
--- a/car/res/values-pt-rPT/strings.xml
+++ b/car/res/values-pt-rPT/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Concentre-se na estrada."</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Botão Expandir/reduzir"</string>
</resources>
diff --git a/car/res/values-pt/strings.xml b/car/res/values-pt/strings.xml
index 6c6e459..a6c515a 100644
--- a/car/res/values-pt/strings.xml
+++ b/car/res/values-pt/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Foco na estrada"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Botão \"Expandir/Recolher\""</string>
</resources>
diff --git a/car/res/values-ro/strings.xml b/car/res/values-ro/strings.xml
index 7fe204a..20cc3e7 100644
--- a/car/res/values-ro/strings.xml
+++ b/car/res/values-ro/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Concentrați-vă asupra drumului"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Butonul de extindere/restrângere"</string>
</resources>
diff --git a/car/res/values-ru/strings.xml b/car/res/values-ru/strings.xml
index 6554dc3..198f7fa 100644
--- a/car/res/values-ru/strings.xml
+++ b/car/res/values-ru/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Следите за дорогой"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Кнопка \"Развернуть/свернуть\""</string>
</resources>
diff --git a/car/res/values-si/strings.xml b/car/res/values-si/strings.xml
index 48977bd..530c12a 100644
--- a/car/res/values-si/strings.xml
+++ b/car/res/values-si/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"මාර්ගයට අවධානය යොමු කරන්න"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"දිග හැරීමේ/හැකිළීමේ බොත්තම"</string>
</resources>
diff --git a/car/res/values-sk/strings.xml b/car/res/values-sk/strings.xml
index d8175c4..a959d09 100644
--- a/car/res/values-sk/strings.xml
+++ b/car/res/values-sk/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Sústreďte sa na cestu"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Tlačidlo rozbalenia/zbalenia"</string>
</resources>
diff --git a/car/res/values-sl/strings.xml b/car/res/values-sl/strings.xml
index 85f2602..c0a8164 100644
--- a/car/res/values-sl/strings.xml
+++ b/car/res/values-sl/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Glejte na cesto"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Gumb za razširitev/strnitev"</string>
</resources>
diff --git a/car/res/values-sq/strings.xml b/car/res/values-sq/strings.xml
index 87cb023..c8c91ef 100644
--- a/car/res/values-sq/strings.xml
+++ b/car/res/values-sq/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Përqendrohu te rruga"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Butoni i zgjerimit/palosjes"</string>
</resources>
diff --git a/car/res/values-sr/strings.xml b/car/res/values-sr/strings.xml
index d3fe526..d7a6b85 100644
--- a/car/res/values-sr/strings.xml
+++ b/car/res/values-sr/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Фокусирајте се на пут"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Дугме Прошири/скупи"</string>
</resources>
diff --git a/car/res/values-sv/strings.xml b/car/res/values-sv/strings.xml
index c4ae438..3798509 100644
--- a/car/res/values-sv/strings.xml
+++ b/car/res/values-sv/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Fokusera på körningen"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Knappen Utöka/komprimera"</string>
</resources>
diff --git a/car/res/values-sw/strings.xml b/car/res/values-sw/strings.xml
index d3472f5..a5b76c7 100644
--- a/car/res/values-sw/strings.xml
+++ b/car/res/values-sw/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Tia makini barabarani"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Kitufe cha kupanua/kukunja"</string>
</resources>
diff --git a/car/res/values-ta/strings.xml b/car/res/values-ta/strings.xml
index e13ede5..e97f385 100644
--- a/car/res/values-ta/strings.xml
+++ b/car/res/values-ta/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"வாகனம் ஓட்டும்போது கவனம் தேவை"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"விரிவாக்குவதற்கான/சுருக்குவதற்கான பட்டன்"</string>
</resources>
diff --git a/car/res/values-te/strings.xml b/car/res/values-te/strings.xml
index b106363..9079a09 100644
--- a/car/res/values-te/strings.xml
+++ b/car/res/values-te/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"రహదారిపై దృష్టి ఉంచండి"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"విస్తరించు/కుదించు బటన్"</string>
</resources>
diff --git a/car/res/values-th/strings.xml b/car/res/values-th/strings.xml
index 05be415..3ba0d6b 100644
--- a/car/res/values-th/strings.xml
+++ b/car/res/values-th/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"จดจ่อกับถนน"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"ปุ่มขยาย/ยุบ"</string>
</resources>
diff --git a/car/res/values-tl/strings.xml b/car/res/values-tl/strings.xml
index a56c37c..395e555 100644
--- a/car/res/values-tl/strings.xml
+++ b/car/res/values-tl/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Tumuon sa kalsada"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Button na i-expand/i-collapse"</string>
</resources>
diff --git a/car/res/values-tr/strings.xml b/car/res/values-tr/strings.xml
index b28b66e..a0f0b22 100644
--- a/car/res/values-tr/strings.xml
+++ b/car/res/values-tr/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Dikkatinizi yola verin"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Genişlet/daralt düğmesi"</string>
</resources>
diff --git a/car/res/values-uk/strings.xml b/car/res/values-uk/strings.xml
index 1964936..2657348 100644
--- a/car/res/values-uk/strings.xml
+++ b/car/res/values-uk/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Зосередьтеся на дорозі"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Кнопка \"Розгорнути або згорнути\""</string>
</resources>
diff --git a/car/res/values-ur/strings.xml b/car/res/values-ur/strings.xml
index c1d6b3e..60c578c 100644
--- a/car/res/values-ur/strings.xml
+++ b/car/res/values-ur/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"سڑک پر توجہ مرکوز کریں"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"پھیلائیں/سکیڑیں بٹن"</string>
</resources>
diff --git a/car/res/values-uz/strings.xml b/car/res/values-uz/strings.xml
index a830b84..bdaba48 100644
--- a/car/res/values-uz/strings.xml
+++ b/car/res/values-uz/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Diqqatingizni yo‘lga qarating"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Yoyish/yig‘ish tugmasi"</string>
</resources>
diff --git a/car/res/values-vi/strings.xml b/car/res/values-vi/strings.xml
index 144f41a..37457d4 100644
--- a/car/res/values-vi/strings.xml
+++ b/car/res/values-vi/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Tập trung vào đường đi"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Nút mở rộng/thu gọn"</string>
</resources>
diff --git a/car/res/values-zh-rCN/strings.xml b/car/res/values-zh-rCN/strings.xml
index 0c2caeaa..ec0c3c4 100644
--- a/car/res/values-zh-rCN/strings.xml
+++ b/car/res/values-zh-rCN/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"请专心驾驶"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"“展开”/“收起”按钮"</string>
</resources>
diff --git a/car/res/values-zh-rHK/strings.xml b/car/res/values-zh-rHK/strings.xml
index 09c1a9e..61102cc 100644
--- a/car/res/values-zh-rHK/strings.xml
+++ b/car/res/values-zh-rHK/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"請專心駕駛"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"展開/收合按鈕"</string>
</resources>
diff --git a/car/res/values-zh-rTW/strings.xml b/car/res/values-zh-rTW/strings.xml
index 09c1a9e..61102cc 100644
--- a/car/res/values-zh-rTW/strings.xml
+++ b/car/res/values-zh-rTW/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"請專心駕駛"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"展開/收合按鈕"</string>
</resources>
diff --git a/car/res/values-zu/strings.xml b/car/res/values-zu/strings.xml
index 9403834..bdf7337 100644
--- a/car/res/values-zu/strings.xml
+++ b/car/res/values-zu/strings.xml
@@ -17,5 +17,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="speed_bump_lockout_message" msgid="5405697774899378511">"Gxila emgwaqweni"</string>
- <string name="action_bar_expand_collapse_button" msgid="196909968432559564">"Inkinobho yokunweba/ukugoqa"</string>
</resources>
diff --git a/car/res/values/styles.xml b/car/res/values/styles.xml
index 5db209e..79978db 100644
--- a/car/res/values/styles.xml
+++ b/car/res/values/styles.xml
@@ -173,20 +173,6 @@
<item name="android:textColor">@color/car_body4</item>
</style>
- <!-- The styling for action button text. -->
- <style name="TextAppearance.Car.Action1">
- <item name="android:fontFamily">sans-serif-medium</item>
- <item name="android:textStyle">normal</item>
- <item name="android:textAllCaps">true</item>
- <item name="android:textSize">@dimen/car_action1_size</item>
- <item name="android:textColor">@color/car_accent</item>
- </style>
-
- <!-- The styling for menu text in action bar. -->
- <style name="TextAppearance.Car.ActionBar.Menu" parent="TextAppearance.Car.Action1">
- <item name="android:textColor">?attr/actionMenuTextColor</item>
- </style>
-
<!-- Styles for TextInputLayout hints. -->
<style name="TextAppearance.Car.Hint" parent="TextAppearance.Car.Body2" />
@@ -195,33 +181,11 @@
<!-- ======= -->
<eat-comment />
- <!-- The styling for Toolbar used as action bar. -->
+ <!-- The styling for the action bar. -->
<style name="Widget.Car.Toolbar" parent="Widget.AppCompat.Toolbar">
- <item name="android:minHeight">?attr/actionBarSize</item>
- <item name="background">@color/car_card</item>
- <item name="contentInsetEnd">@dimen/car_keyline_1</item>
+ <item name="titleTextAppearance">@style/TextAppearance.Car.Title.Light</item>
<item name="contentInsetStart">@dimen/car_keyline_1</item>
- <item name="elevation">@dimen/car_action_bar_elevation</item>
- <item name="subtitleTextAppearance">@style/TextAppearance.Car.Body2</item>
- <item name="titleTextAppearance">@style/TextAppearance.Car.Title2</item>
- <item name="navigationIcon">@drawable/ic_nav_arrow_back</item>
- </style>
-
- <!-- The styling for the navigation button in action bar. -->
- <style name="Widget.Car.Toolbar.Button.Navigation"
- parent="Widget.AppCompat.Toolbar.Button.Navigation">
- <item name="android:background">@drawable/car_card_ripple_background</item>
- <item name="android:scaleType">center</item>
- <item name="android:tint">@color/car_tint</item>
- </style>
-
- <style name="Widget.Car.ActionButton" parent="Widget.AppCompat.ActionButton">
- <item name="android:background">?attr/actionBarItemBackground</item>
- <item name="android:minHeight">@dimen/car_action_bar_height</item>
- <item name="android:paddingLeft">@dimen/car_padding_2</item>
- <item name="android:paddingRight">@dimen/car_padding_2</item>
- <item name="android:scaleType">fitCenter</item>
- <item name="android:tint">@color/car_tint</item>
+ <item name="contentInsetEnd">@dimen/car_keyline_1</item>
</style>
<!-- The style for the menu bar (i.e. hamburger) and back arrow in the navigation drawer. -->
diff --git a/car/res/values/themes.xml b/car/res/values/themes.xml
index 3030396..35c0262 100644
--- a/car/res/values/themes.xml
+++ b/car/res/values/themes.xml
@@ -33,20 +33,13 @@
<item name="android:editTextColor">@color/car_body1</item>
<item name="android:colorControlNormal">@color/car_body2</item>
<item name="android:seekBarStyle">@style/Widget.Car.SeekBar</item>
- <item name="actionBarItemBackground">@drawable/car_card_ripple_background</item>
- <item name="actionBarSize">@dimen/car_app_bar_height</item>
- <item name="actionButtonStyle">@style/Widget.Car.ActionButton</item>
- <item name="actionMenuTextAppearance">@style/TextAppearance.Car.ActionBar.Menu</item>
- <item name="actionMenuTextColor">@color/car_accent</item>
<item name="carDialogTheme">@style/Theme.Car.Dialog</item>
<item name="colorControlHighlight">@color/car_card_ripple_background</item>
+ <item name="pagedListViewStyle">@style/Widget.Car.List</item>
<item name="listItemBackgroundColor">@color/car_card</item>
<item name="listItemTitleTextAppearance">@style/TextAppearance.Car.Body1</item>
<item name="listItemBodyTextAppearance">@style/TextAppearance.Car.Body2</item>
<item name="listItemSubheaderTextAppearance">@style/TextAppearance.Car.Subheader</item>
- <item name="pagedListViewStyle">@style/Widget.Car.List</item>
- <item name="toolbarNavigationButtonStyle">@style/Widget.Car.Toolbar.Button.Navigation</item>
- <item name="toolbarStyle">@style/Widget.Car.Toolbar</item>
</style>
<!-- Theme for the Car that is a passthrough for the default theme. -->
diff --git a/car/src/androidTest/java/androidx/car/widget/SeekbarListItemTest.java b/car/src/androidTest/java/androidx/car/widget/SeekbarListItemTest.java
index 82f5268..13e10ff 100644
--- a/car/src/androidTest/java/androidx/car/widget/SeekbarListItemTest.java
+++ b/car/src/androidTest/java/androidx/car/widget/SeekbarListItemTest.java
@@ -419,3 +419,4 @@
};
}
}
+
diff --git a/car/src/main/java/androidx/car/drawer/CarDrawerActivity.java b/car/src/main/java/androidx/car/drawer/CarDrawerActivity.java
index e43e002..ea944ff 100644
--- a/car/src/main/java/androidx/car/drawer/CarDrawerActivity.java
+++ b/car/src/main/java/androidx/car/drawer/CarDrawerActivity.java
@@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package androidx.car.drawer;
import android.animation.ValueAnimator;
import android.content.res.Configuration;
import android.os.Bundle;
+import android.support.design.widget.AppBarLayout;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MenuItem;
@@ -33,8 +33,6 @@
import androidx.car.R;
import androidx.drawerlayout.widget.DrawerLayout;
-import com.google.android.material.appbar.AppBarLayout;
-
/**
* Common base Activity for car apps that need to present a Drawer.
*
diff --git a/car/src/main/java/androidx/car/widget/SeekbarListItem.java b/car/src/main/java/androidx/car/widget/SeekbarListItem.java
index d859b63..0c64d12 100644
--- a/car/src/main/java/androidx/car/widget/SeekbarListItem.java
+++ b/car/src/main/java/androidx/car/widget/SeekbarListItem.java
@@ -66,8 +66,6 @@
*
* <p>When conflicting methods are called (e.g. setting primary action to both primary icon and
* no icon), the last called method wins.
- *
- * {@code minimum value} is set to 0.
*/
public class SeekbarListItem extends ListItem<SeekbarListItem.ViewHolder> {
@@ -102,9 +100,8 @@
private String mText;
- private int mMax;
private int mProgress;
- private int mSecondaryProgress;
+ private int mMax;
private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener;
@SupplementalActionType private int mSupplementalActionType = SUPPLEMENTAL_ACTION_NO_ACTION;
@@ -133,46 +130,6 @@
}
/**
- * Sets max value of seekbar.
- */
- public void setMax(int max) {
- mMax = max;
- markDirty();
- }
-
- /**
- * Sets progress of seekbar.
- */
- public void setProgress(int progress) {
- mProgress = progress;
- markDirty();
- }
-
- /**
- * Sets secondary progress of seekbar.
- */
- public void setSecondaryProgress(int secondaryProgress) {
- mSecondaryProgress = secondaryProgress;
- markDirty();
- }
-
- /**
- * Sets {@link SeekBar.OnSeekBarChangeListener}.
- */
- public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener listener) {
- mOnSeekBarChangeListener = listener;
- markDirty();
- }
-
- /**
- * Sets text that sits on top of seekbar.
- */
- public void setText(String text) {
- mText = text;
- markDirty();
- }
-
- /**
* Calculates the layout params for views in {@link ViewHolder}.
*/
@Override
@@ -304,7 +261,6 @@
mBinders.add(vh -> {
vh.getSeekBar().setMax(mMax);
vh.getSeekBar().setProgress(mProgress);
- vh.getSeekBar().setSecondaryProgress(mSecondaryProgress);
vh.getSeekBar().setOnSeekBarChangeListener(mOnSeekBarChangeListener);
if (!TextUtils.isEmpty(mText)) {
diff --git a/compat/api/current.txt b/compat/api/current.txt
index 529cbba..0a19457 100644
--- a/compat/api/current.txt
+++ b/compat/api/current.txt
@@ -81,20 +81,6 @@
method public static void setExactAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
}
- public class AppComponentFactory extends android.app.AppComponentFactory {
- ctor public AppComponentFactory();
- method public final android.app.Activity instantiateActivity(java.lang.ClassLoader, java.lang.String, android.content.Intent) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- method public android.app.Activity instantiateActivityCompat(java.lang.ClassLoader, java.lang.String, android.content.Intent) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- method public final android.app.Application instantiateApplication(java.lang.ClassLoader, java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- method public android.app.Application instantiateApplicationCompat(java.lang.ClassLoader, java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- method public final android.content.ContentProvider instantiateProvider(java.lang.ClassLoader, java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- method public android.content.ContentProvider instantiateProviderCompat(java.lang.ClassLoader, java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- method public final android.content.BroadcastReceiver instantiateReceiver(java.lang.ClassLoader, java.lang.String, android.content.Intent) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- method public android.content.BroadcastReceiver instantiateReceiverCompat(java.lang.ClassLoader, java.lang.String, android.content.Intent) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- method public final android.app.Service instantiateService(java.lang.ClassLoader, java.lang.String, android.content.Intent) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- method public android.app.Service instantiateServiceCompat(java.lang.ClassLoader, java.lang.String, android.content.Intent) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
- }
-
public class AppLaunchChecker {
ctor public deprecated AppLaunchChecker();
method public static boolean hasStartedFromLauncher(android.content.Context);
@@ -177,7 +163,6 @@
method public static int getBadgeIconType(android.app.Notification);
method public static java.lang.String getCategory(android.app.Notification);
method public static java.lang.String getChannelId(android.app.Notification);
- method public static java.lang.CharSequence getContentTitle(android.app.Notification);
method public static android.os.Bundle getExtras(android.app.Notification);
method public static java.lang.String getGroup(android.app.Notification);
method public static int getGroupAlertBehavior(android.app.Notification);
@@ -221,7 +206,6 @@
field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
- field public static final java.lang.String EXTRA_MESSAGING_STYLE_USER = "android.messagingStyleUser";
field public static final java.lang.String EXTRA_PEOPLE = "android.people";
field public static final java.lang.String EXTRA_PICTURE = "android.picture";
field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
@@ -458,8 +442,7 @@
}
public static class NotificationCompat.MessagingStyle extends androidx.core.app.NotificationCompat.Style {
- ctor public deprecated NotificationCompat.MessagingStyle(java.lang.CharSequence);
- ctor public NotificationCompat.MessagingStyle(androidx.core.app.Person);
+ ctor public NotificationCompat.MessagingStyle(java.lang.CharSequence);
method public void addCompatExtras(android.os.Bundle);
method public deprecated androidx.core.app.NotificationCompat.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(java.lang.CharSequence, long, androidx.core.app.Person);
@@ -467,8 +450,7 @@
method public static androidx.core.app.NotificationCompat.MessagingStyle extractMessagingStyleFromNotification(android.app.Notification);
method public java.lang.CharSequence getConversationTitle();
method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message> getMessages();
- method public androidx.core.app.Person getUser();
- method public deprecated java.lang.CharSequence getUserDisplayName();
+ method public java.lang.CharSequence getUserDisplayName();
method public boolean isGroupConversation();
method public androidx.core.app.NotificationCompat.MessagingStyle setConversationTitle(java.lang.CharSequence);
method public androidx.core.app.NotificationCompat.MessagingStyle setGroupConversation(boolean);
@@ -827,11 +809,6 @@
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();
@@ -889,10 +866,6 @@
package androidx.core.database {
- public final class CursorWindowCompat {
- method public android.database.CursorWindow create(java.lang.String, long);
- }
-
public final deprecated class DatabaseUtilsCompat {
method public static deprecated java.lang.String[] appendSelectionArgs(java.lang.String[], java.lang.String[]);
method public static deprecated java.lang.String concatenateWhere(java.lang.String, java.lang.String);
@@ -900,14 +873,6 @@
}
-package androidx.core.database.sqlite {
-
- public final class SQLiteCursorCompat {
- method public void setFillWindowForwardOnly(android.database.sqlite.SQLiteCursor, boolean);
- }
-
-}
-
package androidx.core.graphics {
public final class BitmapCompat {
@@ -1310,40 +1275,6 @@
method public static java.lang.String maximizeAndGetScript(java.util.Locale);
}
- public class PrecomputedTextCompat implements android.text.Spannable {
- method public char charAt(int);
- method public static androidx.core.text.PrecomputedTextCompat create(java.lang.CharSequence, androidx.core.text.PrecomputedTextCompat.Params);
- method public int getParagraphCount();
- method public int getParagraphEnd(int);
- method public int getParagraphStart(int);
- method public androidx.core.text.PrecomputedTextCompat.Params getParams();
- method public int getSpanEnd(java.lang.Object);
- method public int getSpanFlags(java.lang.Object);
- method public int getSpanStart(java.lang.Object);
- method public <T> T[] getSpans(int, int, java.lang.Class<T>);
- method public int length();
- method public int nextSpanTransition(int, int, java.lang.Class);
- method public void removeSpan(java.lang.Object);
- method public void setSpan(java.lang.Object, int, int, int);
- method public java.lang.CharSequence subSequence(int, int);
- }
-
- public static final class PrecomputedTextCompat.Params {
- ctor public PrecomputedTextCompat.Params(android.text.PrecomputedText.Params);
- method public int getBreakStrategy();
- method public int getHyphenationFrequency();
- method public android.text.TextDirectionHeuristic getTextDirection();
- method public android.text.TextPaint getTextPaint();
- }
-
- public static class PrecomputedTextCompat.Params.Builder {
- ctor public PrecomputedTextCompat.Params.Builder(android.text.TextPaint);
- method public androidx.core.text.PrecomputedTextCompat.Params build();
- method public androidx.core.text.PrecomputedTextCompat.Params.Builder setBreakStrategy(int);
- method public androidx.core.text.PrecomputedTextCompat.Params.Builder setHyphenationFrequency(int);
- method public androidx.core.text.PrecomputedTextCompat.Params.Builder setTextDirection(android.text.TextDirectionHeuristic);
- }
-
public abstract interface TextDirectionHeuristicCompat {
method public abstract boolean isRtl(char[], int, int);
method public abstract boolean isRtl(java.lang.CharSequence, int, int);
@@ -1470,15 +1401,6 @@
method public abstract void onActionProviderVisibilityChanged(boolean);
}
- public final class DisplayCutoutCompat {
- ctor public DisplayCutoutCompat(android.graphics.Rect, java.util.List<android.graphics.Rect>);
- method public java.util.List<android.graphics.Rect> getBoundingRects();
- method public int getSafeInsetBottom();
- method public int getSafeInsetLeft();
- method public int getSafeInsetRight();
- method public int getSafeInsetTop();
- }
-
public final class DragAndDropPermissionsCompat {
method public void release();
}
@@ -2084,10 +2006,8 @@
public class WindowInsetsCompat {
ctor public WindowInsetsCompat(androidx.core.view.WindowInsetsCompat);
- method public androidx.core.view.WindowInsetsCompat consumeDisplayCutout();
method public androidx.core.view.WindowInsetsCompat consumeStableInsets();
method public androidx.core.view.WindowInsetsCompat consumeSystemWindowInsets();
- method public androidx.core.view.DisplayCutoutCompat getDisplayCutout();
method public int getStableInsetBottom();
method public int getStableInsetLeft();
method public int getStableInsetRight();
@@ -2400,7 +2320,7 @@
method public int getColumnSpan();
method public int getRowIndex();
method public int getRowSpan();
- method public deprecated boolean isHeading();
+ method public boolean isHeading();
method public boolean isSelected();
method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat obtain(int, int, int, int, boolean, boolean);
method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat obtain(int, int, int, int, boolean);
diff --git a/compat/res/values-as/strings.xml b/compat/res/values-as/strings.xml
deleted file mode 100644
index b9c349e..0000000
--- a/compat/res/values-as/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2017 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_notification_info_overflow" msgid="7988687684186075107">"৯৯৯+"</string>
-</resources>
diff --git a/compat/res/values-or/strings.xml b/compat/res/values-or/strings.xml
deleted file mode 100644
index f544aef..0000000
--- a/compat/res/values-or/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2017 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_notification_info_overflow" msgid="7988687684186075107">"999+"</string>
-</resources>
diff --git a/compat/src/androidTest/java/androidx/core/app/NotificationCompatTest.java b/compat/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
index 318a283e7..7cd90f8 100644
--- a/compat/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
+++ b/compat/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
@@ -30,7 +30,6 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import android.app.Notification;
import android.content.Context;
@@ -529,29 +528,6 @@
}
@Test
- public void testMessagingStyle_nullPerson() {
- NotificationCompat.MessagingStyle messagingStyle =
- new NotificationCompat.MessagingStyle("self name");
- messagingStyle.addMessage("text", 200, (Person) null);
-
- Notification notification = new NotificationCompat.Builder(mContext, "test id")
- .setSmallIcon(1)
- .setContentTitle("test title")
- .setStyle(messagingStyle)
- .build();
-
- List<Message> result = NotificationCompat.MessagingStyle
- .extractMessagingStyleFromNotification(notification)
- .getMessages();
-
- assertEquals(1, result.size());
- assertEquals("text", result.get(0).getText());
- assertEquals(200, result.get(0).getTimestamp());
- assertNull(result.get(0).getPerson());
- assertNull(result.get(0).getSender());
- }
-
- @Test
public void testMessagingStyle_message() {
NotificationCompat.MessagingStyle messagingStyle =
new NotificationCompat.MessagingStyle("self name");
@@ -584,16 +560,6 @@
}
@Test
- public void testMessagingStyle_requiresNonEmptyUserName() {
- try {
- new NotificationCompat.MessagingStyle(new Person.Builder().build());
- fail("Expected IllegalArgumentException about a non-empty user name.");
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- @Test
public void testMessagingStyle_isGroupConversation() {
mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.P;
NotificationCompat.MessagingStyle messagingStyle =
@@ -717,113 +683,19 @@
assertTrue(result.isGroupConversation());
}
- @SdkSuppress(minSdkVersion = 28)
@Test
- public void testMessagingStyle_applyNoTitleAndNotGroup() {
+ public void testMessagingStyle_extras() {
NotificationCompat.MessagingStyle messagingStyle =
- new NotificationCompat.MessagingStyle("self name")
- .setGroupConversation(false)
- .addMessage(
- new Message(
- "body",
- 1,
- new Person.Builder().setName("example name").build()))
- .addMessage(new Message("body 2", 2, (Person) null));
-
- Notification resultNotification = new NotificationCompat.Builder(mContext, "test id")
- .setStyle(messagingStyle)
- .build();
- NotificationCompat.MessagingStyle resultCompatMessagingStyle =
- NotificationCompat.MessagingStyle
- .extractMessagingStyleFromNotification(resultNotification);
-
- // SDK >= 28 applies no title when none is provided to MessagingStyle.
- assertNull(resultCompatMessagingStyle.getConversationTitle());
- assertFalse(resultCompatMessagingStyle.isGroupConversation());
- }
-
- @SdkSuppress(minSdkVersion = 24, maxSdkVersion = 27)
- @Test
- public void testMessagingStyle_applyNoTitleAndNotGroup_legacy() {
- NotificationCompat.MessagingStyle messagingStyle =
- new NotificationCompat.MessagingStyle("self name")
- .setGroupConversation(false)
- .addMessage(
- new Message(
- "body",
- 1,
- new Person.Builder().setName("example name").build()))
- .addMessage(new Message("body 2", 2, (Person) null));
-
- Notification resultNotification = new NotificationCompat.Builder(mContext, "test id")
- .setStyle(messagingStyle)
- .build();
- NotificationCompat.MessagingStyle resultCompatMessagingStyle =
- NotificationCompat.MessagingStyle
- .extractMessagingStyleFromNotification(resultNotification);
-
- // SDK [24, 27] applies first incoming message sender name as Notification content title.
- assertEquals("example name", NotificationCompat.getContentTitle(resultNotification));
- assertNull(resultCompatMessagingStyle.getConversationTitle());
- assertFalse(resultCompatMessagingStyle.isGroupConversation());
- }
-
- @SdkSuppress(minSdkVersion = 28)
- @Test
- public void testMessagingStyle_applyConversationTitleAndNotGroup() {
- NotificationCompat.MessagingStyle messagingStyle =
- new NotificationCompat.MessagingStyle("self name")
- .setGroupConversation(false)
- .setConversationTitle("test title");
-
- Notification resultNotification = new NotificationCompat.Builder(mContext, "test id")
- .setStyle(messagingStyle)
- .build();
- NotificationCompat.MessagingStyle resultMessagingStyle =
- NotificationCompat.MessagingStyle
- .extractMessagingStyleFromNotification(resultNotification);
-
- // SDK >= 28 applies provided title to MessagingStyle.
- assertEquals("test title", resultMessagingStyle.getConversationTitle());
- assertFalse(resultMessagingStyle.isGroupConversation());
- }
-
- @SdkSuppress(minSdkVersion = 19, maxSdkVersion = 27)
- @Test
- public void testMessagingStyle_applyConversationTitleAndNotGroup_legacy() {
- NotificationCompat.MessagingStyle messagingStyle =
- new NotificationCompat.MessagingStyle("self name")
- .setGroupConversation(false)
- .setConversationTitle("test title");
-
- Notification resultNotification = new NotificationCompat.Builder(mContext, "test id")
- .setStyle(messagingStyle)
- .build();
- NotificationCompat.MessagingStyle resultMessagingStyle =
- NotificationCompat.MessagingStyle
- .extractMessagingStyleFromNotification(resultNotification);
-
- // SDK <= 27 applies MessagingStyle title as Notification content title.
- assertEquals("test title", NotificationCompat.getContentTitle(resultNotification));
- assertEquals("test title", resultMessagingStyle.getConversationTitle());
- assertFalse(resultMessagingStyle.isGroupConversation());
- }
-
- @Test
- public void testMessagingStyle_restoreFromCompatExtras() {
- NotificationCompat.MessagingStyle messagingStyle =
- new NotificationCompat.MessagingStyle(
- new Person.Builder().setName("test name").build())
+ new NotificationCompat.MessagingStyle("test name")
.setGroupConversation(true);
Bundle bundle = new Bundle();
messagingStyle.addCompatExtras(bundle);
NotificationCompat.MessagingStyle resultMessagingStyle =
- new NotificationCompat.MessagingStyle(new Person.Builder().setName("temp").build());
+ new NotificationCompat.MessagingStyle("test name");
resultMessagingStyle.restoreFromCompatExtras(bundle);
assertTrue(resultMessagingStyle.isGroupConversation());
- assertEquals("test name", resultMessagingStyle.getUser().getName());
}
@Test
@@ -891,16 +763,6 @@
verifyInvisibleActionExists(notification);
}
- @Test
- @SdkSuppress(minSdkVersion = 19)
- public void getContentTitle() {
- Notification notification = new NotificationCompat.Builder(mContext, "test channel")
- .setContentTitle("example title")
- .build();
-
- assertEquals("example title", NotificationCompat.getContentTitle(notification));
- }
-
private static void verifyInvisibleActionExists(Notification notification) {
List<NotificationCompat.Action> result =
NotificationCompat.getInvisibleActions(notification);
diff --git a/compat/src/androidTest/java/androidx/core/content/pm/PermissionInfoCompatTest.java b/compat/src/androidTest/java/androidx/core/content/pm/PermissionInfoCompatTest.java
deleted file mode 100644
index 79613be..0000000
--- a/compat/src/androidTest/java/androidx/core/content/pm/PermissionInfoCompatTest.java
+++ /dev/null
@@ -1,47 +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.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/androidTest/java/androidx/core/text/PrecomputedTextCompatTest.java b/compat/src/androidTest/java/androidx/core/text/PrecomputedTextCompatTest.java
deleted file mode 100644
index a822b7c..0000000
--- a/compat/src/androidTest/java/androidx/core/text/PrecomputedTextCompatTest.java
+++ /dev/null
@@ -1,302 +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.core.text;
-
-import static android.text.TextDirectionHeuristics.LTR;
-import static android.text.TextDirectionHeuristics.RTL;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.graphics.Color;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.text.Layout;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.text.TextDirectionHeuristics;
-import android.text.TextPaint;
-import android.text.style.BackgroundColorSpan;
-import android.text.style.TypefaceSpan;
-
-import androidx.core.text.PrecomputedTextCompat.Params;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class PrecomputedTextCompatTest {
-
- private static final CharSequence NULL_CHAR_SEQUENCE = null;
- private static final String STRING = "Hello, World!";
- private static final String MULTIPARA_STRING = "Hello,\nWorld!";
-
- private static final int SPAN_START = 3;
- private static final int SPAN_END = 7;
- private static final TypefaceSpan SPAN = new TypefaceSpan("serif");
- private static final Spanned SPANNED;
- static {
- final SpannableStringBuilder ssb = new SpannableStringBuilder(STRING);
- ssb.setSpan(SPAN, SPAN_START, SPAN_END, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
- SPANNED = ssb;
- }
-
- private static final TextPaint PAINT = new TextPaint();
-
- @Test
- public void testParams_create() {
- assertNotNull(new Params.Builder(PAINT).build());
- assertNotNull(new Params.Builder(PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE).build());
- assertNotNull(new Params.Builder(PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL).build());
- assertNotNull(new Params.Builder(PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .setTextDirection(LTR).build());
- }
-
- @Test
- public void testParams_SetGet() {
- assertEquals(Layout.BREAK_STRATEGY_SIMPLE, new Params.Builder(PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE).build().getBreakStrategy());
- assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, new Params.Builder(PAINT)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE).build()
- .getHyphenationFrequency());
- assertEquals(RTL, new Params.Builder(PAINT).setTextDirection(RTL).build()
- .getTextDirection());
- }
-
- @Test
- @SdkSuppress(minSdkVersion = 23)
- public void testParams_GetDefaultValues() {
- assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY,
- new Params.Builder(PAINT).build().getBreakStrategy());
- assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL,
- new Params.Builder(PAINT).build().getHyphenationFrequency());
- }
-
- @Test
- @SdkSuppress(minSdkVersion = 18)
- public void testParams_GetDefaultValues2() {
- assertEquals(TextDirectionHeuristics.FIRSTSTRONG_LTR,
- new Params.Builder(PAINT).build().getTextDirection());
- }
-
- @Test
- @SdkSuppress(minSdkVersion = 23)
- public void testParams_equals() {
- final Params base = new Params.Builder(PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .setTextDirection(LTR).build();
-
- assertFalse(base.equals(null));
- assertTrue(base.equals(base));
- assertFalse(base.equals(new Object()));
-
- Params other = new Params.Builder(PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .setTextDirection(LTR).build();
- assertTrue(base.equals(other));
- assertTrue(other.equals(base));
- assertEquals(base.hashCode(), other.hashCode());
-
- other = new Params.Builder(PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .setTextDirection(LTR).build();
- assertFalse(base.equals(other));
- assertFalse(other.equals(base));
-
- other = new Params.Builder(PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
- .setTextDirection(LTR).build();
- assertFalse(base.equals(other));
- assertFalse(other.equals(base));
-
-
- other = new Params.Builder(PAINT)
- .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .setTextDirection(RTL).build();
- assertFalse(base.equals(other));
- assertFalse(other.equals(base));
-
-
- TextPaint anotherPaint = new TextPaint(PAINT);
- anotherPaint.setTextSize(PAINT.getTextSize() * 2.0f);
- other = new Params.Builder(anotherPaint)
- .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
- .setTextDirection(LTR).build();
- assertFalse(base.equals(other));
- assertFalse(other.equals(base));
- }
-
- @Test
- public void testParams_equals2() {
- final Params base = new Params.Builder(PAINT).build();
-
- assertFalse(base.equals(null));
- assertTrue(base.equals(base));
- assertFalse(base.equals(new Object()));
-
- Params other = new Params.Builder(PAINT).build();
- assertTrue(base.equals(other));
- assertTrue(other.equals(base));
- assertEquals(base.hashCode(), other.hashCode());
-
- TextPaint paint = new TextPaint(PAINT);
- paint.setTextSize(paint.getTextSize() * 2.0f + 1.0f);
- other = new Params.Builder(paint).build();
- assertFalse(base.equals(other));
- assertFalse(other.equals(base));
- }
-
- @Test
- public void testCreate_withNull() {
- final Params param = new Params.Builder(PAINT).build();
- try {
- PrecomputedTextCompat.create(NULL_CHAR_SEQUENCE, param);
- fail();
- } catch (NullPointerException e) {
- // pass
- }
- try {
- PrecomputedTextCompat.create(STRING, null);
- fail();
- } catch (NullPointerException e) {
- // pass
- }
- }
-
- @Test
- public void testCharSequenceInteface() {
- final Params param = new Params.Builder(PAINT).build();
- final CharSequence s = PrecomputedTextCompat.create(STRING, param);
- assertEquals(STRING.length(), s.length());
- assertEquals('H', s.charAt(0));
- assertEquals('e', s.charAt(1));
- assertEquals('l', s.charAt(2));
- assertEquals('l', s.charAt(3));
- assertEquals('o', s.charAt(4));
- assertEquals(',', s.charAt(5));
- assertEquals("Hello, World!", s.toString());
-
- final CharSequence s3 = s.subSequence(0, 3);
- assertEquals(3, s3.length());
- assertEquals('H', s3.charAt(0));
- assertEquals('e', s3.charAt(1));
- assertEquals('l', s3.charAt(2));
-
- }
-
- @Test
- public void testSpannedInterface_Spanned() {
- final Params param = new Params.Builder(PAINT).build();
- final Spanned s = PrecomputedTextCompat.create(SPANNED, param);
- final TypefaceSpan[] spans = s.getSpans(0, s.length(), TypefaceSpan.class);
- assertNotNull(spans);
- assertEquals(1, spans.length);
- assertEquals(SPAN, spans[0]);
-
- assertEquals(SPAN_START, s.getSpanStart(SPAN));
- assertEquals(SPAN_END, s.getSpanEnd(SPAN));
- assertTrue((s.getSpanFlags(SPAN) & Spanned.SPAN_INCLUSIVE_EXCLUSIVE) != 0);
-
- assertEquals(SPAN_START, s.nextSpanTransition(0, s.length(), TypefaceSpan.class));
- assertEquals(SPAN_END, s.nextSpanTransition(SPAN_START, s.length(), TypefaceSpan.class));
- }
-
- @Test
- public void testSpannedInterface_Spannable() {
- final BackgroundColorSpan span = new BackgroundColorSpan(Color.RED);
- final Params param = new Params.Builder(PAINT).build();
- final Spannable s = PrecomputedTextCompat.create(STRING, param);
- assertEquals(0, s.getSpans(0, s.length(), BackgroundColorSpan.class).length);
-
- s.setSpan(span, SPAN_START, SPAN_END, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
-
- final BackgroundColorSpan[] spans = s.getSpans(0, s.length(), BackgroundColorSpan.class);
- assertEquals(SPAN_START, s.getSpanStart(span));
- assertEquals(SPAN_END, s.getSpanEnd(span));
- assertTrue((s.getSpanFlags(span) & Spanned.SPAN_INCLUSIVE_EXCLUSIVE) != 0);
-
- assertEquals(SPAN_START, s.nextSpanTransition(0, s.length(), BackgroundColorSpan.class));
- assertEquals(SPAN_END,
- s.nextSpanTransition(SPAN_START, s.length(), BackgroundColorSpan.class));
-
- s.removeSpan(span);
- assertEquals(0, s.getSpans(0, s.length(), BackgroundColorSpan.class).length);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSpannedInterface_Spannable_setSpan_MetricsAffectingSpan() {
- final Params param = new Params.Builder(PAINT).build();
- final Spannable s = PrecomputedTextCompat.create(SPANNED, param);
- s.setSpan(SPAN, SPAN_START, SPAN_END, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSpannedInterface_Spannable_removeSpan_MetricsAffectingSpan() {
- final Params param = new Params.Builder(PAINT).build();
- final Spannable s = PrecomputedTextCompat.create(SPANNED, param);
- s.removeSpan(SPAN);
- }
-
- @Test
- public void testSpannedInterface_String() {
- final Params param = new Params.Builder(PAINT).build();
- final Spanned s = PrecomputedTextCompat.create(STRING, param);
- TypefaceSpan[] spans = s.getSpans(0, s.length(), TypefaceSpan.class);
- assertNotNull(spans);
- assertEquals(0, spans.length);
-
- assertEquals(-1, s.getSpanStart(SPAN));
- assertEquals(-1, s.getSpanEnd(SPAN));
- assertEquals(0, s.getSpanFlags(SPAN));
-
- assertEquals(s.length(), s.nextSpanTransition(0, s.length(), TypefaceSpan.class));
- }
-
- @Test
- public void testGetParagraphCount() {
- final Params param = new Params.Builder(PAINT).build();
- final PrecomputedTextCompat pm = PrecomputedTextCompat.create(STRING, param);
- assertEquals(1, pm.getParagraphCount());
- assertEquals(0, pm.getParagraphStart(0));
- assertEquals(STRING.length(), pm.getParagraphEnd(0));
-
- final PrecomputedTextCompat pm1 = PrecomputedTextCompat.create(MULTIPARA_STRING, param);
- assertEquals(2, pm1.getParagraphCount());
- assertEquals(0, pm1.getParagraphStart(0));
- assertEquals(7, pm1.getParagraphEnd(0));
- assertEquals(7, pm1.getParagraphStart(1));
- assertEquals(pm1.length(), pm1.getParagraphEnd(1));
- }
-
-}
diff --git a/compat/src/androidTest/java/androidx/core/view/DisplayCutoutCompatTest.java b/compat/src/androidTest/java/androidx/core/view/DisplayCutoutCompatTest.java
deleted file mode 100644
index 88a31f6..0000000
--- a/compat/src/androidTest/java/androidx/core/view/DisplayCutoutCompatTest.java
+++ /dev/null
@@ -1,95 +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.core.view;
-
-import static android.os.Build.VERSION.SDK_INT;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
-
-import android.graphics.Rect;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DisplayCutoutCompatTest {
-
- DisplayCutoutCompat mCutoutTop;
- DisplayCutoutCompat mCutoutTopBottom;
- DisplayCutoutCompat mCutoutTopBottomClone;
- DisplayCutoutCompat mCutoutLeftRight;
-
- @Before
- public void setUp() throws Exception {
- mCutoutTop = new DisplayCutoutCompat(new Rect(0, 10, 0, 0), Arrays.asList(
- new Rect(50, 0, 60, 10)));
- mCutoutTopBottom = new DisplayCutoutCompat(new Rect(0, 10, 0, 20), Arrays.asList(
- new Rect(50, 0, 60, 10),
- new Rect(50, 100, 60, 120)));
- mCutoutTopBottomClone = new DisplayCutoutCompat(new Rect(0, 10, 0, 20), Arrays.asList(
- new Rect(50, 0, 60, 10),
- new Rect(50, 100, 60, 120)));
- mCutoutLeftRight = new DisplayCutoutCompat(new Rect(30, 0, 40, 0), Arrays.asList(
- new Rect(0, 50, 30, 60),
- new Rect(100, 60, 140, 50)));
- }
-
- @Test
- public void testSafeInsets() {
- if (SDK_INT >= 28) {
- assertEquals("left", 30, mCutoutLeftRight.getSafeInsetLeft());
- assertEquals("top", 10, mCutoutTopBottom.getSafeInsetTop());
- assertEquals("right", 40, mCutoutLeftRight.getSafeInsetRight());
- assertEquals("bottom", 20, mCutoutTopBottom.getSafeInsetBottom());
- } else {
- assertEquals("left", 0, mCutoutLeftRight.getSafeInsetLeft());
- assertEquals("top", 0, mCutoutTopBottom.getSafeInsetTop());
- assertEquals("right", 0, mCutoutLeftRight.getSafeInsetRight());
- assertEquals("bottom", 0, mCutoutTopBottom.getSafeInsetBottom());
- }
- }
-
- @Test
- public void testBoundingRects() {
- if (SDK_INT >= 28) {
- assertEquals(Arrays.asList(new Rect(50, 0, 60, 10)), mCutoutTop.getBoundingRects());
- } else {
- assertNull(mCutoutTop.getBoundingRects());
- }
- }
-
- @Test
- public void testEquals() {
- assertEquals(mCutoutTopBottomClone, mCutoutTopBottom);
-
- if (SDK_INT >= 28) {
- assertNotEquals(mCutoutTopBottom, mCutoutLeftRight);
- }
- }
- @Test
- public void testHashCode() {
- assertEquals(mCutoutTopBottomClone.hashCode(), mCutoutTopBottom.hashCode());
- }
-}
diff --git a/compat/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java b/compat/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
index 3e668b4..7b862c2 100644
--- a/compat/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
+++ b/compat/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
@@ -19,9 +19,9 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
+import static org.junit.Assume.assumeTrue;
import android.os.Build;
-import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -68,9 +68,9 @@
assertThat(nodeCompat.getTooltipText(), equalTo(tooltipText));
}
- @SdkSuppress(minSdkVersion = 19)
@Test
public void testGetSetShowingHintText() {
+ assumeTrue(Build.VERSION.SDK_INT >= 19);
AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
nodeCompat.setShowingHintText(true);
assertThat(nodeCompat.isShowingHintText(), is(true));
@@ -78,9 +78,9 @@
assertThat(nodeCompat.isShowingHintText(), is(false));
}
- @SdkSuppress(minSdkVersion = 19)
@Test
public void testGetSetScreenReaderFocusable() {
+ assumeTrue(Build.VERSION.SDK_INT >= 19);
AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
nodeCompat.setScreenReaderFocusable(true);
assertThat(nodeCompat.isScreenReaderFocusable(), is(true));
@@ -88,18 +88,14 @@
assertThat(nodeCompat.isScreenReaderFocusable(), is(false));
}
- @SdkSuppress(minSdkVersion = 19)
@Test
public void testGetSetHeading() {
+ assumeTrue(Build.VERSION.SDK_INT >= 19);
AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
nodeCompat.setHeading(true);
assertThat(nodeCompat.isHeading(), is(true));
nodeCompat.setHeading(false);
assertThat(nodeCompat.isHeading(), is(false));
- AccessibilityNodeInfoCompat.CollectionItemInfoCompat collectionItemInfo =
- AccessibilityNodeInfoCompat.CollectionItemInfoCompat.obtain(0, 1, 0, 1, true);
- nodeCompat.setCollectionItemInfo(collectionItemInfo);
- assertThat(nodeCompat.isHeading(), is(true));
}
private AccessibilityNodeInfoCompat obtainedWrappedNodeCompat() {
diff --git a/compat/src/main/java/androidx/core/app/AppComponentFactory.java b/compat/src/main/java/androidx/core/app/AppComponentFactory.java
deleted file mode 100644
index b6383da..0000000
--- a/compat/src/main/java/androidx/core/app/AppComponentFactory.java
+++ /dev/null
@@ -1,197 +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.core.app;
-
-import static androidx.core.app.CoreComponentFactory.checkCompatWrapper;
-
-import android.app.Activity;
-import android.app.Application;
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.ContentProvider;
-import android.content.Intent;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Version of {@link android.app.AppComponentFactory} that works with androidx libraries.
- *
- * Note: This will only work on API 28+ and does not backport AppComponentFactory functionality.
- */
-@RequiresApi(28)
-public class AppComponentFactory extends android.app.AppComponentFactory {
-
- /**
- * @see #instantiateActivityCompat
- */
- @Override
- public final Activity instantiateActivity(ClassLoader cl, String className, Intent intent)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- return checkCompatWrapper(instantiateActivityCompat(cl, className, intent));
- }
-
- /**
- * @see #instantiateApplicationCompat
- */
- @Override
- public final Application instantiateApplication(ClassLoader cl, String className)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- return checkCompatWrapper(instantiateApplicationCompat(cl, className));
- }
-
- /**
- * @see #instantiateReceiverCompat
- */
- @Override
- public final BroadcastReceiver instantiateReceiver(ClassLoader cl, String className,
- Intent intent)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- return checkCompatWrapper(instantiateReceiverCompat(cl, className, intent));
- }
-
- /**
- * @see #instantiateProviderCompat
- */
- @Override
- public final ContentProvider instantiateProvider(ClassLoader cl, String className)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- return checkCompatWrapper(instantiateProviderCompat(cl, className));
- }
-
- /**
- * @see #instantiateServiceCompat
- */
- @Override
- public final Service instantiateService(ClassLoader cl, String className, Intent intent)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- return checkCompatWrapper(instantiateServiceCompat(cl, className, intent));
- }
-
- /**
- * Allows application to override the creation of the application object. This can be used to
- * perform things such as dependency injection or class loader changes to these
- * classes.
- * <p>
- * This method is only intended to provide a hook for instantiation. It does not provide
- * earlier access to the Application object. The returned object will not be initialized
- * as a Context yet and should not be used to interact with other android APIs.
- *
- * @param cl The default classloader to use for instantiation.
- * @param className The class to be instantiated.
- */
- public @NonNull Application instantiateApplicationCompat(@NonNull ClassLoader cl,
- @NonNull String className)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- try {
- return (Application) cl.loadClass(className).getDeclaredConstructor().newInstance();
- } catch (InvocationTargetException | NoSuchMethodException e) {
- throw new RuntimeException("Couldn't call constructor", e);
- }
- }
-
- /**
- * Allows application to override the creation of activities. This can be used to
- * perform things such as dependency injection or class loader changes to these
- * classes.
- * <p>
- * This method is only intended to provide a hook for instantiation. It does not provide
- * earlier access to the Activity object. The returned object will not be initialized
- * as a Context yet and should not be used to interact with other android APIs.
- *
- * @param cl The default classloader to use for instantiation.
- * @param className The class to be instantiated.
- * @param intent Intent creating the class.
- */
- public @NonNull Activity instantiateActivityCompat(@NonNull ClassLoader cl,
- @NonNull String className, @Nullable Intent intent)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- try {
- return (Activity) cl.loadClass(className).getDeclaredConstructor().newInstance();
- } catch (InvocationTargetException | NoSuchMethodException e) {
- throw new RuntimeException("Couldn't call constructor", e);
- }
- }
-
- /**
- * Allows application to override the creation of receivers. This can be used to
- * perform things such as dependency injection or class loader changes to these
- * classes.
- *
- * @param cl The default classloader to use for instantiation.
- * @param className The class to be instantiated.
- * @param intent Intent creating the class.
- */
- public @NonNull BroadcastReceiver instantiateReceiverCompat(@NonNull ClassLoader cl,
- @NonNull String className, @Nullable Intent intent)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- try {
- return (BroadcastReceiver) cl.loadClass(className).getDeclaredConstructor()
- .newInstance();
- } catch (InvocationTargetException | NoSuchMethodException e) {
- throw new RuntimeException("Couldn't call constructor", e);
- }
- }
-
- /**
- * Allows application to override the creation of services. This can be used to
- * perform things such as dependency injection or class loader changes to these
- * classes.
- * <p>
- * This method is only intended to provide a hook for instantiation. It does not provide
- * earlier access to the Service object. The returned object will not be initialized
- * as a Context yet and should not be used to interact with other android APIs.
- *
- * @param cl The default classloader to use for instantiation.
- * @param className The class to be instantiated.
- * @param intent Intent creating the class.
- */
- public @NonNull Service instantiateServiceCompat(@NonNull ClassLoader cl,
- @NonNull String className, @Nullable Intent intent)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- try {
- return (Service) cl.loadClass(className).getDeclaredConstructor().newInstance();
- } catch (InvocationTargetException | NoSuchMethodException e) {
- throw new RuntimeException("Couldn't call constructor", e);
- }
- }
-
- /**
- * Allows application to override the creation of providers. This can be used to
- * perform things such as dependency injection or class loader changes to these
- * classes.
- * <p>
- * This method is only intended to provide a hook for instantiation. It does not provide
- * earlier access to the ContentProvider object. The returned object will not be initialized
- * with a Context yet and should not be used to interact with other android APIs.
- *
- * @param cl The default classloader to use for instantiation.
- * @param className The class to be instantiated.
- */
- public @NonNull ContentProvider instantiateProviderCompat(@NonNull ClassLoader cl,
- @NonNull String className)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- try {
- return (ContentProvider) cl.loadClass(className).getDeclaredConstructor().newInstance();
- } catch (InvocationTargetException | NoSuchMethodException e) {
- throw new RuntimeException("Couldn't call constructor", e);
- }
- }
-}
diff --git a/compat/src/main/java/androidx/core/app/CoreComponentFactory.java b/compat/src/main/java/androidx/core/app/CoreComponentFactory.java
index b55f03f..ef6acc1 100644
--- a/compat/src/main/java/androidx/core/app/CoreComponentFactory.java
+++ b/compat/src/main/java/androidx/core/app/CoreComponentFactory.java
@@ -50,8 +50,7 @@
}
@Override
- public BroadcastReceiver instantiateReceiver(ClassLoader cl, String className,
- Intent intent)
+ public BroadcastReceiver instantiateReceiver(ClassLoader cl, String className, Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return checkCompatWrapper(super.instantiateReceiver(cl, className, intent));
}
@@ -68,7 +67,7 @@
return checkCompatWrapper(super.instantiateService(cl, className, intent));
}
- static <T> T checkCompatWrapper(T obj) {
+ private <T> T checkCompatWrapper(T obj) {
if (obj instanceof CompatWrapped) {
T wrapper = (T) ((CompatWrapped) obj).getWrapper();
if (wrapper != null) {
diff --git a/compat/src/main/java/androidx/core/app/NotificationCompat.java b/compat/src/main/java/androidx/core/app/NotificationCompat.java
index 4d7bf40..9e60574 100644
--- a/compat/src/main/java/androidx/core/app/NotificationCompat.java
+++ b/compat/src/main/java/androidx/core/app/NotificationCompat.java
@@ -386,17 +386,13 @@
/**
* Notification key: the username to be displayed for all messages sent by the user
- * including direct replies {@link MessagingStyle} notification.
+ * including
+ * direct replies
+ * {@link MessagingStyle} notification.
*/
public static final String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
/**
- * Notification key: the person to display for all messages sent by the user, including direct
- * replies to {@link MessagingStyle} notifications.
- */
- public static final String EXTRA_MESSAGING_STYLE_USER = "android.messagingStyleUser";
-
- /**
* Notification key: a {@link String} to be displayed as the title to a conversation
* represented by a {@link MessagingStyle}
*/
@@ -1676,9 +1672,6 @@
}
/**
- * Applies the compat style data to the framework {@link Notification} in a backwards
- * compatible way. All other data should be stored within the Notification's extras.
- *
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
@@ -2158,54 +2151,29 @@
*/
public static final int MAXIMUM_RETAINED_MESSAGES = 25;
- private final List<Message> mMessages = new ArrayList<>();
- private Person mUser;
- private @Nullable CharSequence mConversationTitle;
- private @Nullable Boolean mIsGroupConversation;
+ CharSequence mUserDisplayName;
+ @Nullable CharSequence mConversationTitle;
+ List<Message> mMessages = new ArrayList<>();
+ @Nullable Boolean mIsGroupConversation;
- /** Private empty constructor for {@link Style#restoreFromCompatExtras(Bundle)}. */
- private MessagingStyle() {}
+ MessagingStyle() {
+ }
/**
* @param userDisplayName Required - the name to be displayed for any replies sent by the
* user before the posting app reposts the notification with those messages after they've
* been actually sent and in previous messages sent by the user added in
* {@link #addMessage(Message)}
- * @deprecated Use {@code #MessagingStyle(Person)} instead.
*/
- @Deprecated
public MessagingStyle(@NonNull CharSequence userDisplayName) {
- mUser = new Person.Builder().setName(userDisplayName).build();
+ mUserDisplayName = userDisplayName;
}
/**
- * Creates a new {@link MessagingStyle} object. Note that {@link Person} must have a
- * non-empty name.
- *
- * @param user This {@link Person}'s name will be shown when this app's notification is
- * being replied to. It's used temporarily so the app has time to process the send request
- * and repost the notification with updates to the conversation.
+ * Returns the name to be displayed for any replies sent by the user
*/
- public MessagingStyle(@NonNull Person user) {
- if (TextUtils.isEmpty(user.getName())) {
- throw new IllegalArgumentException("User's name must not be empty.");
- }
- mUser = user;
- }
-
- /**
- * Returns the name to be displayed for any replies sent by the user.
- *
- * @deprecated Use {@link #getUser()} instead.
- */
- @Deprecated
public CharSequence getUserDisplayName() {
- return mUser.getName();
- }
-
- /** Returns the person to be used for any replies sent by the user. */
- public Person getUser() {
- return mUser;
+ return mUserDisplayName;
}
/**
@@ -2346,20 +2314,19 @@
*/
public static MessagingStyle extractMessagingStyleFromNotification(
Notification notification) {
+ MessagingStyle style;
Bundle extras = NotificationCompat.getExtras(notification);
- if (extras != null
- && !extras.containsKey(EXTRA_SELF_DISPLAY_NAME)
- && !extras.containsKey(EXTRA_MESSAGING_STYLE_USER)) {
- return null;
+ if (extras != null && !extras.containsKey(EXTRA_SELF_DISPLAY_NAME)) {
+ style = null;
+ } else {
+ try {
+ style = new MessagingStyle();
+ style.restoreFromCompatExtras(extras);
+ } catch (ClassCastException e) {
+ style = null;
+ }
}
-
- try {
- MessagingStyle style = new MessagingStyle();
- style.restoreFromCompatExtras(extras);
- return style;
- } catch (ClassCastException e) {
- return null;
- }
+ return style;
}
/**
@@ -2376,36 +2343,14 @@
if (Build.VERSION.SDK_INT >= 24) {
Notification.MessagingStyle style =
- new Notification.MessagingStyle(mUser.getName());
-
- // In SDK < 28, base Android will assume a MessagingStyle notification is a group
- // chat if the conversation title is set. In compat, this isn't the case as we've
- // introduced #setGroupConversation. When we apply these settings to base Android
- // notifications, we should only set base Android's MessagingStyle conversation
- // title if it's a group conversation OR SDK >= 28. Otherwise we set the
- // Notification content title so Android won't think it's a group conversation.
- if (isGroupConversation() || Build.VERSION.SDK_INT >= 28) {
- // If group or non-legacy, set MessagingStyle#mConversationTitle.
- style.setConversationTitle(mConversationTitle);
- } else {
- // Otherwise set Notification#mContentTitle.
- builder.getBuilder().setContentTitle(mConversationTitle);
- }
-
- // For SDK >= 28, we can simply denote the group conversation status regardless of
- // if we set the conversation title or not.
- if (Build.VERSION.SDK_INT >= 28) {
- style.setGroupConversation(mIsGroupConversation);
- }
-
+ new Notification.MessagingStyle(mUserDisplayName)
+ .setConversationTitle(mConversationTitle);
for (MessagingStyle.Message message : mMessages) {
- CharSequence name = null;
- if (message.getPerson() != null) {
- name = message.getPerson().getName();
- }
Notification.MessagingStyle.Message frameworkMessage =
new Notification.MessagingStyle.Message(
- message.getText(), message.getTimestamp(), name);
+ message.getText(),
+ message.getTimestamp(),
+ message.getSender());
if (message.getDataMimeType() != null) {
frameworkMessage.setData(message.getDataMimeType(), message.getDataUri());
}
@@ -2418,11 +2363,7 @@
if (mConversationTitle != null) {
builder.getBuilder().setContentTitle(mConversationTitle);
} else if (latestIncomingMessage != null) {
- builder.getBuilder().setContentTitle("");
- if (latestIncomingMessage.getPerson() != null) {
- builder.getBuilder().setContentTitle(
- latestIncomingMessage.getPerson().getName());
- }
+ builder.getBuilder().setContentTitle(latestIncomingMessage.getSender());
}
// Set the text
if (latestIncomingMessage != null) {
@@ -2456,8 +2397,7 @@
for (int i = mMessages.size() - 1; i >= 0; i--) {
MessagingStyle.Message message = mMessages.get(i);
// Incoming messages have a non-empty sender.
- if (message.getPerson() != null
- && !TextUtils.isEmpty(message.getPerson().getName())) {
+ if (!TextUtils.isEmpty(message.getSender())) {
return message;
}
}
@@ -2471,7 +2411,7 @@
private boolean hasMessagesWithoutSender() {
for (int i = mMessages.size() - 1; i >= 0; i--) {
MessagingStyle.Message message = mMessages.get(i);
- if (message.getPerson() != null && message.getPerson().getName() == null) {
+ if (message.getSender() == null) {
return true;
}
}
@@ -2483,10 +2423,10 @@
SpannableStringBuilder sb = new SpannableStringBuilder();
final boolean afterLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
int color = afterLollipop ? Color.BLACK : Color.WHITE;
- CharSequence replyName =
- message.getPerson() == null ? "" : message.getPerson().getName();
- if (TextUtils.isEmpty(replyName)) {
- replyName = mUser.getName();
+ CharSequence replyName = message.getSender();
+ if (TextUtils.isEmpty(message.getSender())) {
+ replyName = mUserDisplayName == null
+ ? "" : mUserDisplayName;
color = afterLollipop && mBuilder.getColor() != NotificationCompat.COLOR_DEFAULT
? mBuilder.getColor()
: color;
@@ -2510,9 +2450,9 @@
@Override
public void addCompatExtras(Bundle extras) {
super.addCompatExtras(extras);
- extras.putCharSequence(EXTRA_SELF_DISPLAY_NAME, mUser.getName());
- extras.putBundle(EXTRA_MESSAGING_STYLE_USER, mUser.toBundle());
-
+ if (mUserDisplayName != null) {
+ extras.putCharSequence(EXTRA_SELF_DISPLAY_NAME, mUserDisplayName);
+ }
if (mConversationTitle != null) {
extras.putCharSequence(EXTRA_CONVERSATION_TITLE, mConversationTitle);
}
@@ -2532,21 +2472,11 @@
@Override
protected void restoreFromCompatExtras(Bundle extras) {
mMessages.clear();
- // Call to #restore requires that there either be a display name OR a user.
- if (extras.containsKey(EXTRA_MESSAGING_STYLE_USER)) {
- // New path simply unpacks Person, but checks if there's a valid name.
- mUser = Person.fromBundle(extras.getBundle(EXTRA_MESSAGING_STYLE_USER));
- } else {
- // Legacy extra simply builds Person with a name.
- mUser = new Person.Builder()
- .setName(extras.getString(EXTRA_SELF_DISPLAY_NAME))
- .build();
- }
-
+ mUserDisplayName = extras.getString(EXTRA_SELF_DISPLAY_NAME);
mConversationTitle = extras.getString(EXTRA_CONVERSATION_TITLE);
Parcelable[] parcelables = extras.getParcelableArray(EXTRA_MESSAGES);
if (parcelables != null) {
- mMessages.addAll(Message.getMessagesFromBundleArray(parcelables));
+ mMessages = Message.getMessagesFromBundleArray(parcelables);
}
if (extras.containsKey(EXTRA_IS_GROUP_CONVERSATION)) {
mIsGroupConversation = extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION);
@@ -2668,7 +2598,7 @@
@Deprecated
@Nullable
public CharSequence getSender() {
- return mPerson == null ? null : mPerson.getName();
+ return mPerson.getName();
}
/** Returns the {@link Person} sender of this message. */
@@ -2699,9 +2629,6 @@
}
bundle.putLong(KEY_TIMESTAMP, mTimestamp);
if (mPerson != null) {
- // We must add both as Frameworks depends on this extra directly in order to
- // render properly.
- bundle.putCharSequence(KEY_SENDER, mPerson.getName());
bundle.putBundle(KEY_PERSON, mPerson.toBundle());
}
if (mDataMimeType != null) {
@@ -2747,21 +2674,22 @@
return null;
}
- Person person = null;
- if (bundle.containsKey(KEY_PERSON)) {
- person = Person.fromBundle(bundle.getBundle(KEY_PERSON));
- } else if (bundle.containsKey(KEY_SENDER)) {
- // Legacy person
- person = new Person.Builder()
- .setName(bundle.getCharSequence(KEY_SENDER))
- .build();
+ Message message;
+ if (bundle.containsKey(KEY_SENDER)) {
+ // Legacy sender
+ message = new Message(
+ bundle.getCharSequence(KEY_TEXT),
+ bundle.getLong(KEY_TIMESTAMP),
+ new Person.Builder()
+ .setName(bundle.getCharSequence(KEY_SENDER))
+ .build());
+ } else {
+ message = new Message(
+ bundle.getCharSequence(KEY_TEXT),
+ bundle.getLong(KEY_TIMESTAMP),
+ Person.fromBundle(bundle.getBundle(KEY_PERSON)));
}
- Message message = new Message(
- bundle.getCharSequence(KEY_TEXT),
- bundle.getLong(KEY_TIMESTAMP),
- person);
-
if (bundle.containsKey(KEY_DATA_MIME_TYPE)
&& bundle.containsKey(KEY_DATA_URI)) {
message.setData(bundle.getString(KEY_DATA_MIME_TYPE),
@@ -5105,12 +5033,6 @@
return result;
}
- /** Returns the content title of a {@link Notification}. **/
- @RequiresApi(19)
- public static CharSequence getContentTitle(Notification notification) {
- return notification.extras.getCharSequence(Notification.EXTRA_TITLE);
- }
-
/**
* Get the category of this notification in a backwards compatible
* manner.
diff --git a/compat/src/main/java/androidx/core/app/NotificationManagerCompat.java b/compat/src/main/java/androidx/core/app/NotificationManagerCompat.java
index e8b6188..3660de3 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(":", -1);
+ final String[] components = enabledNotificationListeners.split(":");
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
deleted file mode 100644
index df095a6..0000000
--- a/compat/src/main/java/androidx/core/content/pm/PermissionInfoCompat.java
+++ /dev/null
@@ -1,92 +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.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/database/CursorWindowCompat.java b/compat/src/main/java/androidx/core/database/CursorWindowCompat.java
deleted file mode 100644
index c675977..0000000
--- a/compat/src/main/java/androidx/core/database/CursorWindowCompat.java
+++ /dev/null
@@ -1,51 +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.core.database;
-
-import android.database.CursorWindow;
-import android.os.Build;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.os.BuildCompat;
-
-/**
- * Helper for accessing features in {@link android.database.CursorWindow}
- */
-public final class CursorWindowCompat {
-
- private CursorWindowCompat() {
- /* Hide constructor */
- }
-
- /**
- * Creates a CursorWindow of the specified size.
- * <p>
- * Prior to Android P, this method will return a CursorWindow of size defined by the platform.
- */
- @NonNull
- public CursorWindow create(@Nullable String name, long windowSizeBytes) {
- if (BuildCompat.isAtLeastP()) {
- return new CursorWindow(name, windowSizeBytes);
- } else if (Build.VERSION.SDK_INT >= 15) {
- return new CursorWindow(name);
- } else {
- //noinspection deprecation
- return new CursorWindow(false);
- }
- }
-}
diff --git a/compat/src/main/java/androidx/core/database/sqlite/SQLiteCursorCompat.java b/compat/src/main/java/androidx/core/database/sqlite/SQLiteCursorCompat.java
deleted file mode 100644
index ebbc037..0000000
--- a/compat/src/main/java/androidx/core/database/sqlite/SQLiteCursorCompat.java
+++ /dev/null
@@ -1,49 +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.core.database.sqlite;
-
-import android.database.sqlite.SQLiteCursor;
-
-import androidx.annotation.NonNull;
-import androidx.core.os.BuildCompat;
-
-/**
- * Helper for accessing features in {@link android.database.AbstractWindowedCursor}
- */
-public final class SQLiteCursorCompat {
-
- private SQLiteCursorCompat() {
- /* Hide constructor */
- }
-
- /**
- * Controls whether the cursor is filled starting at the position passed to
- * {@link SQLiteCursor#moveToPosition(int)}.
- * <p>
- * By default, SQLiteCursor will optimize for accesses around the requested row index by loading
- * data on either side of it. Pass true to this method to disable that behavior, useful to
- * optimize multi-window, continuous reads.
- * <p>
- * Prior to Android P, this method will do nothing.
- */
- public void setFillWindowForwardOnly(
- @NonNull SQLiteCursor cursor, boolean fillWindowForwardOnly) {
- if (BuildCompat.isAtLeastP()) {
- cursor.setFillWindowForwardOnly(fillWindowForwardOnly);
- }
- }
-}
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 4c296ea..366ddf3 100644
--- a/compat/src/main/java/androidx/core/graphics/drawable/IconCompat.java
+++ b/compat/src/main/java/androidx/core/graphics/drawable/IconCompat.java
@@ -569,58 +569,6 @@
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 5ce4c82..001d657 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("-", -1);
+ String[] args = str.split("-");
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("_", -1);
+ String[] args = str.split("_");
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 0be1ff3..a933877 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(",", -1);
+ final String[] tags = list.split(",");
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 137d9cd..0a656bc 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(",", -1);
+ final String[] tags = list.split(",");
final Locale[] localeArray = new Locale[tags.length];
for (int i = 0; i < localeArray.length; i++) {
localeArray[i] = LocaleHelper.forLanguageTag(tags[i]);
diff --git a/compat/src/main/java/androidx/core/text/PrecomputedTextCompat.java b/compat/src/main/java/androidx/core/text/PrecomputedTextCompat.java
deleted file mode 100644
index 075ebb1..0000000
--- a/compat/src/main/java/androidx/core/text/PrecomputedTextCompat.java
+++ /dev/null
@@ -1,622 +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.core.text;
-
-import android.os.Build;
-import android.text.Layout;
-import android.text.PrecomputedText;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.StaticLayout;
-import android.text.TextDirectionHeuristic;
-import android.text.TextDirectionHeuristics;
-import android.text.TextPaint;
-import android.text.TextUtils;
-import android.text.style.MetricAffectingSpan;
-
-import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.core.os.BuildCompat;
-import androidx.core.util.ObjectsCompat;
-import androidx.core.util.Preconditions;
-
-import java.util.ArrayList;
-
-/**
- * A text which has the character metrics data.
- *
- * A text object that contains the character metrics data and can be used to improve the performance
- * of text layout operations. When a PrecomputedTextCompat is created with a given
- * {@link CharSequence}, it will measure the text metrics during the creation. This PrecomputedText
- * instance can be set on {@link android.widget.TextView} or {@link StaticLayout}. Since the text
- * layout information will be included in this instance, {@link android.widget.TextView} or
- * {@link StaticLayout} will not have to recalculate this information.
- *
- * On API 28 or later, there is full PrecomputedText support by framework. From API 21 to API 27,
- * PrecomputedTextCompat relies on internal text layout cache. PrecomputedTextCompat immediately
- * computes the text layout in the constuctor to warm up the internal text layout cache. On API 20
- * or before, PrecomputedTextCompat does nothing.
- *
- * Note that any {@link android.text.NoCopySpan} attached to the original text won't be passed to
- * PrecomputedText.
- */
-public class PrecomputedTextCompat implements Spannable {
- private static final char LINE_FEED = '\n';
-
- /**
- * The information required for building {@link PrecomputedTextCompat}.
- *
- * Contains information required for precomputing text measurement metadata, so it can be done
- * in isolation of a {@link android.widget.TextView} or {@link StaticLayout}, when final layout
- * constraints are not known.
- */
- public static final class Params {
- private final @NonNull TextPaint mPaint;
-
- // null on API 17 or before, non null on API 18 or later.
- private final @Nullable TextDirectionHeuristic mTextDir;
-
- private final int mBreakStrategy;
-
- private final int mHyphenationFrequency;
-
- private final PrecomputedText.Params mWrapped;
-
- /**
- * A builder for creating {@link Params}.
- */
- public static class Builder {
- // The TextPaint used for measurement.
- private final @NonNull TextPaint mPaint;
-
- // The requested text direction.
- private TextDirectionHeuristic mTextDir;
-
- // The break strategy for this measured text.
- private int mBreakStrategy;
-
- // The hyphenation frequency for this measured text.
- private int mHyphenationFrequency;
-
- /**
- * Builder constructor.
- *
- * @param paint the paint to be used for drawing
- */
- public Builder(@NonNull TextPaint paint) {
- mPaint = paint;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mBreakStrategy = Layout.BREAK_STRATEGY_HIGH_QUALITY;
- mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NORMAL;
- } else {
- mBreakStrategy = mHyphenationFrequency = 0;
- }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- mTextDir = TextDirectionHeuristics.FIRSTSTRONG_LTR;
- } else {
- mTextDir = null;
- }
- }
-
- /**
- * Set the line break strategy.
- *
- * The default value is {@link Layout#BREAK_STRATEGY_HIGH_QUALITY}.
- *
- * On API 22 and below, this has no effect as there is no line break strategy.
- *
- * @param strategy the break strategy
- * @return PrecomputedTextCompat.Builder instance
- * @see StaticLayout.Builder#setBreakStrategy
- * @see android.widget.TextView#setBreakStrategy
- */
- @RequiresApi(23)
- public Builder setBreakStrategy(int strategy) {
- mBreakStrategy = strategy;
- return this;
- }
-
- /**
- * Set the hyphenation frequency.
- *
- * The default value is {@link Layout#HYPHENATION_FREQUENCY_NORMAL}.
- *
- * On API 22 and below, this has no effect as there is no hyphenation frequency.
- *
- * @param frequency the hyphenation frequency
- * @return PrecomputedTextCompat.Builder instance
- * @see StaticLayout.Builder#setHyphenationFrequency
- * @see android.widget.TextView#setHyphenationFrequency
- */
- @RequiresApi(23)
- public Builder setHyphenationFrequency(int frequency) {
- mHyphenationFrequency = frequency;
- return this;
- }
-
- /**
- * Set the text direction heuristic.
- *
- * The default value is {@link TextDirectionHeuristics#FIRSTSTRONG_LTR}.
- *
- * On API 17 or before, text direction heuristics cannot be modified, so this method
- * does nothing.
- *
- * @param textDir the text direction heuristic for resolving bidi behavior
- * @return PrecomputedTextCompat.Builder instance
- * @see StaticLayout.Builder#setTextDirection
- */
- @RequiresApi(18)
- public Builder setTextDirection(@NonNull TextDirectionHeuristic textDir) {
- mTextDir = textDir;
- return this;
- }
-
- /**
- * Build the {@link Params}.
- *
- * @return the layout parameter
- */
- public @NonNull Params build() {
- return new Params(mPaint, mTextDir, mBreakStrategy, mHyphenationFrequency);
- }
- }
-
- private Params(@NonNull TextPaint paint, @NonNull TextDirectionHeuristic textDir,
- int strategy, int frequency) {
- if (BuildCompat.isAtLeastP()) {
- mWrapped = new PrecomputedText.Params.Builder(paint).setBreakStrategy(strategy)
- .setHyphenationFrequency(frequency).setTextDirection(textDir).build();
- } else {
- mWrapped = null;
- }
- mPaint = paint;
- mTextDir = textDir;
- mBreakStrategy = strategy;
- mHyphenationFrequency = frequency;
- }
-
- @RequiresApi(28)
- public Params(@NonNull PrecomputedText.Params wrapped) {
- mPaint = wrapped.getTextPaint();
- mTextDir = wrapped.getTextDirection();
- mBreakStrategy = wrapped.getBreakStrategy();
- mHyphenationFrequency = wrapped.getHyphenationFrequency();
- mWrapped = wrapped;
-
- }
-
- /**
- * Returns the {@link TextPaint} for this text.
- *
- * @return A {@link TextPaint}
- */
- public @NonNull TextPaint getTextPaint() {
- return mPaint;
- }
-
- /**
- * Returns the {@link TextDirectionHeuristic} for this text.
- *
- * On API 17 and below, this returns null, otherwise returns non-null
- * TextDirectionHeuristic.
- *
- * @return the {@link TextDirectionHeuristic}
- */
- @RequiresApi(18)
- public @Nullable TextDirectionHeuristic getTextDirection() {
- return mTextDir;
- }
-
- /**
- * Returns the break strategy for this text.
- *
- * On API 22 and below, this returns 0.
- *
- * @return the line break strategy
- */
- @RequiresApi(23)
- public int getBreakStrategy() {
- return mBreakStrategy;
- }
-
- /**
- * Returns the hyphenation frequency for this text.
- *
- * On API 22 and below, this returns 0.
- *
- * @return the hyphenation frequency
- */
- @RequiresApi(23)
- public int getHyphenationFrequency() {
- return mHyphenationFrequency;
- }
-
- /**
- * Check if the same text layout.
- *
- * @return true if this and the given param result in the same text layout
- */
- @Override
- public boolean equals(@Nullable Object o) {
- if (o == this) {
- return true;
- }
- if (o == null || !(o instanceof Params)) {
- return false;
- }
- Params other = (Params) o;
- if (mWrapped != null) {
- return mWrapped.equals(other.mWrapped);
- }
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- if (mBreakStrategy != other.getBreakStrategy()) {
- return false;
- }
- if (mHyphenationFrequency != other.getHyphenationFrequency()) {
- return false;
- }
- }
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- if (mTextDir != other.getTextDirection()) {
- return false;
- }
- }
-
- if (mPaint.getTextSize() != other.getTextPaint().getTextSize()) {
- return false;
- }
- if (mPaint.getTextScaleX() != other.getTextPaint().getTextScaleX()) {
- return false;
- }
- if (mPaint.getTextSkewX() != other.getTextPaint().getTextSkewX()) {
- return false;
- }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- if (mPaint.getLetterSpacing() != other.getTextPaint().getLetterSpacing()) {
- return false;
- }
- if (!TextUtils.equals(mPaint.getFontFeatureSettings(),
- other.getTextPaint().getFontFeatureSettings())) {
- return false;
- }
- }
- if (mPaint.getFlags() != other.getTextPaint().getFlags()) {
- return false;
- }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- if (!mPaint.getTextLocales().equals(other.getTextPaint().getTextLocales())) {
- return false;
- }
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- if (!mPaint.getTextLocale().equals(other.getTextPaint().getTextLocale())) {
- return false;
- }
- }
- if (mPaint.getTypeface() == null) {
- if (other.getTextPaint().getTypeface() != null) {
- return false;
- }
- } else if (!mPaint.getTypeface().equals(other.getTextPaint().getTypeface())) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- return ObjectsCompat.hash(mPaint.getTextSize(), mPaint.getTextScaleX(),
- mPaint.getTextSkewX(), mPaint.getLetterSpacing(), mPaint.getFlags(),
- mPaint.getTextLocales(), mPaint.getTypeface(), mPaint.isElegantTextHeight(),
- mTextDir, mBreakStrategy, mHyphenationFrequency);
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- return ObjectsCompat.hash(mPaint.getTextSize(), mPaint.getTextScaleX(),
- mPaint.getTextSkewX(), mPaint.getLetterSpacing(), mPaint.getFlags(),
- mPaint.getTextLocale(), mPaint.getTypeface(), mPaint.isElegantTextHeight(),
- mTextDir, mBreakStrategy, mHyphenationFrequency);
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- return ObjectsCompat.hash(mPaint.getTextSize(), mPaint.getTextScaleX(),
- mPaint.getTextSkewX(), mPaint.getFlags(), mPaint.getTextLocale(),
- mPaint.getTypeface(), mTextDir, mBreakStrategy, mHyphenationFrequency);
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- return ObjectsCompat.hash(mPaint.getTextSize(), mPaint.getTextScaleX(),
- mPaint.getTextSkewX(), mPaint.getFlags(), mPaint.getTextLocale(),
- mPaint.getTypeface(), mTextDir, mBreakStrategy, mHyphenationFrequency);
- } else {
- return ObjectsCompat.hash(mPaint.getTextSize(), mPaint.getTextScaleX(),
- mPaint.getTextSkewX(), mPaint.getFlags(), mPaint.getTypeface(), mTextDir,
- mBreakStrategy, mHyphenationFrequency);
- }
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("{");
- sb.append("textSize=" + mPaint.getTextSize());
- sb.append(", textScaleX=" + mPaint.getTextScaleX());
- sb.append(", textSkewX=" + mPaint.getTextSkewX());
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- sb.append(", letterSpacing=" + mPaint.getLetterSpacing());
- sb.append(", elegantTextHeight=" + mPaint.isElegantTextHeight());
- }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- sb.append(", textLocale=" + mPaint.getTextLocales());
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- sb.append(", textLocale=" + mPaint.getTextLocale());
- }
- sb.append(", typeface=" + mPaint.getTypeface());
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- sb.append(", variationSettings=" + mPaint.getFontVariationSettings());
- }
- sb.append(", textDir=" + mTextDir);
- sb.append(", breakStrategy=" + mBreakStrategy);
- sb.append(", hyphenationFrequency=" + mHyphenationFrequency);
- sb.append("}");
- return sb.toString();
- }
- };
-
- // The original text.
- private final @NonNull Spannable mText;
-
- private final @NonNull Params mParams;
-
- // The list of measured paragraph info.
- private final @NonNull int[] mParagraphEnds;
-
- // null on API 27 or before. Non-null on API 28 or later
- private final @Nullable PrecomputedText mWrapped;
-
- /**
- * Create a new {@link PrecomputedText} which will pre-compute text measurement and glyph
- * positioning information.
- * <p>
- * This can be expensive, so computing this on a background thread before your text will be
- * presented can save work on the UI thread.
- * </p>
- *
- * Note that any {@link android.text.NoCopySpan} attached to the text won't be passed to the
- * created PrecomputedText.
- *
- * @param text the text to be measured
- * @param params parameters that define how text will be precomputed
- * @return A {@link PrecomputedText}
- */
- public static PrecomputedTextCompat create(@NonNull CharSequence text, @NonNull Params params) {
- Preconditions.checkNotNull(text);
- Preconditions.checkNotNull(params);
-
- if (BuildCompat.isAtLeastP() && params.mWrapped != null) {
- return new PrecomputedTextCompat(PrecomputedText.create(text, params.mWrapped), params);
- }
-
- ArrayList<Integer> ends = new ArrayList<>();
-
- int paraEnd = 0;
- int end = text.length();
- for (int paraStart = 0; paraStart < end; paraStart = paraEnd) {
- paraEnd = TextUtils.indexOf(text, LINE_FEED, paraStart, end);
- if (paraEnd < 0) {
- // No LINE_FEED(U+000A) character found. Use end of the text as the paragraph
- // end.
- paraEnd = end;
- } else {
- paraEnd++; // Includes LINE_FEED(U+000A) to the prev paragraph.
- }
-
- ends.add(paraEnd);
- }
- int[] result = new int[ends.size()];
- for (int i = 0; i < ends.size(); ++i) {
- result[i] = ends.get(i);
- }
-
- // No framework support for PrecomputedText
- // Compute text layout and throw away StaticLayout for the purpose of warming up the
- // internal text layout cache.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- StaticLayout.Builder.obtain(text, 0, text.length(), params.getTextPaint(),
- Integer.MAX_VALUE)
- .setBreakStrategy(params.getBreakStrategy())
- .setHyphenationFrequency(params.getHyphenationFrequency())
- .setTextDirection(params.getTextDirection())
- .build();
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- new StaticLayout(text, params.getTextPaint(), Integer.MAX_VALUE,
- Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
- } else {
- // There is no way of precomputing text layout on API 20 or before
- // Do nothing
- }
-
- return new PrecomputedTextCompat(text, params, result);
- }
-
- // Use PrecomputedText.create instead.
- private PrecomputedTextCompat(@NonNull CharSequence text, @NonNull Params params,
- @NonNull int[] paraEnds) {
- mText = new SpannableString(text);
- mParams = params;
- mParagraphEnds = paraEnds;
- mWrapped = null;
- }
-
- @RequiresApi(28)
- private PrecomputedTextCompat(@NonNull PrecomputedText precomputed, @NonNull Params params) {
- mText = precomputed;
- mParams = params;
- mParagraphEnds = null;
- mWrapped = precomputed;
- }
-
- /**
- * Returns the layout parameters used to measure this text.
- */
- public @NonNull Params getParams() {
- return mParams;
- }
-
- /**
- * Returns the count of paragraphs.
- */
- public @IntRange(from = 0) int getParagraphCount() {
- if (BuildCompat.isAtLeastP()) {
- return mWrapped.getParagraphCount();
- } else {
- return mParagraphEnds.length;
- }
- }
-
- /**
- * Returns the paragraph start offset of the text.
- */
- public @IntRange(from = 0) int getParagraphStart(@IntRange(from = 0) int paraIndex) {
- Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
- if (BuildCompat.isAtLeastP()) {
- return mWrapped.getParagraphStart(paraIndex);
- } else {
- return paraIndex == 0 ? 0 : mParagraphEnds[paraIndex - 1];
- }
- }
-
- /**
- * Returns the paragraph end offset of the text.
- */
- public @IntRange(from = 0) int getParagraphEnd(@IntRange(from = 0) int paraIndex) {
- Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
- if (BuildCompat.isAtLeastP()) {
- return mWrapped.getParagraphEnd(paraIndex);
- } else {
- return mParagraphEnds[paraIndex];
- }
- }
-
-
- private int findParaIndex(@IntRange(from = 0) int pos) {
- for (int i = 0; i < mParagraphEnds.length; ++i) {
- if (pos < mParagraphEnds[i]) {
- return i;
- }
- }
- throw new IndexOutOfBoundsException(
- "pos must be less than " + mParagraphEnds[mParagraphEnds.length - 1]
- + ", gave " + pos);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // Spannable overrides
- //
- // Do not allow to modify MetricAffectingSpan
-
- /**
- * @throws IllegalArgumentException if {@link MetricAffectingSpan} is specified.
- */
- @Override
- public void setSpan(Object what, int start, int end, int flags) {
- if (what instanceof MetricAffectingSpan) {
- throw new IllegalArgumentException(
- "MetricAffectingSpan can not be set to PrecomputedText.");
- }
- if (BuildCompat.isAtLeastP()) {
- mWrapped.setSpan(what, start, end, flags);
- } else {
- mText.setSpan(what, start, end, flags);
- }
- }
-
- /**
- * @throws IllegalArgumentException if {@link MetricAffectingSpan} is specified.
- */
- @Override
- public void removeSpan(Object what) {
- if (what instanceof MetricAffectingSpan) {
- throw new IllegalArgumentException(
- "MetricAffectingSpan can not be removed from PrecomputedText.");
- }
- if (BuildCompat.isAtLeastP()) {
- mWrapped.removeSpan(what);
- } else {
- mText.removeSpan(what);
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // Spanned overrides
- //
- // Just proxy for underlying mText if appropriate.
-
- @Override
- public <T> T[] getSpans(int start, int end, Class<T> type) {
- if (BuildCompat.isAtLeastP()) {
- return mWrapped.getSpans(start, end, type);
- } else {
- return mText.getSpans(start, end, type);
- }
-
- }
-
- @Override
- public int getSpanStart(Object tag) {
- return mText.getSpanStart(tag);
- }
-
- @Override
- public int getSpanEnd(Object tag) {
- return mText.getSpanEnd(tag);
- }
-
- @Override
- public int getSpanFlags(Object tag) {
- return mText.getSpanFlags(tag);
- }
-
- @Override
- public int nextSpanTransition(int start, int limit, Class type) {
- return mText.nextSpanTransition(start, limit, type);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // CharSequence overrides.
- //
- // Just proxy for underlying mText.
-
- @Override
- public int length() {
- return mText.length();
- }
-
- @Override
- public char charAt(int index) {
- return mText.charAt(index);
- }
-
- @Override
- public CharSequence subSequence(int start, int end) {
- return mText.subSequence(start, end);
- }
-
- @Override
- public String toString() {
- return mText.toString();
- }
-}
diff --git a/compat/src/main/java/androidx/core/view/DisplayCutoutCompat.java b/compat/src/main/java/androidx/core/view/DisplayCutoutCompat.java
deleted file mode 100644
index 0ce108c..0000000
--- a/compat/src/main/java/androidx/core/view/DisplayCutoutCompat.java
+++ /dev/null
@@ -1,132 +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.core.view;
-
-import static android.os.Build.VERSION.SDK_INT;
-
-import android.graphics.Rect;
-import android.view.DisplayCutout;
-
-import java.util.List;
-
-
-/**
- * Represents the area of the display that is not functional for displaying content.
- *
- * <p>{@code DisplayCutoutCompat} instances are immutable.
- */
-public final class DisplayCutoutCompat {
-
- private final Object mDisplayCutout;
-
- /**
- * Creates a DisplayCutout instance.
- *
- * @param safeInsets the insets from each edge which avoid the display cutout as returned by
- * {@link #getSafeInsetTop()} etc.
- * @param boundingRects the bounding rects of the display cutouts as returned by
- * {@link #getBoundingRects()} ()}.
- */
- // TODO(b/73953958): @VisibleForTesting(visibility = PRIVATE)
- public DisplayCutoutCompat(Rect safeInsets, List<Rect> boundingRects) {
- this(SDK_INT >= 28 ? new DisplayCutout(safeInsets, boundingRects) : null);
- }
-
- private DisplayCutoutCompat(Object displayCutout) {
- mDisplayCutout = displayCutout;
- }
-
- /** Returns the inset from the top which avoids the display cutout in pixels. */
- public int getSafeInsetTop() {
- if (SDK_INT >= 28) {
- return ((DisplayCutout) mDisplayCutout).getSafeInsetTop();
- } else {
- return 0;
- }
- }
-
- /** Returns the inset from the bottom which avoids the display cutout in pixels. */
- public int getSafeInsetBottom() {
- if (SDK_INT >= 28) {
- return ((DisplayCutout) mDisplayCutout).getSafeInsetBottom();
- } else {
- return 0;
- }
- }
-
- /** Returns the inset from the left which avoids the display cutout in pixels. */
- public int getSafeInsetLeft() {
- if (SDK_INT >= 28) {
- return ((DisplayCutout) mDisplayCutout).getSafeInsetLeft();
- } else {
- return 0;
- }
- }
-
- /** Returns the inset from the right which avoids the display cutout in pixels. */
- public int getSafeInsetRight() {
- if (SDK_INT >= 28) {
- return ((DisplayCutout) mDisplayCutout).getSafeInsetRight();
- } else {
- return 0;
- }
- }
-
- /**
- * Returns a list of {@code Rect}s, each of which is the bounding rectangle for a non-functional
- * area on the display.
- *
- * There will be at most one non-functional area per short edge of the device, and none on
- * the long edges.
- *
- * @return a list of bounding {@code Rect}s, one for each display cutout area.
- */
- public List<Rect> getBoundingRects() {
- if (SDK_INT >= 28) {
- return ((DisplayCutout) mDisplayCutout).getBoundingRects();
- } else {
- return null;
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- DisplayCutoutCompat other = (DisplayCutoutCompat) o;
- return mDisplayCutout == null ? other.mDisplayCutout == null
- : mDisplayCutout.equals(other.mDisplayCutout);
- }
-
- @Override
- public int hashCode() {
- return mDisplayCutout == null ? 0 : mDisplayCutout.hashCode();
- }
-
- @Override
- public String toString() {
- return "DisplayCutoutCompat{" + mDisplayCutout + "}";
- }
-
- static DisplayCutoutCompat wrap(Object displayCutout) {
- return displayCutout == null ? null : new DisplayCutoutCompat(displayCutout);
- }
-}
diff --git a/compat/src/main/java/androidx/core/view/WindowInsetsCompat.java b/compat/src/main/java/androidx/core/view/WindowInsetsCompat.java
index 003044a..eef9b12 100644
--- a/compat/src/main/java/androidx/core/view/WindowInsetsCompat.java
+++ b/compat/src/main/java/androidx/core/view/WindowInsetsCompat.java
@@ -20,7 +20,6 @@
import android.graphics.Rect;
import android.view.WindowInsets;
-import androidx.annotation.Nullable;
/**
* Describes a set of insets for window content.
@@ -344,34 +343,6 @@
}
}
- /**
- * Returns the display cutout if there is one.
- *
- * @return the display cutout or null if there is none
- * @see DisplayCutoutCompat
- */
- @Nullable
- public DisplayCutoutCompat getDisplayCutout() {
- if (SDK_INT >= 28) {
- return DisplayCutoutCompat.wrap(((WindowInsets) mInsets).getDisplayCutout());
- } else {
- return null;
- }
- }
-
- /**
- * Returns a copy of this WindowInsets with the cutout fully consumed.
- *
- * @return A modified copy of this WindowInsets
- */
- public WindowInsetsCompat consumeDisplayCutout() {
- if (SDK_INT >= 28) {
- return new WindowInsetsCompat(((WindowInsets) mInsets).consumeDisplayCutout());
- } else {
- return null;
- }
- }
-
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git a/compat/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java b/compat/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
index 015a77f2..16b570f 100644
--- a/compat/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/compat/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -642,9 +642,7 @@
* @param rowSpan The number of rows the item spans.
* @param columnIndex The column index at which the item is located.
* @param columnSpan The number of columns the item spans.
- * @param heading Whether the item is a heading. This should be set to false and the newer
- * {@link AccessibilityNodeInfoCompat#setHeading(boolean)} used to identify
- * headings.
+ * @param heading Whether the item is a heading.
* @param selected Whether the item is selected.
* @return An instance.
*/
@@ -668,9 +666,7 @@
* @param rowSpan The number of rows the item spans.
* @param columnIndex The column index at which the item is located.
* @param columnSpan The number of columns the item spans.
- * @param heading Whether the item is a heading. This should be set to false and the newer
- * {@link AccessibilityNodeInfoCompat#setHeading(boolean)} used to identify
- * headings.
+ * @param heading Whether the item is a heading.
* @return An instance.
*/
public static CollectionItemInfoCompat obtain(int rowIndex, int rowSpan,
@@ -744,7 +740,6 @@
* heading, table header, etc.
*
* @return If the item is a heading.
- * @deprecated Use {@link AccessibilityNodeInfoCompat#isHeading()}
*/
public boolean isHeading() {
if (Build.VERSION.SDK_INT >= 19) {
@@ -3318,16 +3313,11 @@
/**
* Returns whether node represents a heading.
- * <p><strong>Note:</strong> Returns {@code true} if either {@link #setHeading(boolean)}
- * marks this node as a heading or if the node has a {@link CollectionItemInfoCompat} that marks
- * it as such, to accomodate apps that use the now-deprecated API.</p>
*
* @return {@code true} if the node is a heading, {@code false} otherwise.
*/
public boolean isHeading() {
- if (getBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING)) return true;
- CollectionItemInfoCompat collectionItemInfo = getCollectionItemInfo();
- return (collectionItemInfo != null) && (collectionItemInfo.isHeading());
+ return getBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING);
}
/**
diff --git a/core/ktx/api/current.txt b/core/ktx/api/current.txt
index 883cbc9..61d7de8 100644
--- a/core/ktx/api/current.txt
+++ b/core/ktx/api/current.txt
@@ -308,16 +308,6 @@
}
-package androidx.core.location {
-
- public final class LocationKt {
- ctor public LocationKt();
- method public static operator double component1(android.location.Location);
- method public static operator double component2(android.location.Location);
- }
-
-}
-
package androidx.core.net {
public final class UriKt {
@@ -363,7 +353,6 @@
method public static void forEachIndexed(android.preference.PreferenceGroup, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.preference.Preference,kotlin.Unit> action);
method public static operator android.preference.Preference get(android.preference.PreferenceGroup, CharSequence key);
method public static operator android.preference.Preference get(android.preference.PreferenceGroup, int index);
- method public static kotlin.sequences.Sequence<android.preference.Preference> getChildren(android.preference.PreferenceGroup);
method public static int getSize(android.preference.PreferenceGroup);
method public static boolean isEmpty(android.preference.PreferenceGroup);
method public static boolean isNotEmpty(android.preference.PreferenceGroup);
@@ -399,8 +388,6 @@
method public static android.text.SpannableStringBuilder italic(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
method public static android.text.SpannableStringBuilder scale(android.text.SpannableStringBuilder, float proportion, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
method public static android.text.SpannableStringBuilder strikeThrough(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
- method public static android.text.SpannableStringBuilder subscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
- method public static android.text.SpannableStringBuilder superscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
method public static android.text.SpannableStringBuilder underline(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
}
@@ -618,12 +605,10 @@
method public static void forEach(android.view.Menu, kotlin.jvm.functions.Function1<? super android.view.MenuItem,kotlin.Unit> action);
method public static void forEachIndexed(android.view.Menu, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.MenuItem,kotlin.Unit> action);
method public static operator android.view.MenuItem get(android.view.Menu, int index);
- method public static kotlin.sequences.Sequence<android.view.MenuItem> getChildren(android.view.Menu);
method public static int getSize(android.view.Menu);
method public static boolean isEmpty(android.view.Menu);
method public static boolean isNotEmpty(android.view.Menu);
method public static operator java.util.Iterator<android.view.MenuItem> iterator(android.view.Menu);
- method public static operator void minusAssign(android.view.Menu, android.view.MenuItem item);
}
public final class ViewGroupKt {
diff --git a/core/ktx/src/androidTest/java/androidx/core/location/LocationTest.kt b/core/ktx/src/androidTest/java/androidx/core/location/LocationTest.kt
deleted file mode 100644
index 0f289ef..0000000
--- a/core/ktx/src/androidTest/java/androidx/core/location/LocationTest.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-package androidx.core.location
-
-import android.location.Location
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-class LocationTest {
- @Test fun destructuring() {
- val (lat, lon) = Location("").apply {
- latitude = 1.0
- longitude = 2.0
- }
- assertEquals(lat, 1.0, 0.0)
- assertEquals(lon, 2.0, 0.0)
- }
-}
diff --git a/core/ktx/src/androidTest/java/androidx/core/preference/PreferenceGroupTest.kt b/core/ktx/src/androidTest/java/androidx/core/preference/PreferenceGroupTest.kt
index 120718e..0653a28 100644
--- a/core/ktx/src/androidTest/java/androidx/core/preference/PreferenceGroupTest.kt
+++ b/core/ktx/src/androidTest/java/androidx/core/preference/PreferenceGroupTest.kt
@@ -173,13 +173,4 @@
iterator.next()
}
}
-
- @Test fun children() {
- val preferences = listOf(Preference(context), Preference(context), Preference(context))
- preferences.forEach { preferenceGroup.addPreference(it) }
-
- preferenceGroup.children.forEachIndexed { index, child ->
- assertSame(preferences[index], child)
- }
- }
}
diff --git a/core/ktx/src/androidTest/java/androidx/core/text/SpannableStringBuilderTest.kt b/core/ktx/src/androidTest/java/androidx/core/text/SpannableStringBuilderTest.kt
index c66dd1f..5d67e83 100644
--- a/core/ktx/src/androidTest/java/androidx/core/text/SpannableStringBuilderTest.kt
+++ b/core/ktx/src/androidTest/java/androidx/core/text/SpannableStringBuilderTest.kt
@@ -186,49 +186,15 @@
assertEquals(12, result.getSpanEnd(scale))
}
- @Test fun builderSuperscript() {
- val result: SpannedString = buildSpannedString {
- append("Hello, ")
- superscript {
- append("World")
- }
- }
- assertEquals("Hello, World", result.toString())
-
- val spans = result.getSpans<Any>()
- assertEquals(1, spans.size)
-
- val superscript = spans.filterIsInstance<SuperscriptSpan>().single()
- assertEquals(7, result.getSpanStart(superscript))
- assertEquals(12, result.getSpanEnd(superscript))
- }
-
- @Test fun builderSubscript() {
- val result: SpannedString = buildSpannedString {
- append("Hello, ")
- subscript {
- append("World")
- }
- }
- assertEquals("Hello, World", result.toString())
-
- val spans = result.getSpans<Any>()
- assertEquals(1, spans.size)
-
- val subscript = spans.filterIsInstance<SubscriptSpan>().single()
- assertEquals(7, result.getSpanStart(subscript))
- assertEquals(12, result.getSpanEnd(subscript))
- }
-
@Test fun nested() {
val result: SpannedString = buildSpannedString {
color(RED) {
append('H')
- subscript {
+ inSpans(SubscriptSpan()) {
append('e')
}
append('l')
- superscript {
+ inSpans(SuperscriptSpan()) {
append('l')
}
append('o')
diff --git a/core/ktx/src/androidTest/java/androidx/core/view/MenuTest.kt b/core/ktx/src/androidTest/java/androidx/core/view/MenuTest.kt
index 313ed1b..18e1b56 100644
--- a/core/ktx/src/androidTest/java/androidx/core/view/MenuTest.kt
+++ b/core/ktx/src/androidTest/java/androidx/core/view/MenuTest.kt
@@ -45,20 +45,6 @@
assertTrue(item2 in menu)
}
- @Test fun minusAssign() {
- val item1 = menu.add(NONE, 1, NONE, "")
- val item2 = menu.add(NONE, 2, NONE, "")
-
- assertEquals(2, menu.size)
-
- menu -= item2
- assertEquals(1, menu.size)
- assertSame(item1, menu.getItem(0))
-
- menu -= item1
- assertEquals(0, menu.size)
- }
-
@Test fun size() {
assertEquals(0, menu.size)
@@ -146,16 +132,4 @@
assertFalse(item2 in menu)
assertEquals(0, menu.size())
}
-
- @Test fun children() {
- val items = listOf(
- menu.add(NONE, 1, NONE, ""),
- menu.add(NONE, 2, NONE, ""),
- menu.add(NONE, 3, NONE, "")
- )
-
- menu.children.forEachIndexed { index, child ->
- assertSame(items[index], child)
- }
- }
}
diff --git a/core/ktx/src/androidTest/java/androidx/core/view/ViewTest.kt b/core/ktx/src/androidTest/java/androidx/core/view/ViewTest.kt
index 1ccd517..0b7cfa2 100644
--- a/core/ktx/src/androidTest/java/androidx/core/view/ViewTest.kt
+++ b/core/ktx/src/androidTest/java/androidx/core/view/ViewTest.kt
@@ -17,9 +17,7 @@
package androidx.core.view
import android.graphics.Bitmap
-import android.graphics.Color
import android.support.test.InstrumentationRegistry
-import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
@@ -177,29 +175,6 @@
assertSame(Bitmap.Config.RGB_565, bitmap.config)
}
- @Test
- fun toBitmapScrolls() {
- val scrollView = LayoutInflater.from(context)!!
- .inflate(R.layout.test_bitmap_scrolls, null, false)
-
- val size = 100
-
- scrollView.measure(
- View.MeasureSpec.makeMeasureSpec(size, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(size, View.MeasureSpec.EXACTLY))
- scrollView.layout(0, 0, size, size)
-
- val noScroll = scrollView.toBitmap()
- assertEquals(Color.WHITE, noScroll.getPixel(0, 0))
- assertEquals(Color.WHITE, noScroll.getPixel(size - 1, size - 1))
-
- scrollView.scrollTo(0, size)
- val scrolls = scrollView.toBitmap()
-
- assertEquals(Color.BLACK, scrolls.getPixel(0, 0))
- assertEquals(Color.BLACK, scrolls.getPixel(size - 1, size - 1))
- }
-
@Test fun isVisible() {
view.isVisible = true
assertTrue(view.isVisible)
diff --git a/core/ktx/src/androidTest/res/layout/test_bitmap_scrolls.xml b/core/ktx/src/androidTest/res/layout/test_bitmap_scrolls.xml
deleted file mode 100644
index c2cad5c..0000000
--- a/core/ktx/src/androidTest/res/layout/test_bitmap_scrolls.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="100px"
- android:layout_height="100px"
- android:scrollbars="none"
- >
-
- <LinearLayout
- android:layout_width="100px"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <View
- android:layout_width="match_parent"
- android:layout_height="100px"
- android:background="@android:color/white" />
-
- <View
- android:layout_width="match_parent"
- android:layout_height="100px"
- android:background="@android:color/black" />
-
- </LinearLayout>
-
-</ScrollView>
\ No newline at end of file
diff --git a/core/ktx/src/main/java/androidx/core/location/Location.kt b/core/ktx/src/main/java/androidx/core/location/Location.kt
deleted file mode 100644
index fe48322..0000000
--- a/core/ktx/src/main/java/androidx/core/location/Location.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-@file:Suppress("NOTHING_TO_INLINE")
-
-package androidx.core.location
-
-import android.location.Location
-
-/**
- * Returns the latitude of this [Location].
- *
- * This method allows to use destructuring declarations when working with [Location],
- * for example:
- * ```
- * val (lat, lon) = myLocation
- * ```
- */
-inline operator fun Location.component1() = this.latitude
-
-/**
- * Returns the longitude of this [Location].
- *
- * This method allows to use destructuring declarations when working with [Location],
- * for example:
- * ```
- * val (lat, lon) = myLocation
- * ```
- */
-inline operator fun Location.component2() = this.longitude
diff --git a/core/ktx/src/main/java/androidx/core/preference/PreferenceGroup.kt b/core/ktx/src/main/java/androidx/core/preference/PreferenceGroup.kt
index 5df18a6..ab37dee 100644
--- a/core/ktx/src/main/java/androidx/core/preference/PreferenceGroup.kt
+++ b/core/ktx/src/main/java/androidx/core/preference/PreferenceGroup.kt
@@ -41,8 +41,8 @@
/** Returns `true` if `preference` is found in this preference group. */
@Deprecated("Use Jetpack preference library")
operator fun PreferenceGroup.contains(preference: Preference): Boolean {
- for (index in 0 until preferenceCount) {
- if (getPreference(index) == preference) {
+ for (index in 0 until size) {
+ if (get(index) == preference) {
return true
}
}
@@ -76,7 +76,7 @@
/** Performs the given action on each preference in this preference group. */
@Deprecated("Use Jetpack preference library")
inline fun PreferenceGroup.forEach(action: (preference: Preference) -> Unit) {
- for (index in 0 until preferenceCount) {
+ for (index in 0 until size) {
action(get(index))
}
}
@@ -84,7 +84,7 @@
/** Performs the given action on each preference in this preference group, providing its sequential index. */
@Deprecated("Use Jetpack preference library")
inline fun PreferenceGroup.forEachIndexed(action: (index: Int, preference: Preference) -> Unit) {
- for (index in 0 until preferenceCount) {
+ for (index in 0 until size) {
action(index, get(index))
}
}
diff --git a/core/ktx/src/main/java/androidx/core/text/SpannableStringBuilder.kt b/core/ktx/src/main/java/androidx/core/text/SpannableStringBuilder.kt
index e49ccd2..5834a34 100644
--- a/core/ktx/src/main/java/androidx/core/text/SpannableStringBuilder.kt
+++ b/core/ktx/src/main/java/androidx/core/text/SpannableStringBuilder.kt
@@ -26,8 +26,6 @@
import android.text.style.RelativeSizeSpan
import android.text.style.StrikethroughSpan
import android.text.style.StyleSpan
-import android.text.style.SubscriptSpan
-import android.text.style.SuperscriptSpan
import android.text.style.UnderlineSpan
import androidx.annotation.ColorInt
@@ -136,19 +134,3 @@
proportion: Float,
builderAction: SpannableStringBuilder.() -> Unit
) = inSpans(RelativeSizeSpan(proportion), builderAction = builderAction)
-
-/**
- * Wrap appended text in [builderAction] in a [SuperscriptSpan].
- *
- * @see SpannableStringBuilder.inSpans
- */
-inline fun SpannableStringBuilder.superscript(builderAction: SpannableStringBuilder.() -> Unit) =
- inSpans(SuperscriptSpan(), builderAction = builderAction)
-
-/**
- * Wrap appended text in [builderAction] in a [SubscriptSpan].
- *
- * @see SpannableStringBuilder.inSpans
- */
-inline fun SpannableStringBuilder.subscript(builderAction: SpannableStringBuilder.() -> Unit) =
- inSpans(SubscriptSpan(), builderAction = builderAction)
diff --git a/core/ktx/src/main/java/androidx/core/view/Menu.kt b/core/ktx/src/main/java/androidx/core/view/Menu.kt
index 069e61d..7ab479f 100644
--- a/core/ktx/src/main/java/androidx/core/view/Menu.kt
+++ b/core/ktx/src/main/java/androidx/core/view/Menu.kt
@@ -31,7 +31,7 @@
/** Returns `true` if [item] is found in this menu. */
operator fun Menu.contains(item: MenuItem): Boolean {
@Suppress("LoopToCallChain")
- for (index in 0 until size()) {
+ for (index in 0 until size) {
if (getItem(index) == item) {
return true
}
@@ -39,9 +39,6 @@
return false
}
-/** Removes [item] from this menu. */
-inline operator fun Menu.minusAssign(item: MenuItem) = removeItem(item.itemId)
-
/** Returns the number of items in this menu. */
inline val Menu.size get() = size()
@@ -72,9 +69,3 @@
override fun next() = getItem(index++) ?: throw IndexOutOfBoundsException()
override fun remove() = removeItem(--index)
}
-
-/** Returns a [Sequence] over the items in this menu. */
-val Menu.children: Sequence<MenuItem>
- get() = object : Sequence<MenuItem> {
- override fun iterator() = this@children.iterator()
- }
diff --git a/core/ktx/src/main/java/androidx/core/view/View.kt b/core/ktx/src/main/java/androidx/core/view/View.kt
index bc2e34d..fcb0256 100644
--- a/core/ktx/src/main/java/androidx/core/view/View.kt
+++ b/core/ktx/src/main/java/androidx/core/view/View.kt
@@ -195,10 +195,7 @@
if (!ViewCompat.isLaidOut(this)) {
throw IllegalStateException("View needs to be laid out before calling toBitmap()")
}
- return Bitmap.createBitmap(width, height, config).applyCanvas {
- translate(-scrollX.toFloat(), -scrollY.toFloat())
- draw(this)
- }
+ return Bitmap.createBitmap(width, height, config).applyCanvas(::draw)
}
/**
diff --git a/customview/src/main/java/androidx/customview/widget/ExploreByTouchHelper.java b/customview/src/main/java/androidx/customview/widget/ExploreByTouchHelper.java
index dbe8455..b49afc8 100644
--- a/customview/src/main/java/androidx/customview/widget/ExploreByTouchHelper.java
+++ b/customview/src/main/java/androidx/customview/widget/ExploreByTouchHelper.java
@@ -188,7 +188,7 @@
updateHoveredVirtualView(virtualViewId);
return (virtualViewId != INVALID_ID);
case MotionEvent.ACTION_HOVER_EXIT:
- if (mHoveredVirtualViewId != INVALID_ID) {
+ if (mAccessibilityFocusedVirtualViewId != INVALID_ID) {
updateHoveredVirtualView(INVALID_ID);
return true;
}
diff --git a/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java b/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java
index d685bf1..f697f24 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(",", -1);
+ final String[] values = value.split(",");
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(",", -1);
+ final String[] values = value.split(",");
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(",", -1);
+ final String[] values = value.split(",");
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(",", -1);
+ final String[] values = value.split(",");
final Rational[] rationalArray = new Rational[values.length];
for (int j = 0; j < values.length; ++j) {
- final String[] numbers = values[j].split("/", -1);
+ final String[] numbers = values[j].split("/");
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(",", -1);
+ final String[] values = value.split(",");
final Rational[] rationalArray = new Rational[values.length];
for (int j = 0; j < values.length; ++j) {
- final String[] numbers = values[j].split("/", -1);
+ final String[] numbers = values[j].split("/");
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(",", -1);
+ final String[] values = value.split(",");
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+", -1);
+ String[] dateTime = sFormatter.format(new Date(location.getTime())).split("\\s+");
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(",", -1);
+ String [] parts = rationalString.split(",");
String [] pair;
- pair = parts[0].split("/", -1);
+ pair = parts[0].split("/");
double degrees = Double.parseDouble(pair[0].trim())
/ Double.parseDouble(pair[1].trim());
- pair = parts[1].split("/", -1);
+ pair = parts[1].split("/");
double minutes = Double.parseDouble(pair[0].trim())
/ Double.parseDouble(pair[1].trim());
- pair = parts[2].split("/", -1);
+ pair = parts[2].split("/");
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(",", -1);
+ String[] entryValues = entryValue.split(",");
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("/", -1);
+ String[] rationalNumber = entryValue.split("/");
if (rationalNumber.length == 2) {
try {
long numerator = (long) Double.parseDouble(rationalNumber[0]);
diff --git a/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java b/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java
index 35d34d4..9b5df45 100644
--- a/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java
+++ b/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java
@@ -25,8 +25,6 @@
import android.util.Log;
import android.view.Surface;
-import java.util.Objects;
-
/**
* Holds state associated with a Surface used for MediaCodec encoder input.
* <p>
@@ -65,7 +63,7 @@
*/
private void eglSetup() {
mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
- if (Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) {
+ if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) {
throw new RuntimeException("unable to get EGL14 display");
}
int[] version = new int[2];
@@ -132,7 +130,7 @@
}
private void releaseEGLSurface() {
- if (!Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) {
+ if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) {
EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);
mEGLSurface = EGL14.EGL_NO_SURFACE;
}
@@ -143,7 +141,7 @@
* Surface that was passed to our constructor.
*/
public void release() {
- if (!Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) {
+ if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) {
EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);
EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);
EGL14.eglReleaseThread();
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 aa29bdc..b5ab7ea 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
@@ -61,11 +61,11 @@
return value
}
- 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()
+ 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()
}
// We might be working with an internal type or field reference, e.g.
@@ -81,10 +81,10 @@
// Try rewrite rules
if (context.useFallbackIfTypeIsMissing) {
- val rewrittenType = context.config.rulesMap.rewriteType(type)
- if (rewrittenType != null) {
- Log.i(TAG, "Map string: '%s' -> '%s' via fallback", value, rewrittenType)
- return rewrittenType.toDotNotation()
+ val result = context.config.rulesMap.rewriteType(type)
+ if (result != null) {
+ Log.i(TAG, "Map string: '%s' -> '%s' via fallback", value, result)
+ return result.toDotNotation()
}
}
diff --git a/jetifier/jetifier/source-transformer/rewritePackageNames.py b/jetifier/jetifier/source-transformer/rewritePackageNames.py
index 32d9a91..8e348a4 100755
--- a/jetifier/jetifier/source-transformer/rewritePackageNames.py
+++ b/jetifier/jetifier/source-transformer/rewritePackageNames.py
@@ -95,7 +95,7 @@
rewriterTextBuilder = StringBuilder()
rewriteRules = executionConfig.jetifierConfig.getTypesMap()
for rule in rewriteRules:
- rewriterTextBuilder.add("s|").add(rule.fromName.replace(".", "\.")).add("|").add(rule.toName).add("|g\n")
+ rewriterTextBuilder.add("s|").add(rule.fromName).add("|").add(rule.toName).add("|g\n")
for rule in HARDCODED_RULES_REVERSE:
rewriterTextBuilder.add(rule)
scriptPath = "/tmp/jetifier-sed-script.txt"
diff --git a/leanback/src/main/res/values-as/strings.xml b/leanback/src/main/res/values-as/strings.xml
deleted file mode 100644
index eb3b2b0..0000000
--- a/leanback/src/main/res/values-as/strings.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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="lb_navigation_menu_contentDescription" msgid="8126335323963415494">"নেভিগেশ্বন মেনু"</string>
- <string name="orb_search_action" msgid="7534843523462177008">"সন্ধান সম্পৰ্কীয় কাৰ্য"</string>
- <string name="lb_search_bar_hint" msgid="4819380969103509861">"সন্ধান"</string>
- <string name="lb_search_bar_hint_speech" msgid="2795474673510974502">"সন্ধান কৰিবলৈ কথা কওক"</string>
- <string name="lb_search_bar_hint_with_title" msgid="7453744869467668159">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> সন্ধান কৰক"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="5851694095153624617">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> সন্ধান কৰিবলৈ কথা কওক"</string>
- <string name="lb_control_display_fast_forward_multiplier" msgid="2721825378927619928">"%1$dX"</string>
- <string name="lb_control_display_rewind_multiplier" msgid="6173753802428649303">"%1$dX"</string>
- <string name="lb_playback_controls_play" msgid="1590369760862605402">"প্লে কৰক"</string>
- <string name="lb_playback_controls_pause" msgid="1769131316742618433">"পজ কৰক"</string>
- <string name="lb_playback_controls_fast_forward" msgid="8966769845721269304">"ফাষ্ট ফৰৱাৰ্ড"</string>
- <string name="lb_playback_controls_fast_forward_multiplier" msgid="801276177839339511">"ফাষ্ট ফৰৱার্ড কৰক %1$dX"</string>
- <string name="lb_playback_controls_rewind" msgid="1412664391757869774">"ৰিৱাইণ্ড কৰক"</string>
- <string name="lb_playback_controls_rewind_multiplier" msgid="8651612807713092781">"ৰিৱাইণ্ড কৰক %1$dX"</string>
- <string name="lb_playback_controls_skip_next" msgid="4877009494447817003">"পৰৱৰ্তীটোলৈ এৰি যাওক"</string>
- <string name="lb_playback_controls_skip_previous" msgid="3147124289285911980">"আগৰটোলৈ এৰি যাওক"</string>
- <string name="lb_playback_controls_more_actions" msgid="2827883329510404797">"অধিক কাৰ্য"</string>
- <string name="lb_playback_controls_thumb_up" msgid="8332816524260995892">"থাম্ব আপ বাছনি নাইকিয়া কৰক"</string>
- <string name="lb_playback_controls_thumb_up_outline" msgid="1038344559734334272">"থাম্ব আপ বাছনি কৰক"</string>
- <string name="lb_playback_controls_thumb_down" msgid="5075744418630733006">"থাম্ব ডাউন বাছনি নাইকিয়া কৰক"</string>
- <string name="lb_playback_controls_thumb_down_outline" msgid="2847309435442474470">"থাম্ব ডাউন বাছনি কৰক"</string>
- <string name="lb_playback_controls_repeat_none" msgid="5812341701962930499">"একো পুনৰাই প্লে নকৰিব"</string>
- <string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"সকলো পুনৰাই প্লে কৰক"</string>
- <string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"এটা পুনৰাই প্লে কৰক"</string>
- <string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"সান-মিহলি সক্ষম কৰক"</string>
- <string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"সান-মিহলি অক্ষম কৰক"</string>
- <string name="lb_playback_controls_high_quality_enable" msgid="1862669142355962638">"উচ্চ মানৰ প্লেবেক সক্ষম কৰক"</string>
- <string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"উচ্চ মান অক্ষম কৰক"</string>
- <string name="lb_playback_controls_closed_captioning_enable" msgid="3934392140182327163">"ছাব-টাইটেল সক্ষম কৰক"</string>
- <string name="lb_playback_controls_closed_captioning_disable" msgid="5508271941331836786">"ছাব-টাইটেল অক্ষম কৰক"</string>
- <string name="lb_playback_controls_picture_in_picture" msgid="8800305194045609275">"চিত্ৰৰ ভিতৰত চিত্ৰ ম\'ড আৰম্ভ কৰক"</string>
- <string name="lb_playback_time_separator" msgid="6549544638083578695">"/"</string>
- <string name="lb_playback_controls_shown" msgid="7794717158616536936">"মিডিয়াৰ নিয়ন্ত্ৰণসমূহ দেখুওৱা হ\'ল"</string>
- <string name="lb_playback_controls_hidden" msgid="619396299825306757">"মিডিয়াৰ নিয়ন্ত্ৰণসমূহ লুকুৱাই ৰখা হৈছে, দেখুওৱাবলৈ ডি-পেডত টিপক"</string>
- <string name="lb_guidedaction_finish_title" msgid="7747913934287176843">"সমাপ্ত"</string>
- <string name="lb_guidedaction_continue_title" msgid="1122271825827282965">"অব্যাহত ৰাখক"</string>
- <string name="lb_media_player_error" msgid="8748646000835486516">"MediaPlayer ত্ৰুটি ক\'ড %1$d, অতিৰিক্ত %2$d"</string>
- <string name="lb_onboarding_get_started" msgid="7674487829030291492">"আৰম্ভ কৰক"</string>
- <string name="lb_onboarding_accessibility_next" msgid="4213611627196077555">"পৰৱৰ্তী"</string>
-</resources>
diff --git a/leanback/src/main/res/values-be/strings.xml b/leanback/src/main/res/values-be/strings.xml
index a4038d6..2828004 100644
--- a/leanback/src/main/res/values-be/strings.xml
+++ b/leanback/src/main/res/values-be/strings.xml
@@ -21,8 +21,8 @@
<string name="orb_search_action" msgid="7534843523462177008">"Пошук"</string>
<string name="lb_search_bar_hint" msgid="4819380969103509861">"Пошук"</string>
<string name="lb_search_bar_hint_speech" msgid="2795474673510974502">"Прамоўце пошукавы запыт"</string>
- <string name="lb_search_bar_hint_with_title" msgid="7453744869467668159">"Шукаць тут: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="5851694095153624617">"Прамоўце запыт для пошуку тут: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title" msgid="7453744869467668159">"Шукаць тут <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="5851694095153624617">"Прамоўце пошукавы запыт тут <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_control_display_fast_forward_multiplier" msgid="2721825378927619928">"%1$dX"</string>
<string name="lb_control_display_rewind_multiplier" msgid="6173753802428649303">"%1$dX"</string>
<string name="lb_playback_controls_play" msgid="1590369760862605402">"Прайграць"</string>
@@ -53,7 +53,7 @@
<string name="lb_playback_controls_hidden" msgid="619396299825306757">"Элементы кіравання мультымедыя схаваны. Каб паказаць іх, націсніце d-pad"</string>
<string name="lb_guidedaction_finish_title" msgid="7747913934287176843">"Завяршыць"</string>
<string name="lb_guidedaction_continue_title" msgid="1122271825827282965">"Працягнуць"</string>
- <string name="lb_media_player_error" msgid="8748646000835486516">"Код памылкі MediaPlayer: %1$d (дадатковы: %2$d)"</string>
+ <string name="lb_media_player_error" msgid="8748646000835486516">"Код памылкі MediaPlayer %1$d дадаткова %2$d"</string>
<string name="lb_onboarding_get_started" msgid="7674487829030291492">"ПАЧАЦЬ"</string>
<string name="lb_onboarding_accessibility_next" msgid="4213611627196077555">"Далей"</string>
</resources>
diff --git a/leanback/src/main/res/values-bn/strings.xml b/leanback/src/main/res/values-bn/strings.xml
index a7ae625..c7c7bed 100644
--- a/leanback/src/main/res/values-bn/strings.xml
+++ b/leanback/src/main/res/values-bn/strings.xml
@@ -18,7 +18,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="lb_navigation_menu_contentDescription" msgid="8126335323963415494">"নেভিগেশন মেনু"</string>
- <string name="orb_search_action" msgid="7534843523462177008">"খোঁজার অ্যাক্টিভিটি"</string>
+ <string name="orb_search_action" msgid="7534843523462177008">"খোঁজার কার্যকলাপ"</string>
<string name="lb_search_bar_hint" msgid="4819380969103509861">"সার্চ"</string>
<string name="lb_search_bar_hint_speech" msgid="2795474673510974502">"বলার মাধ্যমে খুঁজুন"</string>
<string name="lb_search_bar_hint_with_title" msgid="7453744869467668159">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> খুঁজুন"</string>
@@ -33,7 +33,7 @@
<string name="lb_playback_controls_rewind_multiplier" msgid="8651612807713092781">"%1$dX স্পিডে পিছিয়ে যান"</string>
<string name="lb_playback_controls_skip_next" msgid="4877009494447817003">"সরাসরি পরেরটিতে চলে যান"</string>
<string name="lb_playback_controls_skip_previous" msgid="3147124289285911980">"সরাসরি আগেরটিতে চলে যান"</string>
- <string name="lb_playback_controls_more_actions" msgid="2827883329510404797">"আরও অ্যাক্টিভিটি"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2827883329510404797">"আরও কার্যকলাপ"</string>
<string name="lb_playback_controls_thumb_up" msgid="8332816524260995892">"উপরের দিকে করা বুড়ো আঙ্গুলের চিহ্নকে বাদ দিন"</string>
<string name="lb_playback_controls_thumb_up_outline" msgid="1038344559734334272">"উপরের দিকে করা বুড়ো আঙ্গুলের চিহ্নকে বেছে নিন"</string>
<string name="lb_playback_controls_thumb_down" msgid="5075744418630733006">"নিচের দিকে করা বুড়ো আঙ্গুলের চিহ্নকে বাদ দিন"</string>
diff --git a/leanback/src/main/res/values-bs/strings.xml b/leanback/src/main/res/values-bs/strings.xml
index d114d87..33111a1 100644
--- a/leanback/src/main/res/values-bs/strings.xml
+++ b/leanback/src/main/res/values-bs/strings.xml
@@ -19,7 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="lb_navigation_menu_contentDescription" msgid="8126335323963415494">"Meni za navigaciju"</string>
<string name="orb_search_action" msgid="7534843523462177008">"Pretraživanje"</string>
- <string name="lb_search_bar_hint" msgid="4819380969103509861">"Pretražite"</string>
+ <string name="lb_search_bar_hint" msgid="4819380969103509861">"Traži"</string>
<string name="lb_search_bar_hint_speech" msgid="2795474673510974502">"Kažite nešto da pokrenete pretragu"</string>
<string name="lb_search_bar_hint_with_title" msgid="7453744869467668159">"Pretraži <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="5851694095153624617">"Kažite nešto da pokrenete pretragu <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
diff --git a/leanback/src/main/res/values-es/strings.xml b/leanback/src/main/res/values-es/strings.xml
index 53e67972..dc33a6b 100644
--- a/leanback/src/main/res/values-es/strings.xml
+++ b/leanback/src/main/res/values-es/strings.xml
@@ -22,7 +22,7 @@
<string name="lb_search_bar_hint" msgid="4819380969103509861">"Haz una búsqueda"</string>
<string name="lb_search_bar_hint_speech" msgid="2795474673510974502">"Habla para buscar"</string>
<string name="lb_search_bar_hint_with_title" msgid="7453744869467668159">"Busca <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="5851694095153624617">"Habla para buscar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="5851694095153624617">"Busca <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> por voz"</string>
<string name="lb_control_display_fast_forward_multiplier" msgid="2721825378927619928">"%1$dx"</string>
<string name="lb_control_display_rewind_multiplier" msgid="6173753802428649303">"%1$dx"</string>
<string name="lb_playback_controls_play" msgid="1590369760862605402">"Reproducir"</string>
@@ -47,7 +47,7 @@
<string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"Inhabilitar alta calidad"</string>
<string name="lb_playback_controls_closed_captioning_enable" msgid="3934392140182327163">"Habilitar subtítulos"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="5508271941331836786">"Inhabilitar subtítulos"</string>
- <string name="lb_playback_controls_picture_in_picture" msgid="8800305194045609275">"Activar modo imagen en imagen"</string>
+ <string name="lb_playback_controls_picture_in_picture" msgid="8800305194045609275">"Activar modo pantalla en pantalla"</string>
<string name="lb_playback_time_separator" msgid="6549544638083578695">"/"</string>
<string name="lb_playback_controls_shown" msgid="7794717158616536936">"Controles multimedia mostrados"</string>
<string name="lb_playback_controls_hidden" msgid="619396299825306757">"Controles multimedia ocultos (pulsa la cruceta para mostrarlos)"</string>
diff --git a/leanback/src/main/res/values-eu/strings.xml b/leanback/src/main/res/values-eu/strings.xml
index 72c433f..6b7226f 100644
--- a/leanback/src/main/res/values-eu/strings.xml
+++ b/leanback/src/main/res/values-eu/strings.xml
@@ -49,8 +49,8 @@
<string name="lb_playback_controls_closed_captioning_disable" msgid="5508271941331836786">"Desgaitu azpitituluak"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="8800305194045609275">"Aktibatu \"Pantaila txiki gainjarri\" modua"</string>
<string name="lb_playback_time_separator" msgid="6549544638083578695">"/"</string>
- <string name="lb_playback_controls_shown" msgid="7794717158616536936">"Multimedia-edukia kontrolatzeko aukerak ikusgai"</string>
- <string name="lb_playback_controls_hidden" msgid="619396299825306757">"Ezkutatuta daude multimedia-edukia kontrolatzeko aukerak. Haiek erakusteko, sakatu nabigazio-gurutzea."</string>
+ <string name="lb_playback_controls_shown" msgid="7794717158616536936">"Multimedia kontrolatzeko aukerak ikusgai"</string>
+ <string name="lb_playback_controls_hidden" msgid="619396299825306757">"Ezkutatuta daude multimedia-edukia kontrolatzeko aukerak. Erakusteko, sakatu nabigazio-gurutzea."</string>
<string name="lb_guidedaction_finish_title" msgid="7747913934287176843">"Amaitu"</string>
<string name="lb_guidedaction_continue_title" msgid="1122271825827282965">"Egin aurrera"</string>
<string name="lb_media_player_error" msgid="8748646000835486516">"MediaPlayer errore-kodea: %1$d (%2$d gehigarria)"</string>
diff --git a/leanback/src/main/res/values-fr-rCA/strings.xml b/leanback/src/main/res/values-fr-rCA/strings.xml
index ad38e94..de3fde5 100644
--- a/leanback/src/main/res/values-fr-rCA/strings.xml
+++ b/leanback/src/main/res/values-fr-rCA/strings.xml
@@ -32,7 +32,7 @@
<string name="lb_playback_controls_rewind" msgid="1412664391757869774">"Retour arrière"</string>
<string name="lb_playback_controls_rewind_multiplier" msgid="8651612807713092781">"Retour rapide à %1$dX"</string>
<string name="lb_playback_controls_skip_next" msgid="4877009494447817003">"Passer à l\'élément suivant"</string>
- <string name="lb_playback_controls_skip_previous" msgid="3147124289285911980">"Retourner à l\'élément précédent"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="3147124289285911980">"Passer à l\'élément précédent"</string>
<string name="lb_playback_controls_more_actions" msgid="2827883329510404797">"Autres actions"</string>
<string name="lb_playback_controls_thumb_up" msgid="8332816524260995892">"Désélectionner la mention « J\'aime »"</string>
<string name="lb_playback_controls_thumb_up_outline" msgid="1038344559734334272">"Sélectionner la mention « J\'aime »"</string>
diff --git a/leanback/src/main/res/values-ja/strings.xml b/leanback/src/main/res/values-ja/strings.xml
index 96f27e28..22980f1 100644
--- a/leanback/src/main/res/values-ja/strings.xml
+++ b/leanback/src/main/res/values-ja/strings.xml
@@ -43,8 +43,8 @@
<string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"1 曲をリピート"</string>
<string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"シャッフルを有効にする"</string>
<string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"シャッフルを無効にする"</string>
- <string name="lb_playback_controls_high_quality_enable" msgid="1862669142355962638">"高画質を有効にする"</string>
- <string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"高画質を無効にする"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="1862669142355962638">"高品質を有効にする"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"高品質を無効にする"</string>
<string name="lb_playback_controls_closed_captioning_enable" msgid="3934392140182327163">"クローズド キャプションを有効にする"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="5508271941331836786">"クローズド キャプションを無効にする"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="8800305194045609275">"ピクチャー イン ピクチャー モードに移動"</string>
diff --git a/leanback/src/main/res/values-ko/strings.xml b/leanback/src/main/res/values-ko/strings.xml
index b1587b91..9eacb53 100644
--- a/leanback/src/main/res/values-ko/strings.xml
+++ b/leanback/src/main/res/values-ko/strings.xml
@@ -40,7 +40,7 @@
<string name="lb_playback_controls_thumb_down_outline" msgid="2847309435442474470">"싫어요 선택"</string>
<string name="lb_playback_controls_repeat_none" msgid="5812341701962930499">"반복 안함"</string>
<string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"전체 반복"</string>
- <string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"한 개 반복"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"한 항목 반복"</string>
<string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"셔플 사용 설정"</string>
<string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"셔플 사용 중지"</string>
<string name="lb_playback_controls_high_quality_enable" msgid="1862669142355962638">"고품질 사용 설정"</string>
diff --git a/leanback/src/main/res/values-mr/strings.xml b/leanback/src/main/res/values-mr/strings.xml
index 07b4e14..b01e273 100644
--- a/leanback/src/main/res/values-mr/strings.xml
+++ b/leanback/src/main/res/values-mr/strings.xml
@@ -29,7 +29,7 @@
<!-- String.format failed for translation -->
<!-- no translation found for lb_control_display_rewind_multiplier (6173753802428649303) -->
<skip />
- <string name="lb_playback_controls_play" msgid="1590369760862605402">"प्ले"</string>
+ <string name="lb_playback_controls_play" msgid="1590369760862605402">"खेळा"</string>
<string name="lb_playback_controls_pause" msgid="1769131316742618433">"विराम द्या"</string>
<string name="lb_playback_controls_fast_forward" msgid="8966769845721269304">"पुढे ढकला"</string>
<string name="lb_playback_controls_fast_forward_multiplier" msgid="801276177839339511">"फास्ट फॉरवर्ड %1$d"</string>
@@ -38,10 +38,10 @@
<string name="lb_playback_controls_skip_next" msgid="4877009494447817003">"पुढील वगळा"</string>
<string name="lb_playback_controls_skip_previous" msgid="3147124289285911980">"मागील वगळा"</string>
<string name="lb_playback_controls_more_actions" msgid="2827883329510404797">"आणखी क्रिया"</string>
- <string name="lb_playback_controls_thumb_up" msgid="8332816524260995892">"थंब अप निवड रद्द करा"</string>
- <string name="lb_playback_controls_thumb_up_outline" msgid="1038344559734334272">"थंब अप निवडा"</string>
- <string name="lb_playback_controls_thumb_down" msgid="5075744418630733006">"थंब डाउन निवड रद्द करा"</string>
- <string name="lb_playback_controls_thumb_down_outline" msgid="2847309435442474470">"थंब डाउन निवडा"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="8332816524260995892">"वर अंगठा निवड रद्द करा"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1038344559734334272">"वर अंगठा निवडा"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="5075744418630733006">"खाली अंगठा निवड रद्द करा"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2847309435442474470">"खाली अंगठा निवडा"</string>
<string name="lb_playback_controls_repeat_none" msgid="5812341701962930499">"काहीही रिपीट करू नका"</string>
<string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"सर्व रिपीट करा"</string>
<string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"एक रिपीट करा"</string>
diff --git a/leanback/src/main/res/values-or/strings.xml b/leanback/src/main/res/values-or/strings.xml
deleted file mode 100644
index ce6d1ea..0000000
--- a/leanback/src/main/res/values-or/strings.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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="lb_navigation_menu_contentDescription" msgid="8126335323963415494">"ନେଭିଗେଶନ୍ ମେନୁ"</string>
- <string name="orb_search_action" msgid="7534843523462177008">"ଖୋଜିବା କାମ"</string>
- <string name="lb_search_bar_hint" msgid="4819380969103509861">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
- <string name="lb_search_bar_hint_speech" msgid="2795474673510974502">"ଖୋଜିବା ପାଇଁ କୁହନ୍ତୁ"</string>
- <string name="lb_search_bar_hint_with_title" msgid="7453744869467668159">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ଖୋଜନ୍ତୁ"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="5851694095153624617">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ଖୋଜିବା ପାଇଁ କୁହନ୍ତୁ"</string>
- <string name="lb_control_display_fast_forward_multiplier" msgid="2721825378927619928">"%1$dX"</string>
- <string name="lb_control_display_rewind_multiplier" msgid="6173753802428649303">"%1$dX"</string>
- <string name="lb_playback_controls_play" msgid="1590369760862605402">"ଚଲାନ୍ତୁ"</string>
- <string name="lb_playback_controls_pause" msgid="1769131316742618433">"ପଜ୍ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_fast_forward" msgid="8966769845721269304">"ଫାଷ୍ଟ ଫର୍ୱାର୍ଡ"</string>
- <string name="lb_playback_controls_fast_forward_multiplier" msgid="801276177839339511">"%1$dX ବେଗରେ ଫାଷ୍ଟ ଫରୱାର୍ଡ"</string>
- <string name="lb_playback_controls_rewind" msgid="1412664391757869774">"ରିୱାଇଣ୍ଡ"</string>
- <string name="lb_playback_controls_rewind_multiplier" msgid="8651612807713092781">"%1$dX ବେଗରେ ରିୱାଇଣ୍ଡ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_skip_next" msgid="4877009494447817003">"ପରବର୍ତ୍ତୀକୁ ଯାଆନ୍ତୁ"</string>
- <string name="lb_playback_controls_skip_previous" msgid="3147124289285911980">"ପୂର୍ବଟିକୁ ଛାଡ଼ିଦିଅନ୍ତୁ"</string>
- <string name="lb_playback_controls_more_actions" msgid="2827883329510404797">"ଅଧିକ ଗତିବିଧି"</string>
- <string name="lb_playback_controls_thumb_up" msgid="8332816524260995892">"ପସନ୍ଦକୁ ଚୟନ କରନ୍ତୁ ନାହିଁ"</string>
- <string name="lb_playback_controls_thumb_up_outline" msgid="1038344559734334272">"ପସନ୍ଦକୁ ଚୟନ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_thumb_down" msgid="5075744418630733006">"ପସନ୍ଦହୀନକୁ ଚୟନ କରନ୍ତୁ ନାହିଁ"</string>
- <string name="lb_playback_controls_thumb_down_outline" msgid="2847309435442474470">"ପସନ୍ଦହୀନକୁ ଚୟନ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_repeat_none" msgid="5812341701962930499">"କୌଣସିଟି ଦୋହରାନ୍ତୁ ନାହିଁ"</string>
- <string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"ସବୁଗୁଡ଼ିକୁ ଦୋହରାନ୍ତୁ"</string>
- <string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"ଗୋଟିଏ ଦୋହରାନ୍ତୁ"</string>
- <string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"ଅଦଳବଦଳକୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"ଅଦଳବଦଳକୁ ଅକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_high_quality_enable" msgid="1862669142355962638">"ଉଚ୍ଚ କ୍ୱାଲିଟୀକୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"ଉଚ୍ଚ କ୍ୱାଲିଟୀକୁ ଅକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_closed_captioning_enable" msgid="3934392140182327163">"କ୍ଲୋଜଡ୍ କ୍ୟାପ୍ସନିଙ୍ଗକୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_closed_captioning_disable" msgid="5508271941331836786">"କ୍ଲୋଜଡ୍ କ୍ୟାପ୍ସନିଙ୍ଗକୁ ଅକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="lb_playback_controls_picture_in_picture" msgid="8800305194045609275">"ଛବି ଭିତରେ ଛବି ମୋଡ୍ରେ ପ୍ରବେଶ କରନ୍ତୁ"</string>
- <string name="lb_playback_time_separator" msgid="6549544638083578695">"/"</string>
- <string name="lb_playback_controls_shown" msgid="7794717158616536936">"ମିଡିଆ ନିୟନ୍ତ୍ରଣ ଦେଖାଯାଇଛି"</string>
- <string name="lb_playback_controls_hidden" msgid="619396299825306757">"ମିଡିଆ ନିୟନ୍ତ୍ରଣ ଲୁଚିଯାଇଛି, ଦେଖାଇବାକୁ ଡି-ପ୍ୟାଡ୍ ଦବାନ୍ତୁ"</string>
- <string name="lb_guidedaction_finish_title" msgid="7747913934287176843">"ସମାପ୍ତ କରନ୍ତୁ"</string>
- <string name="lb_guidedaction_continue_title" msgid="1122271825827282965">"ଜାରି ରଖନ୍ତୁ"</string>
- <string name="lb_media_player_error" msgid="8748646000835486516">"MediaPlayer ତ୍ରୁଟି କୋଡ୍ %1$d ଅତିରିକ୍ତ %2$d"</string>
- <string name="lb_onboarding_get_started" msgid="7674487829030291492">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
- <string name="lb_onboarding_accessibility_next" msgid="4213611627196077555">"ପରବର୍ତ୍ତୀ"</string>
-</resources>
diff --git a/leanback/src/main/res/values-pt-rBR/strings.xml b/leanback/src/main/res/values-pt-rBR/strings.xml
index 6acead9..01d56cb 100644
--- a/leanback/src/main/res/values-pt-rBR/strings.xml
+++ b/leanback/src/main/res/values-pt-rBR/strings.xml
@@ -41,8 +41,8 @@
<string name="lb_playback_controls_repeat_none" msgid="5812341701962930499">"Não repetir"</string>
<string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"Repetir tudo"</string>
<string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"Repetir um item"</string>
- <string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"Ativar ordem aleatória"</string>
- <string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"Desativar ordem aleatória"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"Ativar reprodução aleatória"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"Desativar reprodução aleatória"</string>
<string name="lb_playback_controls_high_quality_enable" msgid="1862669142355962638">"Ativar alta qualidade"</string>
<string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"Desativar alta qualidade"</string>
<string name="lb_playback_controls_closed_captioning_enable" msgid="3934392140182327163">"Ativar closed captioning"</string>
diff --git a/leanback/src/main/res/values-pt/strings.xml b/leanback/src/main/res/values-pt/strings.xml
index 6acead9..01d56cb 100644
--- a/leanback/src/main/res/values-pt/strings.xml
+++ b/leanback/src/main/res/values-pt/strings.xml
@@ -41,8 +41,8 @@
<string name="lb_playback_controls_repeat_none" msgid="5812341701962930499">"Não repetir"</string>
<string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"Repetir tudo"</string>
<string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"Repetir um item"</string>
- <string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"Ativar ordem aleatória"</string>
- <string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"Desativar ordem aleatória"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"Ativar reprodução aleatória"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"Desativar reprodução aleatória"</string>
<string name="lb_playback_controls_high_quality_enable" msgid="1862669142355962638">"Ativar alta qualidade"</string>
<string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"Desativar alta qualidade"</string>
<string name="lb_playback_controls_closed_captioning_enable" msgid="3934392140182327163">"Ativar closed captioning"</string>
diff --git a/leanback/src/main/res/values-te/strings.xml b/leanback/src/main/res/values-te/strings.xml
index e4ee49e6..312b570 100644
--- a/leanback/src/main/res/values-te/strings.xml
+++ b/leanback/src/main/res/values-te/strings.xml
@@ -55,5 +55,5 @@
<string name="lb_guidedaction_continue_title" msgid="1122271825827282965">"కొనసాగించండి"</string>
<string name="lb_media_player_error" msgid="8748646000835486516">"MediaPlayer ఎర్రర్ కోడ్ %1$d అదనంగా %2$d"</string>
<string name="lb_onboarding_get_started" msgid="7674487829030291492">"ప్రారంభించు"</string>
- <string name="lb_onboarding_accessibility_next" msgid="4213611627196077555">"తర్వాత"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="4213611627196077555">"తదుపరి"</string>
</resources>
diff --git a/leanback/src/main/res/values-uz/strings.xml b/leanback/src/main/res/values-uz/strings.xml
index 95e0b67..50a86af 100644
--- a/leanback/src/main/res/values-uz/strings.xml
+++ b/leanback/src/main/res/values-uz/strings.xml
@@ -21,8 +21,8 @@
<string name="orb_search_action" msgid="7534843523462177008">"Qidiruv amali"</string>
<string name="lb_search_bar_hint" msgid="4819380969103509861">"Qidiruv"</string>
<string name="lb_search_bar_hint_speech" msgid="2795474673510974502">"Qidirish uchun gapiring"</string>
- <string name="lb_search_bar_hint_with_title" msgid="7453744869467668159">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ichidan qidirish"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="5851694095153624617">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ichidan qidirish uchun gapiring"</string>
+ <string name="lb_search_bar_hint_with_title" msgid="7453744869467668159">"Qidirish: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="5851694095153624617">"Qidirish uchun ayting: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_control_display_fast_forward_multiplier" msgid="2721825378927619928">"%1$dX"</string>
<string name="lb_control_display_rewind_multiplier" msgid="6173753802428649303">"%1$dX"</string>
<string name="lb_playback_controls_play" msgid="1590369760862605402">"Ijro"</string>
@@ -39,14 +39,14 @@
<string name="lb_playback_controls_thumb_down" msgid="5075744418630733006">"Salbiy baho tanlovini bekor qilish"</string>
<string name="lb_playback_controls_thumb_down_outline" msgid="2847309435442474470">"Salbiy bahoni tanlash"</string>
<string name="lb_playback_controls_repeat_none" msgid="5812341701962930499">"Takrorlamaslik"</string>
- <string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"Hammasini takrorlash"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"Barchasini takrorlash"</string>
<string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"Bir marta takrorlash"</string>
<string name="lb_playback_controls_shuffle_enable" msgid="7809089255981448519">"Aralashtirish funksiyasini yoqish"</string>
- <string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"Aralashtirmaslik"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8182435535948303910">"Aralashtirish funksiyasini o‘chirish"</string>
<string name="lb_playback_controls_high_quality_enable" msgid="1862669142355962638">"Yuqori sifatni yoqish"</string>
- <string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"Yuqori sifatda ijro qilmaslik"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="3000046054608531995">"Yuqori sifatni o‘chirib qo‘yish"</string>
<string name="lb_playback_controls_closed_captioning_enable" msgid="3934392140182327163">"Taglavhalarni yoqish"</string>
- <string name="lb_playback_controls_closed_captioning_disable" msgid="5508271941331836786">"Taglavhalarni chiqarmaslik"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="5508271941331836786">"Taglavhalarni o‘chirib qo‘yish"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="8800305194045609275">"Tasvir ustida tasvir rejimiga kirish"</string>
<string name="lb_playback_time_separator" msgid="6549544638083578695">"/"</string>
<string name="lb_playback_controls_shown" msgid="7794717158616536936">"Boshqaruv elementlari ochiq"</string>
diff --git a/leanback/src/main/res/values-zh-rCN/strings.xml b/leanback/src/main/res/values-zh-rCN/strings.xml
index 4e6cbd4..9ba86b4 100644
--- a/leanback/src/main/res/values-zh-rCN/strings.xml
+++ b/leanback/src/main/res/values-zh-rCN/strings.xml
@@ -54,6 +54,6 @@
<string name="lb_guidedaction_finish_title" msgid="7747913934287176843">"完成"</string>
<string name="lb_guidedaction_continue_title" msgid="1122271825827282965">"继续"</string>
<string name="lb_media_player_error" msgid="8748646000835486516">"MediaPlayer 错误代码:%1$d extra %2$d"</string>
- <string name="lb_onboarding_get_started" msgid="7674487829030291492">"开始使用"</string>
+ <string name="lb_onboarding_get_started" msgid="7674487829030291492">"开始"</string>
<string name="lb_onboarding_accessibility_next" msgid="4213611627196077555">"继续"</string>
</resources>
diff --git a/leanback/src/main/res/values-zh-rTW/strings.xml b/leanback/src/main/res/values-zh-rTW/strings.xml
index 9aea4d2..bcaf11e 100644
--- a/leanback/src/main/res/values-zh-rTW/strings.xml
+++ b/leanback/src/main/res/values-zh-rTW/strings.xml
@@ -34,10 +34,10 @@
<string name="lb_playback_controls_skip_next" msgid="4877009494447817003">"跳至下一個項目"</string>
<string name="lb_playback_controls_skip_previous" msgid="3147124289285911980">"跳至上一個項目"</string>
<string name="lb_playback_controls_more_actions" msgid="2827883329510404797">"更多動作"</string>
- <string name="lb_playback_controls_thumb_up" msgid="8332816524260995892">"取消選取「喜歡」"</string>
- <string name="lb_playback_controls_thumb_up_outline" msgid="1038344559734334272">"選取「喜歡」"</string>
- <string name="lb_playback_controls_thumb_down" msgid="5075744418630733006">"取消選取「不喜歡」"</string>
- <string name="lb_playback_controls_thumb_down_outline" msgid="2847309435442474470">"選取「不喜歡」"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="8332816524260995892">"取消選取喜歡"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1038344559734334272">"選取喜歡"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="5075744418630733006">"取消選取不喜歡"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2847309435442474470">"選取不喜歡"</string>
<string name="lb_playback_controls_repeat_none" msgid="5812341701962930499">"不重複播放"</string>
<string name="lb_playback_controls_repeat_all" msgid="5164826436271322261">"重複播放所有項目"</string>
<string name="lb_playback_controls_repeat_one" msgid="7675097479246139440">"重複播放單一項目"</string>
diff --git a/lifecycle/viewmodel/ktx/build.gradle b/lifecycle/viewmodel/ktx/build.gradle
deleted file mode 100644
index a963911..0000000
--- a/lifecycle/viewmodel/ktx/build.gradle
+++ /dev/null
@@ -1,49 +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.
- */
-
-import static androidx.build.dependencies.DependenciesKt.*
-import androidx.build.LibraryGroups
-import androidx.build.LibraryVersions
-
-plugins {
- id("SupportAndroidLibraryPlugin")
- id("org.jetbrains.kotlin.android")
-}
-
-android {
- buildTypes {
- debug {
- testCoverageEnabled = false // Breaks Kotlin compiler.
- }
- }
-}
-
-dependencies {
- api(project(":lifecycle:lifecycle-viewmodel"))
- api(KOTLIN_STDLIB)
-
- testImplementation(JUNIT)
- testImplementation(TEST_RUNNER)
-}
-
-supportLibrary {
- name = "Android Lifecycle ViewModel Kotlin Extensions"
- publish = true
- mavenVersion = LibraryVersions.LIFECYCLES_VIEWMODEL
- mavenGroup = LibraryGroups.LIFECYCLE
- inceptionYear = "2018"
- description = "Kotlin extensions for 'viewmodel' artifact"
-}
diff --git a/lifecycle/viewmodel/ktx/src/main/AndroidManifest.xml b/lifecycle/viewmodel/ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 75b1d20..0000000
--- a/lifecycle/viewmodel/ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<manifest package="androidx.lifecycle.viewmodel.ktx"/>
diff --git a/lifecycle/viewmodel/ktx/src/main/java/androidx/lifecycle/ViewModelProvider.kt b/lifecycle/viewmodel/ktx/src/main/java/androidx/lifecycle/ViewModelProvider.kt
deleted file mode 100644
index bc42e1b..0000000
--- a/lifecycle/viewmodel/ktx/src/main/java/androidx/lifecycle/ViewModelProvider.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.lifecycle
-
-import androidx.annotation.MainThread
-
-/**
- * Returns an existing ViewModel or creates a new one in the scope (usually, a fragment or
- * an activity), associated with this `ViewModelProvider`.
- *
- * @see ViewModelProvider.get(Class)
- */
-@MainThread
-inline fun <reified VM : ViewModel> ViewModelProvider.get() = get(VM::class.java)
diff --git a/lifecycle/viewmodel/ktx/src/test/java/androidx/lifecycle/ViewModelProviderTest.kt b/lifecycle/viewmodel/ktx/src/test/java/androidx/lifecycle/ViewModelProviderTest.kt
deleted file mode 100644
index e8e76ce..0000000
--- a/lifecycle/viewmodel/ktx/src/test/java/androidx/lifecycle/ViewModelProviderTest.kt
+++ /dev/null
@@ -1,40 +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.lifecycle
-
-import android.support.test.filters.SmallTest
-import org.junit.Assert.assertNotNull
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-@SmallTest
-class ViewModelProviderTest {
- class TestViewModel : ViewModel()
-
- @Test
- fun providerReifiedGet() {
- val factory = object : ViewModelProvider.Factory {
- override fun <T : ViewModel> create(modelClass: Class<T>) = modelClass.newInstance()
- }
- val provider = ViewModelProvider(ViewModelStore(), factory)
-
- val viewModel = provider.get<TestViewModel>()
- assertNotNull(viewModel)
- }
-}
diff --git a/media-widget/api/current.txt b/media-widget/api/current.txt
deleted file mode 100644
index d81423b..0000000
--- a/media-widget/api/current.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-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);
- method public void onMeasure(int, int);
- method public void requestPlayButtonFocus();
- method public void setOnFullScreenListener(androidx.media.widget.MediaControlView2.OnFullScreenListener);
- }
-
- public static abstract interface MediaControlView2.OnFullScreenListener {
- method public abstract void onFullScreen(android.view.View, boolean);
- }
-
- 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);
- 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 e6ff65d..de3f9d9 100644
--- a/media-widget/build.gradle
+++ b/media-widget/build.gradle
@@ -37,13 +37,10 @@
}
supportLibrary {
- name = "Android Support Media Widget"
+ name = "Android Media Support Library"
publish = true
mavenVersion = LibraryVersions.SUPPORT_LIBRARY
mavenGroup = LibraryGroups.MEDIA
inceptionYear = "2011"
- description = "Android Support Media Widget"
- minSdkVersion = 19
- failOnDeprecationWarnings = false
- failOnDeprecationWarnings = false
+ description = "Android Media Support Library"
}
diff --git a/media-widget/src/androidTest/AndroidManifest.xml b/media-widget/src/androidTest/AndroidManifest.xml
index 5304a48..dd6e9e0 100644
--- a/media-widget/src/androidTest/AndroidManifest.xml
+++ b/media-widget/src/androidTest/AndroidManifest.xml
@@ -1,26 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
+ ~ Copyright 2018 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="androidx.media.widget.test">
<uses-sdk android:targetSdkVersion="${target-sdk-version}"/>
<application>
<activity android:name="androidx.media.widget.VideoView2TestActivity"
- android:theme="@style/Theme.AppCompat"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="VideoView2TestActivity">
<intent-filter>
diff --git a/media-widget/src/androidTest/java/androidx/media/widget/VideoView2Test.java b/media-widget/src/androidTest/java/androidx/media/widget/VideoView2Test.java
index da38bd2..2876e47 100644
--- a/media-widget/src/androidTest/java/androidx/media/widget/VideoView2Test.java
+++ b/media-widget/src/androidTest/java/androidx/media/widget/VideoView2Test.java
@@ -61,7 +61,7 @@
/**
* Test {@link VideoView2}.
*/
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.P) // TODO: KITKAT
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP) // TODO: KITKAT
@LargeTest
@RunWith(AndroidJUnit4.class)
public class VideoView2Test {
@@ -107,17 +107,10 @@
@Override
public void run() {
// Keep screen on while testing.
- if (Build.VERSION.SDK_INT >= 27) {
- mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- mActivity.setTurnScreenOn(true);
- mActivity.setShowWhenLocked(true);
- mKeyguardManager.requestDismissKeyguard(mActivity, null);
- } else {
- mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
- | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
- | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
- | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
- }
+ mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ mActivity.setTurnScreenOn(true);
+ mActivity.setShowWhenLocked(true);
+ mKeyguardManager.requestDismissKeyguard(mActivity, null);
}
});
mInstrumentation.waitForIdleSync();
diff --git a/media-widget/src/androidTest/java/androidx/media/widget/VideoView2TestActivity.java b/media-widget/src/androidTest/java/androidx/media/widget/VideoView2TestActivity.java
index 912d336..d6a3ebc 100644
--- a/media-widget/src/androidTest/java/androidx/media/widget/VideoView2TestActivity.java
+++ b/media-widget/src/androidTest/java/androidx/media/widget/VideoView2TestActivity.java
@@ -16,15 +16,15 @@
package androidx.media.widget;
+import android.app.Activity;
import android.os.Bundle;
-import androidx.fragment.app.FragmentActivity;
import androidx.media.widget.test.R;
/**
* A minimal application for {@link VideoView2} test.
*/
-public class VideoView2TestActivity extends FragmentActivity {
+public class VideoView2TestActivity extends Activity {
/**
* Called with the activity is first created.
*/
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 982513a..0b6988a 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) {
- super(context, attrs);
+ this(context, attrs, 0);
}
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 a8371f2..89fa946 100644
--- a/media-widget/src/main/java/androidx/media/widget/MediaControlView2.java
+++ b/media-widget/src/main/java/androidx/media/widget/MediaControlView2.java
@@ -27,7 +27,6 @@
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;
@@ -52,8 +51,6 @@
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.media.SessionToken2;
-import androidx.mediarouter.app.MediaRouteButton;
-import androidx.mediarouter.media.MediaRouteSelector;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -63,34 +60,41 @@
import java.util.List;
import java.util.Locale;
+// import androidx.mediarouter.app.MediaRouteButton;
+// import androidx.mediarouter.media.MediaRouter;
+// import androidx.mediarouter.media.MediaRouteSelector;
+
/**
- * 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.
+ * @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.
*
* <p>
* <em> MediaControlView2 can be initialized in two different ways: </em>
- * 1) When initializing {@link VideoView2} a default MediaControlView2 is created.
- * 2) Initialize MediaControlView2 programmatically and add it to a {@link ViewGroup} instance.
+ * 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.
*
* In the first option, VideoView2 automatically connects MediaControlView2 to MediaController,
- * 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.
+ * 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).
*
* <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 {@link View#setVisibility(int)}.
- * The values supported are View.VISIBLE and View.GONE.
+ * 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().
*
* <p>
- * In addition, the following customizations are supported:
- * 1) Set focus to the play/pause button by calling requestPlayButtonFocus().
- * 2) Set full screen mode
- *
+ * 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.
*/
@RequiresApi(21) // TODO correct minSdk API use incompatibilities and remove before release.
+@RestrictTo(LIBRARY_GROUP)
public class MediaControlView2 extends BaseLayout {
/**
* @hide
@@ -181,6 +185,10 @@
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";
@@ -188,6 +196,8 @@
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";
@@ -195,6 +205,8 @@
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.
@@ -218,6 +230,7 @@
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;
@@ -233,7 +246,6 @@
private MediaControllerCompat.TransportControls mControls;
private PlaybackStateCompat mPlaybackState;
private MediaMetadataCompat mMetadata;
- private OnFullScreenListener mOnFullScreenListener;
private int mDuration;
private int mPrevState;
private int mPrevWidth;
@@ -249,7 +261,8 @@
private int mSelectedSpeedIndex;
private int mEmbeddedSettingsItemWidth;
private int mFullSettingsItemWidth;
- private int mSettingsItemHeight;
+ private int mEmbeddedSettingsItemHeight;
+ private int mFullSettingsItemHeight;
private int mSettingsWindowMargin;
private int mMediaType;
private int mSizeType;
@@ -271,8 +284,9 @@
private TextView mTitleView;
private View mAdExternalLink;
private ImageButton mBackButton;
- private MediaRouteButton mRouteButton;
- private MediaRouteSelector mRouteSelector;
+ // TODO (b/77158231) revive
+ // private MediaRouteButton mRouteButton;
+ // private MediaRouteSelector mRouteSelector;
// Relating to Center View
private ViewGroup mCenterView;
@@ -340,9 +354,20 @@
public MediaControlView2(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
- super(context, attrs, defStyleAttr);
+ this(context, attrs, defStyleAttr, 0);
+ }
- mResources = context.getResources();
+ 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);
+
+ mResources = getContext().getResources();
// Inflate MediaControlView2 from XML
mRoot = makeControllerView();
addView(mRoot);
@@ -350,10 +375,9 @@
/**
* Sets MediaSession2 token to control corresponding MediaSession2.
- * @hide
*/
- @RestrictTo(LIBRARY_GROUP)
public void setMediaSessionToken(SessionToken2 token) {
+ //mProvider.setMediaSessionToken_impl(token);
}
/**
@@ -361,20 +385,17 @@
* @param l The callback that will be run
*/
public void setOnFullScreenListener(OnFullScreenListener l) {
- mOnFullScreenListener = l;
+ //mProvider.setOnFullScreenListener_impl(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 = mController.getTransportControls();
+ mControls = controller.getTransportControls();
// Set mMetadata and mPlaybackState to existing MediaSession variables since they may
// be called before the callback is called
mPlaybackState = mController.getPlaybackState();
@@ -408,6 +429,8 @@
*/
@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()) {
@@ -494,6 +517,7 @@
return false;
}
+ // TODO: Should this function be removed?
@Override
public boolean onTrackballEvent(MotionEvent ev) {
return false;
@@ -522,13 +546,17 @@
manager.getDefaultDisplay().getSize(screenSize);
int screenWidth = screenSize.x;
int screenHeight = screenSize.y;
- int iconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_size);
+ int fullIconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_full_icon_size);
+ int embeddedIconSize = mResources.getDimensionPixelSize(
+ 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;
- updateLayout(maxIconCount, iconSize, currWidth, currHeight, screenWidth,
- screenHeight);
+ updateLayout(maxIconCount, fullIconSize, embeddedIconSize, marginSize, currWidth,
+ currHeight, screenWidth, screenHeight);
} else if (mMediaType == MEDIA_TYPE_MUSIC) {
if (mNeedUXUpdate) {
@@ -547,12 +575,13 @@
// Max number of icons inside BottomBarRightView for Music mode is 3.
int maxIconCount = 3;
- updateLayout(maxIconCount, iconSize, currWidth, currHeight, screenWidth,
- screenHeight);
+ updateLayout(maxIconCount, fullIconSize, embeddedIconSize, marginSize, currWidth,
+ currHeight, screenWidth, screenHeight);
}
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();
@@ -562,6 +591,7 @@
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
+ // TODO: Merge the below code with disableUnsupportedButtons().
if (mPlayPauseButton != null) {
mPlayPauseButton.setEnabled(enabled);
}
@@ -596,16 +626,19 @@
}
}
+ // TODO (b/77158231) revive once androidx.mediarouter.* packagaes are available.
+ /*
void setRouteSelector(MediaRouteSelector selector) {
mRouteSelector = selector;
if (mRouteSelector != null && !mRouteSelector.isEmpty()) {
- mRouteButton.setRouteSelector(selector);
+ 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
@@ -665,12 +698,14 @@
*
* @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);
@@ -688,7 +723,8 @@
mBackButton.setOnClickListener(mBackListener);
mBackButton.setVisibility(View.GONE);
}
- mRouteButton = v.findViewById(R.id.cast);
+ // TODO (b/77158231) revive
+ // mRouteButton = v.findViewById(R.id.cast);
// Relating to Center View
mCenterView = v.findViewById(R.id.center_view);
@@ -699,7 +735,7 @@
mMinimalExtraView = (LinearLayout) v.findViewById(R.id.minimal_extra_view);
LinearLayout.LayoutParams params =
(LinearLayout.LayoutParams) mMinimalExtraView.getLayoutParams();
- int iconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_size);
+ int iconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_embedded_icon_size);
int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
params.setMargins(0, (iconSize + marginSize * 2) * (-1), 0, 0);
mMinimalExtraView.setLayoutParams(params);
@@ -742,6 +778,7 @@
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) {
@@ -778,8 +815,10 @@
mEmbeddedSettingsItemWidth = mResources.getDimensionPixelSize(
R.dimen.mcv2_embedded_settings_width);
mFullSettingsItemWidth = mResources.getDimensionPixelSize(R.dimen.mcv2_full_settings_width);
- mSettingsItemHeight = mResources.getDimensionPixelSize(
- R.dimen.mcv2_settings_height);
+ mEmbeddedSettingsItemHeight = mResources.getDimensionPixelSize(
+ R.dimen.mcv2_embedded_settings_height);
+ mFullSettingsItemHeight = mResources.getDimensionPixelSize(
+ R.dimen.mcv2_full_settings_height);
mSettingsWindowMargin = (-1) * mResources.getDimensionPixelSize(
R.dimen.mcv2_settings_offset);
mSettingsWindow = new PopupWindow(mSettingsListView, mEmbeddedSettingsItemWidth,
@@ -801,6 +840,13 @@
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);
}
@@ -1032,11 +1078,7 @@
private final OnClickListener mBackListener = new OnClickListener() {
@Override
public void onClick(View v) {
- View parent = (View) getParent();
- if (parent != null) {
- parent.onKeyDown(KeyEvent.KEYCODE_BACK,
- new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
- }
+ // TODO: implement
}
};
@@ -1063,11 +1105,8 @@
private final OnClickListener mFullScreenListener = new OnClickListener() {
@Override
public void onClick(View v) {
- if (mOnFullScreenListener == 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));
@@ -1075,9 +1114,11 @@
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;
- mOnFullScreenListener.onFullScreen(MediaControlView2.this,
- mIsFullScreen);
}
};
@@ -1142,6 +1183,7 @@
mSubSettingsAdapter.setCheckPosition(mSelectedSpeedIndex);
mSettingsMode = SETTINGS_MODE_PLAYBACK_SPEED;
} else if (position == SETTINGS_MODE_HELP) {
+ // TODO: implement this.
mSettingsWindow.dismiss();
return;
}
@@ -1172,6 +1214,7 @@
mSettingsWindow.dismiss();
break;
case SETTINGS_MODE_HELP:
+ // TODO: implement this.
break;
case SETTINGS_MODE_SUBTITLE_TRACK:
if (position != mSelectedSubtitleTrackIndex) {
@@ -1197,6 +1240,7 @@
mSettingsWindow.dismiss();
break;
case SETTINGS_MODE_VIDEO_QUALITY:
+ // TODO: add support for video quality
mSelectedVideoQualityIndex = position;
mSettingsWindow.dismiss();
break;
@@ -1306,14 +1350,21 @@
}
}
- private void updateLayout(int maxIconCount, int iconSize, int currWidth,
- int currHeight, int screenWidth, int screenHeight) {
- int bottomBarRightWidthMax = iconSize * maxIconCount;
+ private void updateLayout(int maxIconCount, int fullIconSize, int embeddedIconSize,
+ int marginSize, int currWidth, int currHeight, int screenWidth, int screenHeight) {
+ int fullBottomBarRightWidthMax = fullIconSize * maxIconCount
+ + marginSize * (maxIconCount * 2);
+ int embeddedBottomBarRightWidthMax = embeddedIconSize * maxIconCount
+ + marginSize * (maxIconCount * 2);
int fullWidth = mTransportControls.getWidth() + mTimeView.getWidth()
- + bottomBarRightWidthMax;
- int embeddedWidth = mTimeView.getWidth() + bottomBarRightWidthMax;
+ + fullBottomBarRightWidthMax;
+ 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);
@@ -1352,11 +1403,6 @@
// Relating to Title Bar
mTitleBar.setVisibility(View.VISIBLE);
mBackButton.setVisibility(View.GONE);
- mTitleView.setPadding(
- mResources.getDimensionPixelSize(R.dimen.mcv2_embedded_icon_padding),
- mTitleView.getPaddingTop(),
- mTitleView.getPaddingRight(),
- mTitleView.getPaddingBottom());
// Relating to Full Screen Button
mMinimalExtraView.setVisibility(View.GONE);
@@ -1385,11 +1431,6 @@
// Relating to Title Bar
mTitleBar.setVisibility(View.VISIBLE);
mBackButton.setVisibility(View.VISIBLE);
- mTitleView.setPadding(
- 0,
- mTitleView.getPaddingTop(),
- mTitleView.getPaddingRight(),
- mTitleView.getPaddingBottom());
// Relating to Full Screen Button
mMinimalExtraView.setVisibility(View.GONE);
@@ -1482,6 +1523,7 @@
mRewButton.setVisibility(View.GONE);
}
}
+ // TODO: Add support for Next and Previous buttons
mNextButton = v.findViewById(R.id.next);
if (mNextButton != null) {
mNextButton.setOnClickListener(mNextListener);
@@ -1548,12 +1590,15 @@
mSettingsWindow.setWidth(itemWidth);
// Calculate height of window and show
- int totalHeight = adapter.getCount() * mSettingsItemHeight;
+ int itemHeight = (mSizeType == SIZE_TYPE_EMBEDDED)
+ ? mEmbeddedSettingsItemHeight : mFullSettingsItemHeight;
+ int totalHeight = adapter.getCount() * itemHeight;
mSettingsWindow.dismiss();
mSettingsWindow.showAsDropDown(this, mSettingsWindowMargin,
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) {
@@ -1625,12 +1670,16 @@
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);
}
@@ -1659,6 +1708,7 @@
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);
@@ -1737,12 +1787,14 @@
@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;
}
@@ -1786,6 +1838,7 @@
}
}
+ // TODO: extend this class from SettingsAdapter
private class SubSettingsAdapter extends BaseAdapter {
private List<String> mTexts;
private int mCheckPosition;
@@ -1812,12 +1865,14 @@
@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/RoutePlayer.java b/media-widget/src/main/java/androidx/media/widget/RoutePlayer.java
deleted file mode 100644
index 00ac36a..0000000
--- a/media-widget/src/main/java/androidx/media/widget/RoutePlayer.java
+++ /dev/null
@@ -1,215 +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.media.widget;
-
-import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.content.Context;
-import android.media.session.MediaSession;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.v4.media.session.PlaybackStateCompat;
-
-import androidx.annotation.RequiresApi;
-import androidx.annotation.RestrictTo;
-import androidx.mediarouter.media.MediaItemStatus;
-import androidx.mediarouter.media.MediaRouter;
-import androidx.mediarouter.media.MediaSessionStatus;
-import androidx.mediarouter.media.RemotePlaybackClient;
-import androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback;
-import androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback;
-import androidx.mediarouter.media.RemotePlaybackClient.StatusCallback;
-
-/**
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
-public class RoutePlayer extends MediaSession.Callback {
- public static final long PLAYBACK_ACTIONS = PlaybackStateCompat.ACTION_PAUSE
- | PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_SEEK_TO
- | PlaybackStateCompat.ACTION_FAST_FORWARD | PlaybackStateCompat.ACTION_REWIND;
-
- private RemotePlaybackClient mClient;
- private String mSessionId;
- private String mItemId;
- private PlayerEventCallback mCallback;
-
- private StatusCallback mStatusCallback = new StatusCallback() {
- @Override
- public void onItemStatusChanged(Bundle data,
- String sessionId, MediaSessionStatus sessionStatus,
- String itemId, MediaItemStatus itemStatus) {
- updateSessionStatus(sessionId, sessionStatus);
- updateItemStatus(itemId, itemStatus);
- }
- };
-
- public RoutePlayer(Context context, MediaRouter.RouteInfo route) {
- mClient = new RemotePlaybackClient(context, route);
- mClient.setStatusCallback(mStatusCallback);
- if (mClient.isSessionManagementSupported()) {
- mClient.startSession(null, new SessionActionCallback() {
- @Override
- public void onResult(Bundle data,
- String sessionId, MediaSessionStatus sessionStatus) {
- updateSessionStatus(sessionId, sessionStatus);
- }
- });
- }
- }
-
- @Override
- public void onPlay() {
- if (mClient.isSessionManagementSupported()) {
- mClient.resume(null, new SessionActionCallback() {
- @Override
- public void onResult(Bundle data,
- String sessionId, MediaSessionStatus sessionStatus) {
- updateSessionStatus(sessionId, sessionStatus);
- }
- });
- }
- }
-
- @Override
- public void onPause() {
- if (mClient.isSessionManagementSupported()) {
- mClient.pause(null, new SessionActionCallback() {
- @Override
- public void onResult(Bundle data,
- String sessionId, MediaSessionStatus sessionStatus) {
- updateSessionStatus(sessionId, sessionStatus);
- }
- });
- }
- }
-
- @Override
- public void onSeekTo(long pos) {
- if (mClient.isSessionManagementSupported()) {
- mClient.seek(mItemId, pos, null, new ItemActionCallback() {
- @Override
- public void onResult(Bundle data,
- String sessionId, MediaSessionStatus sessionStatus,
- String itemId, MediaItemStatus itemStatus) {
- updateSessionStatus(sessionId, sessionStatus);
- updateItemStatus(itemId, itemStatus);
- }
- });
- }
- }
-
- @Override
- public void onStop() {
- if (mClient.isSessionManagementSupported()) {
- mClient.stop(null, new SessionActionCallback() {
- @Override
- public void onResult(Bundle data,
- String sessionId, MediaSessionStatus sessionStatus) {
- updateSessionStatus(sessionId, sessionStatus);
- }
- });
- }
- }
-
- /**
- * Sets a callback to be notified of events for this player.
- * @param callback the callback to receive the events.
- */
- public void setPlayerEventCallback(PlayerEventCallback callback) {
- mCallback = callback;
- }
-
- // b/77556429
-// public void openVideo(DataSourceDesc dsd) {
-// mClient.play(dsd.getUri(), "video/mp4", null, 0, null, new ItemActionCallback() {
-// @Override
-// public void onResult(Bundle data,
-// String sessionId, MediaSessionStatus sessionStatus,
-// String itemId, MediaItemStatus itemStatus) {
-// updateSessionStatus(sessionId, sessionStatus);
-// updateItemStatus(itemId, itemStatus);
-// playInternal(dsd.getUri());
-// }
-// });
-// }
-
- /**
- * Opens the video based on the given uri and updates the media session and item statuses.
- * @param uri link to the video
- */
- public void openVideo(Uri uri) {
- mClient.play(uri, "video/mp4", null, 0, null, new ItemActionCallback() {
- @Override
- public void onResult(Bundle data,
- String sessionId, MediaSessionStatus sessionStatus,
- String itemId, MediaItemStatus itemStatus) {
- updateSessionStatus(sessionId, sessionStatus);
- updateItemStatus(itemId, itemStatus);
- }
- });
- }
-
- /**
- * Releases the {@link RemotePlaybackClient} and {@link PlayerEventCallback} instances.
- */
- public void release() {
- if (mClient != null) {
- mClient.release();
- mClient = null;
- }
- if (mCallback != null) {
- mCallback = null;
- }
- }
-
- private void playInternal(Uri uri) {
- mClient.play(uri, "video/mp4", null, 0, null, new ItemActionCallback() {
- @Override
- public void onResult(Bundle data,
- String sessionId, MediaSessionStatus sessionStatus,
- String itemId, MediaItemStatus itemStatus) {
- updateSessionStatus(sessionId, sessionStatus);
- updateItemStatus(itemId, itemStatus);
- }
- });
- }
-
- private void updateSessionStatus(String sessionId, MediaSessionStatus sessionStatus) {
- mSessionId = sessionId;
- }
-
- private void updateItemStatus(String itemId, MediaItemStatus itemStatus) {
- mItemId = itemId;
- if (itemStatus == null || mCallback == null) return;
- mCallback.onPlayerStateChanged(itemStatus);
- }
-
- /**
- * A callback class to receive notifications for events on the route player.
- */
- public abstract static class PlayerEventCallback {
- /**
- * Override to handle changes in playback state.
- *
- * @param itemStatus The new MediaItemStatus of the RoutePlayer
- */
- public void onPlayerStateChanged(MediaItemStatus itemStatus) { }
- }
-}
diff --git a/media-widget/src/main/java/androidx/media/widget/SubtitleView.java b/media-widget/src/main/java/androidx/media/widget/SubtitleView.java
deleted file mode 100644
index 1faff2f..0000000
--- a/media-widget/src/main/java/androidx/media/widget/SubtitleView.java
+++ /dev/null
@@ -1,144 +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.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/impl_with_mp1/VideoSurfaceViewWithMp1.java b/media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java
similarity index 82%
rename from media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoSurfaceViewWithMp1.java
rename to media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java
index 740d908..d417bd2 100644
--- a/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoSurfaceViewWithMp1.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoSurfaceView.java
@@ -21,6 +21,7 @@
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,24 +31,39 @@
import androidx.annotation.RequiresApi;
@RequiresApi(21)
-class VideoSurfaceViewWithMp1 extends SurfaceView
- implements VideoViewInterfaceWithMp1, SurfaceHolder.Callback {
- private static final String TAG = "VideoSurfaceViewWithMp1";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+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);
private SurfaceHolder mSurfaceHolder = null;
private SurfaceListener mSurfaceListener = null;
private MediaPlayer mMediaPlayer;
// A flag to indicate taking over other view should be proceed.
private boolean mIsTakingOverOldView;
- private VideoViewInterfaceWithMp1 mOldView;
+ private VideoViewInterface mOldView;
- VideoSurfaceViewWithMp1(Context context) {
- super(context, null);
+
+ 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);
getHolder().addCallback(this);
}
////////////////////////////////////////////////////
- // implements VideoViewInterfaceWithMp1
+ // implements VideoViewInterface
////////////////////////////////////////////////////
@Override
@@ -79,7 +95,7 @@
}
@Override
- public void takeOver(@NonNull VideoViewInterfaceWithMp1 oldView) {
+ public void takeOver(@NonNull VideoViewInterface oldView) {
if (assignSurfaceToMediaPlayer(mMediaPlayer)) {
((View) oldView).setVisibility(GONE);
mIsTakingOverOldView = false;
@@ -134,6 +150,7 @@
}
}
+ // TODO: Investigate the way to move onMeasure() code into FrameLayout.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int videoWidth = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoWidth();
@@ -177,4 +194,10 @@
Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
}
}
+
+ @Override
+ public String toString() {
+ return "ViewType: SurfaceView / Visibility: " + getVisibility()
+ + " / surfaceHolder: " + mSurfaceHolder;
+ }
}
diff --git a/media-widget/src/main/java/androidx/media/widget/impl/VideoTextureView.java b/media-widget/src/main/java/androidx/media/widget/VideoTextureView.java
similarity index 87%
rename from media-widget/src/main/java/androidx/media/widget/impl/VideoTextureView.java
rename to media-widget/src/main/java/androidx/media/widget/VideoTextureView.java
index 3726047..cdc833b 100644
--- a/media-widget/src/main/java/androidx/media/widget/impl/VideoTextureView.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoTextureView.java
@@ -20,6 +20,8 @@
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;
@@ -27,32 +29,44 @@
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
-import androidx.media.MediaPlayer2;
@RequiresApi(21)
class VideoTextureView extends TextureView
implements VideoViewInterface, TextureView.SurfaceTextureListener {
- private static final String TAG = "VideoTextureViewWithMp1";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final String TAG = "VideoTextureView";
+ private static final boolean DEBUG = true; // STOPSHIP: Log.isLoggable(TAG, Log.DEBUG);
private Surface mSurface;
private SurfaceListener mSurfaceListener;
- private MediaPlayer2 mMediaPlayer;
+ private MediaPlayer mMediaPlayer;
// A flag to indicate taking over other view should be proceed.
private boolean mIsTakingOverOldView;
private VideoViewInterface mOldView;
VideoTextureView(Context context) {
- super(context, null);
+ 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);
setSurfaceTextureListener(this);
}
////////////////////////////////////////////////////
- // implements VideoViewInterfaceWithMp1
+ // implements VideoViewInterface
////////////////////////////////////////////////////
@Override
- public boolean assignSurfaceToMediaPlayer(MediaPlayer2 mp) {
+ public boolean assignSurfaceToMediaPlayer(MediaPlayer mp) {
if (mp == null || !hasAvailableSurface()) {
// Surface is not ready.
return false;
@@ -72,7 +86,7 @@
}
@Override
- public void setMediaPlayer(MediaPlayer2 mp) {
+ public void setMediaPlayer(MediaPlayer mp) {
mMediaPlayer = mp;
if (mIsTakingOverOldView) {
takeOver(mOldView);
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 a851370..a8ea450 100644
--- a/media-widget/src/main/java/androidx/media/widget/VideoView2.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoView2.java
@@ -19,17 +19,38 @@
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Point;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.media.AudioAttributes;
+import android.media.AudioFocusRequest;
import android.media.AudioManager;
+import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
+import android.media.PlaybackParams;
import android.net.Uri;
import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaControllerCompat.PlaybackInfo;
+import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.ImageView;
+import android.widget.TextView;
import android.widget.VideoView;
import androidx.annotation.IntDef;
@@ -38,21 +59,25 @@
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
-import androidx.media.AudioAttributesCompat;
import androidx.media.DataSourceDesc;
import androidx.media.MediaItem2;
import androidx.media.MediaMetadata2;
import androidx.media.SessionToken2;
+import androidx.palette.graphics.Palette;
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
+// TODO: Replace MediaSession wtih MediaSession2 once MediaSession2 is submitted.
/**
- * 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.
+ * @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.
*
* <p>
* <em> Data sources that VideoView2 supports : </em>
@@ -73,12 +98,20 @@
* VideoView2 covers and inherits the most of
* VideoView's functionalities. The main differences are
* <ul>
- * <li> VideoView2 inherits ViewGroup and renders videos using SurfaceView and TextureView
+ * <li> VideoView2 inherits FrameLayout 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.
- * <li> If a developer wants to attach a customed MediaControlView2,
- * assign the customed media control widget using {@link #setMediaControlView2}.
+ * 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>
+ * <VideoView2
+ * android:id="@+id/video_view"
+ * xmlns:widget="http://schemas.android.com/apk/com.android.media.update"
+ * widget:enableControlView="false" />
+ * </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.
* <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.
@@ -101,7 +134,8 @@
* {@link android.app.Activity#onRestoreInstanceState}.
*/
@RequiresApi(21) // TODO correct minSdk API use incompatibilities and remove before release.
-public class VideoView2 extends BaseLayout {
+@RestrictTo(LIBRARY_GROUP)
+public class VideoView2 extends BaseLayout implements VideoViewInterface.SurfaceListener {
/** @hide */
@RestrictTo(LIBRARY_GROUP)
@IntDef({
@@ -126,10 +160,171 @@
public static final int VIEW_TYPE_TEXTUREVIEW = 1;
private static final String TAG = "VideoView2";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final boolean USE_MP2 = Log.isLoggable("VV2MP2", Log.DEBUG);
+ private static final boolean DEBUG = true; // STOPSHIP: Log.isLoggable(TAG, Log.DEBUG);
+ private static final long DEFAULT_SHOW_CONTROLLER_INTERVAL_MS = 2000;
- private VideoView2Impl mImpl;
+ private static final int STATE_ERROR = -1;
+ private static final int STATE_IDLE = 0;
+ private static final int STATE_PREPARING = 1;
+ private static final int STATE_PREPARED = 2;
+ private static final int STATE_PLAYING = 3;
+ private static final int STATE_PAUSED = 4;
+ private static final int STATE_PLAYBACK_COMPLETED = 5;
+
+ private static final int INVALID_TRACK_INDEX = -1;
+ private static final float INVALID_SPEED = 0f;
+
+ 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;
+ private AudioManager mAudioManager;
+ private AudioAttributes mAudioAttributes;
+ private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain
+ private boolean mAudioFocused = false;
+
+ private Pair<Executor, OnCustomActionListener> mCustomActionListenerRecord;
+ private OnViewTypeChangedListener mViewTypeChangedListener;
+ private OnFullScreenRequestListener mFullScreenRequestListener;
+
+ private VideoViewInterface mCurrentView;
+ private VideoTextureView mTextureView;
+ private VideoSurfaceView mSurfaceView;
+
+ private MediaPlayer mMediaPlayer;
+ private DataSourceDesc mDsd;
+ private MediaControlView2 mMediaControlView;
+ private MediaSessionCompat mMediaSession;
+ private MediaControllerCompat mMediaController;
+ private MediaMetadata2 mMediaMetadata;
+ private MediaMetadataRetriever mRetriever;
+ private boolean mNeedUpdateMediaType;
+ 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;
+ private Drawable mMusicAlbumDrawable;
+ private String mMusicTitleText;
+ private String mMusicArtistText;
+ private boolean mIsMusicMediaType;
+ private int mPrevWidth;
+ private int mPrevHeight;
+ private int mDominantColor;
+ private int mSizeType;
+
+ private PlaybackStateCompat.Builder mStateBuilder;
+ private List<PlaybackStateCompat.CustomAction> mCustomActionList;
+
+ private int mTargetState = STATE_IDLE;
+ private int mCurrentState = STATE_IDLE;
+ private int mCurrentBufferPercentage;
+ private long mSeekWhenPrepared; // recording the seek position while preparing
+
+ private int mVideoWidth;
+ private int mVideoHeight;
+
+ private ArrayList<Integer> mVideoTrackIndices;
+ private ArrayList<Integer> mAudioTrackIndices;
+ // 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 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);
@@ -140,20 +335,86 @@
}
public VideoView2(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- if (android.os.Build.VERSION.SDK_INT >= 28) {
- if (USE_MP2) {
- Log.d(TAG, "Create VideoView2ImplBase");
- mImpl = new VideoView2ImplBase();
- } else {
- Log.d(TAG, "Create VideoView2ImplApi28WithMp1");
- mImpl = new VideoView2ImplApi28WithMp1();
- }
- } else {
- Log.d(TAG, "Create VideoView2ImplBaseWithMp1");
- mImpl = new VideoView2ImplBaseWithMp1();
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public VideoView2(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ 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(
+ Context.ACCESSIBILITY_SERVICE);
+
+ mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ mAudioAttributes = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA)
+ .setContentType(AudioAttributes.CONTENT_TYPE_MOVIE).build();
+ setFocusable(true);
+ 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());
+ LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT);
+ mTextureView.setLayoutParams(params);
+ mSurfaceView.setLayoutParams(params);
+ mTextureView.setSurfaceListener(this);
+ mSurfaceView.setSurfaceListener(this);
+
+ addView(mTextureView);
+ addView(mSurfaceView);
+
+ // mSubtitleView = new SubtitleView(getContext());
+ // 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());
}
- mImpl.initialize(this, context, attrs, defStyleAttr);
+
+ 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(
+ "http://schemas.android.com/apk/res/android",
+ "viewType", VideoView2.VIEW_TYPE_SURFACEVIEW);
+ if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
+ Log.d(TAG, "viewType attribute is surfaceView.");
+ mTextureView.setVisibility(View.GONE);
+ mSurfaceView.setVisibility(View.VISIBLE);
+ mCurrentView = mSurfaceView;
+ } else if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
+ Log.d(TAG, "viewType attribute is textureView.");
+ mTextureView.setVisibility(View.VISIBLE);
+ 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();
+ */
}
/**
@@ -164,7 +425,15 @@
* @param intervalMs a time interval in milliseconds until VideoView2 hides MediaControlView2.
*/
public void setMediaControlView2(MediaControlView2 mediaControlView, long intervalMs) {
- mImpl.setMediaControlView2(mediaControlView, intervalMs);
+ mMediaControlView = mediaControlView;
+ mShowControllerIntervalMs = intervalMs;
+ // TODO: Call MediaControlView2.setRouteSelector only when cast availalbe.
+ // TODO (b/77158231)
+ // mMediaControlView.setRouteSelector(mRouteSelector);
+
+ if (isAttachedToWindow()) {
+ attachMediaControlView();
+ }
}
/**
@@ -172,7 +441,7 @@
* {@link #setMediaControlView2} method.
*/
public MediaControlView2 getMediaControlView2() {
- return mImpl.getMediaControlView2();
+ return mMediaControlView;
}
/**
@@ -194,7 +463,7 @@
*/
@RestrictTo(LIBRARY_GROUP)
public MediaMetadata2 getMediaMetadata() {
- return mImpl.getMediaMetadata();
+ return mMediaMetadata;
}
/**
@@ -209,7 +478,10 @@
*/
@RestrictTo(LIBRARY_GROUP)
public MediaControllerCompat getMediaController() {
- return mImpl.getMediaController();
+ if (mMediaSession == null) {
+ throw new IllegalStateException("MediaSession instance is not available.");
+ }
+ return mMediaController;
}
/**
@@ -222,6 +494,7 @@
*/
@RestrictTo(LIBRARY_GROUP)
public SessionToken2 getMediaSessionToken() {
+ //return mProvider.getMediaSessionToken_impl();
return null;
}
@@ -232,7 +505,10 @@
* @param enable shows closed caption or subtitles if this value is true, or hides.
*/
public void setSubtitleEnabled(boolean enable) {
- mImpl.setSubtitleEnabled(enable);
+ if (enable != mSubtitleEnabled) {
+ selectOrDeselectSubtitle(enable);
+ }
+ mSubtitleEnabled = enable;
}
/**
@@ -241,7 +517,7 @@
* has been enabled by {@link #setSubtitleEnabled}.
*/
public boolean isSubtitleEnabled() {
- return mImpl.isSubtitleEnabled();
+ return mSubtitleEnabled;
}
/**
@@ -253,18 +529,17 @@
* 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) {
- mImpl.setSpeed(speed);
- }
-
- /**
- * 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 mImpl.getSpeed();
+ if (speed <= 0.0f) {
+ Log.e(TAG, "Unsupported speed (" + speed + ") is ignored.");
+ return;
+ }
+ mSpeed = speed;
+ if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
+ applySpeed();
+ }
+ updatePlaybackState();
}
/**
@@ -283,7 +558,14 @@
* playback.
*/
public void setAudioFocusRequest(int focusGain) {
- mImpl.setAudioFocusRequest(focusGain);
+ if (focusGain != AudioManager.AUDIOFOCUS_NONE
+ && focusGain != AudioManager.AUDIOFOCUS_GAIN
+ && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
+ && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
+ && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) {
+ throw new IllegalArgumentException("Illegal audio focus type " + focusGain);
+ }
+ mAudioFocusType = focusGain;
}
/**
@@ -292,19 +574,10 @@
* @param attributes non-null <code>AudioAttributes</code>.
*/
public void setAudioAttributes(@NonNull AudioAttributes attributes) {
- mImpl.setAudioAttributes(AudioAttributesCompat.wrap(attributes));
- }
-
- /**
- * Sets the {@link AudioAttributesCompat} to be used during the playback of the video.
- *
- * @param attributes non-null <code>AudioAttributesCompat</code>.
- *
- * @hide TODO unhide and remove setAudioAttributes with framework attributes
- */
- @RestrictTo(LIBRARY_GROUP)
- public void setAudioAttributes(@NonNull AudioAttributesCompat attributes) {
- mImpl.setAudioAttributes(attributes);
+ if (attributes == null) {
+ throw new IllegalArgumentException("Illegal null AudioAttributes");
+ }
+ mAudioAttributes = attributes;
}
/**
@@ -312,11 +585,11 @@
*
* @param path the path of the video.
*
- * @hide
+ * @hide TODO remove
*/
@RestrictTo(LIBRARY_GROUP)
public void setVideoPath(String path) {
- mImpl.setVideoUri(Uri.parse(path));
+ setVideoUri(Uri.parse(path));
}
/**
@@ -324,11 +597,11 @@
*
* @param uri the URI of the video.
*
- * @hide
+ * @hide TODO remove
*/
@RestrictTo(LIBRARY_GROUP)
public void setVideoUri(Uri uri) {
- mImpl.setVideoUri(uri, null);
+ setVideoUri(uri, null);
}
/**
@@ -340,9 +613,13 @@
* 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
*/
- public void setVideoUri(Uri uri, @Nullable Map<String, String> headers) {
- mImpl.setVideoUri(uri, headers);
+ @RestrictTo(LIBRARY_GROUP)
+ public void setVideoUri(Uri uri, Map<String, String> headers) {
+ mSeekWhenPrepared = 0;
+ openVideo(uri, headers);
}
/**
@@ -350,11 +627,9 @@
* 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);
}
/**
@@ -365,6 +640,7 @@
*/
@RestrictTo(LIBRARY_GROUP)
public void setDataSource(@NonNull DataSourceDesc dataSource) {
+ //mProvider.setDataSource_impl(dataSource);
}
/**
@@ -377,7 +653,22 @@
* </ul>
*/
public void setViewType(@ViewType int viewType) {
- mImpl.setViewType(viewType);
+ if (viewType == mCurrentView.getViewType()) {
+ return;
+ }
+ VideoViewInterface targetView;
+ if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
+ Log.d(TAG, "switching to TextureView");
+ targetView = mTextureView;
+ } else if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
+ Log.d(TAG, "switching to SurfaceView");
+ targetView = mSurfaceView;
+ } else {
+ throw new IllegalArgumentException("Unknown view type: " + viewType);
+ }
+ ((View) targetView).setVisibility(View.VISIBLE);
+ targetView.takeOver(mCurrentView);
+ requestLayout();
}
/**
@@ -387,7 +678,7 @@
*/
@ViewType
public int getViewType() {
- return mImpl.getViewType();
+ return mCurrentView.getViewType();
}
/**
@@ -398,12 +689,17 @@
* 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
+ * @hide TODO remove
*/
@RestrictTo(LIBRARY_GROUP)
public void setCustomActions(List<PlaybackStateCompat.CustomAction> actionList,
Executor executor, OnCustomActionListener listener) {
- mImpl.setCustomActions(actionList, executor, listener);
+ mCustomActionList = actionList;
+ mCustomActionListenerRecord = new Pair<>(executor, listener);
+
+ // Create a new playback builder in order to clear existing the custom actions.
+ mStateBuilder = null;
+ updatePlaybackState();
}
/**
@@ -415,19 +711,54 @@
@VisibleForTesting
@RestrictTo(LIBRARY_GROUP)
public void setOnViewTypeChangedListener(OnViewTypeChangedListener l) {
- mImpl.setOnViewTypeChangedListener(l);
+ 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();
- mImpl.onAttachedToWindowImpl();
+
+ // Create MediaSession
+ mMediaSession = new MediaSessionCompat(getContext(), "VideoView2MediaSession");
+ 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();
+ extractAudioMetadata();
+ if (mNeedUpdateMediaType) {
+ mMediaSession.sendSessionEvent(
+ MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS,
+ mMediaTypeData);
+ mNeedUpdateMediaType = false;
+ }
+ }
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
- mImpl.onDetachedFromWindowImpl();
+
+ mMediaSession.release();
+ mMediaSession = null;
+ mMediaController = null;
}
@Override
@@ -437,25 +768,76 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
- mImpl.onTouchEventImpl(ev);
+ if (DEBUG) {
+ Log.d(TAG, "onTouchEvent(). mCurrentState=" + mCurrentState
+ + ", mTargetState=" + mTargetState);
+ }
+ if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
+ if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
+ toggleMediaControlViewVisibility();
+ }
+ }
+
return super.onTouchEvent(ev);
}
@Override
public boolean onTrackballEvent(MotionEvent ev) {
- mImpl.onTrackballEventImpl(ev);
+ if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
+ if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
+ toggleMediaControlViewVisibility();
+ }
+ }
+
return super.onTrackballEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
+ // TODO: Test touch event handling logic thoroughly and simplify the logic.
return super.dispatchTouchEvent(ev);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- mImpl.onMeasureImpl(widthMeasureSpec, heightMeasureSpec);
+
+ if (mIsMusicMediaType) {
+ if (mPrevWidth != getMeasuredWidth()
+ || mPrevHeight != getMeasuredHeight()) {
+ int currWidth = getMeasuredWidth();
+ int currHeight = getMeasuredHeight();
+ Point screenSize = new Point();
+ mManager.getDefaultDisplay().getSize(screenSize);
+ int screenWidth = screenSize.x;
+ int screenHeight = screenSize.y;
+
+ if (currWidth == screenWidth && currHeight == screenHeight) {
+ int orientation = retrieveOrientation();
+ if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
+ inflateMusicView(R.layout.full_landscape_music);
+ } else {
+ inflateMusicView(R.layout.full_portrait_music);
+ }
+
+ if (mSizeType != SIZE_TYPE_FULL) {
+ mSizeType = SIZE_TYPE_FULL;
+ // Remove existing mFadeOut callback
+ mMediaControlView.removeCallbacks(mFadeOut);
+ mMediaControlView.setVisibility(View.VISIBLE);
+ }
+ } else {
+ if (mSizeType != SIZE_TYPE_EMBEDDED) {
+ mSizeType = SIZE_TYPE_EMBEDDED;
+ inflateMusicView(R.layout.embedded_music);
+ // Add new mFadeOut callback
+ mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
+ }
+ }
+ mPrevWidth = currWidth;
+ mPrevHeight = currHeight;
+ }
+ }
}
/**
@@ -463,6 +845,7 @@
*
* @hide
*/
+ @VisibleForTesting
@RestrictTo(LIBRARY_GROUP)
public interface OnViewTypeChangedListener {
/**
@@ -479,6 +862,19 @@
}
/**
+ * 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
*/
@@ -493,4 +889,901 @@
*/
void onCustomAction(String action, Bundle extras);
}
+
+ ///////////////////////////////////////////////////
+ // Implements VideoViewInterface.SurfaceListener
+ ///////////////////////////////////////////////////
+
+ @Override
+ public void onSurfaceCreated(View view, int width, int height) {
+ if (DEBUG) {
+ Log.d(TAG, "onSurfaceCreated(). mCurrentState=" + mCurrentState
+ + ", mTargetState=" + mTargetState + ", width/height: " + width + "/" + height
+ + ", " + view.toString());
+ }
+ if (needToStart()) {
+ mMediaController.getTransportControls().play();
+ }
+ }
+
+ @Override
+ public void onSurfaceDestroyed(View view) {
+ if (DEBUG) {
+ Log.d(TAG, "onSurfaceDestroyed(). mCurrentState=" + mCurrentState
+ + ", mTargetState=" + mTargetState + ", " + view.toString());
+ }
+ }
+
+ @Override
+ 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());
+ }
+ }
+
+ @Override
+ public void onSurfaceTakeOverDone(VideoViewInterface view) {
+ if (DEBUG) {
+ Log.d(TAG, "onSurfaceTakeOverDone(). Now current view is: " + view);
+ }
+ mCurrentView = view;
+ if (mViewTypeChangedListener != null) {
+ mViewTypeChangedListener.onViewTypeChanged(this, view.getViewType());
+ }
+ if (needToStart()) {
+ mMediaController.getTransportControls().play();
+ }
+ }
+
+ ///////////////////////////////////////////////////
+ // Protected or private methods
+ ///////////////////////////////////////////////////
+
+ private void attachMediaControlView() {
+ // Get MediaController from MediaSession and set it inside MediaControlView
+ mMediaControlView.setController(mMediaSession.getController());
+
+ LayoutParams params =
+ new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+ addView(mMediaControlView, params);
+ }
+
+ private boolean isInPlaybackState() {
+ // TODO (b/77158231)
+ // return (mMediaPlayer != null || mRoutePlayer != null)
+ return (mMediaPlayer != null)
+ && mCurrentState != STATE_ERROR
+ && mCurrentState != STATE_IDLE
+ && mCurrentState != STATE_PREPARING;
+ }
+
+ private boolean needToStart() {
+ // TODO (b/77158231)
+ // return (mMediaPlayer != null || mRoutePlayer != null)
+ return (mMediaPlayer != null)
+ && isAudioGranted()
+ && isWaitingPlayback();
+ }
+
+ private boolean isWaitingPlayback() {
+ return mCurrentState != STATE_PLAYING && mTargetState == STATE_PLAYING;
+ }
+
+ private boolean isAudioGranted() {
+ return mAudioFocused || mAudioFocusType == AudioManager.AUDIOFOCUS_NONE;
+ }
+
+ AudioManager.OnAudioFocusChangeListener mAudioFocusListener =
+ new AudioManager.OnAudioFocusChangeListener() {
+ @Override
+ public void onAudioFocusChange(int focusChange) {
+ switch (focusChange) {
+ case AudioManager.AUDIOFOCUS_GAIN:
+ mAudioFocused = true;
+ if (needToStart()) {
+ mMediaController.getTransportControls().play();
+ }
+ break;
+ 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();
+ } else {
+ mTargetState = STATE_PAUSED;
+ }
+ }
+ }
+ };
+
+ @SuppressWarnings("deprecation")
+ private void requestAudioFocus(int focusType) {
+ int result;
+ if (android.os.Build.VERSION.SDK_INT >= 26) {
+ AudioFocusRequest focusRequest;
+ focusRequest = new AudioFocusRequest.Builder(focusType)
+ .setAudioAttributes(mAudioAttributes)
+ .setOnAudioFocusChangeListener(mAudioFocusListener)
+ .build();
+ result = mAudioManager.requestAudioFocus(focusRequest);
+ } else {
+ result = mAudioManager.requestAudioFocus(mAudioFocusListener,
+ AudioManager.STREAM_MUSIC,
+ focusType);
+ }
+ if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
+ mAudioFocused = false;
+ } else if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+ mAudioFocused = true;
+ } else if (result == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
+ mAudioFocused = false;
+ }
+ }
+
+ // Creates a MediaPlayer instance and prepare playback.
+ private void openVideo(Uri uri, Map<String, String> headers) {
+ resetPlayer();
+ if (isRemotePlayback()) {
+ // TODO (b/77158231)
+ // mRoutePlayer.openVideo(dsd);
+ return;
+ }
+
+ try {
+ Log.d(TAG, "openVideo(): creating new MediaPlayer instance.");
+ mMediaPlayer = new MediaPlayer();
+ mSurfaceView.setMediaPlayer(mMediaPlayer);
+ mTextureView.setMediaPlayer(mMediaPlayer);
+ 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);
+
+ mMediaPlayer.setOnPreparedListener(mPreparedListener);
+ mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
+ mMediaPlayer.setOnCompletionListener(mCompletionListener);
+ mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener);
+ mMediaPlayer.setOnErrorListener(mErrorListener);
+ mMediaPlayer.setOnInfoListener(mInfoListener);
+ mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
+
+ mCurrentBufferPercentage = -1;
+ mMediaPlayer.setDataSource(getContext(), uri, headers);
+ mMediaPlayer.setAudioAttributes(mAudioAttributes);
+ // mMediaPlayer.setOnSubtitleDataListener(mSubtitleListener);
+ // we don't set the target state here either, but preserve the
+ // target state that was there before.
+ mCurrentState = STATE_PREPARING;
+ mMediaPlayer.prepareAsync();
+
+ // Save file name as title since the file may not have a title Metadata.
+ mTitle = uri.getPath();
+ String scheme = uri.getScheme();
+ if (scheme != null && scheme.equals("file")) {
+ mTitle = uri.getLastPathSegment();
+ }
+ mRetriever = new MediaMetadataRetriever();
+ mRetriever.setDataSource(getContext(), uri);
+
+ if (DEBUG) {
+ Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState
+ + ", mTargetState=" + mTargetState);
+ }
+ } catch (IOException | IllegalArgumentException ex) {
+ Log.w(TAG, "Unable to open content: " + uri, ex);
+ mCurrentState = STATE_ERROR;
+ mTargetState = STATE_ERROR;
+ mErrorListener.onError(mMediaPlayer,
+ MediaPlayer.MEDIA_ERROR_UNKNOWN, MediaPlayer.MEDIA_ERROR_IO);
+ }
+ }
+
+ /*
+ * Reset the media player in any state
+ */
+ @SuppressWarnings("deprecation")
+ private void resetPlayer() {
+ if (mMediaPlayer != null) {
+ mMediaPlayer.reset();
+ mMediaPlayer.release();
+ mMediaPlayer = null;
+ mTextureView.setMediaPlayer(null);
+ mSurfaceView.setMediaPlayer(null);
+ mCurrentState = STATE_IDLE;
+ mTargetState = STATE_IDLE;
+ if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
+ mAudioManager.abandonAudioFocus(null);
+ }
+ }
+ mVideoWidth = 0;
+ mVideoHeight = 0;
+ }
+
+ 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
+ | PlaybackStateCompat.ACTION_SEEK_TO;
+ mStateBuilder = new PlaybackStateCompat.Builder();
+ mStateBuilder.setActions(playbackActions);
+
+ if (mCustomActionList != null) {
+ for (PlaybackStateCompat.CustomAction action : mCustomActionList) {
+ mStateBuilder.addCustomAction(action);
+ }
+ }
+ }
+ mStateBuilder.setState(getCorrespondingPlaybackState(),
+ mMediaPlayer.getCurrentPosition(), mSpeed);
+ 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 {
+ mStateBuilder.setBufferedPosition(
+ (long) (mCurrentBufferPercentage / 100.0 * mMediaPlayer.getDuration()));
+ }
+ }
+
+ // Set PlaybackState for MediaSession
+ if (mMediaSession != null) {
+ PlaybackStateCompat state = mStateBuilder.build();
+ mMediaSession.setPlaybackState(state);
+ }
+ }
+
+ private int getCorrespondingPlaybackState() {
+ switch (mCurrentState) {
+ case STATE_ERROR:
+ return PlaybackStateCompat.STATE_ERROR;
+ case STATE_IDLE:
+ return PlaybackStateCompat.STATE_NONE;
+ case STATE_PREPARING:
+ return PlaybackStateCompat.STATE_CONNECTING;
+ case STATE_PREPARED:
+ return PlaybackStateCompat.STATE_PAUSED;
+ case STATE_PLAYING:
+ return PlaybackStateCompat.STATE_PLAYING;
+ case STATE_PAUSED:
+ return PlaybackStateCompat.STATE_PAUSED;
+ case STATE_PLAYBACK_COMPLETED:
+ return PlaybackStateCompat.STATE_STOPPED;
+ default:
+ return -1;
+ }
+ }
+
+ private final Runnable mFadeOut = new Runnable() {
+ @Override
+ public void run() {
+ if (mCurrentState == STATE_PLAYING) {
+ mMediaControlView.setVisibility(View.GONE);
+ }
+ }
+ };
+
+ 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;
+ }
+ mMediaControlView.removeCallbacks(mFadeOut);
+ mMediaControlView.setVisibility(View.VISIBLE);
+ if (mShowControllerIntervalMs != 0
+ && !mAccessibilityManager.isTouchExplorationEnabled()) {
+ mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
+ }
+ }
+
+ private void toggleMediaControlViewVisibility() {
+ if (mMediaControlView.getVisibility() == View.VISIBLE) {
+ mMediaControlView.removeCallbacks(mFadeOut);
+ mMediaControlView.setVisibility(View.GONE);
+ } else {
+ showController();
+ }
+ }
+
+ 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();
+ if (mSpeed != params.getSpeed()) {
+ try {
+ params.setSpeed(mSpeed);
+ mMediaPlayer.setPlaybackParams(params);
+ 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;
+ }
+ mSpeed = mFallbackSpeed;
+ }
+ }
+ }
+
+ private boolean isRemotePlayback() {
+ if (mMediaController == null) {
+ return false;
+ }
+ PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo();
+ return playbackInfo != null
+ && playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
+ }
+
+ private void selectOrDeselectSubtitle(boolean select) {
+ 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);
+ mSubtitleView.setVisibility(View.VISIBLE);
+ }
+ } else {
+ if (mSelectedSubtitleTrackIndex != INVALID_TRACK_INDEX) {
+ mMediaPlayer.deselectTrack(mSelectedSubtitleTrackIndex);
+ mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
+ 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) {
+ SubtitleTrack track = mSubtitleController.addTrack(trackInfos[i].getFormat());
+ if (track != null) {
+ mSubtitleTrackIndices.add(new Pair<>(i, track));
+ }
+ */
+ }
+ }
+ // Select first tracks as default
+ if (mVideoTrackIndices.size() > 0) {
+ mSelectedVideoTrackIndex = 0;
+ }
+ if (mAudioTrackIndices.size() > 0) {
+ mSelectedAudioTrackIndex = 0;
+ }
+ if (mVideoTrackIndices.size() == 0 && mAudioTrackIndices.size() > 0) {
+ mIsMusicMediaType = true;
+ }
+
+ 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);
+ }
+
+ private void extractMetadata() {
+ // Get and set duration and title values as MediaMetadata for MediaControlView2
+ MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
+ String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
+ if (title != null) {
+ mTitle = title;
+ }
+ builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle);
+ builder.putLong(
+ MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
+
+ if (mMediaSession != null) {
+ mMediaSession.setMetadata(builder.build());
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private void extractAudioMetadata() {
+ if (!mIsMusicMediaType) {
+ return;
+ }
+
+ mResources = getResources();
+ mManager = (WindowManager) getContext().getApplicationContext()
+ .getSystemService(Context.WINDOW_SERVICE);
+
+ byte[] album = mRetriever.getEmbeddedPicture();
+ if (album != null) {
+ 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);
+ }
+ }
+ });
+ } else {
+ mMusicAlbumDrawable = mResources.getDrawable(R.drawable.ic_default_album_image);
+ }
+
+ String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
+ if (title != null) {
+ mMusicTitleText = title;
+ } else {
+ mMusicTitleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
+ }
+
+ String artist = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
+ if (artist != null) {
+ mMusicArtistText = artist;
+ } else {
+ mMusicArtistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
+ }
+
+ // Send title and artist string to MediaControlView2
+ MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
+ builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mMusicTitleText);
+ builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mMusicArtistText);
+ mMediaSession.setMetadata(builder.build());
+
+ // Display Embedded mode as default
+ removeView(mSurfaceView);
+ removeView(mTextureView);
+ inflateMusicView(R.layout.embedded_music);
+ }
+
+ private int retrieveOrientation() {
+ DisplayMetrics dm = Resources.getSystem().getDisplayMetrics();
+ int width = dm.widthPixels;
+ int height = dm.heightPixels;
+
+ return (height > width)
+ ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+ : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+ }
+
+ private void inflateMusicView(int layoutId) {
+ removeView(mMusicView);
+
+ LayoutInflater inflater = (LayoutInflater) getContext()
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View v = inflater.inflate(layoutId, null);
+ v.setBackgroundColor(mDominantColor);
+
+ ImageView albumView = v.findViewById(R.id.album);
+ if (albumView != null) {
+ albumView.setImageDrawable(mMusicAlbumDrawable);
+ }
+
+ TextView titleView = v.findViewById(R.id.title);
+ if (titleView != null) {
+ titleView.setText(mMusicTitleText);
+ }
+
+ TextView artistView = v.findViewById(R.id.artist);
+ if (artistView != null) {
+ artistView.setText(mMusicArtistText);
+ }
+
+ mMusicView = v;
+ addView(mMusicView, 0);
+ }
+
+ /*
+ OnSubtitleDataListener mSubtitleListener =
+ new OnSubtitleDataListener() {
+ @Override
+ public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
+ if (DEBUG) {
+ Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
+ + ", getCurrentPosition: " + mp.getCurrentPosition()
+ + ", getStartTimeUs(): " + data.getStartTimeUs()
+ + ", diff: "
+ + (data.getStartTimeUs() / 1000 - mp.getCurrentPosition())
+ + "ms, getDurationUs(): " + data.getDurationUs());
+
+ }
+ final int index = data.getTrackIndex();
+ if (index != mSelectedSubtitleTrackIndex) {
+ Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
+ + ", selected track index: " + mSelectedSubtitleTrackIndex);
+ return;
+ }
+ for (Pair<Integer, SubtitleTrack> p : mSubtitleTrackIndices) {
+ if (p.first == index) {
+ SubtitleTrack track = p.second;
+ track.onData(data);
+ }
+ }
+ }
+ };
+ */
+
+ MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
+ new MediaPlayer.OnVideoSizeChangedListener() {
+ @Override
+ public void onVideoSizeChanged(
+ MediaPlayer mp, int width, int height) {
+ if (DEBUG) {
+ Log.d(TAG, "onVideoSizeChanged(): size: " + width + "/" + height);
+ }
+ mVideoWidth = mp.getVideoWidth();
+ mVideoHeight = mp.getVideoHeight();
+ if (DEBUG) {
+ Log.d(TAG, "onVideoSizeChanged(): mVideoSize:" + mVideoWidth + "/"
+ + mVideoHeight);
+ }
+ if (mVideoWidth != 0 && mVideoHeight != 0) {
+ requestLayout();
+ }
+ }
+ };
+ MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
+ @Override
+ public void onPrepared(MediaPlayer mp) {
+ if (DEBUG) {
+ Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState
+ + ", mTargetState=" + mTargetState);
+ }
+ mCurrentState = STATE_PREPARED;
+ // 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();
+ }
+
+ if (mMediaControlView != null) {
+ mMediaControlView.setEnabled(true);
+ }
+ int videoWidth = mp.getVideoWidth();
+ int videoHeight = mp.getVideoHeight();
+
+ // mSeekWhenPrepared may be changed after seekTo() call
+ long seekToPosition = mSeekWhenPrepared;
+ if (seekToPosition != 0) {
+ mMediaController.getTransportControls().seekTo(seekToPosition);
+ }
+
+ if (videoWidth != 0 && videoHeight != 0) {
+ if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) {
+ if (DEBUG) {
+ Log.i(TAG, "OnPreparedListener() : ");
+ Log.i(TAG, " video size: " + videoWidth + "/" + videoHeight);
+ Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/"
+ + getMeasuredHeight());
+ Log.i(TAG, " viewSize: " + getWidth() + "/" + getHeight());
+ }
+ mVideoWidth = videoWidth;
+ mVideoHeight = videoHeight;
+ requestLayout();
+ }
+
+ if (needToStart()) {
+ mMediaController.getTransportControls().play();
+ }
+ } else {
+ // We don't know the video size yet, but should start anyway.
+ // The video size might be reported to us later.
+ if (needToStart()) {
+ mMediaController.getTransportControls().play();
+ }
+ }
+ // 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);
+ mNeedUpdateMediaType = false;
+ }
+ }
+ }
+ };
+
+ MediaPlayer.OnSeekCompleteListener mSeekCompleteListener =
+ new MediaPlayer.OnSeekCompleteListener() {
+ @Override
+ public void onSeekComplete(MediaPlayer mp) {
+ updatePlaybackState();
+ }
+ };
+
+ MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
+ @Override
+ @SuppressWarnings("deprecation")
+ public void onCompletion(MediaPlayer mp) {
+ mCurrentState = STATE_PLAYBACK_COMPLETED;
+ mTargetState = STATE_PLAYBACK_COMPLETED;
+ updatePlaybackState();
+ if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
+ mAudioManager.abandonAudioFocus(null);
+ }
+ }
+ };
+
+ MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
+ @Override
+ public boolean onInfo(MediaPlayer mp, int what, int extra) {
+ if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
+ extractTracks();
+ }
+ return true;
+ }
+ };
+
+ MediaPlayer.OnErrorListener mErrorListener = new MediaPlayer.OnErrorListener() {
+ @Override
+ public boolean onError(MediaPlayer mp, int frameworkErr, int implErr) {
+ if (DEBUG) {
+ Log.d(TAG, "Error: " + frameworkErr + "," + implErr);
+ }
+ mCurrentState = STATE_ERROR;
+ mTargetState = STATE_ERROR;
+ updatePlaybackState();
+
+ if (mMediaControlView != null) {
+ mMediaControlView.setVisibility(View.GONE);
+ }
+ return true;
+ }
+ };
+
+ MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =
+ new MediaPlayer.OnBufferingUpdateListener() {
+ @Override
+ public void onBufferingUpdate(MediaPlayer mp, int percent) {
+ mCurrentBufferPercentage = percent;
+ updatePlaybackState();
+ }
+ };
+
+ private class MediaSessionCallback extends MediaSessionCompat.Callback {
+ @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);
+ if (subtitleIndex != INVALID_TRACK_INDEX) {
+ int subtitleTrackIndex = mSubtitleTrackIndices.get(subtitleIndex).first;
+ if (subtitleTrackIndex != mSelectedSubtitleTrackIndex) {
+ mSelectedSubtitleTrackIndex = subtitleTrackIndex;
+ 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);
+ if (audioIndex != INVALID_TRACK_INDEX) {
+ int audioTrackIndex = mAudioTrackIndices.get(audioIndex);
+ if (audioTrackIndex != mSelectedAudioTrackIndex) {
+ mSelectedAudioTrackIndex = audioTrackIndex;
+ mMediaPlayer.selectTrack(mSelectedAudioTrackIndex);
+ }
+ }
+ break;
+ case MediaControlView2.COMMAND_SET_PLAYBACK_SPEED:
+ float speed = args.getFloat(
+ MediaControlView2.KEY_PLAYBACK_SPEED, INVALID_SPEED);
+ if (speed != INVALID_SPEED && speed != mSpeed) {
+ setSpeed(speed);
+ mSpeed = speed;
+ }
+ break;
+ case MediaControlView2.COMMAND_MUTE:
+ mVolumeLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+ mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
+ break;
+ case MediaControlView2.COMMAND_UNMUTE:
+ mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeLevel, 0);
+ break;
+ }
+ }
+ showController();
+ }
+
+ @Override
+ public void onCustomAction(final String action, final Bundle extras) {
+ mCustomActionListenerRecord.first.execute(new Runnable() {
+ @Override
+ public void run() {
+ mCustomActionListenerRecord.second.onCustomAction(action, extras);
+ }
+ });
+ showController();
+ }
+
+ @Override
+ public void onPlay() {
+ if (!isAudioGranted()) {
+ requestAudioFocus(mAudioFocusType);
+ }
+
+ if ((isInPlaybackState() && mCurrentView.hasAvailableSurface()) || mIsMusicMediaType) {
+ if (isRemotePlayback()) {
+ // TODO (b/77158231)
+ // mRoutePlayer.onPlay();
+ } else {
+ applySpeed();
+ mMediaPlayer.start();
+ mCurrentState = STATE_PLAYING;
+ updatePlaybackState();
+ }
+ mCurrentState = STATE_PLAYING;
+ }
+ mTargetState = STATE_PLAYING;
+ if (DEBUG) {
+ Log.d(TAG, "onPlay(). mCurrentState=" + mCurrentState
+ + ", mTargetState=" + mTargetState);
+ }
+ showController();
+ }
+
+ @Override
+ public void onPause() {
+ if (isInPlaybackState()) {
+ if (isRemotePlayback()) {
+ // TODO (b/77158231)
+ // mRoutePlayer.onPause();
+ mCurrentState = STATE_PAUSED;
+ } else if (mMediaPlayer.isPlaying()) {
+ mMediaPlayer.pause();
+ mCurrentState = STATE_PAUSED;
+ updatePlaybackState();
+ }
+ }
+ mTargetState = STATE_PAUSED;
+ if (DEBUG) {
+ Log.d(TAG, "onPause(). mCurrentState=" + mCurrentState
+ + ", mTargetState=" + mTargetState);
+ }
+ showController();
+ }
+
+ @Override
+ 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 {
+ mMediaPlayer.seekTo(pos, MediaPlayer.SEEK_PREVIOUS_SYNC);
+ }
+ mSeekWhenPrepared = 0;
+ }
+ } else {
+ mSeekWhenPrepared = pos;
+ }
+ showController();
+ }
+
+ @Override
+ public void onStop() {
+ if (isRemotePlayback()) {
+ // TODO (b/77158231)
+ // mRoutePlayer.onStop();
+ } else {
+ resetPlayer();
+ }
+ showController();
+ }
+ }
}
diff --git a/media-widget/src/main/java/androidx/media/widget/VideoView2Impl.java b/media-widget/src/main/java/androidx/media/widget/VideoView2Impl.java
deleted file mode 100644
index 7632490..0000000
--- a/media-widget/src/main/java/androidx/media/widget/VideoView2Impl.java
+++ /dev/null
@@ -1,243 +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.media.widget;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.support.v4.media.session.MediaControllerCompat;
-import android.support.v4.media.session.PlaybackStateCompat;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.media.AudioAttributesCompat;
-import androidx.media.DataSourceDesc;
-import androidx.media.MediaItem2;
-import androidx.media.MediaMetadata2;
-import androidx.media.SessionToken2;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * Interface for impl classes.
- */
-interface VideoView2Impl {
- void initialize(
- VideoView2 instance, Context context,
- @Nullable AttributeSet attrs, int defStyleAttr);
-
- /**
- * Sets MediaControlView2 instance. It will replace the previously assigned MediaControlView2
- * instance if any.
- *
- * @param mediaControlView a media control view2 instance.
- * @param intervalMs a time interval in milliseconds until VideoView2 hides MediaControlView2.
- */
- void setMediaControlView2(MediaControlView2 mediaControlView, long intervalMs);
-
- /**
- * Returns MediaControlView2 instance which is currently attached to VideoView2 by default or by
- * {@link #setMediaControlView2} method.
- */
- MediaControlView2 getMediaControlView2();
-
- /**
- * Sets MediaMetadata2 instance. It will replace the previously assigned MediaMetadata2 instance
- * if any.
- *
- * @param metadata a MediaMetadata2 instance.
- */
- void setMediaMetadata(MediaMetadata2 metadata);
-
- /**
- * Returns MediaMetadata2 instance which is retrieved from MediaPlayer inside VideoView2 by
- * default or by {@link #setMediaMetadata} method.
- */
- MediaMetadata2 getMediaMetadata();
-
- /**
- * Returns MediaController instance which is connected with MediaSession that VideoView2 is
- * using. This method should be called when VideoView2 is attached to window, or it throws
- * IllegalStateException, since internal MediaSession instance is not available until
- * this view is attached to window. Please check {@link View#isAttachedToWindow}
- * before calling this method.
- *
- * @throws IllegalStateException if interal MediaSession is not created yet.
- */
- MediaControllerCompat getMediaController();
-
- /**
- * Returns {@link SessionToken2} so that developers create their own
- * {@link androidx.media.MediaController2} instance. This method should be called when
- * VideoView2 is attached to window, or it throws IllegalStateException.
- *
- * @throws IllegalStateException if interal MediaSession is not created yet.
- */
- SessionToken2 getMediaSessionToken();
-
- /**
- * Shows or hides closed caption or subtitles if there is any.
- * The first subtitle track will be chosen if there multiple subtitle tracks exist.
- * Default behavior of VideoView2 is not showing subtitle.
- * @param enable shows closed caption or subtitles if this value is true, or hides.
- */
- void setSubtitleEnabled(boolean enable);
-
- /**
- * Returns true if showing subtitle feature is enabled or returns false.
- * Although there is no subtitle track or closed caption, it can return true, if the feature
- * has been enabled by {@link #setSubtitleEnabled}.
- */
- boolean isSubtitleEnabled();
-
- /**
- * Sets playback speed.
- *
- * It is expressed as a multiplicative factor, where normal speed is 1.0f. If it is less than
- * or equal to zero, it will be just ignored and nothing will be changed. If it exceeds the
- * maximum speed that internal engine supports, system will determine best handling or it will
- * be reset to the normal speed 1.0f.
- * @param speed the playback speed. It should be positive.
- */
- void setSpeed(float speed);
-
- /**
- * 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.
- */
- float getSpeed();
-
- /**
- * 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},
- * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
- * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. Or use
- * {@link AudioManager#AUDIOFOCUS_NONE} to express that audio focus should not be
- * requested when playback starts. You can for instance use this when playing a silent animation
- * through this class, and you don't want to affect other audio applications playing in the
- * background.
- *
- * @param focusGain the type of audio focus gain that will be requested, or
- * {@link AudioManager#AUDIOFOCUS_NONE} to disable the use audio focus during
- * playback.
- */
- void setAudioFocusRequest(int focusGain);
-
- /**
- * Sets the {@link AudioAttributesCompat} to be used during the playback of the video.
- *
- * @param attributes non-null <code>AudioAttributesCompat</code>.
- */
- void setAudioAttributes(@NonNull AudioAttributesCompat attributes);
-
- /**
- * Sets video path.
- *
- * @param path the path of the video.
- */
- void setVideoPath(String path);
-
- /**
- * Sets video URI.
- *
- * @param uri the URI of the video.
- */
- void setVideoUri(Uri uri);
-
- /**
- * Sets video URI using specific headers.
- *
- * @param uri the URI of the video.
- * @param headers the headers for the URI request.
- * Note that the cross domain redirection is allowed by default, but that can be
- * 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.
- */
- void setVideoUri(Uri uri, @Nullable Map<String, String> headers);
-
- /**
- * Sets {@link MediaItem2} object to render using VideoView2. Alternative way to set media
- * object to VideoView2 is {@link #setDataSource}.
- * @param mediaItem the MediaItem2 to play
- * @see #setDataSource
- */
- void setMediaItem(@NonNull MediaItem2 mediaItem);
-
- /**
- * Sets {@link DataSourceDesc} object to render using VideoView2.
- * @param dataSource the {@link DataSourceDesc} object to play.
- * @see #setMediaItem
- */
- void setDataSource(@NonNull DataSourceDesc dataSource);
-
- /**
- * Selects which view will be used to render video between SurfacView and TextureView.
- *
- * @param viewType the view type to render video
- * <ul>
- * <li>{@link #VideoView2.VIEW_TYPE_SURFACEVIEW}
- * <li>{@link #VideoView2.VIEW_TYPE_TEXTUREVIEW}
- * </ul>
- */
- void setViewType(@VideoView2.ViewType int viewType);
-
- /**
- * Returns view type.
- *
- * @return view type. See {@see setViewType}.
- */
- @VideoView2.ViewType
- int getViewType();
-
- /**
- * Sets custom actions which will be shown as custom buttons in {@link MediaControlView2}.
- *
- * @param actionList A list of {@link PlaybackStateCompat.CustomAction}. The return value of
- * {@link PlaybackStateCompat.CustomAction#getIcon()} will be used to draw
- * buttons in {@link MediaControlView2}.
- * @param executor executor to run callbacks on.
- * @param listener A listener to be called when a custom button is clicked.
- */
- void setCustomActions(List<PlaybackStateCompat.CustomAction> actionList,
- Executor executor, VideoView2.OnCustomActionListener listener);
-
- /**
- * Registers a callback to be invoked when a view type change is done.
- * {@see #setViewType(int)}
- * @param l The callback that will be run
- */
- void setOnViewTypeChangedListener(VideoView2.OnViewTypeChangedListener l);
-
- void onAttachedToWindowImpl();
-
- void onDetachedFromWindowImpl();
-
- void onTouchEventImpl(MotionEvent ev);
-
- void onTrackballEventImpl(MotionEvent ev);
-
- void onMeasureImpl(int widthMeasureSpec, int heightMeasureSpec);
-}
diff --git a/media-widget/src/main/java/androidx/media/widget/impl/VideoViewInterface.java b/media-widget/src/main/java/androidx/media/widget/VideoViewInterface.java
similarity index 94%
rename from media-widget/src/main/java/androidx/media/widget/impl/VideoViewInterface.java
rename to media-widget/src/main/java/androidx/media/widget/VideoViewInterface.java
index a497e32..81b40a9 100644
--- a/media-widget/src/main/java/androidx/media/widget/impl/VideoViewInterface.java
+++ b/media-widget/src/main/java/androidx/media/widget/VideoViewInterface.java
@@ -16,10 +16,10 @@
package androidx.media.widget;
+import android.media.MediaPlayer;
import android.view.View;
import androidx.annotation.NonNull;
-import androidx.media.MediaPlayer2;
interface VideoViewInterface {
/**
@@ -29,10 +29,10 @@
* @return true if the surface is successfully assigned, false if not. It will fail to assign
* if any of MediaPlayer or surface is unavailable.
*/
- boolean assignSurfaceToMediaPlayer(MediaPlayer2 mp);
+ boolean assignSurfaceToMediaPlayer(MediaPlayer mp);
void setSurfaceListener(SurfaceListener l);
int getViewType();
- void setMediaPlayer(MediaPlayer2 mp);
+ void setMediaPlayer(MediaPlayer mp);
/**
* Takes over oldView. It means that the MediaPlayer will start rendering on this view.
diff --git a/media-widget/src/main/java/androidx/media/widget/impl/VideoSurfaceView.java b/media-widget/src/main/java/androidx/media/widget/impl/VideoSurfaceView.java
deleted file mode 100644
index 5c140c8..0000000
--- a/media-widget/src/main/java/androidx/media/widget/impl/VideoSurfaceView.java
+++ /dev/null
@@ -1,181 +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.media.widget;
-
-import static androidx.media.widget.VideoView2.VIEW_TYPE_SURFACEVIEW;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.media.MediaPlayer2;
-
-@RequiresApi(21)
-class VideoSurfaceView extends SurfaceView
- implements VideoViewInterface, SurfaceHolder.Callback {
- private static final String TAG = "VideoSurfaceView";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private Surface mSurface = null;
- private SurfaceListener mSurfaceListener = null;
- private MediaPlayer2 mMediaPlayer;
- // A flag to indicate taking over other view should be proceed.
- private boolean mIsTakingOverOldView;
- private VideoViewInterface mOldView;
-
- VideoSurfaceView(Context context) {
- super(context, null);
- getHolder().addCallback(this);
- }
-
- ////////////////////////////////////////////////////
- // implements VideoViewInterfaceWithMp1
- ////////////////////////////////////////////////////
-
- @Override
- public boolean assignSurfaceToMediaPlayer(MediaPlayer2 mp) {
- Log.d(TAG, "assignSurfaceToMediaPlayer(): mSurface: " + mSurface);
- if (mp == null || !hasAvailableSurface()) {
- return false;
- }
- mp.setSurface(mSurface);
- return true;
- }
-
- @Override
- public void setSurfaceListener(SurfaceListener l) {
- mSurfaceListener = l;
- }
-
- @Override
- public int getViewType() {
- return VIEW_TYPE_SURFACEVIEW;
- }
-
- @Override
- public void setMediaPlayer(MediaPlayer2 mp) {
- mMediaPlayer = mp;
- if (mIsTakingOverOldView) {
- takeOver(mOldView);
- }
- }
-
- @Override
- public void takeOver(@NonNull VideoViewInterface oldView) {
- if (assignSurfaceToMediaPlayer(mMediaPlayer)) {
- ((View) oldView).setVisibility(GONE);
- mIsTakingOverOldView = false;
- mOldView = null;
- if (mSurfaceListener != null) {
- mSurfaceListener.onSurfaceTakeOverDone(this);
- }
- } else {
- mIsTakingOverOldView = true;
- mOldView = oldView;
- }
- }
-
- @Override
- public boolean hasAvailableSurface() {
- return mSurface != null && mSurface.isValid();
- }
-
- ////////////////////////////////////////////////////
- // implements SurfaceHolder.Callback
- ////////////////////////////////////////////////////
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- Log.d(TAG, "surfaceCreated: mSurface: " + mSurface + ", new : " + holder.getSurface());
- mSurface = holder.getSurface();
- if (mIsTakingOverOldView) {
- takeOver(mOldView);
- } else {
- assignSurfaceToMediaPlayer(mMediaPlayer);
- }
-
- if (mSurfaceListener != null) {
- Rect rect = holder.getSurfaceFrame();
- mSurfaceListener.onSurfaceCreated(this, rect.width(), rect.height());
- }
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- if (mSurfaceListener != null) {
- mSurfaceListener.onSurfaceChanged(this, width, height);
- }
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- // After we return from this we can't use the surface any more
- mSurface = null;
- if (mSurfaceListener != null) {
- mSurfaceListener.onSurfaceDestroyed(this);
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int videoWidth = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoWidth();
- int videoHeight = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoHeight();
- if (DEBUG) {
- Log.d(TAG, "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", "
- + MeasureSpec.toString(heightMeasureSpec) + ")");
- Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
- Log.i(TAG, " viewSize: " + getWidth() + "/" + getHeight());
- Log.i(TAG, " mVideoWidth/height: " + videoWidth + ", " + videoHeight);
- }
-
- int width = getDefaultSize(videoWidth, widthMeasureSpec);
- int height = getDefaultSize(videoHeight, heightMeasureSpec);
-
- if (videoWidth > 0 && videoHeight > 0) {
- int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
- int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
-
- width = widthSpecSize;
- height = heightSpecSize;
-
- // for compatibility, we adjust size based on aspect ratio
- if (videoWidth * height < width * videoHeight) {
- width = height * videoWidth / videoHeight;
- if (DEBUG) {
- Log.d(TAG, "image too wide, correcting. width: " + width);
- }
- } else if (videoWidth * height > width * videoHeight) {
- height = width * videoHeight / videoWidth;
- if (DEBUG) {
- Log.d(TAG, "image too tall, correcting. height: " + height);
- }
- }
- } else {
- // no size yet, just adopt the given spec sizes
- }
- setMeasuredDimension(width, height);
- if (DEBUG) {
- Log.i(TAG, "end of onMeasure()");
- Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
- }
- }
-}
diff --git a/media-widget/src/main/java/androidx/media/widget/impl/VideoView2ImplBase.java b/media-widget/src/main/java/androidx/media/widget/impl/VideoView2ImplBase.java
deleted file mode 100644
index 68477f8..0000000
--- a/media-widget/src/main/java/androidx/media/widget/impl/VideoView2ImplBase.java
+++ /dev/null
@@ -1,1570 +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.media.widget;
-
-import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.media.AudioAttributes;
-import android.media.AudioFocusRequest;
-import android.media.AudioManager;
-import android.media.MediaMetadataRetriever;
-import android.media.PlaybackParams;
-import android.media.SubtitleData;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.support.v4.media.MediaMetadataCompat;
-import android.support.v4.media.session.MediaControllerCompat;
-import android.support.v4.media.session.MediaControllerCompat.PlaybackInfo;
-import android.support.v4.media.session.MediaSessionCompat;
-import android.support.v4.media.session.PlaybackStateCompat;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.annotation.RestrictTo;
-import androidx.media.AudioAttributesCompat;
-import androidx.media.DataSourceDesc;
-import androidx.media.MediaItem2;
-import androidx.media.MediaMetadata2;
-import androidx.media.MediaPlayer2;
-import androidx.media.MediaPlayer2.MediaPlayer2EventCallback;
-import androidx.media.SessionToken2;
-import androidx.media.subtitle.ClosedCaptionRenderer;
-import androidx.media.subtitle.SubtitleController;
-import androidx.media.subtitle.SubtitleTrack;
-import androidx.mediarouter.media.MediaControlIntent;
-import androidx.mediarouter.media.MediaItemStatus;
-import androidx.mediarouter.media.MediaRouteSelector;
-import androidx.mediarouter.media.MediaRouter;
-import androidx.palette.graphics.Palette;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * Base implementation of VideoView2.
- */
-@RequiresApi(28) // TODO correct minSdk API use incompatibilities and remove before release.
-class VideoView2ImplBase implements VideoView2Impl, VideoViewInterface.SurfaceListener {
- private static final String TAG = "VideoView2ImplBase";
- 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;
- private static final int STATE_IDLE = 0;
- private static final int STATE_PREPARING = 1;
- private static final int STATE_PREPARED = 2;
- private static final int STATE_PLAYING = 3;
- private static final int STATE_PAUSED = 4;
- private static final int STATE_PLAYBACK_COMPLETED = 5;
-
- private static final int INVALID_TRACK_INDEX = -1;
- private static final float INVALID_SPEED = 0f;
-
- private static final int SIZE_TYPE_EMBEDDED = 0;
- private static final int SIZE_TYPE_FULL = 1;
- private static final int SIZE_TYPE_MINIMAL = 2;
-
- private AccessibilityManager mAccessibilityManager;
- private AudioManager mAudioManager;
- private AudioAttributesCompat mAudioAttributes;
- private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain
- private boolean mAudioFocused = false;
-
- private Pair<Executor, VideoView2.OnCustomActionListener> mCustomActionListenerRecord;
- private VideoView2.OnViewTypeChangedListener mViewTypeChangedListener;
-
- private VideoViewInterface mCurrentView;
- private VideoTextureView mTextureView;
- private VideoSurfaceView mSurfaceView;
-
- private MediaPlayer2 mMediaPlayer;
- private DataSourceDesc mDsd;
- private Uri mUri;
- private Map<String, String> mHeaders;
- private MediaControlView2 mMediaControlView;
- private MediaSessionCompat mMediaSession;
- private MediaControllerCompat mMediaController;
- private MediaMetadata2 mMediaMetadata;
- private MediaMetadataRetriever mRetriever;
- private boolean mNeedUpdateMediaType;
- private Bundle mMediaTypeData;
- private String mTitle;
-
- private WindowManager mManager;
- private Resources mResources;
- private View mMusicView;
- private Drawable mMusicAlbumDrawable;
- private String mMusicTitleText;
- private String mMusicArtistText;
- private boolean mIsMusicMediaType;
- private int mPrevWidth;
- private int mPrevHeight;
- private int mDominantColor;
- private int mSizeType;
-
- private PlaybackStateCompat.Builder mStateBuilder;
- private List<PlaybackStateCompat.CustomAction> mCustomActionList;
-
- private int mTargetState = STATE_IDLE;
- private int mCurrentState = STATE_IDLE;
- private int mCurrentBufferPercentage;
- private long mSeekWhenPrepared; // recording the seek position while preparing
-
- private int mVideoWidth;
- private int mVideoHeight;
-
- private ArrayList<Integer> mVideoTrackIndices;
- private ArrayList<Integer> mAudioTrackIndices;
- 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 boolean mSubtitleEnabled;
-
- private float mSpeed;
- private float mFallbackSpeed; // keep the original speed before 'pause' is called.
- private float mVolumeLevelFloat;
- private int mVolumeLevel;
- private VideoView2 mInstance;
-
- private long mShowControllerIntervalMs;
-
- private MediaRouter mMediaRouter;
- private MediaRouteSelector mRouteSelector;
- private MediaRouter.RouteInfo mRoute;
- private RoutePlayer mRoutePlayer;
-
- 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(mInstance.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)
- // TODO: b/77556429
- mRoutePlayer.openVideo(mUri);
- }
- }
-
- @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)
- // TODO: b/77556429
- openVideo(mDsd);
- }
- }
- };
-
- @Override
- public void initialize(
- VideoView2 instance, Context context,
- @Nullable AttributeSet attrs, int defStyleAttr) {
- mInstance = instance;
-
- mVideoWidth = 0;
- mVideoHeight = 0;
- mSpeed = 1.0f;
- mFallbackSpeed = mSpeed;
- mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
- mShowControllerIntervalMs = DEFAULT_SHOW_CONTROLLER_INTERVAL_MS;
-
- mAccessibilityManager = (AccessibilityManager) context.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
-
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- mAudioAttributes = new AudioAttributesCompat.Builder()
- .setUsage(AudioAttributesCompat.USAGE_MEDIA)
- .setContentType(AudioAttributesCompat.CONTENT_TYPE_MOVIE).build();
-
- mInstance.setFocusable(true);
- mInstance.setFocusableInTouchMode(true);
- mInstance.requestFocus();
-
- mTextureView = new VideoTextureView(context);
- mSurfaceView = new VideoSurfaceView(context);
- LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT);
- mTextureView.setLayoutParams(params);
- mSurfaceView.setLayoutParams(params);
- mTextureView.setSurfaceListener(this);
- mSurfaceView.setSurfaceListener(this);
-
- mInstance.addView(mTextureView);
- mInstance.addView(mSurfaceView);
-
- mSubtitleView = new SubtitleView(context);
- mSubtitleView.setLayoutParams(params);
- mSubtitleView.setBackgroundColor(0);
- mInstance.addView(mSubtitleView);
-
- boolean enableControlView = (attrs == null) || attrs.getAttributeBooleanValue(
- "http://schemas.android.com/apk/res/android",
- "enableControlView", true);
- if (enableControlView) {
- mMediaControlView = new MediaControlView2(context);
- }
-
- mSubtitleEnabled = (attrs == null) || attrs.getAttributeBooleanValue(
- "http://schemas.android.com/apk/res/android",
- "enableSubtitle", false);
-
- // Choose surface view by default
- int viewType = (attrs == null) ? VideoView2.VIEW_TYPE_SURFACEVIEW
- : attrs.getAttributeIntValue(
- "http://schemas.android.com/apk/res/android",
- "viewType", VideoView2.VIEW_TYPE_SURFACEVIEW);
- if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
- Log.d(TAG, "viewType attribute is surfaceView.");
- mTextureView.setVisibility(View.GONE);
- mSurfaceView.setVisibility(View.VISIBLE);
- mCurrentView = mSurfaceView;
- } else if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
- Log.d(TAG, "viewType attribute is textureView.");
- mTextureView.setVisibility(View.VISIBLE);
- mSurfaceView.setVisibility(View.GONE);
- mCurrentView = mTextureView;
- }
-
- 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();
- }
-
- /**
- * Sets MediaControlView2 instance. It will replace the previously assigned MediaControlView2
- * instance if any.
- *
- * @param mediaControlView a media control view2 instance.
- * @param intervalMs a time interval in milliseconds until VideoView2 hides MediaControlView2.
- */
- @Override
- public void setMediaControlView2(MediaControlView2 mediaControlView, long intervalMs) {
- mMediaControlView = mediaControlView;
- mShowControllerIntervalMs = intervalMs;
- mMediaControlView.setRouteSelector(mRouteSelector);
-
- if (mInstance.isAttachedToWindow()) {
- attachMediaControlView();
- }
- }
-
- /**
- * Returns MediaControlView2 instance which is currently attached to VideoView2 by default or by
- * {@link #setMediaControlView2} method.
- */
- @Override
- public MediaControlView2 getMediaControlView2() {
- return mMediaControlView;
- }
-
- /**
- * Sets MediaMetadata2 instance. It will replace the previously assigned MediaMetadata2 instance
- * if any.
- *
- * @param metadata a MediaMetadata2 instance.
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setMediaMetadata(MediaMetadata2 metadata) {
- //mProvider.setMediaMetadata_impl(metadata);
- }
-
- /**
- * Returns MediaMetadata2 instance which is retrieved from MediaPlayer inside VideoView2 by
- * default or by {@link #setMediaMetadata} method.
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public MediaMetadata2 getMediaMetadata() {
- return mMediaMetadata;
- }
-
- /**
- * Returns MediaController instance which is connected with MediaSession that VideoView2 is
- * using. This method should be called when VideoView2 is attached to window, or it throws
- * IllegalStateException, since internal MediaSession instance is not available until
- * this view is attached to window. Please check {@link View#isAttachedToWindow}
- * before calling this method.
- *
- * @throws IllegalStateException if interal MediaSession is not created yet.
- * @hide TODO: remove
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public MediaControllerCompat getMediaController() {
- if (mMediaSession == null) {
- throw new IllegalStateException("MediaSession instance is not available.");
- }
- return mMediaController;
- }
-
- /**
- * Returns {@link SessionToken2} so that developers create their own
- * {@link androidx.media.MediaController2} instance. This method should be called when
- * VideoView2 is attached to window, or it throws IllegalStateException.
- *
- * @throws IllegalStateException if interal MediaSession is not created yet.
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public SessionToken2 getMediaSessionToken() {
- //return mProvider.getMediaSessionToken_impl();
- return null;
- }
-
- /**
- * Shows or hides closed caption or subtitles if there is any.
- * The first subtitle track will be chosen if there multiple subtitle tracks exist.
- * Default behavior of VideoView2 is not showing subtitle.
- * @param enable shows closed caption or subtitles if this value is true, or hides.
- */
- @Override
- public void setSubtitleEnabled(boolean enable) {
- // No-op on API < 28
- }
-
- /**
- * Returns true if showing subtitle feature is enabled or returns false.
- * Although there is no subtitle track or closed caption, it can return true, if the feature
- * has been enabled by {@link #setSubtitleEnabled}.
- */
- @Override
- public boolean isSubtitleEnabled() {
- // Not supported on API < 28
- return false;
- }
-
- /**
- * Sets playback speed.
- *
- * It is expressed as a multiplicative factor, where normal speed is 1.0f. If it is less than
- * or equal to zero, it will be just ignored and nothing will be changed. If it exceeds the
- * maximum speed that internal engine supports, system will determine best handling or it will
- * be reset to the normal speed 1.0f.
- * @param speed the playback speed. It should be positive.
- */
- @Override
- public void setSpeed(float speed) {
- if (speed <= 0.0f) {
- Log.e(TAG, "Unsupported speed (" + speed + ") is ignored.");
- return;
- }
- mSpeed = speed;
- if (isPlaying()) {
- applySpeed();
- }
- updatePlaybackState();
- }
-
- /**
- * 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.
- */
- @Override
- 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},
- * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
- * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. Or use
- * {@link AudioManager#AUDIOFOCUS_NONE} to express that audio focus should not be
- * requested when playback starts. You can for instance use this when playing a silent animation
- * through this class, and you don't want to affect other audio applications playing in the
- * background.
- *
- * @param focusGain the type of audio focus gain that will be requested, or
- * {@link AudioManager#AUDIOFOCUS_NONE} to disable the use audio focus during
- * playback.
- */
- @Override
- public void setAudioFocusRequest(int focusGain) {
- if (focusGain != AudioManager.AUDIOFOCUS_NONE
- && focusGain != AudioManager.AUDIOFOCUS_GAIN
- && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
- && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
- && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) {
- throw new IllegalArgumentException("Illegal audio focus type " + focusGain);
- }
- mAudioFocusType = focusGain;
- }
-
- /**
- * Sets the {@link AudioAttributesCompat} to be used during the playback of the video.
- *
- * @param attributes non-null <code>AudioAttributesCompat</code>.
- */
- @Override
- public void setAudioAttributes(@NonNull AudioAttributesCompat attributes) {
- if (attributes == null) {
- throw new IllegalArgumentException("Illegal null AudioAttributes");
- }
- mAudioAttributes = attributes;
- }
-
- /**
- * Sets video path.
- *
- * @param path the path of the video.
- *
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setVideoPath(String path) {
- setVideoUri(Uri.parse(path));
- }
-
- /**
- * Sets video URI.
- *
- * @param uri the URI of the video.
- *
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setVideoUri(Uri uri) {
- setVideoUri(uri, null);
- }
-
- /**
- * Sets video URI using specific headers.
- *
- * @param uri the URI of the video.
- * @param headers the headers for the URI request.
- * Note that the cross domain redirection is allowed by default, but that can be
- * 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.
- */
- @Override
- public void setVideoUri(Uri uri, @Nullable Map<String, String> headers) {
- DataSourceDesc.Builder builder = new DataSourceDesc.Builder();
- builder.setDataSource(mInstance.getContext(), uri, headers, null);
- setDataSource(builder.build());
- }
-
- /**
- * Sets {@link MediaItem2} object to render using VideoView2. Alternative way to set media
- * object to VideoView2 is {@link #setDataSource}.
- * @param mediaItem the MediaItem2 to play
- * @see #setDataSource
- *
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setMediaItem(@NonNull MediaItem2 mediaItem) {
- }
-
- /**
- * Sets {@link DataSourceDesc} object to render using VideoView2.
- * @param dataSource the {@link DataSourceDesc} object to play.
- * @see #setMediaItem
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setDataSource(@NonNull DataSourceDesc dataSource) {
- mDsd = dataSource;
- mSeekWhenPrepared = 0;
- openVideo(dataSource);
- }
-
- /**
- * Selects which view will be used to render video between SurfacView and TextureView.
- *
- * @param viewType the view type to render video
- * <ul>
- * <li>{@link #VideoView2.VIEW_TYPE_SURFACEVIEW}
- * <li>{@link #VideoView2.VIEW_TYPE_TEXTUREVIEW}
- * </ul>
- */
- @Override
- public void setViewType(@VideoView2.ViewType int viewType) {
- if (viewType == mCurrentView.getViewType()) {
- return;
- }
- VideoViewInterface targetView;
- if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
- Log.d(TAG, "switching to TextureView");
- targetView = mTextureView;
- } else if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
- Log.d(TAG, "switching to SurfaceView");
- targetView = mSurfaceView;
- } else {
- throw new IllegalArgumentException("Unknown view type: " + viewType);
- }
- ((View) targetView).setVisibility(View.VISIBLE);
- targetView.takeOver(mCurrentView);
- mInstance.requestLayout();
- }
-
- /**
- * Returns view type.
- *
- * @return view type. See {@see setViewType}.
- */
- @VideoView2.ViewType
- @Override
- public int getViewType() {
- return mCurrentView.getViewType();
- }
-
- /**
- * Sets custom actions which will be shown as custom buttons in {@link MediaControlView2}.
- *
- * @param actionList A list of {@link PlaybackStateCompat.CustomAction}. The return value of
- * {@link PlaybackStateCompat.CustomAction#getIcon()} will be used to draw
- * 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
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setCustomActions(List<PlaybackStateCompat.CustomAction> actionList,
- Executor executor, VideoView2.OnCustomActionListener listener) {
- mCustomActionList = actionList;
- mCustomActionListenerRecord = new Pair<>(executor, listener);
-
- // Create a new playback builder in order to clear existing the custom actions.
- mStateBuilder = null;
- updatePlaybackState();
- }
-
- /**
- * Registers a callback to be invoked when a view type change is done.
- * {@see #setViewType(int)}
- * @param l The callback that will be run
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setOnViewTypeChangedListener(VideoView2.OnViewTypeChangedListener l) {
- mViewTypeChangedListener = l;
- }
-
- @Override
- public void onAttachedToWindowImpl() {
- // Create MediaSession
- mMediaSession = new MediaSessionCompat(mInstance.getContext(), "VideoView2MediaSession");
- mMediaSession.setCallback(new MediaSessionCallback());
- mMediaSession.setActive(true);
- mMediaController = mMediaSession.getController();
- attachMediaControlView();
- if (mCurrentState == STATE_PREPARED) {
- extractTracks();
- extractMetadata();
- extractAudioMetadata();
- if (mNeedUpdateMediaType) {
- mMediaSession.sendSessionEvent(
- MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS,
- mMediaTypeData);
- mNeedUpdateMediaType = false;
- }
- }
-
- mMediaRouter = MediaRouter.getInstance(mInstance.getContext());
- mMediaRouter.setMediaSessionCompat(mMediaSession);
- mMediaRouter.addCallback(mRouteSelector, mRouterCallback,
- MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
- }
-
- @Override
- public void onDetachedFromWindowImpl() {
- mMediaSession.release();
- mMediaSession = null;
- mMediaController = null;
- }
-
- @Override
- public void onTouchEventImpl(MotionEvent ev) {
- if (DEBUG) {
- Log.d(TAG, "onTouchEvent(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
- if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
- toggleMediaControlViewVisibility();
- }
- }
- }
-
- @Override
- public void onTrackballEventImpl(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
- if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
- toggleMediaControlViewVisibility();
- }
- }
- }
-
- @Override
- public void onMeasureImpl(int widthMeasureSpec, int heightMeasureSpec) {
- if (mIsMusicMediaType) {
- int currWidth = mInstance.getMeasuredWidth();
- int currHeight = mInstance.getMeasuredHeight();
- if (mPrevWidth != currWidth || mPrevHeight != currHeight) {
- Point screenSize = new Point();
- mManager.getDefaultDisplay().getSize(screenSize);
- int screenWidth = screenSize.x;
- int screenHeight = screenSize.y;
-
- if (currWidth == screenWidth && currHeight == screenHeight) {
- int orientation = retrieveOrientation();
- if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
- inflateMusicView(R.layout.full_landscape_music);
- } else {
- inflateMusicView(R.layout.full_portrait_music);
- }
-
- if (mSizeType != SIZE_TYPE_FULL) {
- mSizeType = SIZE_TYPE_FULL;
- // Remove existing mFadeOut callback
- mMediaControlView.removeCallbacks(mFadeOut);
- mMediaControlView.setVisibility(View.VISIBLE);
- }
- } else {
- if (mSizeType != SIZE_TYPE_EMBEDDED) {
- mSizeType = SIZE_TYPE_EMBEDDED;
- inflateMusicView(R.layout.embedded_music);
- // Add new mFadeOut callback
- mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
- }
- }
- mPrevWidth = currWidth;
- mPrevHeight = currHeight;
- }
- }
- }
-
- ///////////////////////////////////////////////////
- // 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
- + ", mTargetState=" + mTargetState + ", width/height: " + width + "/" + height
- + ", " + view.toString());
- }
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
- }
-
- /**
- * @hide
- */
- @Override
- @RestrictTo(LIBRARY_GROUP)
- public void onSurfaceDestroyed(View view) {
- if (DEBUG) {
- Log.d(TAG, "onSurfaceDestroyed(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState + ", " + view.toString());
- }
- }
-
- /**
- * @hide
- */
- @Override
- @RestrictTo(LIBRARY_GROUP)
- public void onSurfaceChanged(View view, int width, int height) {
- 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);
- }
- mCurrentView = view;
- if (mViewTypeChangedListener != null) {
- mViewTypeChangedListener.onViewTypeChanged(mInstance, view.getViewType());
- }
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
- }
-
- ///////////////////////////////////////////////////
- // Protected or private methods
- ///////////////////////////////////////////////////
-
- private void attachMediaControlView() {
- // Get MediaController from MediaSession and set it inside MediaControlView
- mMediaControlView.setController(mMediaSession.getController());
-
- LayoutParams params =
- new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
- mInstance.addView(mMediaControlView, params);
- }
-
- private boolean isInPlaybackState() {
- return (mMediaPlayer != null || mRoutePlayer != null)
- && mCurrentState != STATE_ERROR
- && mCurrentState != STATE_IDLE
- && mCurrentState != STATE_PREPARING;
- }
-
- private boolean needToStart() {
- return (mMediaPlayer != null || mRoutePlayer != null)
- && isAudioGranted()
- && isWaitingPlayback();
- }
-
- private boolean isPlaying() {
- return mMediaPlayer != null
- && mMediaPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING;
- }
-
- private boolean isWaitingPlayback() {
- return mCurrentState != STATE_PLAYING && mTargetState == STATE_PLAYING;
- }
-
- private boolean isAudioGranted() {
- return mAudioFocused || mAudioFocusType == AudioManager.AUDIOFOCUS_NONE;
- }
-
- private AudioManager.OnAudioFocusChangeListener mAudioFocusListener =
- new AudioManager.OnAudioFocusChangeListener() {
- @Override
- public void onAudioFocusChange(int focusChange) {
- switch (focusChange) {
- case AudioManager.AUDIOFOCUS_GAIN:
- mAudioFocused = true;
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
- break;
- case AudioManager.AUDIOFOCUS_LOSS:
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
- mAudioFocused = false;
- if (isInPlaybackState() && isPlaying()) {
- mMediaController.getTransportControls().pause();
- } else {
- mTargetState = STATE_PAUSED;
- }
- }
- }
- };
-
- @SuppressWarnings("deprecation")
- private void requestAudioFocus(int focusType) {
- int result;
- if (android.os.Build.VERSION.SDK_INT >= 26) {
- AudioFocusRequest focusRequest;
- focusRequest = new AudioFocusRequest.Builder(focusType)
- .setAudioAttributes((AudioAttributes) mAudioAttributes.unwrap())
- .setOnAudioFocusChangeListener(mAudioFocusListener)
- .build();
- result = mAudioManager.requestAudioFocus(focusRequest);
- } else {
- result = mAudioManager.requestAudioFocus(mAudioFocusListener,
- AudioManager.STREAM_MUSIC,
- focusType);
- }
- if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
- mAudioFocused = false;
- } else if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
- mAudioFocused = true;
- } else if (result == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
- mAudioFocused = false;
- }
- }
-
- // Creates a MediaPlayer instance and prepare playback.
- private void openVideo(DataSourceDesc dsd) {
- Uri uri = dsd.getUri();
- Map<String, String> headers = dsd.getUriHeaders();
- resetPlayer();
- if (isRemotePlayback()) {
- // TODO: b/77556429
- mRoutePlayer.openVideo(uri);
- return;
- }
-
- try {
- Log.d(TAG, "openVideo(): creating new MediaPlayer instance.");
- mMediaPlayer = MediaPlayer2.create();
- mSurfaceView.setMediaPlayer(mMediaPlayer);
- mTextureView.setMediaPlayer(mMediaPlayer);
- mCurrentView.assignSurfaceToMediaPlayer(mMediaPlayer);
-
- final Context context = mInstance.getContext();
- mSubtitleController = new SubtitleController(context);
- mSubtitleController.registerRenderer(new ClosedCaptionRenderer(context));
- mSubtitleController.setAnchor((SubtitleController.Anchor) mSubtitleView);
- Executor executor = new Executor() {
- @Override
- public void execute(Runnable runnable) {
- runnable.run();
- }
- };
- mMediaPlayer.setMediaPlayer2EventCallback(executor, mMediaPlayer2Callback);
-
- mCurrentBufferPercentage = -1;
- mMediaPlayer.setDataSource(dsd);
- mMediaPlayer.setAudioAttributes(mAudioAttributes);
- // we don't set the target state here either, but preserve the
- // target state that was there before.
- mCurrentState = STATE_PREPARING;
- mMediaPlayer.prepare();
-
- // Save file name as title since the file may not have a title Metadata.
- mTitle = uri.getPath();
- String scheme = uri.getScheme();
- if (scheme != null && scheme.equals("file")) {
- mTitle = uri.getLastPathSegment();
- mRetriever = new MediaMetadataRetriever();
- mRetriever.setDataSource(context, uri);
- }
-
- if (DEBUG) {
- Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- } catch (IllegalArgumentException ex) {
- Log.w(TAG, "Unable to open content: " + uri, ex);
- mCurrentState = STATE_ERROR;
- mTargetState = STATE_ERROR;
- mMediaPlayer2Callback.onError(mMediaPlayer, dsd,
- MediaPlayer2.MEDIA_ERROR_UNKNOWN, MediaPlayer2.MEDIA_ERROR_IO);
- }
- }
-
- /*
- * Reset the media player in any state
- */
- @SuppressWarnings("deprecation")
- private void resetPlayer() {
- if (mMediaPlayer != null) {
- final MediaPlayer2 player = mMediaPlayer;
- new AsyncTask<MediaPlayer2, Void, Void>() {
- @Override
- protected Void doInBackground(MediaPlayer2... players) {
- // TODO: Fix NPE while MediaPlayer2.close()
- //players[0].close();
- return null;
- }
- }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, player);
- mMediaPlayer = null;
- mTextureView.setMediaPlayer(null);
- mSurfaceView.setMediaPlayer(null);
- mCurrentState = STATE_IDLE;
- mTargetState = STATE_IDLE;
- if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
- mAudioManager.abandonAudioFocus(null);
- }
- }
- mVideoWidth = 0;
- mVideoHeight = 0;
- }
-
- private void updatePlaybackState() {
- if (mStateBuilder == null) {
- long playbackActions = PlaybackStateCompat.ACTION_PLAY
- | PlaybackStateCompat.ACTION_PAUSE
- | PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD
- | PlaybackStateCompat.ACTION_SEEK_TO;
- mStateBuilder = new PlaybackStateCompat.Builder();
- mStateBuilder.setActions(playbackActions);
-
- if (mCustomActionList != null) {
- for (PlaybackStateCompat.CustomAction action : mCustomActionList) {
- mStateBuilder.addCustomAction(action);
- }
- }
- }
- mStateBuilder.setState(getCorrespondingPlaybackState(),
- mMediaPlayer.getCurrentPosition(), mSpeed);
- if (mCurrentState != STATE_ERROR
- && mCurrentState != STATE_IDLE
- && mCurrentState != STATE_PREPARING) {
- if (mCurrentBufferPercentage == -1) {
- mStateBuilder.setBufferedPosition(-1);
- } else {
- mStateBuilder.setBufferedPosition(
- (long) (mCurrentBufferPercentage / 100.0 * mMediaPlayer.getDuration()));
- }
- }
-
- // Set PlaybackState for MediaSession
- if (mMediaSession != null) {
- PlaybackStateCompat state = mStateBuilder.build();
- mMediaSession.setPlaybackState(state);
- }
- }
-
- private int getCorrespondingPlaybackState() {
- switch (mCurrentState) {
- case STATE_ERROR:
- return PlaybackStateCompat.STATE_ERROR;
- case STATE_IDLE:
- return PlaybackStateCompat.STATE_NONE;
- case STATE_PREPARING:
- return PlaybackStateCompat.STATE_CONNECTING;
- case STATE_PREPARED:
- return PlaybackStateCompat.STATE_PAUSED;
- case STATE_PLAYING:
- return PlaybackStateCompat.STATE_PLAYING;
- case STATE_PAUSED:
- return PlaybackStateCompat.STATE_PAUSED;
- case STATE_PLAYBACK_COMPLETED:
- return PlaybackStateCompat.STATE_STOPPED;
- default:
- return -1;
- }
- }
-
- private final Runnable mFadeOut = new Runnable() {
- @Override
- public void run() {
- if (mCurrentState == STATE_PLAYING) {
- mMediaControlView.setVisibility(View.GONE);
- }
- }
- };
-
- private void showController() {
- if (mMediaControlView == null || !isInPlaybackState()
- || (mIsMusicMediaType && mSizeType == SIZE_TYPE_FULL)) {
- return;
- }
- mMediaControlView.removeCallbacks(mFadeOut);
- mMediaControlView.setVisibility(View.VISIBLE);
- if (mShowControllerIntervalMs != 0
- && !mAccessibilityManager.isTouchExplorationEnabled()) {
- mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
- }
- }
-
- private void toggleMediaControlViewVisibility() {
- if (mMediaControlView.getVisibility() == View.VISIBLE) {
- mMediaControlView.removeCallbacks(mFadeOut);
- mMediaControlView.setVisibility(View.GONE);
- } else {
- showController();
- }
- }
-
- private void applySpeed() {
- if (android.os.Build.VERSION.SDK_INT < 23) {
- return;
- }
- PlaybackParams params = mMediaPlayer.getPlaybackParams().allowDefaults();
- if (mSpeed != params.getSpeed()) {
- try {
- params.setSpeed(mSpeed);
- mMediaPlayer.setPlaybackParams(params);
- mFallbackSpeed = mSpeed;
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "PlaybackParams has unsupported value: " + e);
- float fallbackSpeed = mMediaPlayer.getPlaybackParams().allowDefaults().getSpeed();
- if (fallbackSpeed > 0.0f) {
- mFallbackSpeed = fallbackSpeed;
- }
- mSpeed = mFallbackSpeed;
- }
- }
- }
-
- private boolean isRemotePlayback() {
- if (mMediaController == null) {
- return false;
- }
- PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo();
- return playbackInfo != null
- && playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
- }
-
- private void selectOrDeselectSubtitle(boolean select) {
- if (!isInPlaybackState()) {
- return;
- }
- if (select) {
- if (mSubtitleTrackIndices.size() > 0) {
- mSelectedSubtitleTrackIndex = mSubtitleTrackIndices.get(0).first;
- mSubtitleController.selectTrack(mSubtitleTrackIndices.get(0).second);
- mMediaPlayer.selectTrack(mSelectedSubtitleTrackIndex);
- mSubtitleView.setVisibility(View.VISIBLE);
- }
- } else {
- if (mSelectedSubtitleTrackIndex != INVALID_TRACK_INDEX) {
- mMediaPlayer.deselectTrack(mSelectedSubtitleTrackIndex);
- mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
- mSubtitleView.setVisibility(View.GONE);
- }
- }
- }
-
- private void extractTracks() {
- List<MediaPlayer2.TrackInfo> trackInfos = mMediaPlayer.getTrackInfo();
- mVideoTrackIndices = new ArrayList<>();
- mAudioTrackIndices = new ArrayList<>();
- mSubtitleTrackIndices = new ArrayList<>();
- mSubtitleController.reset();
- for (int i = 0; i < trackInfos.size(); ++i) {
- int trackType = trackInfos.get(i).getTrackType();
- if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
- mVideoTrackIndices.add(i);
- } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
- mAudioTrackIndices.add(i);
- } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
- SubtitleTrack track = mSubtitleController.addTrack(trackInfos.get(i).getFormat());
- if (track != null) {
- mSubtitleTrackIndices.add(new Pair<>(i, track));
- }
- }
- }
- // Select first tracks as default
- if (mVideoTrackIndices.size() > 0) {
- mSelectedVideoTrackIndex = 0;
- }
- if (mAudioTrackIndices.size() > 0) {
- mSelectedAudioTrackIndex = 0;
- }
- if (mVideoTrackIndices.size() == 0 && mAudioTrackIndices.size() > 0) {
- mIsMusicMediaType = true;
- }
-
- 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);
- }
-
- private void extractMetadata() {
- if (mRetriever == null) {
- return;
- }
- // Get and set duration and title values as MediaMetadata for MediaControlView2
- MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
- String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
- if (title != null) {
- mTitle = title;
- }
- builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle);
- builder.putLong(
- MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
-
- if (mMediaSession != null) {
- mMediaSession.setMetadata(builder.build());
- }
- }
-
- @SuppressWarnings("deprecation")
- private void extractAudioMetadata() {
- if (mRetriever == null || !mIsMusicMediaType) {
- return;
- }
-
- mResources = mInstance.getResources();
- mManager = (WindowManager) mInstance.getContext().getApplicationContext()
- .getSystemService(Context.WINDOW_SERVICE);
-
- byte[] album = mRetriever.getEmbeddedPicture();
- if (album != null) {
- Bitmap bitmap = BitmapFactory.decodeByteArray(album, 0, album.length);
- mMusicAlbumDrawable = new BitmapDrawable(bitmap);
-
- Palette.Builder builder = Palette.from(bitmap);
- builder.generate(new Palette.PaletteAsyncListener() {
- @Override
- public void onGenerated(Palette palette) {
- mDominantColor = palette.getDominantColor(0);
- if (mMusicView != null) {
- mMusicView.setBackgroundColor(mDominantColor);
- }
- }
- });
- } else {
- mMusicAlbumDrawable = mResources.getDrawable(R.drawable.ic_default_album_image);
- }
-
- String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
- if (title != null) {
- mMusicTitleText = title;
- } else {
- mMusicTitleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
- }
-
- String artist = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
- if (artist != null) {
- mMusicArtistText = artist;
- } else {
- mMusicArtistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
- }
-
- // Send title and artist string to MediaControlView2
- MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
- builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mMusicTitleText);
- builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mMusicArtistText);
- mMediaSession.setMetadata(builder.build());
-
- // Display Embedded mode as default
- mInstance.removeView(mSurfaceView);
- mInstance.removeView(mTextureView);
- inflateMusicView(R.layout.embedded_music);
- }
-
- private int retrieveOrientation() {
- DisplayMetrics dm = Resources.getSystem().getDisplayMetrics();
- int width = dm.widthPixels;
- int height = dm.heightPixels;
-
- return (height > width)
- ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
- : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
- }
-
- private void inflateMusicView(int layoutId) {
- mInstance.removeView(mMusicView);
-
- LayoutInflater inflater = (LayoutInflater) mInstance.getContext()
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View v = inflater.inflate(layoutId, null);
- v.setBackgroundColor(mDominantColor);
-
- ImageView albumView = v.findViewById(R.id.album);
- if (albumView != null) {
- albumView.setImageDrawable(mMusicAlbumDrawable);
- }
-
- TextView titleView = v.findViewById(R.id.title);
- if (titleView != null) {
- titleView.setText(mMusicTitleText);
- }
-
- TextView artistView = v.findViewById(R.id.artist);
- if (artistView != null) {
- artistView.setText(mMusicArtistText);
- }
-
- mMusicView = v;
- mInstance.addView(mMusicView, 0);
- }
-
- MediaPlayer2EventCallback mMediaPlayer2Callback =
- new MediaPlayer2EventCallback() {
- @Override
- public void onVideoSizeChanged(
- MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) {
- if (DEBUG) {
- Log.d(TAG, "onVideoSizeChanged(): size: " + width + "/" + height);
- }
- mVideoWidth = mp.getVideoWidth();
- mVideoHeight = mp.getVideoHeight();
- if (DEBUG) {
- Log.d(TAG, "onVideoSizeChanged(): mVideoSize:" + mVideoWidth + "/"
- + mVideoHeight);
- }
- if (mVideoWidth != 0 && mVideoHeight != 0) {
- mInstance.requestLayout();
- }
- }
-
- @Override
- public void onInfo(
- MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
- if (what == MediaPlayer2.MEDIA_INFO_METADATA_UPDATE) {
- extractTracks();
- } else if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
- this.onPrepared(mp, dsd);
- } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
- this.onCompletion(mp, dsd);
- } else if (what == MediaPlayer2.MEDIA_INFO_BUFFERING_UPDATE) {
- this.onBufferingUpdate(mp, dsd, extra);
- }
- }
-
- @Override
- public void onError(
- MediaPlayer2 mp, DataSourceDesc dsd, int frameworkErr, int implErr) {
- if (DEBUG) {
- Log.d(TAG, "Error: " + frameworkErr + "," + implErr);
- }
- mCurrentState = STATE_ERROR;
- mTargetState = STATE_ERROR;
- updatePlaybackState();
-
- if (mMediaControlView != null) {
- mMediaControlView.setVisibility(View.GONE);
- }
- }
-
- @Override
- public void onCallCompleted(
- MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
- if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
- updatePlaybackState();
- }
- }
-
- @Override
- public void onSubtitleData(MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) {
- if (DEBUG) {
- Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
- + ", getCurrentPosition: " + mp.getCurrentPosition()
- + ", getStartTimeUs(): " + data.getStartTimeUs()
- + ", diff: "
- + (data.getStartTimeUs() / 1000 - mp.getCurrentPosition())
- + "ms, getDurationUs(): " + data.getDurationUs());
-
- }
- final int index = data.getTrackIndex();
- if (index != mSelectedSubtitleTrackIndex) {
- Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
- + ", selected track index: " + mSelectedSubtitleTrackIndex);
- return;
- }
- for (Pair<Integer, SubtitleTrack> p : mSubtitleTrackIndices) {
- if (p.first == index) {
- SubtitleTrack track = p.second;
- track.onData(data);
- }
- }
- }
-
- private void onPrepared(MediaPlayer2 mp, DataSourceDesc dsd) {
- if (DEBUG) {
- Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- mCurrentState = STATE_PREPARED;
- // Create and set playback state for MediaControlView2
- updatePlaybackState();
-
- if (mMediaSession != null) {
- extractTracks();
- extractMetadata();
- extractAudioMetadata();
- }
-
- if (mMediaControlView != null) {
- mMediaControlView.setEnabled(true);
- }
- int videoWidth = mp.getVideoWidth();
- int videoHeight = mp.getVideoHeight();
-
- // mSeekWhenPrepared may be changed after seekTo() call
- long seekToPosition = mSeekWhenPrepared;
- if (seekToPosition != 0) {
- mMediaController.getTransportControls().seekTo(seekToPosition);
- }
-
- if (videoWidth != 0 && videoHeight != 0) {
- if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) {
- mVideoWidth = videoWidth;
- mVideoHeight = videoHeight;
- mInstance.requestLayout();
- }
-
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
-
- } else {
- // We don't know the video size yet, but should start anyway.
- // The video size might be reported to us later.
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
- }
- // Get and set duration and title values as MediaMetadata for MediaControlView2
- MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
-
- builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle);
- builder.putLong(
- MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
-
- if (mMediaSession != null) {
- mMediaSession.setMetadata(builder.build());
-
- if (mNeedUpdateMediaType) {
- mMediaSession.sendSessionEvent(
- MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS,
- mMediaTypeData);
- mNeedUpdateMediaType = false;
- }
- }
- }
-
- @SuppressWarnings("deprecation")
- private void onCompletion(MediaPlayer2 mp, DataSourceDesc dsd) {
- mCurrentState = STATE_PLAYBACK_COMPLETED;
- mTargetState = STATE_PLAYBACK_COMPLETED;
- updatePlaybackState();
- if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
- mAudioManager.abandonAudioFocus(null);
- }
- }
-
- private void onBufferingUpdate(MediaPlayer2 mp, DataSourceDesc dsd, int percent) {
- mCurrentBufferPercentage = percent;
- updatePlaybackState();
- }
- };
-
- private class MediaSessionCallback extends MediaSessionCompat.Callback {
- @Override
- public void onCommand(String command, Bundle args, ResultReceiver receiver) {
- if (isRemotePlayback()) {
- 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);
- if (subtitleIndex != INVALID_TRACK_INDEX) {
- int subtitleTrackIndex = mSubtitleTrackIndices.get(subtitleIndex).first;
- if (subtitleTrackIndex != mSelectedSubtitleTrackIndex) {
- mSelectedSubtitleTrackIndex = subtitleTrackIndex;
- mInstance.setSubtitleEnabled(true);
- }
- }
- break;
- case MediaControlView2.COMMAND_HIDE_SUBTITLE:
- mInstance.setSubtitleEnabled(false);
- break;
- case MediaControlView2.COMMAND_SELECT_AUDIO_TRACK:
- int audioIndex = args.getInt(MediaControlView2.KEY_SELECTED_AUDIO_INDEX,
- INVALID_TRACK_INDEX);
- if (audioIndex != INVALID_TRACK_INDEX) {
- int audioTrackIndex = mAudioTrackIndices.get(audioIndex);
- if (audioTrackIndex != mSelectedAudioTrackIndex) {
- mSelectedAudioTrackIndex = audioTrackIndex;
- mMediaPlayer.selectTrack(mSelectedAudioTrackIndex);
- }
- }
- break;
- case MediaControlView2.COMMAND_SET_PLAYBACK_SPEED:
- float speed = args.getFloat(
- MediaControlView2.KEY_PLAYBACK_SPEED, INVALID_SPEED);
- if (speed != INVALID_SPEED && speed != mSpeed) {
- setSpeed(speed);
- mSpeed = speed;
- }
- break;
- case MediaControlView2.COMMAND_MUTE:
- mVolumeLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
- mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
- break;
- case MediaControlView2.COMMAND_UNMUTE:
- mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeLevel, 0);
- break;
- }
- }
- showController();
- }
-
- @Override
- public void onCustomAction(final String action, final Bundle extras) {
- mCustomActionListenerRecord.first.execute(new Runnable() {
- @Override
- public void run() {
- mCustomActionListenerRecord.second.onCustomAction(action, extras);
- }
- });
- showController();
- }
-
- @Override
- public void onPlay() {
- if (!isAudioGranted()) {
- requestAudioFocus(mAudioFocusType);
- }
-
- if ((isInPlaybackState() && mCurrentView.hasAvailableSurface()) || mIsMusicMediaType) {
- if (isRemotePlayback()) {
- mRoutePlayer.onPlay();
- } else {
- applySpeed();
- mMediaPlayer.play();
- mCurrentState = STATE_PLAYING;
- updatePlaybackState();
- }
- mCurrentState = STATE_PLAYING;
- }
- mTargetState = STATE_PLAYING;
- if (DEBUG) {
- Log.d(TAG, "onPlay(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- showController();
- }
-
- @Override
- public void onPause() {
- if (isInPlaybackState()) {
- if (isRemotePlayback()) {
- mRoutePlayer.onPlay();
- mCurrentState = STATE_PAUSED;
- } else if (isPlaying()) {
- mMediaPlayer.pause();
- mCurrentState = STATE_PAUSED;
- updatePlaybackState();
- }
- }
- mTargetState = STATE_PAUSED;
- if (DEBUG) {
- Log.d(TAG, "onPause(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- showController();
- }
-
- @Override
- public void onSeekTo(long pos) {
- if (isInPlaybackState()) {
- if (isRemotePlayback()) {
- mRoutePlayer.onPlay();
- } else {
- if (android.os.Build.VERSION.SDK_INT < 26) {
- mMediaPlayer.seekTo((int) pos);
- } else {
- mMediaPlayer.seekTo(pos, MediaPlayer2.SEEK_PREVIOUS_SYNC);
- }
- mSeekWhenPrepared = 0;
- }
- } else {
- mSeekWhenPrepared = pos;
- }
- showController();
- }
-
- @Override
- public void onStop() {
- if (isRemotePlayback()) {
- mRoutePlayer.onPlay();
- } else {
- resetPlayer();
- }
- showController();
- }
- }
-}
diff --git a/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoTextureViewWithMp1.java b/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoTextureViewWithMp1.java
deleted file mode 100644
index e20d78f..0000000
--- a/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoTextureViewWithMp1.java
+++ /dev/null
@@ -1,184 +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.media.widget;
-
-import static androidx.media.widget.VideoView2.VIEW_TYPE_TEXTUREVIEW;
-
-import android.content.Context;
-import android.graphics.SurfaceTexture;
-import android.media.MediaPlayer;
-import android.util.Log;
-import android.view.Surface;
-import android.view.TextureView;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-
-@RequiresApi(21)
-class VideoTextureViewWithMp1 extends TextureView
- implements VideoViewInterfaceWithMp1, TextureView.SurfaceTextureListener {
- private static final String TAG = "VideoTextureViewWithMp1";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private Surface mSurface;
- private SurfaceListener mSurfaceListener;
- private MediaPlayer mMediaPlayer;
- // A flag to indicate taking over other view should be proceed.
- private boolean mIsTakingOverOldView;
- private VideoViewInterfaceWithMp1 mOldView;
-
- VideoTextureViewWithMp1(Context context) {
- super(context, null);
- setSurfaceTextureListener(this);
- }
-
- ////////////////////////////////////////////////////
- // implements VideoViewInterfaceWithMp1
- ////////////////////////////////////////////////////
-
- @Override
- public boolean assignSurfaceToMediaPlayer(MediaPlayer mp) {
- if (mp == null || !hasAvailableSurface()) {
- // Surface is not ready.
- return false;
- }
- mp.setSurface(mSurface);
- return true;
- }
-
- @Override
- public void setSurfaceListener(SurfaceListener l) {
- mSurfaceListener = l;
- }
-
- @Override
- public int getViewType() {
- return VIEW_TYPE_TEXTUREVIEW;
- }
-
- @Override
- public void setMediaPlayer(MediaPlayer mp) {
- mMediaPlayer = mp;
- if (mIsTakingOverOldView) {
- takeOver(mOldView);
- }
- }
-
- @Override
- public void takeOver(@NonNull VideoViewInterfaceWithMp1 oldView) {
- if (assignSurfaceToMediaPlayer(mMediaPlayer)) {
- ((View) oldView).setVisibility(GONE);
- mIsTakingOverOldView = false;
- mOldView = null;
- if (mSurfaceListener != null) {
- mSurfaceListener.onSurfaceTakeOverDone(this);
- }
- } else {
- mIsTakingOverOldView = true;
- mOldView = oldView;
- }
- }
-
- @Override
- public boolean hasAvailableSurface() {
- return mSurface != null && mSurface.isValid();
- }
-
- ////////////////////////////////////////////////////
- // implements TextureView.SurfaceTextureListener
- ////////////////////////////////////////////////////
-
- @Override
- public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
- mSurface = new Surface(surfaceTexture);
- if (mIsTakingOverOldView) {
- takeOver(mOldView);
- } else {
- assignSurfaceToMediaPlayer(mMediaPlayer);
- }
- if (mSurfaceListener != null) {
- mSurfaceListener.onSurfaceCreated(this, width, height);
- }
- }
-
- @Override
- public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
- if (mSurfaceListener != null) {
- mSurfaceListener.onSurfaceChanged(this, width, height);
- }
- // requestLayout(); // TODO: figure out if it should be called here?
- }
-
- @Override
- public void onSurfaceTextureUpdated(SurfaceTexture surface) {
- // no-op
- }
-
- @Override
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
- if (mSurfaceListener != null) {
- mSurfaceListener.onSurfaceDestroyed(this);
- }
- mSurface = null;
- return true;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int videoWidth = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoWidth();
- int videoHeight = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoHeight();
- if (DEBUG) {
- Log.d(TAG, "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", "
- + MeasureSpec.toString(heightMeasureSpec) + ")");
- Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
- Log.i(TAG, " viewSize: " + getWidth() + "/" + getHeight());
- Log.i(TAG, " mVideoWidth/height: " + videoWidth + ", " + videoHeight);
- }
-
- int width = getDefaultSize(videoWidth, widthMeasureSpec);
- int height = getDefaultSize(videoHeight, heightMeasureSpec);
-
- if (videoWidth > 0 && videoHeight > 0) {
- int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
- int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
-
- width = widthSpecSize;
- height = heightSpecSize;
-
- // for compatibility, we adjust size based on aspect ratio
- if (videoWidth * height < width * videoHeight) {
- width = height * videoWidth / videoHeight;
- if (DEBUG) {
- Log.d(TAG, "image too wide, correcting. width: " + width);
- }
- } else if (videoWidth * height > width * videoHeight) {
- height = width * videoHeight / videoWidth;
- if (DEBUG) {
- Log.d(TAG, "image too tall, correcting. height: " + height);
- }
- }
- } else {
- // no size yet, just adopt the given spec sizes
- }
- setMeasuredDimension(width, height);
- if (DEBUG) {
- Log.i(TAG, "end of onMeasure()");
- Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
- }
- }
-}
diff --git a/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoView2ImplApi28WithMp1.java b/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoView2ImplApi28WithMp1.java
deleted file mode 100644
index e0f6d36..0000000
--- a/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoView2ImplApi28WithMp1.java
+++ /dev/null
@@ -1,226 +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.media.widget;
-
-import android.content.Context;
-import android.media.MediaPlayer;
-import android.media.MediaPlayer.OnSubtitleDataListener;
-import android.media.SubtitleData;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Pair;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.media.subtitle.ClosedCaptionRenderer;
-import androidx.media.subtitle.SubtitleController;
-import androidx.media.subtitle.SubtitleTrack;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-
-/**
- * Base implementation of VideoView2.
- */
-@RequiresApi(28)
-class VideoView2ImplApi28WithMp1 extends VideoView2ImplBaseWithMp1 {
- private static final String TAG = "VideoView2ImplApi28_1";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private static final int INVALID_TRACK_INDEX = -1;
-
- private ArrayList<Pair<Integer, SubtitleTrack>> mSubtitleTrackIndices;
- private SubtitleController mSubtitleController;
-
- // selected video/audio/subtitle track index as MediaPlayer returns
- private int mSelectedSubtitleTrackIndex;
-
- private SubtitleView mSubtitleView;
- private boolean mSubtitleEnabled;
-
- @Override
- public void initialize(
- VideoView2 instance, Context context,
- @Nullable AttributeSet attrs, int defStyleAttr) {
- super.initialize(instance, context, attrs, defStyleAttr);
- mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
-
- LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT);
- mSubtitleView = new SubtitleView(context);
- mSubtitleView.setLayoutParams(params);
- mSubtitleView.setBackgroundColor(0);
- mInstance.addView(mSubtitleView);
-
- mSubtitleEnabled = (attrs == null) || attrs.getAttributeBooleanValue(
- "http://schemas.android.com/apk/res/android",
- "enableSubtitle", false);
- }
-
- /**
- * Shows or hides closed caption or subtitles if there is any.
- * The first subtitle track will be chosen if there multiple subtitle tracks exist.
- * Default behavior of VideoView2 is not showing subtitle.
- * @param enable shows closed caption or subtitles if this value is true, or hides.
- */
- @Override
- public void setSubtitleEnabled(boolean enable) {
- if (enable != mSubtitleEnabled) {
- selectOrDeselectSubtitle(enable);
- }
- mSubtitleEnabled = enable;
- }
-
- /**
- * Returns true if showing subtitle feature is enabled or returns false.
- * Although there is no subtitle track or closed caption, it can return true, if the feature
- * has been enabled by {@link #setSubtitleEnabled}.
- */
- @Override
- public boolean isSubtitleEnabled() {
- return mSubtitleEnabled;
- }
-
- ///////////////////////////////////////////////////
- // Protected or private methods
- ///////////////////////////////////////////////////
-
- /**
- * Used in openVideo(). Setup MediaPlayer and related objects before calling prepare.
- */
- @Override
- protected void setupMediaPlayer(Context context, Uri uri, Map<String, String> headers)
- throws IOException {
- super.setupMediaPlayer(context, uri, headers);
-
- mSubtitleController = new SubtitleController(context);
- mSubtitleController.registerRenderer(new ClosedCaptionRenderer(context));
- mSubtitleController.setAnchor((SubtitleController.Anchor) mSubtitleView);
-
- mMediaPlayer.setOnSubtitleDataListener(mSubtitleListener);
- }
-
- private void selectOrDeselectSubtitle(boolean select) {
- if (!isInPlaybackState()) {
- return;
- }
- if (select) {
- if (mSubtitleTrackIndices.size() > 0) {
- mSelectedSubtitleTrackIndex = mSubtitleTrackIndices.get(0).first;
- mSubtitleController.selectTrack(mSubtitleTrackIndices.get(0).second);
- mMediaPlayer.selectTrack(mSelectedSubtitleTrackIndex);
- mSubtitleView.setVisibility(View.VISIBLE);
- }
- } else {
- if (mSelectedSubtitleTrackIndex != INVALID_TRACK_INDEX) {
- mMediaPlayer.deselectTrack(mSelectedSubtitleTrackIndex);
- mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
- mSubtitleView.setVisibility(View.GONE);
- }
- }
- }
-
- @Override
- protected 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) {
- SubtitleTrack track = mSubtitleController.addTrack(trackInfos[i].getFormat());
- if (track != null) {
- mSubtitleTrackIndices.add(new Pair<>(i, track));
- }
- }
- }
- // Select first tracks as default
- if (mVideoTrackIndices.size() > 0) {
- mSelectedVideoTrackIndex = 0;
- }
- if (mAudioTrackIndices.size() > 0) {
- mSelectedAudioTrackIndex = 0;
- }
-
- 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);
- }
-
- private OnSubtitleDataListener mSubtitleListener =
- new OnSubtitleDataListener() {
- @Override
- public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
- if (DEBUG) {
- Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
- + ", getCurrentPosition: " + mp.getCurrentPosition()
- + ", getStartTimeUs(): " + data.getStartTimeUs()
- + ", diff: "
- + (data.getStartTimeUs() / 1000 - mp.getCurrentPosition())
- + "ms, getDurationUs(): " + data.getDurationUs());
-
- }
- final int index = data.getTrackIndex();
- if (index != mSelectedSubtitleTrackIndex) {
- Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
- + ", selected track index: " + mSelectedSubtitleTrackIndex);
- return;
- }
- for (Pair<Integer, SubtitleTrack> p : mSubtitleTrackIndices) {
- if (p.first == index) {
- SubtitleTrack track = p.second;
- track.onData(data);
- }
- }
- }
- };
-
- @Override
- protected void doShowSubtitleCommand(Bundle args) {
- int subtitleIndex = args.getInt(
- MediaControlView2.KEY_SELECTED_SUBTITLE_INDEX,
- INVALID_TRACK_INDEX);
- if (subtitleIndex != INVALID_TRACK_INDEX) {
- int subtitleTrackIndex = mSubtitleTrackIndices.get(subtitleIndex).first;
- if (subtitleTrackIndex != mSelectedSubtitleTrackIndex) {
- mSelectedSubtitleTrackIndex = subtitleTrackIndex;
- mInstance.setSubtitleEnabled(true);
- }
- }
- }
-
- @Override
- protected void doHideSubtitleCommand() {
- mInstance.setSubtitleEnabled(false);
- }
-}
diff --git a/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoView2ImplBaseWithMp1.java b/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoView2ImplBaseWithMp1.java
deleted file mode 100644
index 8fdb1b1..0000000
--- a/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoView2ImplBaseWithMp1.java
+++ /dev/null
@@ -1,1473 +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.media.widget;
-
-import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.media.AudioAttributes;
-import android.media.AudioFocusRequest;
-import android.media.AudioManager;
-import android.media.MediaMetadataRetriever;
-import android.media.MediaPlayer;
-import android.media.PlaybackParams;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.support.v4.media.MediaMetadataCompat;
-import android.support.v4.media.session.MediaControllerCompat;
-import android.support.v4.media.session.MediaControllerCompat.PlaybackInfo;
-import android.support.v4.media.session.MediaSessionCompat;
-import android.support.v4.media.session.PlaybackStateCompat;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.annotation.RestrictTo;
-import androidx.media.AudioAttributesCompat;
-import androidx.media.DataSourceDesc;
-import androidx.media.MediaItem2;
-import androidx.media.MediaMetadata2;
-import androidx.media.SessionToken2;
-import androidx.mediarouter.media.MediaControlIntent;
-import androidx.mediarouter.media.MediaItemStatus;
-import androidx.mediarouter.media.MediaRouteSelector;
-import androidx.mediarouter.media.MediaRouter;
-import androidx.palette.graphics.Palette;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * Base implementation of VideoView2.
- */
-@RequiresApi(21) // TODO correct minSdk API use incompatibilities and remove before release.
-class VideoView2ImplBaseWithMp1
- implements VideoView2Impl, VideoViewInterfaceWithMp1.SurfaceListener {
- private static final String TAG = "VideoView2ImplBase_1";
- 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;
- private static final int STATE_IDLE = 0;
- private static final int STATE_PREPARING = 1;
- private static final int STATE_PREPARED = 2;
- private static final int STATE_PLAYING = 3;
- private static final int STATE_PAUSED = 4;
- private static final int STATE_PLAYBACK_COMPLETED = 5;
-
- private static final int INVALID_TRACK_INDEX = -1;
- private static final float INVALID_SPEED = 0f;
-
- private static final int SIZE_TYPE_EMBEDDED = 0;
- private static final int SIZE_TYPE_FULL = 1;
- private static final int SIZE_TYPE_MINIMAL = 2;
-
- private AccessibilityManager mAccessibilityManager;
- private AudioManager mAudioManager;
- private AudioAttributes mAudioAttributes;
- private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain
- private boolean mAudioFocused = false;
-
- private Pair<Executor, VideoView2.OnCustomActionListener> mCustomActionListenerRecord;
- private VideoView2.OnViewTypeChangedListener mViewTypeChangedListener;
-
- private VideoViewInterfaceWithMp1 mCurrentView;
- private VideoTextureViewWithMp1 mTextureView;
- private VideoSurfaceViewWithMp1 mSurfaceView;
-
- protected MediaPlayer mMediaPlayer;
- private DataSourceDesc mDsd;
- private Uri mUri;
- private Map<String, String> mHeaders;
- private MediaControlView2 mMediaControlView;
- protected MediaSessionCompat mMediaSession;
- private MediaControllerCompat mMediaController;
- private MediaMetadata2 mMediaMetadata;
- private MediaMetadataRetriever mRetriever;
- private boolean mNeedUpdateMediaType;
- private Bundle mMediaTypeData;
- private String mTitle;
-
- private WindowManager mManager;
- private Resources mResources;
- private View mMusicView;
- private Drawable mMusicAlbumDrawable;
- private String mMusicTitleText;
- private String mMusicArtistText;
- private int mPrevWidth;
- private int mPrevHeight;
- private int mDominantColor;
- private int mSizeType;
-
- private PlaybackStateCompat.Builder mStateBuilder;
- private List<PlaybackStateCompat.CustomAction> mCustomActionList;
-
- private int mTargetState = STATE_IDLE;
- private int mCurrentState = STATE_IDLE;
- private int mCurrentBufferPercentage;
- private long mSeekWhenPrepared; // recording the seek position while preparing
-
- private int mVideoWidth;
- private int mVideoHeight;
-
- protected ArrayList<Integer> mVideoTrackIndices;
- protected ArrayList<Integer> mAudioTrackIndices;
-
- // selected video/audio/subtitle track index as MediaPlayer returns
- protected int mSelectedVideoTrackIndex;
- protected int mSelectedAudioTrackIndex;
-
- private float mSpeed;
- private float mFallbackSpeed; // keep the original speed before 'pause' is called.
- private float mVolumeLevelFloat;
- private int mVolumeLevel;
- protected VideoView2 mInstance;
-
- private long mShowControllerIntervalMs;
-
- private MediaRouter mMediaRouter;
- private MediaRouteSelector mRouteSelector;
- private MediaRouter.RouteInfo mRoute;
- private RoutePlayer mRoutePlayer;
-
- 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(mInstance.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)
- // TODO: b/77556429
- mRoutePlayer.openVideo(mUri);
- }
- }
-
- @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)
- // TODO: b/77556429
- openVideo(mUri, mHeaders);
- }
- }
- };
-
- @Override
- public void initialize(
- VideoView2 instance, Context context,
- @Nullable AttributeSet attrs, int defStyleAttr) {
- mInstance = instance;
-
- mVideoWidth = 0;
- mVideoHeight = 0;
- mSpeed = 1.0f;
- mFallbackSpeed = mSpeed;
- mShowControllerIntervalMs = DEFAULT_SHOW_CONTROLLER_INTERVAL_MS;
-
- mAccessibilityManager = (AccessibilityManager) context.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
-
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- mAudioAttributes = new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_MEDIA)
- .setContentType(AudioAttributes.CONTENT_TYPE_MOVIE).build();
-
- mInstance.setFocusable(true);
- mInstance.setFocusableInTouchMode(true);
- mInstance.requestFocus();
-
- mTextureView = new VideoTextureViewWithMp1(context);
- mSurfaceView = new VideoSurfaceViewWithMp1(context);
- LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT);
- mTextureView.setLayoutParams(params);
- mSurfaceView.setLayoutParams(params);
- mTextureView.setSurfaceListener(this);
- mSurfaceView.setSurfaceListener(this);
-
- mInstance.addView(mTextureView);
- mInstance.addView(mSurfaceView);
-
- boolean enableControlView = (attrs == null) || attrs.getAttributeBooleanValue(
- "http://schemas.android.com/apk/res/android",
- "enableControlView", true);
- if (enableControlView) {
- mMediaControlView = new MediaControlView2(context);
- }
-
- // Choose surface view by default
- int viewType = (attrs == null) ? VideoView2.VIEW_TYPE_SURFACEVIEW
- : attrs.getAttributeIntValue(
- "http://schemas.android.com/apk/res/android",
- "viewType", VideoView2.VIEW_TYPE_SURFACEVIEW);
- if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
- Log.d(TAG, "viewType attribute is surfaceView.");
- mTextureView.setVisibility(View.GONE);
- mSurfaceView.setVisibility(View.VISIBLE);
- mCurrentView = mSurfaceView;
- } else if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
- Log.d(TAG, "viewType attribute is textureView.");
- mTextureView.setVisibility(View.VISIBLE);
- mSurfaceView.setVisibility(View.GONE);
- mCurrentView = mTextureView;
- }
-
- 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();
- }
-
- /**
- * Sets MediaControlView2 instance. It will replace the previously assigned MediaControlView2
- * instance if any.
- *
- * @param mediaControlView a media control view2 instance.
- * @param intervalMs a time interval in milliseconds until VideoView2 hides MediaControlView2.
- */
- @Override
- public void setMediaControlView2(MediaControlView2 mediaControlView, long intervalMs) {
- mMediaControlView = mediaControlView;
- mShowControllerIntervalMs = intervalMs;
- mMediaControlView.setRouteSelector(mRouteSelector);
-
- if (mInstance.isAttachedToWindow()) {
- attachMediaControlView();
- }
- }
-
- /**
- * Returns MediaControlView2 instance which is currently attached to VideoView2 by default or by
- * {@link #setMediaControlView2} method.
- */
- @Override
- public MediaControlView2 getMediaControlView2() {
- return mMediaControlView;
- }
-
- /**
- * Sets MediaMetadata2 instance. It will replace the previously assigned MediaMetadata2 instance
- * if any.
- *
- * @param metadata a MediaMetadata2 instance.
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setMediaMetadata(MediaMetadata2 metadata) {
- //mProvider.setMediaMetadata_impl(metadata);
- }
-
- /**
- * Returns MediaMetadata2 instance which is retrieved from MediaPlayer inside VideoView2 by
- * default or by {@link #setMediaMetadata} method.
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public MediaMetadata2 getMediaMetadata() {
- return mMediaMetadata;
- }
-
- /**
- * Returns MediaController instance which is connected with MediaSession that VideoView2 is
- * using. This method should be called when VideoView2 is attached to window, or it throws
- * IllegalStateException, since internal MediaSession instance is not available until
- * this view is attached to window. Please check {@link View#isAttachedToWindow}
- * before calling this method.
- *
- * @throws IllegalStateException if interal MediaSession is not created yet.
- * @hide TODO: remove
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public MediaControllerCompat getMediaController() {
- if (mMediaSession == null) {
- throw new IllegalStateException("MediaSession instance is not available.");
- }
- return mMediaController;
- }
-
- /**
- * Returns {@link SessionToken2} so that developers create their own
- * {@link androidx.media.MediaController2} instance. This method should be called when
- * VideoView2 is attached to window, or it throws IllegalStateException.
- *
- * @throws IllegalStateException if interal MediaSession is not created yet.
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public SessionToken2 getMediaSessionToken() {
- //return mProvider.getMediaSessionToken_impl();
- return null;
- }
-
- /**
- * Shows or hides closed caption or subtitles if there is any.
- * The first subtitle track will be chosen if there multiple subtitle tracks exist.
- * Default behavior of VideoView2 is not showing subtitle.
- * @param enable shows closed caption or subtitles if this value is true, or hides.
- */
- @Override
- public void setSubtitleEnabled(boolean enable) {
- // No-op on API < 28
- }
-
- /**
- * Returns true if showing subtitle feature is enabled or returns false.
- * Although there is no subtitle track or closed caption, it can return true, if the feature
- * has been enabled by {@link #setSubtitleEnabled}.
- */
- @Override
- public boolean isSubtitleEnabled() {
- // Not supported on API < 28
- return false;
- }
-
- /**
- * Sets playback speed.
- *
- * It is expressed as a multiplicative factor, where normal speed is 1.0f. If it is less than
- * or equal to zero, it will be just ignored and nothing will be changed. If it exceeds the
- * maximum speed that internal engine supports, system will determine best handling or it will
- * be reset to the normal speed 1.0f.
- * @param speed the playback speed. It should be positive.
- */
- @Override
- public void setSpeed(float speed) {
- if (speed <= 0.0f) {
- Log.e(TAG, "Unsupported speed (" + speed + ") is ignored.");
- return;
- }
- mSpeed = speed;
- if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
- applySpeed();
- }
- updatePlaybackState();
- }
-
- /**
- * 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.
- */
- @Override
- 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},
- * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
- * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. Or use
- * {@link AudioManager#AUDIOFOCUS_NONE} to express that audio focus should not be
- * requested when playback starts. You can for instance use this when playing a silent animation
- * through this class, and you don't want to affect other audio applications playing in the
- * background.
- *
- * @param focusGain the type of audio focus gain that will be requested, or
- * {@link AudioManager#AUDIOFOCUS_NONE} to disable the use audio focus during
- * playback.
- */
- @Override
- public void setAudioFocusRequest(int focusGain) {
- if (focusGain != AudioManager.AUDIOFOCUS_NONE
- && focusGain != AudioManager.AUDIOFOCUS_GAIN
- && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
- && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
- && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) {
- throw new IllegalArgumentException("Illegal audio focus type " + focusGain);
- }
- mAudioFocusType = focusGain;
- }
-
- /**
- * Sets the {@link AudioAttributesCompat} to be used during the playback of the video.
- *
- * @param attributes non-null <code>AudioAttributesCompat</code>.
- */
- @Override
- public void setAudioAttributes(@NonNull AudioAttributesCompat attributes) {
- if (attributes == null) {
- throw new IllegalArgumentException("Illegal null AudioAttributesCompat");
- }
- mAudioAttributes = (AudioAttributes) attributes.unwrap();
- }
-
- /**
- * Sets video path.
- *
- * @param path the path of the video.
- *
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setVideoPath(String path) {
- setVideoUri(Uri.parse(path));
- }
-
- /**
- * Sets video URI.
- *
- * @param uri the URI of the video.
- *
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setVideoUri(Uri uri) {
- setVideoUri(uri, null);
- }
-
- /**
- * Sets video URI using specific headers.
- *
- * @param uri the URI of the video.
- * @param headers the headers for the URI request.
- * Note that the cross domain redirection is allowed by default, but that can be
- * 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.
- */
- @Override
- public void setVideoUri(Uri uri, @Nullable Map<String, String> headers) {
- mSeekWhenPrepared = 0;
- openVideo(uri, headers);
- }
-
- /**
- * Sets {@link MediaItem2} object to render using VideoView2. Alternative way to set media
- * object to VideoView2 is {@link #setDataSource}.
- * @param mediaItem the MediaItem2 to play
- * @see #setDataSource
- *
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setMediaItem(@NonNull MediaItem2 mediaItem) {
- }
-
- /**
- * Sets {@link DataSourceDesc} object to render using VideoView2.
- * @param dataSource the {@link DataSourceDesc} object to play.
- * @see #setMediaItem
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setDataSource(@NonNull DataSourceDesc dataSource) {
- }
-
- /**
- * Selects which view will be used to render video between SurfacView and TextureView.
- *
- * @param viewType the view type to render video
- * <ul>
- * <li>{@link #VideoView2.VIEW_TYPE_SURFACEVIEW}
- * <li>{@link #VideoView2.VIEW_TYPE_TEXTUREVIEW}
- * </ul>
- */
- @Override
- public void setViewType(@VideoView2.ViewType int viewType) {
- if (viewType == mCurrentView.getViewType()) {
- return;
- }
- VideoViewInterfaceWithMp1 targetView;
- if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
- Log.d(TAG, "switching to TextureView");
- targetView = mTextureView;
- } else if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
- Log.d(TAG, "switching to SurfaceView");
- targetView = mSurfaceView;
- } else {
- throw new IllegalArgumentException("Unknown view type: " + viewType);
- }
- ((View) targetView).setVisibility(View.VISIBLE);
- targetView.takeOver(mCurrentView);
- mInstance.requestLayout();
- }
-
- /**
- * Returns view type.
- *
- * @return view type. See {@see setViewType}.
- */
- @Override
- @VideoView2.ViewType
- public int getViewType() {
- return mCurrentView.getViewType();
- }
-
- /**
- * Sets custom actions which will be shown as custom buttons in {@link MediaControlView2}.
- *
- * @param actionList A list of {@link PlaybackStateCompat.CustomAction}. The return value of
- * {@link PlaybackStateCompat.CustomAction#getIcon()} will be used to draw
- * 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
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setCustomActions(List<PlaybackStateCompat.CustomAction> actionList,
- Executor executor, VideoView2.OnCustomActionListener listener) {
- mCustomActionList = actionList;
- mCustomActionListenerRecord = new Pair<>(executor, listener);
-
- // Create a new playback builder in order to clear existing the custom actions.
- mStateBuilder = null;
- updatePlaybackState();
- }
-
- /**
- * Registers a callback to be invoked when a view type change is done.
- * {@see #setViewType(int)}
- * @param l The callback that will be run
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void setOnViewTypeChangedListener(VideoView2.OnViewTypeChangedListener l) {
- mViewTypeChangedListener = l;
- }
-
- @Override
- public void onAttachedToWindowImpl() {
- // Create MediaSession
- mMediaSession = new MediaSessionCompat(mInstance.getContext(), "VideoView2MediaSession");
- mMediaSession.setCallback(new MediaSessionCallback());
- mMediaSession.setActive(true);
- mMediaController = mMediaSession.getController();
- attachMediaControlView();
- if (mCurrentState == STATE_PREPARED) {
- extractTracks();
- extractMetadata();
- extractAudioMetadata();
- if (mNeedUpdateMediaType) {
- mMediaSession.sendSessionEvent(
- MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS,
- mMediaTypeData);
- mNeedUpdateMediaType = false;
- }
- }
-
- mMediaRouter = MediaRouter.getInstance(mInstance.getContext());
- mMediaRouter.setMediaSessionCompat(mMediaSession);
- mMediaRouter.addCallback(mRouteSelector, mRouterCallback,
- MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
- }
-
- @Override
- public void onDetachedFromWindowImpl() {
- mMediaSession.release();
- mMediaSession = null;
- mMediaController = null;
- }
-
- @Override
- public void onTouchEventImpl(MotionEvent ev) {
- if (DEBUG) {
- Log.d(TAG, "onTouchEvent(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
- if (!isMusicMediaType() || mSizeType != SIZE_TYPE_FULL) {
- toggleMediaControlViewVisibility();
- }
- }
- }
-
- @Override
- public void onTrackballEventImpl(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
- if (!isMusicMediaType() || mSizeType != SIZE_TYPE_FULL) {
- toggleMediaControlViewVisibility();
- }
- }
- }
-
- @Override
- public void onMeasureImpl(int widthMeasureSpec, int heightMeasureSpec) {
- if (isMusicMediaType()) {
- int currWidth = mInstance.getMeasuredWidth();
- int currHeight = mInstance.getMeasuredHeight();
- if (mPrevWidth != currWidth || mPrevHeight != currHeight) {
- Point screenSize = new Point();
- mManager.getDefaultDisplay().getSize(screenSize);
- int screenWidth = screenSize.x;
- int screenHeight = screenSize.y;
-
- if (currWidth == screenWidth && currHeight == screenHeight) {
- int orientation = retrieveOrientation();
- if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
- inflateMusicView(R.layout.full_landscape_music);
- } else {
- inflateMusicView(R.layout.full_portrait_music);
- }
-
- if (mSizeType != SIZE_TYPE_FULL) {
- mSizeType = SIZE_TYPE_FULL;
- // Remove existing mFadeOut callback
- mMediaControlView.removeCallbacks(mFadeOut);
- mMediaControlView.setVisibility(View.VISIBLE);
- }
- } else {
- if (mSizeType != SIZE_TYPE_EMBEDDED) {
- mSizeType = SIZE_TYPE_EMBEDDED;
- inflateMusicView(R.layout.embedded_music);
- // Add new mFadeOut callback
- mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
- }
- }
- mPrevWidth = currWidth;
- mPrevHeight = currHeight;
- }
- }
- }
-
- ///////////////////////////////////////////////////
- // Implements VideoViewInterfaceWithMp1.SurfaceListener
- ///////////////////////////////////////////////////
-
- @Override
- public void onSurfaceCreated(View view, int width, int height) {
- if (DEBUG) {
- Log.d(TAG, "onSurfaceCreated(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState + ", width/height: " + width + "/" + height
- + ", " + view.toString());
- }
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
- }
-
- @Override
- public void onSurfaceDestroyed(View view) {
- if (DEBUG) {
- Log.d(TAG, "onSurfaceDestroyed(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState + ", " + view.toString());
- }
- }
-
- @Override
- public void onSurfaceChanged(View view, int width, int height) {
- if (DEBUG) {
- Log.d(TAG, "onSurfaceChanged(). width/height: " + width + "/" + height
- + ", " + view.toString());
- }
- }
-
- @Override
- public void onSurfaceTakeOverDone(VideoViewInterfaceWithMp1 view) {
- if (DEBUG) {
- Log.d(TAG, "onSurfaceTakeOverDone(). Now current view is: " + view);
- }
- mCurrentView = view;
- if (mViewTypeChangedListener != null) {
- mViewTypeChangedListener.onViewTypeChanged(mInstance, view.getViewType());
- }
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
- }
-
- ///////////////////////////////////////////////////
- // Protected or private methods
- ///////////////////////////////////////////////////
-
- private void attachMediaControlView() {
- // Get MediaController from MediaSession and set it inside MediaControlView
- mMediaControlView.setController(mMediaSession.getController());
-
- LayoutParams params =
- new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
- mInstance.addView(mMediaControlView, params);
- }
-
- protected boolean isInPlaybackState() {
- return (mMediaPlayer != null || mRoutePlayer != null)
- && mCurrentState != STATE_ERROR
- && mCurrentState != STATE_IDLE
- && mCurrentState != STATE_PREPARING;
- }
-
- private boolean needToStart() {
- return (mMediaPlayer != null || mRoutePlayer != null)
- && isAudioGranted()
- && isWaitingPlayback();
- }
-
- private boolean isMusicMediaType() {
- return mVideoTrackIndices != null && mVideoTrackIndices.size() == 0;
- }
-
- private boolean isWaitingPlayback() {
- return mCurrentState != STATE_PLAYING && mTargetState == STATE_PLAYING;
- }
-
- private boolean isAudioGranted() {
- return mAudioFocused || mAudioFocusType == AudioManager.AUDIOFOCUS_NONE;
- }
-
- private AudioManager.OnAudioFocusChangeListener mAudioFocusListener =
- new AudioManager.OnAudioFocusChangeListener() {
- @Override
- public void onAudioFocusChange(int focusChange) {
- switch (focusChange) {
- case AudioManager.AUDIOFOCUS_GAIN:
- mAudioFocused = true;
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
- break;
- case AudioManager.AUDIOFOCUS_LOSS:
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
- mAudioFocused = false;
- if (isInPlaybackState() && mMediaPlayer.isPlaying()) {
- mMediaController.getTransportControls().pause();
- } else {
- mTargetState = STATE_PAUSED;
- }
- }
- }
- };
-
- @SuppressWarnings("deprecation")
- private void requestAudioFocus(int focusType) {
- int result;
- if (android.os.Build.VERSION.SDK_INT >= 26) {
- AudioFocusRequest focusRequest;
- focusRequest = new AudioFocusRequest.Builder(focusType)
- .setAudioAttributes(mAudioAttributes)
- .setOnAudioFocusChangeListener(mAudioFocusListener)
- .build();
- result = mAudioManager.requestAudioFocus(focusRequest);
- } else {
- result = mAudioManager.requestAudioFocus(mAudioFocusListener,
- AudioManager.STREAM_MUSIC,
- focusType);
- }
- if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
- mAudioFocused = false;
- } else if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
- mAudioFocused = true;
- } else if (result == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
- mAudioFocused = false;
- }
- }
-
- // Creates a MediaPlayer instance and prepare playback.
- private void openVideo(Uri uri, Map<String, String> headers) {
- resetPlayer();
- mUri = uri;
- if (isRemotePlayback()) {
- // TODO: b/77556429
- mRoutePlayer.openVideo(uri);
- return;
- }
-
- try {
- Log.d(TAG, "openVideo(): creating new MediaPlayer instance.");
- mMediaPlayer = new MediaPlayer();
- final Context context = mInstance.getContext();
- setupMediaPlayer(context, uri, headers);
-
- // we don't set the target state here either, but preserve the
- // target state that was there before.
- mCurrentState = STATE_PREPARING;
- mMediaPlayer.prepareAsync();
-
- // Save file name as title since the file may not have a title Metadata.
- mTitle = uri.getPath();
- String scheme = uri.getScheme();
- if (scheme != null && scheme.equals("file")) {
- mTitle = uri.getLastPathSegment();
- mRetriever = new MediaMetadataRetriever();
- mRetriever.setDataSource(context, uri);
- }
-
- if (DEBUG) {
- Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- } catch (IOException | IllegalArgumentException ex) {
- Log.w(TAG, "Unable to open content: " + uri, ex);
- mCurrentState = STATE_ERROR;
- mTargetState = STATE_ERROR;
- mErrorListener.onError(mMediaPlayer,
- MediaPlayer.MEDIA_ERROR_UNKNOWN, MediaPlayer.MEDIA_ERROR_IO);
- }
- }
-
- /**
- * Used in openVideo(). Setup MediaPlayer and related objects before calling prepare.
- */
- protected void setupMediaPlayer(Context context, Uri uri, Map<String, String> headers)
- throws IOException {
- mSurfaceView.setMediaPlayer(mMediaPlayer);
- mTextureView.setMediaPlayer(mMediaPlayer);
- mCurrentView.assignSurfaceToMediaPlayer(mMediaPlayer);
-
- mMediaPlayer.setOnPreparedListener(mPreparedListener);
- mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
- mMediaPlayer.setOnCompletionListener(mCompletionListener);
- mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener);
- mMediaPlayer.setOnErrorListener(mErrorListener);
- mMediaPlayer.setOnInfoListener(mInfoListener);
- mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
-
- mCurrentBufferPercentage = -1;
- mMediaPlayer.setDataSource(context, uri, headers);
- mMediaPlayer.setAudioAttributes(mAudioAttributes);
- }
-
- /*
- * Reset the media player in any state
- */
- @SuppressWarnings("deprecation")
- private void resetPlayer() {
- if (mMediaPlayer != null) {
- mMediaPlayer.reset();
- mMediaPlayer.release();
- mMediaPlayer = null;
- mTextureView.setMediaPlayer(null);
- mSurfaceView.setMediaPlayer(null);
- mCurrentState = STATE_IDLE;
- mTargetState = STATE_IDLE;
- if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
- mAudioManager.abandonAudioFocus(null);
- }
- }
- mVideoWidth = 0;
- mVideoHeight = 0;
- }
-
- private void updatePlaybackState() {
- if (mStateBuilder == null) {
- long playbackActions = PlaybackStateCompat.ACTION_PLAY
- | PlaybackStateCompat.ACTION_PAUSE
- | PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD
- | PlaybackStateCompat.ACTION_SEEK_TO;
- mStateBuilder = new PlaybackStateCompat.Builder();
- mStateBuilder.setActions(playbackActions);
-
- if (mCustomActionList != null) {
- for (PlaybackStateCompat.CustomAction action : mCustomActionList) {
- mStateBuilder.addCustomAction(action);
- }
- }
- }
- mStateBuilder.setState(getCorrespondingPlaybackState(),
- mMediaPlayer.getCurrentPosition(), mSpeed);
- if (mCurrentState != STATE_ERROR
- && mCurrentState != STATE_IDLE
- && mCurrentState != STATE_PREPARING) {
- if (mCurrentBufferPercentage == -1) {
- mStateBuilder.setBufferedPosition(-1);
- } else {
- mStateBuilder.setBufferedPosition(
- (long) (mCurrentBufferPercentage / 100.0 * mMediaPlayer.getDuration()));
- }
- }
-
- // Set PlaybackState for MediaSession
- if (mMediaSession != null) {
- PlaybackStateCompat state = mStateBuilder.build();
- mMediaSession.setPlaybackState(state);
- }
- }
-
- private int getCorrespondingPlaybackState() {
- switch (mCurrentState) {
- case STATE_ERROR:
- return PlaybackStateCompat.STATE_ERROR;
- case STATE_IDLE:
- return PlaybackStateCompat.STATE_NONE;
- case STATE_PREPARING:
- return PlaybackStateCompat.STATE_CONNECTING;
- case STATE_PREPARED:
- return PlaybackStateCompat.STATE_PAUSED;
- case STATE_PLAYING:
- return PlaybackStateCompat.STATE_PLAYING;
- case STATE_PAUSED:
- return PlaybackStateCompat.STATE_PAUSED;
- case STATE_PLAYBACK_COMPLETED:
- return PlaybackStateCompat.STATE_STOPPED;
- default:
- return -1;
- }
- }
-
- private final Runnable mFadeOut = new Runnable() {
- @Override
- public void run() {
- if (mCurrentState == STATE_PLAYING) {
- mMediaControlView.setVisibility(View.GONE);
- }
- }
- };
-
- private void showController() {
- if (mMediaControlView == null || !isInPlaybackState()
- || (isMusicMediaType() && mSizeType == SIZE_TYPE_FULL)) {
- return;
- }
- mMediaControlView.removeCallbacks(mFadeOut);
- mMediaControlView.setVisibility(View.VISIBLE);
- if (mShowControllerIntervalMs != 0
- && !mAccessibilityManager.isTouchExplorationEnabled()) {
- mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
- }
- }
-
- private void toggleMediaControlViewVisibility() {
- if (mMediaControlView.getVisibility() == View.VISIBLE) {
- mMediaControlView.removeCallbacks(mFadeOut);
- mMediaControlView.setVisibility(View.GONE);
- } else {
- showController();
- }
- }
-
- private void applySpeed() {
- if (android.os.Build.VERSION.SDK_INT < 23) {
- return;
- }
- PlaybackParams params = mMediaPlayer.getPlaybackParams().allowDefaults();
- if (mSpeed != params.getSpeed()) {
- try {
- params.setSpeed(mSpeed);
- mMediaPlayer.setPlaybackParams(params);
- mFallbackSpeed = mSpeed;
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "PlaybackParams has unsupported value: " + e);
- float fallbackSpeed = mMediaPlayer.getPlaybackParams().allowDefaults().getSpeed();
- if (fallbackSpeed > 0.0f) {
- mFallbackSpeed = fallbackSpeed;
- }
- mSpeed = mFallbackSpeed;
- }
- }
- }
-
- private boolean isRemotePlayback() {
- if (mMediaController == null) {
- return false;
- }
- PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo();
- return playbackInfo != null
- && playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
- }
-
- protected void extractTracks() {
- MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
- mVideoTrackIndices = new ArrayList<>();
- mAudioTrackIndices = new ArrayList<>();
- 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);
- }
- }
- // Select first tracks as default
- if (mVideoTrackIndices.size() > 0) {
- mSelectedVideoTrackIndex = 0;
- }
- if (mAudioTrackIndices.size() > 0) {
- mSelectedAudioTrackIndex = 0;
- }
-
- Bundle data = new Bundle();
- data.putInt(MediaControlView2.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size());
- data.putInt(MediaControlView2.KEY_AUDIO_TRACK_COUNT, mAudioTrackIndices.size());
- mMediaSession.sendSessionEvent(MediaControlView2.EVENT_UPDATE_TRACK_STATUS, data);
- }
-
- protected void doShowSubtitleCommand(Bundle args) {
- // No-op
- }
-
- protected void doHideSubtitleCommand() {
- // No-op
- }
-
- private void extractMetadata() {
- if (mRetriever == null) {
- return;
- }
- // Get and set duration and title values as MediaMetadata for MediaControlView2
- MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
- String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
- if (title != null) {
- mTitle = title;
- }
- builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle);
- builder.putLong(
- MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
-
- if (mMediaSession != null) {
- mMediaSession.setMetadata(builder.build());
- }
- }
-
- @SuppressWarnings("deprecation")
- private void extractAudioMetadata() {
- if (mRetriever == null || !isMusicMediaType()) {
- return;
- }
-
- mResources = mInstance.getResources();
- mManager = (WindowManager) mInstance.getContext().getApplicationContext()
- .getSystemService(Context.WINDOW_SERVICE);
-
- byte[] album = mRetriever.getEmbeddedPicture();
- if (album != null) {
- Bitmap bitmap = BitmapFactory.decodeByteArray(album, 0, album.length);
- mMusicAlbumDrawable = new BitmapDrawable(bitmap);
-
- Palette.Builder builder = Palette.from(bitmap);
- builder.generate(new Palette.PaletteAsyncListener() {
- @Override
- public void onGenerated(Palette palette) {
- mDominantColor = palette.getDominantColor(0);
- if (mMusicView != null) {
- mMusicView.setBackgroundColor(mDominantColor);
- }
- }
- });
- } else {
- mMusicAlbumDrawable = mResources.getDrawable(R.drawable.ic_default_album_image);
- }
-
- String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
- if (title != null) {
- mMusicTitleText = title;
- } else {
- mMusicTitleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
- }
-
- String artist = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
- if (artist != null) {
- mMusicArtistText = artist;
- } else {
- mMusicArtistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
- }
-
- // Send title and artist string to MediaControlView2
- MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
- builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mMusicTitleText);
- builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mMusicArtistText);
- mMediaSession.setMetadata(builder.build());
-
- // Display Embedded mode as default
- mInstance.removeView(mSurfaceView);
- mInstance.removeView(mTextureView);
- inflateMusicView(R.layout.embedded_music);
- }
-
- private int retrieveOrientation() {
- DisplayMetrics dm = Resources.getSystem().getDisplayMetrics();
- int width = dm.widthPixels;
- int height = dm.heightPixels;
-
- return (height > width)
- ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
- : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
- }
-
- private void inflateMusicView(int layoutId) {
- mInstance.removeView(mMusicView);
-
- LayoutInflater inflater = (LayoutInflater) mInstance.getContext()
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View v = inflater.inflate(layoutId, null);
- v.setBackgroundColor(mDominantColor);
-
- ImageView albumView = v.findViewById(R.id.album);
- if (albumView != null) {
- albumView.setImageDrawable(mMusicAlbumDrawable);
- }
-
- TextView titleView = v.findViewById(R.id.title);
- if (titleView != null) {
- titleView.setText(mMusicTitleText);
- }
-
- TextView artistView = v.findViewById(R.id.artist);
- if (artistView != null) {
- artistView.setText(mMusicArtistText);
- }
-
- mMusicView = v;
- mInstance.addView(mMusicView, 0);
- }
-
- private MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
- new MediaPlayer.OnVideoSizeChangedListener() {
- @Override
- public void onVideoSizeChanged(
- MediaPlayer mp, int width, int height) {
- if (DEBUG) {
- Log.d(TAG, "onVideoSizeChanged(): size: " + width + "/" + height);
- }
- mVideoWidth = mp.getVideoWidth();
- mVideoHeight = mp.getVideoHeight();
- if (DEBUG) {
- Log.d(TAG, "onVideoSizeChanged(): mVideoSize:" + mVideoWidth + "/"
- + mVideoHeight);
- }
- if (mVideoWidth != 0 && mVideoHeight != 0) {
- mInstance.requestLayout();
- }
- }
- };
-
- private MediaPlayer.OnPreparedListener mPreparedListener =
- new MediaPlayer.OnPreparedListener() {
- @Override
- public void onPrepared(MediaPlayer mp) {
- if (DEBUG) {
- Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- mCurrentState = STATE_PREPARED;
- // Create and set playback state for MediaControlView2
- updatePlaybackState();
-
- if (mMediaSession != null) {
- extractTracks();
- extractMetadata();
- extractAudioMetadata();
- }
-
- if (mMediaControlView != null) {
- mMediaControlView.setEnabled(true);
- }
- int videoWidth = mp.getVideoWidth();
- int videoHeight = mp.getVideoHeight();
-
- // mSeekWhenPrepared may be changed after seekTo() call
- long seekToPosition = mSeekWhenPrepared;
- if (seekToPosition != 0) {
- mMediaController.getTransportControls().seekTo(seekToPosition);
- }
-
- if (videoWidth != 0 && videoHeight != 0) {
- if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) {
- mVideoWidth = videoWidth;
- mVideoHeight = videoHeight;
- mInstance.requestLayout();
- }
-
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
- } else {
- // We don't know the video size yet, but should start anyway.
- // The video size might be reported to us later.
- if (needToStart()) {
- mMediaController.getTransportControls().play();
- }
- }
- // Get and set duration and title values as MediaMetadata for MediaControlView2
- MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
-
- builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle);
- builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
-
- if (mMediaSession != null) {
- mMediaSession.setMetadata(builder.build());
-
- if (mNeedUpdateMediaType) {
- mMediaSession.sendSessionEvent(
- MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS, mMediaTypeData);
- mNeedUpdateMediaType = false;
- }
- }
- }
- };
-
- private MediaPlayer.OnSeekCompleteListener mSeekCompleteListener =
- new MediaPlayer.OnSeekCompleteListener() {
- @Override
- public void onSeekComplete(MediaPlayer mp) {
- updatePlaybackState();
- }
- };
-
- private MediaPlayer.OnCompletionListener mCompletionListener =
- new MediaPlayer.OnCompletionListener() {
- @Override
- @SuppressWarnings("deprecation")
- public void onCompletion(MediaPlayer mp) {
- mCurrentState = STATE_PLAYBACK_COMPLETED;
- mTargetState = STATE_PLAYBACK_COMPLETED;
- updatePlaybackState();
- if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
- mAudioManager.abandonAudioFocus(null);
- }
- }
- };
-
- private MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
- @Override
- public boolean onInfo(MediaPlayer mp, int what, int extra) {
- if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
- extractTracks();
- }
- return true;
- }
- };
-
- private MediaPlayer.OnErrorListener mErrorListener = new MediaPlayer.OnErrorListener() {
- @Override
- public boolean onError(MediaPlayer mp, int frameworkErr, int implErr) {
- if (DEBUG) {
- Log.d(TAG, "Error: " + frameworkErr + "," + implErr);
- }
- mCurrentState = STATE_ERROR;
- mTargetState = STATE_ERROR;
- updatePlaybackState();
-
- if (mMediaControlView != null) {
- mMediaControlView.setVisibility(View.GONE);
- }
- return true;
- }
- };
-
- private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =
- new MediaPlayer.OnBufferingUpdateListener() {
- @Override
- public void onBufferingUpdate(MediaPlayer mp, int percent) {
- mCurrentBufferPercentage = percent;
- updatePlaybackState();
- }
- };
-
- private class MediaSessionCallback extends MediaSessionCompat.Callback {
- @Override
- public void onCommand(String command, Bundle args, ResultReceiver receiver) {
- if (isRemotePlayback()) {
- mRoutePlayer.onCommand(command, args, receiver);
- } else {
- switch (command) {
- case MediaControlView2.COMMAND_SHOW_SUBTITLE:
- doShowSubtitleCommand(args);
- break;
- case MediaControlView2.COMMAND_HIDE_SUBTITLE:
- doHideSubtitleCommand();
- break;
- case MediaControlView2.COMMAND_SELECT_AUDIO_TRACK:
- int audioIndex = args.getInt(MediaControlView2.KEY_SELECTED_AUDIO_INDEX,
- INVALID_TRACK_INDEX);
- if (audioIndex != INVALID_TRACK_INDEX) {
- int audioTrackIndex = mAudioTrackIndices.get(audioIndex);
- if (audioTrackIndex != mSelectedAudioTrackIndex) {
- mSelectedAudioTrackIndex = audioTrackIndex;
- mMediaPlayer.selectTrack(mSelectedAudioTrackIndex);
- }
- }
- break;
- case MediaControlView2.COMMAND_SET_PLAYBACK_SPEED:
- float speed = args.getFloat(
- MediaControlView2.KEY_PLAYBACK_SPEED, INVALID_SPEED);
- if (speed != INVALID_SPEED && speed != mSpeed) {
- setSpeed(speed);
- mSpeed = speed;
- }
- break;
- case MediaControlView2.COMMAND_MUTE:
- mVolumeLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
- mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
- break;
- case MediaControlView2.COMMAND_UNMUTE:
- mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeLevel, 0);
- break;
- }
- }
- showController();
- }
-
- @Override
- public void onCustomAction(final String action, final Bundle extras) {
- mCustomActionListenerRecord.first.execute(new Runnable() {
- @Override
- public void run() {
- mCustomActionListenerRecord.second.onCustomAction(action, extras);
- }
- });
- showController();
- }
-
- @Override
- public void onPlay() {
- if (!isAudioGranted()) {
- requestAudioFocus(mAudioFocusType);
- }
-
- if ((isInPlaybackState() && mCurrentView.hasAvailableSurface()) || isMusicMediaType()) {
- if (isRemotePlayback()) {
- mRoutePlayer.onPlay();
- } else {
- applySpeed();
- mMediaPlayer.start();
- mCurrentState = STATE_PLAYING;
- updatePlaybackState();
- }
- mCurrentState = STATE_PLAYING;
- }
- mTargetState = STATE_PLAYING;
- if (DEBUG) {
- Log.d(TAG, "onPlay(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- showController();
- }
-
- @Override
- public void onPause() {
- if (isInPlaybackState()) {
- if (isRemotePlayback()) {
- mRoutePlayer.onPlay();
- mCurrentState = STATE_PAUSED;
- } else if (mMediaPlayer.isPlaying()) {
- mMediaPlayer.pause();
- mCurrentState = STATE_PAUSED;
- updatePlaybackState();
- }
- }
- mTargetState = STATE_PAUSED;
- if (DEBUG) {
- Log.d(TAG, "onPause(). mCurrentState=" + mCurrentState
- + ", mTargetState=" + mTargetState);
- }
- showController();
- }
-
- @Override
- public void onSeekTo(long pos) {
- if (isInPlaybackState()) {
- if (isRemotePlayback()) {
- mRoutePlayer.onPlay();
- } else {
- if (android.os.Build.VERSION.SDK_INT < 26) {
- mMediaPlayer.seekTo((int) pos);
- } else {
- mMediaPlayer.seekTo(pos, MediaPlayer.SEEK_PREVIOUS_SYNC);
- }
- mSeekWhenPrepared = 0;
- }
- } else {
- mSeekWhenPrepared = pos;
- }
- showController();
- }
-
- @Override
- public void onStop() {
- if (isRemotePlayback()) {
- mRoutePlayer.onPlay();
- } else {
- resetPlayer();
- }
- showController();
- }
- }
-}
diff --git a/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoViewInterfaceWithMp1.java b/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoViewInterfaceWithMp1.java
deleted file mode 100644
index a3bac28..0000000
--- a/media-widget/src/main/java/androidx/media/widget/impl_with_mp1/VideoViewInterfaceWithMp1.java
+++ /dev/null
@@ -1,66 +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.media.widget;
-
-import android.media.MediaPlayer;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-
-interface VideoViewInterfaceWithMp1 {
- /**
- * Assigns the view's surface to the given MediaPlayer instance.
- *
- * @param mp MediaPlayer
- * @return true if the surface is successfully assigned, false if not. It will fail to assign
- * if any of MediaPlayer or surface is unavailable.
- */
- boolean assignSurfaceToMediaPlayer(MediaPlayer mp);
- void setSurfaceListener(SurfaceListener l);
- int getViewType();
- void setMediaPlayer(MediaPlayer mp);
-
- /**
- * Takes over oldView. It means that the MediaPlayer will start rendering on this view.
- * The visibility of oldView will be set as {@link View.GONE}. If the view doesn't have a
- * MediaPlayer instance or its surface is not available, the actual execution is deferred until
- * a MediaPlayer instance is set by {@link #setMediaPlayer} or its surface becomes available.
- * {@link SurfaceListener.onSurfaceTakeOverDone} will be called when the actual execution is
- * done.
- *
- * @param oldView The view that MediaPlayer is currently rendering on.
- */
- void takeOver(@NonNull VideoViewInterfaceWithMp1 oldView);
-
- /**
- * Indicates if the view's surface is available.
- *
- * @return true if the surface is available.
- */
- boolean hasAvailableSurface();
-
- /**
- * An instance of VideoViewInterface calls these surface notification methods accordingly if
- * a listener has been registered via {@link #setSurfaceListener(SurfaceListener)}.
- */
- interface SurfaceListener {
- void onSurfaceCreated(View view, int width, int height);
- void onSurfaceDestroyed(View view);
- void onSurfaceChanged(View view, int width, int height);
- void onSurfaceTakeOverDone(VideoViewInterfaceWithMp1 view);
- }
-}
diff --git a/media-widget/src/main/res/layout/embedded_settings_list_item.xml b/media-widget/src/main/res/layout/embedded_settings_list_item.xml
index c690c48..1156dca 100644
--- a/media-widget/src/main/res/layout/embedded_settings_list_item.xml
+++ b/media-widget/src/main/res/layout/embedded_settings_list_item.xml
@@ -16,50 +16,48 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_embedded_settings_height"
android:orientation="horizontal"
android:background="@color/black_opacity_70">
<LinearLayout
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_embedded_settings_height"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon"
- android:layout_width="@dimen/mcv2_settings_icon_size"
- android:layout_height="@dimen/mcv2_settings_icon_size"
+ android:layout_width="@dimen/mcv2_embedded_settings_icon_size"
+ android:layout_height="@dimen/mcv2_embedded_settings_icon_size"
android:layout_margin="8dp"
android:gravity="center" />
</LinearLayout>
- <LinearLayout
+ <RelativeLayout
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center|left">
+ android:layout_height="@dimen/mcv2_embedded_settings_height"
+ android:gravity="center"
+ android:orientation="vertical">
- <LinearLayout
+ <TextView
+ android:id="@+id/main_text"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center|left"
- android:orientation="vertical">
+ android:layout_height="@dimen/mcv2_embedded_settings_text_height"
+ android:gravity="center"
+ android:paddingLeft="2dp"
+ android:textColor="@color/white"
+ android:textSize="@dimen/mcv2_embedded_settings_main_text_size"/>
- <TextView
- android:id="@+id/main_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="2dp"
- android:textColor="@color/white"
- android:textSize="@dimen/mcv2_settings_main_text_size"/>
-
- <TextView
- android:id="@+id/sub_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="2dp"
- android:textColor="@color/white_opacity_70"
- android:textSize="@dimen/mcv2_settings_sub_text_size"/>
- </LinearLayout>
- </LinearLayout>
+ <TextView
+ android:id="@+id/sub_text"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/mcv2_embedded_settings_text_height"
+ android:layout_below="@id/main_text"
+ android:gravity="center"
+ android:paddingLeft="2dp"
+ android:textColor="@color/white_opacity_70"
+ android:textSize="@dimen/mcv2_embedded_settings_sub_text_size"/>
+ </RelativeLayout>
</LinearLayout>
+
diff --git a/media-widget/src/main/res/layout/embedded_sub_settings_list_item.xml b/media-widget/src/main/res/layout/embedded_sub_settings_list_item.xml
index c455504..5947a72 100644
--- a/media-widget/src/main/res/layout/embedded_sub_settings_list_item.xml
+++ b/media-widget/src/main/res/layout/embedded_sub_settings_list_item.xml
@@ -16,20 +16,20 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_embedded_settings_height"
android:orientation="horizontal"
android:background="@color/black_opacity_70">
<LinearLayout
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_embedded_settings_height"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/check"
- android:layout_width="@dimen/mcv2_settings_icon_size"
- android:layout_height="@dimen/mcv2_settings_icon_size"
+ android:layout_width="@dimen/mcv2_embedded_settings_icon_size"
+ android:layout_height="@dimen/mcv2_embedded_settings_icon_size"
android:layout_margin="8dp"
android:gravity="center"
android:src="@drawable/ic_check"/>
@@ -37,17 +37,17 @@
<RelativeLayout
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_embedded_settings_height"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_text_height"
+ android:layout_height="@dimen/mcv2_embedded_settings_text_height"
android:gravity="center"
android:paddingLeft="2dp"
android:textColor="@color/white"
- android:textSize="@dimen/mcv2_settings_main_text_size"/>
+ android:textSize="@dimen/mcv2_embedded_settings_main_text_size"/>
</RelativeLayout>
</LinearLayout>
diff --git a/media-widget/src/main/res/layout/embedded_transport_controls.xml b/media-widget/src/main/res/layout/embedded_transport_controls.xml
index 89b98b7..a3a5957 100644
--- a/media-widget/src/main/res/layout/embedded_transport_controls.xml
+++ b/media-widget/src/main/res/layout/embedded_transport_controls.xml
@@ -15,10 +15,12 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal"
+ android:paddingLeft="@dimen/mcv2_transport_controls_padding"
+ android:paddingRight="@dimen/mcv2_transport_controls_padding"
android:visibility="visible">
<ImageButton android:id="@+id/prev" style="@style/EmbeddedTransportControlsButton.Previous" />
diff --git a/media-widget/src/main/res/layout/full_settings_list_item.xml b/media-widget/src/main/res/layout/full_settings_list_item.xml
index c4406d9..f92ea5e 100644
--- a/media-widget/src/main/res/layout/full_settings_list_item.xml
+++ b/media-widget/src/main/res/layout/full_settings_list_item.xml
@@ -16,50 +16,47 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_full_settings_height"
android:orientation="horizontal"
android:background="@color/black_opacity_70">
<LinearLayout
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_full_settings_height"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon"
- android:layout_width="@dimen/mcv2_settings_icon_size"
- android:layout_height="@dimen/mcv2_settings_icon_size"
+ android:layout_width="@dimen/mcv2_full_settings_icon_size"
+ android:layout_height="@dimen/mcv2_full_settings_icon_size"
android:layout_margin="8dp"
android:gravity="center"/>
</LinearLayout>
- <LinearLayout
+ <RelativeLayout
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center|left">
+ android:layout_height="@dimen/mcv2_full_settings_height"
+ android:gravity="center"
+ android:orientation="vertical">
- <LinearLayout
+ <TextView
+ android:id="@+id/main_text"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center|left"
- android:orientation="vertical">
+ android:layout_height="@dimen/mcv2_full_settings_text_height"
+ android:paddingLeft="2dp"
+ android:gravity="center"
+ android:textColor="@color/white"
+ android:textSize="@dimen/mcv2_full_settings_main_text_size"/>
- <TextView
- android:id="@+id/main_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="2dp"
- android:textColor="@color/white"
- android:textSize="@dimen/mcv2_settings_main_text_size"/>
-
- <TextView
- android:id="@+id/sub_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="2dp"
- android:textColor="@color/white_opacity_70"
- android:textSize="@dimen/mcv2_settings_sub_text_size"/>
- </LinearLayout>
- </LinearLayout>
+ <TextView
+ android:id="@+id/sub_text"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/mcv2_full_settings_text_height"
+ android:layout_below="@id/main_text"
+ android:gravity="center"
+ android:paddingLeft="2dp"
+ android:textColor="@color/white_opacity_70"
+ android:textSize="@dimen/mcv2_full_settings_sub_text_size"/>
+ </RelativeLayout>
</LinearLayout>
diff --git a/media-widget/src/main/res/layout/full_sub_settings_list_item.xml b/media-widget/src/main/res/layout/full_sub_settings_list_item.xml
index 3bd4ed1..49128d0 100644
--- a/media-widget/src/main/res/layout/full_sub_settings_list_item.xml
+++ b/media-widget/src/main/res/layout/full_sub_settings_list_item.xml
@@ -16,20 +16,20 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_full_settings_height"
android:orientation="horizontal"
android:background="@color/black_opacity_70">
<LinearLayout
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_full_settings_height"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/check"
- android:layout_width="@dimen/mcv2_settings_icon_size"
- android:layout_height="@dimen/mcv2_settings_icon_size"
+ android:layout_width="@dimen/mcv2_full_settings_icon_size"
+ android:layout_height="@dimen/mcv2_full_settings_icon_size"
android:layout_margin="8dp"
android:gravity="center"
android:src="@drawable/ic_check"/>
@@ -37,17 +37,17 @@
<RelativeLayout
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_height"
+ android:layout_height="@dimen/mcv2_full_settings_height"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
- android:layout_height="@dimen/mcv2_settings_text_height"
+ android:layout_height="@dimen/mcv2_full_settings_text_height"
android:gravity="center"
android:paddingLeft="2dp"
android:textColor="@color/white"
- android:textSize="@dimen/mcv2_settings_main_text_size"/>
+ android:textSize="@dimen/mcv2_full_settings_main_text_size"/>
</RelativeLayout>
</LinearLayout>
\ No newline at end of file
diff --git a/media-widget/src/main/res/layout/full_transport_controls.xml b/media-widget/src/main/res/layout/full_transport_controls.xml
index f5d8b00..0914785 100644
--- a/media-widget/src/main/res/layout/full_transport_controls.xml
+++ b/media-widget/src/main/res/layout/full_transport_controls.xml
@@ -15,10 +15,12 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal"
+ android:paddingLeft="@dimen/mcv2_transport_controls_padding"
+ android:paddingRight="@dimen/mcv2_transport_controls_padding"
android:visibility="visible">
<ImageButton android:id="@+id/prev" style="@style/FullTransportControlsButton.Previous" />
diff --git a/media-widget/src/main/res/layout/media_controller.xml b/media-widget/src/main/res/layout/media_controller.xml
index 7fec8cc..8749a7b 100644
--- a/media-widget/src/main/res/layout/media_controller.xml
+++ b/media-widget/src/main/res/layout/media_controller.xml
@@ -29,16 +29,19 @@
android:id="@+id/title_bar_left"
android:gravity="center"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentStart="true"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:orientation="horizontal">
<ImageButton
android:id="@+id/back"
android:clickable="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
+ android:paddingLeft="5dip"
android:visibility="visible"
style="@style/TitleBarButton.Back"/>
@@ -50,7 +53,8 @@
android:layout_toRightOf="@id/back"
android:layout_centerVertical="true"
android:maxLines="1"
- android:paddingStart="@dimen/mcv2_embedded_icon_padding"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
android:textSize="15sp"
android:textColor="#FFFFFFFF"/>
</LinearLayout>
@@ -95,12 +99,13 @@
style="@style/TitleBarButton.Launch" />
</LinearLayout>
- <view class="androidx.mediarouter.app.MediaRouteButton"
+ <!-- TODO (b/77158231): Causes java.lang.ClassNotFoundException as of Apr 02 2018 -->
+ <!--view class="androidx.mediarouter.app.MediaRouteButton"
android:id="@+id/cast"
android:layout_centerVertical="true"
android:visibility="gone"
android:contentDescription="@string/mr_button_content_description"
- style="@style/TitleBarButton" />
+ style="@style/TitleBarButton" /-->
</LinearLayout>
</RelativeLayout>
@@ -152,9 +157,9 @@
<RelativeLayout
android:id="@+id/bottom_bar"
android:layout_width="match_parent"
- android:layout_height="@dimen/mcv2_bottom_bar_height"
- android:background="@color/bottom_bar_background"
- android:orientation="horizontal">
+ android:layout_height="44dp"
+ android:orientation="horizontal"
+ android:background="@color/bottom_bar_background">
<LinearLayout
android:id="@+id/bottom_bar_left"
@@ -165,12 +170,12 @@
<TextView
android:id="@+id/ad_skip_time"
+ android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="4dp"
- android:gravity="center"
- android:textColor="#FFFFFF"
android:textSize="12sp"
+ android:textColor="#FFFFFF"
android:visibility="gone" />
</LinearLayout>
@@ -179,21 +184,19 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toRightOf="@id/bottom_bar_left"
- android:gravity="center"
android:paddingLeft="10dp"
- android:paddingRight="10dp">
+ android:paddingRight="10dp"
+ android:gravity="center" >
<TextView
android:id="@+id/time_current"
- style="@style/TimeText.Current" />
-
+ style="@style/TimeText.Current"/>
<TextView
android:id="@+id/time_interpunct"
- style="@style/TimeText.Interpunct" />
-
+ style="@style/TimeText.Interpunct"/>
<TextView
android:id="@+id/time_end"
- style="@style/TimeText.End" />
+ style="@style/TimeText.End"/>
</LinearLayout>
<LinearLayout
@@ -201,68 +204,63 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
- android:layout_centerVertical="true">
+ android:gravity="right">
<LinearLayout
android:id="@+id/basic_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal">
+ android:gravity="center_vertical"
+ android:orientation="horizontal" >
<TextView
android:id="@+id/ad_remaining"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
- android:textColor="#FFFFFF"
android:textSize="12sp"
+ android:textColor="#FFFFFF"
android:visibility="gone" />
<ImageButton
android:id="@+id/mute"
style="@style/BottomBarButton.Mute" />
-
<ImageButton
android:id="@+id/subtitle"
- style="@style/BottomBarButton.CC"
android:scaleType="fitCenter"
- android:visibility="gone" />
-
+ android:visibility="gone"
+ style="@style/BottomBarButton.CC" />
<ImageButton
android:id="@+id/fullscreen"
- style="@style/BottomBarButton.FullScreen" />
-
+ style="@style/BottomBarButton.FullScreen"/>
<ImageButton
android:id="@+id/overflow_right"
- style="@style/BottomBarButton.OverflowRight" />
+ style="@style/BottomBarButton.OverflowRight"/>
</LinearLayout>
<LinearLayout
android:id="@+id/extra_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="center"
+ android:visibility="gone"
android:orientation="horizontal"
- android:visibility="gone">
+ android:gravity="center_vertical">
<LinearLayout
android:id="@+id/custom_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="horizontal" />
+ android:orientation="horizontal"/>
<ImageButton
android:id="@+id/video_quality"
style="@style/BottomBarButton.VideoQuality" />
-
<ImageButton
android:id="@+id/settings"
style="@style/BottomBarButton.Settings" />
-
<ImageButton
android:id="@+id/overflow_left"
- style="@style/BottomBarButton.OverflowLeft" />
+ style="@style/BottomBarButton.OverflowLeft"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
diff --git a/media-widget/src/main/res/layout/minimal_transport_controls.xml b/media-widget/src/main/res/layout/minimal_transport_controls.xml
index a72adc7..800c80b 100644
--- a/media-widget/src/main/res/layout/minimal_transport_controls.xml
+++ b/media-widget/src/main/res/layout/minimal_transport_controls.xml
@@ -15,8 +15,8 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
diff --git a/media-widget/src/main/res/layout/settings_list.xml b/media-widget/src/main/res/layout/settings_list.xml
index f08f81b..ea30538 100644
--- a/media-widget/src/main/res/layout/settings_list.xml
+++ b/media-widget/src/main/res/layout/settings_list.xml
@@ -16,8 +16,7 @@
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/mcv2_embedded_settings_width"
- android:layout_height="@dimen/mcv2_settings_height"
- android:layout_gravity="center_vertical"
+ android:layout_height="@dimen/mcv2_embedded_settings_height"
android:divider="@null"
android:dividerHeight="0dp">
</ListView>
\ No newline at end of file
diff --git a/media-widget/src/main/res/values/dimens.xml b/media-widget/src/main/res/values/dimens.xml
index f03c871..796f345 100644
--- a/media-widget/src/main/res/values/dimens.xml
+++ b/media-widget/src/main/res/values/dimens.xml
@@ -17,19 +17,25 @@
<resources>
<dimen name="mcv2_embedded_settings_width">150dp</dimen>
+ <dimen name="mcv2_embedded_settings_height">36dp</dimen>
+ <dimen name="mcv2_embedded_settings_icon_size">20dp</dimen>
+ <dimen name="mcv2_embedded_settings_text_height">18dp</dimen>
+ <dimen name="mcv2_embedded_settings_main_text_size">12sp</dimen>
+ <dimen name="mcv2_embedded_settings_sub_text_size">10sp</dimen>
<dimen name="mcv2_full_settings_width">225dp</dimen>
- <dimen name="mcv2_settings_height">48dp</dimen>
- <dimen name="mcv2_settings_icon_size">24dp</dimen>
- <dimen name="mcv2_settings_text_height">24dp</dimen>
- <dimen name="mcv2_settings_main_text_size">14sp</dimen>
- <dimen name="mcv2_settings_sub_text_size">12sp</dimen>
+ <dimen name="mcv2_full_settings_height">54dp</dimen>
+ <dimen name="mcv2_full_settings_icon_size">30dp</dimen>
+ <dimen name="mcv2_full_settings_text_height">27dp</dimen>
+ <dimen name="mcv2_full_settings_main_text_size">16sp</dimen>
+ <dimen name="mcv2_full_settings_sub_text_size">13sp</dimen>
<dimen name="mcv2_settings_offset">8dp</dimen>
- <dimen name="mcv2_icon_size">48dp</dimen>
+ <dimen name="mcv2_transport_controls_padding">4dp</dimen>
+ <dimen name="mcv2_pause_icon_size">36dp</dimen>
+ <dimen name="mcv2_full_icon_size">28dp</dimen>
+ <dimen name="mcv2_embedded_icon_size">24dp</dimen>
+ <dimen name="mcv2_minimal_icon_size">24dp</dimen>
<dimen name="mcv2_icon_margin">10dp</dimen>
- <dimen name="mcv2_pause_icon_padding">6dp</dimen>
- <dimen name="mcv2_full_icon_padding">10dp</dimen>
- <dimen name="mcv2_embedded_icon_padding">12dp</dimen>
<dimen name="mcv2_full_album_image_portrait_size">232dp</dimen>
<dimen name="mcv2_full_album_image_landscape_size">176dp</dimen>
@@ -37,7 +43,4 @@
<dimen name="mcv2_custom_progress_max_size">2dp</dimen>
<dimen name="mcv2_custom_progress_thumb_size">12dp</dimen>
<dimen name="mcv2_buffer_view_height">5dp</dimen>
-
- <dimen name="mcv2_title_bar_height">54dp</dimen>
- <dimen name="mcv2_bottom_bar_height">58dp</dimen>
</resources>
diff --git a/media-widget/src/main/res/values/styles.xml b/media-widget/src/main/res/values/styles.xml
index 2e03acb..fc42bd4 100644
--- a/media-widget/src/main/res/values/styles.xml
+++ b/media-widget/src/main/res/values/styles.xml
@@ -2,99 +2,91 @@
<resources>
<style name="FullTransportControlsButton">
<item name="android:background">@null</item>
+ <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
<item name="android:scaleType">fitXY</item>
</style>
<style name="FullTransportControlsButton.Previous">
<item name="android:src">@drawable/ic_skip_previous</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
<item name="android:contentDescription">@string/mcv2_previous_button_desc</item>
- <item name="android:padding">@dimen/mcv2_full_icon_padding</item>
</style>
<style name="FullTransportControlsButton.Next">
<item name="android:src">@drawable/ic_skip_next</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
<item name="android:contentDescription">@string/mcv2_next_button_desc</item>
- <item name="android:padding">@dimen/mcv2_full_icon_padding</item>
</style>
<style name="FullTransportControlsButton.Pause">
<item name="android:src">@drawable/ic_pause_circle_filled</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
<item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
- <item name="android:padding">@dimen/mcv2_pause_icon_padding</item>
</style>
<style name="FullTransportControlsButton.Ffwd">
<item name="android:src">@drawable/ic_forward_30</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
<item name="android:contentDescription">@string/mcv2_ffwd_button_desc</item>
- <item name="android:padding">@dimen/mcv2_full_icon_padding</item>
</style>
<style name="FullTransportControlsButton.Rew">
<item name="android:src">@drawable/ic_rewind_10</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
<item name="android:contentDescription">@string/mcv2_rewind_button_desc</item>
- <item name="android:padding">@dimen/mcv2_full_icon_padding</item>
</style>
<style name="EmbeddedTransportControlsButton">
<item name="android:background">@null</item>
+ <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
<item name="android:scaleType">fitXY</item>
</style>
<style name="EmbeddedTransportControlsButton.Previous">
<item name="android:src">@drawable/ic_skip_previous</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
<item name="android:contentDescription">@string/mcv2_previous_button_desc</item>
- <item name="android:padding">@dimen/mcv2_embedded_icon_padding</item>
</style>
<style name="EmbeddedTransportControlsButton.Next">
<item name="android:src">@drawable/ic_skip_next</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
<item name="android:contentDescription">@string/mcv2_next_button_desc</item>
- <item name="android:padding">@dimen/mcv2_embedded_icon_padding</item>
</style>
<style name="EmbeddedTransportControlsButton.Pause">
<item name="android:src">@drawable/ic_pause_circle_filled</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
<item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
- <item name="android:padding">@dimen/mcv2_pause_icon_padding</item>
</style>
<style name="EmbeddedTransportControlsButton.Ffwd">
<item name="android:src">@drawable/ic_forward_30</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
<item name="android:contentDescription">@string/mcv2_ffwd_button_desc</item>
- <item name="android:padding">@dimen/mcv2_embedded_icon_padding</item>
</style>
<style name="EmbeddedTransportControlsButton.Rew">
<item name="android:src">@drawable/ic_rewind_10</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
<item name="android:contentDescription">@string/mcv2_rewind_button_desc</item>
- <item name="android:padding">@dimen/mcv2_embedded_icon_padding</item>
</style>
<style name="MinimalTransportControlsButton">
<item name="android:background">@null</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
- <item name="android:padding">@dimen/mcv2_pause_icon_padding</item>
+ <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
+ <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
<item name="android:scaleType">fitXY</item>
<item name="android:src">@drawable/ic_pause_circle_filled</item>
<item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
@@ -102,15 +94,15 @@
<style name="TitleBar">
<item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">@dimen/mcv2_title_bar_height</item>
+ <item name="android:layout_height">46dp</item>
+ <item name="android:paddingLeft">5dp</item>
+ <item name="android:paddingRight">5dp</item>
</style>
<style name="TitleBarButton">
<item name="android:background">@null</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
- <item name="android:padding">@dimen/mcv2_embedded_icon_padding</item>
- <item name="android:scaleType">fitXY</item>
+ <item name="android:layout_width">36dp</item>
+ <item name="android:layout_height">36dp</item>
</style>
<style name="TitleBarButton.Back">
@@ -150,10 +142,10 @@
<style name="BottomBarButton">
<item name="android:background">@null</item>
- <item name="android:layout_width">@dimen/mcv2_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_icon_size</item>
+ <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
+ <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
<item name="android:gravity">center_horizontal</item>
- <item name="android:padding">@dimen/mcv2_embedded_icon_padding</item>
<item name="android:scaleType">fitXY</item>
</style>
diff --git a/media/api/current.txt b/media/api/current.txt
index c3c28f5..a9e2161 100644
--- a/media/api/current.txt
+++ b/media/api/current.txt
@@ -300,7 +300,6 @@
method public void addOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener);
method public static android.support.v4.media.session.MediaSessionCompat fromMediaSession(android.content.Context, java.lang.Object);
method public android.support.v4.media.session.MediaControllerCompat getController();
- method public final androidx.media.MediaSessionManager.RemoteUserInfo getCurrentControllerInfo();
method public java.lang.Object getMediaSession();
method public java.lang.Object getRemoteControlClient();
method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
@@ -601,38 +600,10 @@
method public androidx.media.DataSourceDesc.Builder setStartPosition(long);
}
- public abstract class Media2DataSource implements java.io.Closeable {
- ctor public Media2DataSource();
- method public abstract long getSize() throws java.io.IOException;
- method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
- }
-
- public class MediaBrowser2 extends androidx.media.MediaController2 {
- ctor public MediaBrowser2(android.content.Context, androidx.media.SessionToken2, java.util.concurrent.Executor, androidx.media.MediaBrowser2.BrowserCallback);
- method public void getChildren(java.lang.String, int, int, android.os.Bundle);
- method public void getItem(java.lang.String);
- method public void getLibraryRoot(android.os.Bundle);
- method public void getSearchResult(java.lang.String, int, int, android.os.Bundle);
- method public void search(java.lang.String, android.os.Bundle);
- method public void subscribe(java.lang.String, android.os.Bundle);
- method public void unsubscribe(java.lang.String);
- }
-
- public static class MediaBrowser2.BrowserCallback extends androidx.media.MediaController2.ControllerCallback {
- ctor public MediaBrowser2.BrowserCallback();
- method public void onChildrenChanged(androidx.media.MediaBrowser2, java.lang.String, int, android.os.Bundle);
- method public void onGetChildrenDone(androidx.media.MediaBrowser2, java.lang.String, int, int, java.util.List<androidx.media.MediaItem2>, android.os.Bundle);
- method public void onGetItemDone(androidx.media.MediaBrowser2, java.lang.String, androidx.media.MediaItem2);
- method public void onGetLibraryRootDone(androidx.media.MediaBrowser2, android.os.Bundle, java.lang.String, android.os.Bundle);
- method public void onGetSearchResultDone(androidx.media.MediaBrowser2, java.lang.String, int, int, java.util.List<androidx.media.MediaItem2>, android.os.Bundle);
- method public void onSearchResultChanged(androidx.media.MediaBrowser2, java.lang.String, int, android.os.Bundle);
- }
-
public abstract class MediaBrowserServiceCompat extends android.app.Service {
ctor public MediaBrowserServiceCompat();
method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
method public final android.os.Bundle getBrowserRootHints();
- method public final androidx.media.MediaSessionManager.RemoteUserInfo getCurrentBrowserInfo();
method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
method public void notifyChildrenChanged(java.lang.String);
method public void notifyChildrenChanged(java.lang.String, android.os.Bundle);
@@ -768,48 +739,6 @@
method public androidx.media.MediaItem2.Builder setMetadata(androidx.media.MediaMetadata2);
}
- public abstract class MediaLibraryService2 extends androidx.media.MediaSessionService2 {
- ctor public MediaLibraryService2();
- method public abstract androidx.media.MediaLibraryService2.MediaLibrarySession onCreateSession(java.lang.String);
- field public static final java.lang.String SERVICE_INTERFACE = "android.media.MediaLibraryService2";
- }
-
- public static final class MediaLibraryService2.LibraryRoot {
- ctor public MediaLibraryService2.LibraryRoot(java.lang.String, android.os.Bundle);
- method public android.os.Bundle getExtras();
- method public java.lang.String getRootId();
- field public static final java.lang.String EXTRA_OFFLINE = "android.media.extra.OFFLINE";
- field public static final java.lang.String EXTRA_RECENT = "android.media.extra.RECENT";
- field public static final java.lang.String EXTRA_SUGGESTED = "android.media.extra.SUGGESTED";
- }
-
- public static final class MediaLibraryService2.MediaLibrarySession extends androidx.media.MediaSession2 {
- method public void notifyChildrenChanged(androidx.media.MediaSession2.ControllerInfo, java.lang.String, int, android.os.Bundle);
- method public void notifyChildrenChanged(java.lang.String, int, android.os.Bundle);
- method public void notifySearchResultChanged(androidx.media.MediaSession2.ControllerInfo, java.lang.String, int, android.os.Bundle);
- }
-
- public static final class MediaLibraryService2.MediaLibrarySession.Builder {
- ctor public MediaLibraryService2.MediaLibrarySession.Builder(androidx.media.MediaLibraryService2, java.util.concurrent.Executor, androidx.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback);
- method public androidx.media.MediaLibraryService2.MediaLibrarySession build();
- method public androidx.media.MediaLibraryService2.MediaLibrarySession.Builder setId(java.lang.String);
- method public androidx.media.MediaLibraryService2.MediaLibrarySession.Builder setPlayer(androidx.media.MediaPlayerInterface);
- method public androidx.media.MediaLibraryService2.MediaLibrarySession.Builder setPlaylistAgent(androidx.media.MediaPlaylistAgent);
- method public androidx.media.MediaLibraryService2.MediaLibrarySession.Builder setSessionActivity(android.app.PendingIntent);
- method public androidx.media.MediaLibraryService2.MediaLibrarySession.Builder setVolumeProvider(androidx.media.VolumeProviderCompat);
- }
-
- public static class MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback extends androidx.media.MediaSession2.SessionCallback {
- ctor public MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback();
- method public java.util.List<androidx.media.MediaItem2> onGetChildren(androidx.media.MediaLibraryService2.MediaLibrarySession, androidx.media.MediaSession2.ControllerInfo, java.lang.String, int, int, android.os.Bundle);
- method public androidx.media.MediaItem2 onGetItem(androidx.media.MediaLibraryService2.MediaLibrarySession, androidx.media.MediaSession2.ControllerInfo, java.lang.String);
- method public androidx.media.MediaLibraryService2.LibraryRoot onGetLibraryRoot(androidx.media.MediaLibraryService2.MediaLibrarySession, androidx.media.MediaSession2.ControllerInfo, android.os.Bundle);
- method public java.util.List<androidx.media.MediaItem2> onGetSearchResult(androidx.media.MediaLibraryService2.MediaLibrarySession, androidx.media.MediaSession2.ControllerInfo, java.lang.String, int, int, android.os.Bundle);
- method public void onSearch(androidx.media.MediaLibraryService2.MediaLibrarySession, androidx.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
- method public void onSubscribe(androidx.media.MediaLibraryService2.MediaLibrarySession, androidx.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
- method public void onUnsubscribe(androidx.media.MediaLibraryService2.MediaLibrarySession, androidx.media.MediaSession2.ControllerInfo, java.lang.String);
- }
-
public final class MediaMetadata2 {
method public boolean containsKey(java.lang.String);
method public static androidx.media.MediaMetadata2 fromBundle(android.os.Bundle);
@@ -881,201 +810,8 @@
method public androidx.media.MediaMetadata2.Builder setExtras(android.os.Bundle);
}
- public abstract class MediaPlayer2 {
- method public abstract void attachAuxEffect(int);
- method public abstract void clearDrmEventCallback();
- method public abstract void clearMediaPlayer2EventCallback();
- method public abstract void clearPendingCommands();
- method public abstract void close();
- method public static final androidx.media.MediaPlayer2 create();
- method public abstract void deselectTrack(int);
- method public abstract androidx.media.AudioAttributesCompat getAudioAttributes();
- method public abstract int getAudioSessionId();
- method public abstract long getBufferedPosition();
- method public abstract androidx.media.DataSourceDesc getCurrentDataSource();
- method public abstract long getCurrentPosition();
- method public abstract androidx.media.MediaPlayer2.DrmInfo getDrmInfo();
- method public abstract android.media.MediaDrm.KeyRequest getDrmKeyRequest(byte[], byte[], java.lang.String, int, java.util.Map<java.lang.String, java.lang.String>) throws androidx.media.MediaPlayer2.NoDrmSchemeException;
- method public abstract java.lang.String getDrmPropertyString(java.lang.String) throws androidx.media.MediaPlayer2.NoDrmSchemeException;
- method public abstract long getDuration();
- method public float getMaxPlayerVolume();
- method public abstract int getMediaPlayer2State();
- method public abstract androidx.media.MediaPlayerInterface getMediaPlayerInterface();
- method public abstract android.os.PersistableBundle getMetrics();
- method public abstract android.media.PlaybackParams getPlaybackParams();
- method public float getPlaybackSpeed();
- method public abstract float getPlayerVolume();
- method public abstract int getSelectedTrack(int);
- method public abstract android.media.SyncParams getSyncParams();
- method public abstract android.media.MediaTimestamp getTimestamp();
- method public abstract java.util.List<androidx.media.MediaPlayer2.TrackInfo> getTrackInfo();
- method public abstract int getVideoHeight();
- method public abstract int getVideoWidth();
- method public boolean isReversePlaybackSupported();
- method public abstract void loopCurrent(boolean);
- method public void notifyWhenCommandLabelReached(java.lang.Object);
- method public abstract void pause();
- method public abstract void play();
- method public abstract void prepare();
- method public abstract void prepareDrm(java.util.UUID) throws androidx.media.MediaPlayer2.ProvisioningNetworkErrorException, androidx.media.MediaPlayer2.ProvisioningServerErrorException, android.media.ResourceBusyException, android.media.UnsupportedSchemeException;
- method public abstract byte[] provideDrmKeyResponse(byte[], byte[]) throws android.media.DeniedByServerException, androidx.media.MediaPlayer2.NoDrmSchemeException;
- method public abstract void releaseDrm() throws androidx.media.MediaPlayer2.NoDrmSchemeException;
- method public abstract void reset();
- method public abstract void restoreDrmKeys(byte[]) throws androidx.media.MediaPlayer2.NoDrmSchemeException;
- method public void seekTo(long);
- method public abstract void seekTo(long, int);
- method public abstract void selectTrack(int);
- method public abstract void setAudioAttributes(androidx.media.AudioAttributesCompat);
- method public abstract void setAudioSessionId(int);
- method public abstract void setAuxEffectSendLevel(float);
- method public abstract void setDataSource(androidx.media.DataSourceDesc);
- method public abstract void setDrmEventCallback(java.util.concurrent.Executor, androidx.media.MediaPlayer2.DrmEventCallback);
- method public abstract void setDrmPropertyString(java.lang.String, java.lang.String) throws androidx.media.MediaPlayer2.NoDrmSchemeException;
- method public abstract void setMediaPlayer2EventCallback(java.util.concurrent.Executor, androidx.media.MediaPlayer2.MediaPlayer2EventCallback);
- method public abstract void setNextDataSource(androidx.media.DataSourceDesc);
- method public abstract void setNextDataSources(java.util.List<androidx.media.DataSourceDesc>);
- method public abstract void setOnDrmConfigHelper(androidx.media.MediaPlayer2.OnDrmConfigHelper);
- method public abstract void setPlaybackParams(android.media.PlaybackParams);
- method public abstract void setPlaybackSpeed(float);
- method public abstract void setPlayerVolume(float);
- method public abstract void setSurface(android.view.Surface);
- method public abstract void setSyncParams(android.media.SyncParams);
- method public abstract void skipToNext();
- field public static final int CALL_COMPLETED_ATTACH_AUX_EFFECT = 1; // 0x1
- field public static final int CALL_COMPLETED_DESELECT_TRACK = 2; // 0x2
- field public static final int CALL_COMPLETED_LOOP_CURRENT = 3; // 0x3
- field public static final int CALL_COMPLETED_PAUSE = 4; // 0x4
- field public static final int CALL_COMPLETED_PLAY = 5; // 0x5
- field public static final int CALL_COMPLETED_PREPARE = 6; // 0x6
- field public static final int CALL_COMPLETED_SEEK_TO = 14; // 0xe
- field public static final int CALL_COMPLETED_SELECT_TRACK = 15; // 0xf
- field public static final int CALL_COMPLETED_SET_AUDIO_ATTRIBUTES = 16; // 0x10
- field public static final int CALL_COMPLETED_SET_AUDIO_SESSION_ID = 17; // 0x11
- field public static final int CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL = 18; // 0x12
- field public static final int CALL_COMPLETED_SET_DATA_SOURCE = 19; // 0x13
- field public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCE = 22; // 0x16
- field public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCES = 23; // 0x17
- field public static final int CALL_COMPLETED_SET_PLAYBACK_PARAMS = 24; // 0x18
- field public static final int CALL_COMPLETED_SET_PLAYBACK_SPEED = 25; // 0x19
- field public static final int CALL_COMPLETED_SET_PLAYER_VOLUME = 26; // 0x1a
- field public static final int CALL_COMPLETED_SET_SURFACE = 27; // 0x1b
- field public static final int CALL_COMPLETED_SET_SYNC_PARAMS = 28; // 0x1c
- field public static final int CALL_COMPLETED_SKIP_TO_NEXT = 29; // 0x1d
- field public static final int CALL_STATUS_BAD_VALUE = 2; // 0x2
- field public static final int CALL_STATUS_ERROR_IO = 4; // 0x4
- field public static final int CALL_STATUS_ERROR_UNKNOWN = -2147483648; // 0x80000000
- field public static final int CALL_STATUS_INVALID_OPERATION = 1; // 0x1
- field public static final int CALL_STATUS_NO_ERROR = 0; // 0x0
- field public static final int CALL_STATUS_PERMISSION_DENIED = 3; // 0x3
- field public static final int MEDIAPLAYER2_STATE_ERROR = 1005; // 0x3ed
- field public static final int MEDIAPLAYER2_STATE_IDLE = 1001; // 0x3e9
- field public static final int MEDIAPLAYER2_STATE_PAUSED = 1003; // 0x3eb
- field public static final int MEDIAPLAYER2_STATE_PLAYING = 1004; // 0x3ec
- field public static final int MEDIAPLAYER2_STATE_PREPARED = 1002; // 0x3ea
- field public static final int MEDIA_ERROR_IO = -1004; // 0xfffffc14
- field public static final int MEDIA_ERROR_MALFORMED = -1007; // 0xfffffc11
- field public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200; // 0xc8
- field public static final int MEDIA_ERROR_TIMED_OUT = -110; // 0xffffff92
- field public static final int MEDIA_ERROR_UNKNOWN = 1; // 0x1
- field public static final int MEDIA_ERROR_UNSUPPORTED = -1010; // 0xfffffc0e
- field public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804; // 0x324
- field public static final int MEDIA_INFO_AUDIO_RENDERING_START = 4; // 0x4
- field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
- field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
- field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
- field public static final int MEDIA_INFO_BUFFERING_UPDATE = 704; // 0x2c0
- field public static final int MEDIA_INFO_METADATA_UPDATE = 802; // 0x322
- field public static final int MEDIA_INFO_NOT_SEEKABLE = 801; // 0x321
- field public static final int MEDIA_INFO_PLAYBACK_COMPLETE = 5; // 0x5
- field public static final int MEDIA_INFO_PLAYLIST_END = 6; // 0x6
- field public static final int MEDIA_INFO_PREPARED = 100; // 0x64
- field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
- field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
- field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
- field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
- field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
- field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
- field public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3; // 0x3
- field public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1; // 0x1
- field public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2; // 0x2
- field public static final int PREPARE_DRM_STATUS_SUCCESS = 0; // 0x0
- field public static final int SEEK_CLOSEST = 3; // 0x3
- field public static final int SEEK_CLOSEST_SYNC = 2; // 0x2
- field public static final int SEEK_NEXT_SYNC = 1; // 0x1
- field public static final int SEEK_PREVIOUS_SYNC = 0; // 0x0
- field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
- }
-
- public static abstract class MediaPlayer2.DrmEventCallback {
- ctor public MediaPlayer2.DrmEventCallback();
- method public void onDrmInfo(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc, androidx.media.MediaPlayer2.DrmInfo);
- method public void onDrmPrepared(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc, int);
- }
-
- public static abstract class MediaPlayer2.DrmInfo {
- ctor public MediaPlayer2.DrmInfo();
- method public abstract java.util.Map<java.util.UUID, byte[]> getPssh();
- method public abstract java.util.List<java.util.UUID> getSupportedSchemes();
- }
-
- public static abstract class MediaPlayer2.MediaPlayer2EventCallback {
- ctor public MediaPlayer2.MediaPlayer2EventCallback();
- method public void onCallCompleted(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc, int, int);
- method public void onCommandLabelReached(androidx.media.MediaPlayer2, java.lang.Object);
- method public void onError(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc, int, int);
- method public void onInfo(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc, int, int);
- method public void onMediaTimeDiscontinuity(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc, android.media.MediaTimestamp);
- method public void onSubtitleData(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc, android.media.SubtitleData);
- method public void onTimedMetaDataAvailable(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc, android.media.TimedMetaData);
- method public void onVideoSizeChanged(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc, int, int);
- }
-
- public static final class MediaPlayer2.MetricsConstants {
- field public static final java.lang.String CODEC_AUDIO = "android.media.mediaplayer.audio.codec";
- field public static final java.lang.String CODEC_VIDEO = "android.media.mediaplayer.video.codec";
- field public static final java.lang.String DURATION = "android.media.mediaplayer.durationMs";
- field public static final java.lang.String ERRORS = "android.media.mediaplayer.err";
- field public static final java.lang.String ERROR_CODE = "android.media.mediaplayer.errcode";
- field public static final java.lang.String FRAMES = "android.media.mediaplayer.frames";
- field public static final java.lang.String FRAMES_DROPPED = "android.media.mediaplayer.dropped";
- field public static final java.lang.String HEIGHT = "android.media.mediaplayer.height";
- field public static final java.lang.String MIME_TYPE_AUDIO = "android.media.mediaplayer.audio.mime";
- field public static final java.lang.String MIME_TYPE_VIDEO = "android.media.mediaplayer.video.mime";
- field public static final java.lang.String PLAYING = "android.media.mediaplayer.playingMs";
- field public static final java.lang.String WIDTH = "android.media.mediaplayer.width";
- }
-
- public static class MediaPlayer2.NoDrmSchemeException extends android.media.MediaDrmException {
- ctor public MediaPlayer2.NoDrmSchemeException(java.lang.String);
- }
-
- public static abstract interface MediaPlayer2.OnDrmConfigHelper {
- method public abstract void onDrmConfig(androidx.media.MediaPlayer2, androidx.media.DataSourceDesc);
- }
-
- public static class MediaPlayer2.ProvisioningNetworkErrorException extends android.media.MediaDrmException {
- ctor public MediaPlayer2.ProvisioningNetworkErrorException(java.lang.String);
- }
-
- public static class MediaPlayer2.ProvisioningServerErrorException extends android.media.MediaDrmException {
- ctor public MediaPlayer2.ProvisioningServerErrorException(java.lang.String);
- }
-
- public static abstract class MediaPlayer2.TrackInfo {
- ctor public MediaPlayer2.TrackInfo();
- method public abstract android.media.MediaFormat getFormat();
- method public abstract java.lang.String getLanguage();
- method public abstract int getTrackType();
- method public abstract java.lang.String toString();
- field public static final int MEDIA_TRACK_TYPE_AUDIO = 2; // 0x2
- field public static final int MEDIA_TRACK_TYPE_METADATA = 5; // 0x5
- field public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4; // 0x4
- field public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0; // 0x0
- field public static final int MEDIA_TRACK_TYPE_VIDEO = 1; // 0x1
- }
-
- public abstract class MediaPlayerInterface implements java.lang.AutoCloseable {
- ctor public MediaPlayerInterface();
+ public abstract class MediaPlayerBase implements java.lang.AutoCloseable {
+ ctor public MediaPlayerBase();
method public abstract androidx.media.AudioAttributesCompat getAudioAttributes();
method public long getBufferedPosition();
method public abstract int getBufferingState();
@@ -1091,7 +827,7 @@
method public abstract void pause();
method public abstract void play();
method public abstract void prepare();
- method public abstract void registerPlayerEventCallback(java.util.concurrent.Executor, androidx.media.MediaPlayerInterface.PlayerEventCallback);
+ method public abstract void registerPlayerEventCallback(java.util.concurrent.Executor, androidx.media.MediaPlayerBase.PlayerEventCallback);
method public abstract void reset();
method public abstract void seekTo(long);
method public abstract void setAudioAttributes(androidx.media.AudioAttributesCompat);
@@ -1101,7 +837,7 @@
method public abstract void setPlaybackSpeed(float);
method public abstract void setPlayerVolume(float);
method public abstract void skipToNext();
- method public abstract void unregisterPlayerEventCallback(androidx.media.MediaPlayerInterface.PlayerEventCallback);
+ method public abstract void unregisterPlayerEventCallback(androidx.media.MediaPlayerBase.PlayerEventCallback);
field public static final int BUFFERING_STATE_BUFFERING_AND_PLAYABLE = 1; // 0x1
field public static final int BUFFERING_STATE_BUFFERING_AND_STARVED = 2; // 0x2
field public static final int BUFFERING_STATE_BUFFERING_COMPLETE = 3; // 0x3
@@ -1113,14 +849,14 @@
field public static final long UNKNOWN_TIME = -1L; // 0xffffffffffffffffL
}
- public static abstract class MediaPlayerInterface.PlayerEventCallback {
- ctor public MediaPlayerInterface.PlayerEventCallback();
- method public void onBufferingStateChanged(androidx.media.MediaPlayerInterface, androidx.media.DataSourceDesc, int);
- method public void onCurrentDataSourceChanged(androidx.media.MediaPlayerInterface, androidx.media.DataSourceDesc);
- method public void onMediaPrepared(androidx.media.MediaPlayerInterface, androidx.media.DataSourceDesc);
- method public void onPlaybackSpeedChanged(androidx.media.MediaPlayerInterface, float);
- method public void onPlayerStateChanged(androidx.media.MediaPlayerInterface, int);
- method public void onSeekCompleted(androidx.media.MediaPlayerInterface, long);
+ public static abstract class MediaPlayerBase.PlayerEventCallback {
+ ctor public MediaPlayerBase.PlayerEventCallback();
+ method public void onBufferingStateChanged(androidx.media.MediaPlayerBase, androidx.media.DataSourceDesc, int);
+ method public void onCurrentDataSourceChanged(androidx.media.MediaPlayerBase, androidx.media.DataSourceDesc);
+ method public void onMediaPrepared(androidx.media.MediaPlayerBase, androidx.media.DataSourceDesc);
+ method public void onPlaybackSpeedChanged(androidx.media.MediaPlayerBase, float);
+ method public void onPlayerStateChanged(androidx.media.MediaPlayerBase, int);
+ method public void onSeekCompleted(androidx.media.MediaPlayerBase, long);
}
public abstract class MediaPlaylistAgent {
@@ -1175,7 +911,7 @@
method public long getCurrentPosition();
method public long getDuration();
method public float getPlaybackSpeed();
- method public androidx.media.MediaPlayerInterface getPlayer();
+ method public androidx.media.MediaPlayerBase getPlayer();
method public int getPlayerState();
method public java.util.List<androidx.media.MediaItem2> getPlaylist();
method public androidx.media.MediaPlaylistAgent getPlaylistAgent();
@@ -1206,7 +942,7 @@
method public void skipToNextItem();
method public void skipToPlaylistItem(androidx.media.MediaItem2);
method public void skipToPreviousItem();
- method public void updatePlayer(androidx.media.MediaPlayerInterface, androidx.media.MediaPlaylistAgent, androidx.media.VolumeProviderCompat);
+ method public void updatePlayer(androidx.media.MediaPlayerBase, androidx.media.MediaPlaylistAgent, androidx.media.VolumeProviderCompat);
method public void updatePlaylistMetadata(androidx.media.MediaMetadata2);
field public static final int ERROR_CODE_ACTION_ABORTED = 10; // 0xa
field public static final int ERROR_CODE_APP_ERROR = 1; // 0x1
@@ -1227,7 +963,7 @@
ctor public MediaSession2.Builder(android.content.Context);
method public androidx.media.MediaSession2 build();
method public androidx.media.MediaSession2.Builder setId(java.lang.String);
- method public androidx.media.MediaSession2.Builder setPlayer(androidx.media.MediaPlayerInterface);
+ method public androidx.media.MediaSession2.Builder setPlayer(androidx.media.MediaPlayerBase);
method public androidx.media.MediaSession2.Builder setPlaylistAgent(androidx.media.MediaPlaylistAgent);
method public androidx.media.MediaSession2.Builder setSessionActivity(android.app.PendingIntent);
method public androidx.media.MediaSession2.Builder setSessionCallback(java.util.concurrent.Executor, androidx.media.MediaSession2.SessionCallback);
@@ -1263,19 +999,19 @@
public static abstract class MediaSession2.SessionCallback {
ctor public MediaSession2.SessionCallback();
- method public void onBufferingStateChanged(androidx.media.MediaSession2, androidx.media.MediaPlayerInterface, androidx.media.MediaItem2, int);
+ method public void onBufferingStateChanged(androidx.media.MediaSession2, androidx.media.MediaPlayerBase, androidx.media.MediaItem2, int);
method public boolean onCommandRequest(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo, androidx.media.SessionCommand2);
method public androidx.media.SessionCommandGroup2 onConnect(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo);
- method public void onCurrentMediaItemChanged(androidx.media.MediaSession2, androidx.media.MediaPlayerInterface, androidx.media.MediaItem2);
+ method public void onCurrentMediaItemChanged(androidx.media.MediaSession2, androidx.media.MediaPlayerBase, androidx.media.MediaItem2);
method public void onCustomCommand(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo, androidx.media.SessionCommand2, android.os.Bundle, android.os.ResultReceiver);
method public void onDisconnected(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo);
method public void onFastForward(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo);
- method public void onMediaPrepared(androidx.media.MediaSession2, androidx.media.MediaPlayerInterface, androidx.media.MediaItem2);
+ method public void onMediaPrepared(androidx.media.MediaSession2, androidx.media.MediaPlayerBase, androidx.media.MediaItem2);
method public void onPlayFromMediaId(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
method public void onPlayFromSearch(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
method public void onPlayFromUri(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo, android.net.Uri, android.os.Bundle);
- method public void onPlaybackSpeedChanged(androidx.media.MediaSession2, androidx.media.MediaPlayerInterface, float);
- method public void onPlayerStateChanged(androidx.media.MediaSession2, androidx.media.MediaPlayerInterface, int);
+ method public void onPlaybackSpeedChanged(androidx.media.MediaSession2, androidx.media.MediaPlayerBase, float);
+ method public void onPlayerStateChanged(androidx.media.MediaSession2, androidx.media.MediaPlayerBase, int);
method public void onPlaylistChanged(androidx.media.MediaSession2, androidx.media.MediaPlaylistAgent, java.util.List<androidx.media.MediaItem2>, androidx.media.MediaMetadata2);
method public void onPlaylistMetadataChanged(androidx.media.MediaSession2, androidx.media.MediaPlaylistAgent, androidx.media.MediaMetadata2);
method public void onPrepareFromMediaId(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
@@ -1283,7 +1019,7 @@
method public void onPrepareFromUri(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo, android.net.Uri, android.os.Bundle);
method public void onRepeatModeChanged(androidx.media.MediaSession2, androidx.media.MediaPlaylistAgent, int);
method public void onRewind(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo);
- method public void onSeekCompleted(androidx.media.MediaSession2, androidx.media.MediaPlayerInterface, long);
+ method public void onSeekCompleted(androidx.media.MediaSession2, androidx.media.MediaPlayerBase, long);
method public void onSelectRoute(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo, android.os.Bundle);
method public void onSetRating(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo, java.lang.String, androidx.media.Rating2);
method public void onShuffleModeChanged(androidx.media.MediaSession2, androidx.media.MediaPlaylistAgent, int);
@@ -1291,35 +1027,6 @@
method public void onUnsubscribeRoutesInfo(androidx.media.MediaSession2, androidx.media.MediaSession2.ControllerInfo);
}
- public final class MediaSessionManager {
- method public static androidx.media.MediaSessionManager getSessionManager(android.content.Context);
- method public boolean isTrustedForMediaControl(androidx.media.MediaSessionManager.RemoteUserInfo);
- }
-
- public static final class MediaSessionManager.RemoteUserInfo {
- ctor public MediaSessionManager.RemoteUserInfo(java.lang.String, int, int);
- method public java.lang.String getPackageName();
- method public int getPid();
- method public int getUid();
- field public static java.lang.String LEGACY_CONTROLLER;
- }
-
- public abstract class MediaSessionService2 extends android.app.Service {
- ctor public MediaSessionService2();
- method public final androidx.media.MediaSession2 getSession();
- method public android.os.IBinder onBind(android.content.Intent);
- method public abstract androidx.media.MediaSession2 onCreateSession(java.lang.String);
- method public androidx.media.MediaSessionService2.MediaNotification onUpdateNotification();
- field public static final java.lang.String SERVICE_INTERFACE = "android.media.MediaSessionService2";
- field public static final java.lang.String SERVICE_META_DATA = "android.media.session";
- }
-
- public static class MediaSessionService2.MediaNotification {
- ctor public MediaSessionService2.MediaNotification(int, android.app.Notification);
- method public android.app.Notification getNotification();
- method public int getNotificationId();
- }
-
public final class Rating2 {
method public static androidx.media.Rating2 fromBundle(android.os.Bundle);
method public float getPercentRating();
@@ -1350,13 +1057,6 @@
method public java.lang.String getCustomCommand();
method public android.os.Bundle getExtras();
field public static final int COMMAND_CODE_CUSTOM = 0; // 0x0
- field public static final int COMMAND_CODE_LIBRARY_GET_CHILDREN = 29; // 0x1d
- field public static final int COMMAND_CODE_LIBRARY_GET_ITEM = 30; // 0x1e
- field public static final int COMMAND_CODE_LIBRARY_GET_LIBRARY_ROOT = 31; // 0x1f
- field public static final int COMMAND_CODE_LIBRARY_GET_SEARCH_RESULT = 32; // 0x20
- field public static final int COMMAND_CODE_LIBRARY_SEARCH = 33; // 0x21
- field public static final int COMMAND_CODE_LIBRARY_SUBSCRIBE = 34; // 0x22
- field public static final int COMMAND_CODE_LIBRARY_UNSUBSCRIBE = 35; // 0x23
field public static final int COMMAND_CODE_PLAYBACK_PAUSE = 2; // 0x2
field public static final int COMMAND_CODE_PLAYBACK_PLAY = 1; // 0x1
field public static final int COMMAND_CODE_PLAYBACK_PREPARE = 6; // 0x6
@@ -1406,7 +1106,6 @@
}
public final class SessionToken2 {
- ctor public SessionToken2(android.content.Context, android.content.ComponentName);
method public static androidx.media.SessionToken2 fromBundle(android.os.Bundle);
method public java.lang.String getId();
method public java.lang.String getPackageName();
@@ -1414,9 +1113,7 @@
method public int getType();
method public int getUid();
method public android.os.Bundle toBundle();
- field public static final int TYPE_LIBRARY_SERVICE = 2; // 0x2
field public static final int TYPE_SESSION = 0; // 0x0
- field public static final int TYPE_SESSION_SERVICE = 1; // 0x1
}
public abstract class VolumeProviderCompat {
diff --git a/media/src/androidTest/java/androidx/media/MediaBrowser2Test.java b/media/src/androidTest/java/androidx/media/MediaBrowser2Test.java
index 211b5a9..4b75986 100644
--- a/media/src/androidTest/java/androidx/media/MediaBrowser2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaBrowser2Test.java
@@ -29,12 +29,9 @@
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.LargeTest;
-import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -68,15 +65,17 @@
* {@link MediaController2} works cleanly.
*/
// TODO(jaewan): Implement host-side test so browser and service can run in different processes.
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
@RunWith(AndroidJUnit4.class)
@SmallTest
+@Ignore
public class MediaBrowser2Test extends MediaController2Test {
private static final String TAG = "MediaBrowser2Test";
@Override
TestControllerInterface onCreateController(final @NonNull SessionToken2 token,
- final @Nullable ControllerCallback callback) throws InterruptedException {
+ @Nullable ControllerCallback callback) throws InterruptedException {
+ final BrowserCallback browserCallback =
+ callback != null ? (BrowserCallback) callback : new BrowserCallback() {};
final AtomicReference<TestControllerInterface> controller = new AtomicReference<>();
sHandler.postAndSync(new Runnable() {
@Override
@@ -85,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(callback)));
+ mContext, token, new TestBrowserCallback(browserCallback)));
}
});
return controller.get();
@@ -121,9 +120,7 @@
Bundle rootHints, String rootMediaId, Bundle rootExtra) {
assertTrue(TestUtils.equals(param, rootHints));
assertEquals(ROOT_ID, rootMediaId);
- // Note that TestUtils#equals() cannot be used for this because
- // MediaBrowserServiceCompat adds extra_client_version to the rootHints.
- assertTrue(TestUtils.contains(rootExtra, EXTRAS));
+ assertTrue(TestUtils.equals(EXTRAS, rootExtra));
latch.countDown();
}
};
@@ -262,6 +259,7 @@
assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
}
+ @Ignore
@Test
public void testSearch() throws InterruptedException {
prepareLooper();
@@ -319,7 +317,6 @@
}
@Test
- @LargeTest
public void testSearchTakesTime() throws InterruptedException {
prepareLooper();
final String query = MockMediaLibraryService2.SEARCH_QUERY_TAKES_TIME;
@@ -421,201 +418,82 @@
}
@Test
- public void testBrowserCallback_onChildrenChangedIsNotCalledWhenNotSubscribed()
- throws InterruptedException {
- // This test uses MediaLibrarySession.notifyChildrenChanged().
+ public void testBrowserCallback_notifyChildrenChanged() throws InterruptedException {
prepareLooper();
- final String subscribedMediaId = "subscribedMediaId";
- final String anotherMediaId = "anotherMediaId";
+ // TODO(jaewan): Add test for the notifyChildrenChanged itself.
+ final String testParentId1 = "testBrowserCallback_notifyChildrenChanged_unexpectedParent";
+ final String testParentId2 = "testBrowserCallback_notifyChildrenChanged";
final int testChildrenCount = 101;
- final CountDownLatch latch = new CountDownLatch(1);
+ final Bundle testExtras = new Bundle();
+ testExtras.putString(testParentId1, testParentId1);
- final MediaLibrarySessionCallback sessionCallback = new MediaLibrarySessionCallback() {
- @Override
- public void onSubscribe(@NonNull MediaLibrarySession session,
- @NonNull ControllerInfo controller, @NonNull String parentId,
- @Nullable Bundle extras) {
- if (Process.myUid() == controller.getUid()) {
- // Shouldn't trigger onChildrenChanged() for the browser,
- // because the browser didn't subscribe this media id.
- session.notifyChildrenChanged(anotherMediaId, testChildrenCount, null);
- }
- }
+ final CountDownLatch latch = new CountDownLatch(3);
+ final MediaLibrarySessionCallback sessionCallback =
+ new MediaLibrarySessionCallback() {
+ @Override
+ public SessionCommandGroup2 onConnect(@NonNull MediaSession2 session,
+ @NonNull ControllerInfo controller) {
+ if (Process.myUid() == controller.getUid()) {
+ assertTrue(session instanceof MediaLibrarySession);
+ if (mSession != null) {
+ mSession.close();
+ }
+ mSession = session;
+ // Shouldn't trigger onChildrenChanged() for the browser, because it
+ // hasn't subscribed.
+ ((MediaLibrarySession) session).notifyChildrenChanged(
+ testParentId1, testChildrenCount, null);
+ ((MediaLibrarySession) session).notifyChildrenChanged(
+ controller, testParentId1, testChildrenCount, null);
+ }
+ return super.onConnect(session, controller);
+ }
- @Override
- public List<MediaItem2> onGetChildren(MediaLibrarySession session,
- ControllerInfo controller, String parentId, int page, int pageSize,
- Bundle extras) {
- return TestUtils.createPlaylist(testChildrenCount);
- }
+ @Override
+ public void onSubscribe(@NonNull MediaLibrarySession session,
+ @NonNull ControllerInfo info, @NonNull String parentId,
+ @Nullable Bundle extras) {
+ if (Process.myUid() == info.getUid()) {
+ session.notifyChildrenChanged(testParentId2, testChildrenCount, null);
+ session.notifyChildrenChanged(info, testParentId2, testChildrenCount,
+ testExtras);
+ }
+ }
};
- final BrowserCallback controllerCallbackProxy = new BrowserCallback() {
- @Override
- public void onChildrenChanged(MediaBrowser2 browser, String parentId,
- int itemCount, Bundle extras) {
- // Unexpected call.
- fail();
- }
- };
-
+ final BrowserCallback controllerCallbackProxy =
+ new BrowserCallback() {
+ @Override
+ public void onChildrenChanged(MediaBrowser2 browser, String parentId,
+ int itemCount, Bundle extras) {
+ switch ((int) latch.getCount()) {
+ case 3:
+ assertEquals(testParentId2, parentId);
+ assertEquals(testChildrenCount, itemCount);
+ assertNull(extras);
+ latch.countDown();
+ break;
+ case 2:
+ assertEquals(testParentId2, parentId);
+ assertEquals(testChildrenCount, itemCount);
+ assertTrue(TestUtils.equals(testExtras, extras));
+ latch.countDown();
+ break;
+ default:
+ // Unexpected call.
+ fail();
+ }
+ }
+ };
TestServiceRegistry.getInstance().setSessionCallback(sessionCallback);
final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
final MediaBrowser2 browser = (MediaBrowser2) createController(
token, true, controllerCallbackProxy);
- browser.subscribe(subscribedMediaId, null);
-
- // onChildrenChanged() should not be called.
+ assertTrue(mSession instanceof MediaLibrarySession);
+ browser.subscribe(testParentId2, null);
+ // This ensures that onChildrenChanged() is only called for the expected reasons.
assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
}
- @Test
- public void testBrowserCallback_onChildrenChangedIsCalledWhenSubscribed()
- throws InterruptedException {
- // This test uses MediaLibrarySession.notifyChildrenChanged().
- prepareLooper();
- final String expectedParentId = "expectedParentId";
- final int testChildrenCount = 101;
- final Bundle testExtras = TestUtils.createTestBundle();
-
- final CountDownLatch latch = new CountDownLatch(1);
- final MediaLibrarySessionCallback sessionCallback = new MediaLibrarySessionCallback() {
- @Override
- public void onSubscribe(@NonNull MediaLibrarySession session,
- @NonNull ControllerInfo controller, @NonNull String parentId,
- @Nullable Bundle extras) {
- if (Process.myUid() == controller.getUid()) {
- // Should trigger onChildrenChanged() for the browser.
- session.notifyChildrenChanged(expectedParentId, testChildrenCount, testExtras);
- }
- }
-
- @Override
- public List<MediaItem2> onGetChildren(MediaLibrarySession session,
- ControllerInfo controller, String parentId, int page, int pageSize,
- Bundle extras) {
- return TestUtils.createPlaylist(testChildrenCount);
- }
- };
- final BrowserCallback controllerCallbackProxy = new BrowserCallback() {
- @Override
- public void onChildrenChanged(MediaBrowser2 browser, String parentId,
- int itemCount, Bundle extras) {
- assertEquals(expectedParentId, parentId);
- assertEquals(testChildrenCount, itemCount);
- assertTrue(TestUtils.equals(testExtras, extras));
- latch.countDown();
- }
- };
-
- TestServiceRegistry.getInstance().setSessionCallback(sessionCallback);
- final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
- final MediaBrowser2 browser = (MediaBrowser2) createController(
- token, true, controllerCallbackProxy);
- browser.subscribe(expectedParentId, null);
-
- // onChildrenChanged() should be called.
- assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testBrowserCallback_onChildrenChangedIsNotCalledWhenNotSubscribed2()
- throws InterruptedException {
- // This test uses MediaLibrarySession.notifyChildrenChanged(ControllerInfo).
- prepareLooper();
- final String subscribedMediaId = "subscribedMediaId";
- final String anotherMediaId = "anotherMediaId";
- final int testChildrenCount = 101;
- final CountDownLatch latch = new CountDownLatch(1);
-
- final MediaLibrarySessionCallback sessionCallback = new MediaLibrarySessionCallback() {
- @Override
- public void onSubscribe(@NonNull MediaLibrarySession session,
- @NonNull ControllerInfo controller, @NonNull String parentId,
- @Nullable Bundle extras) {
- if (Process.myUid() == controller.getUid()) {
- // Shouldn't trigger onChildrenChanged() for the browser,
- // because the browser didn't subscribe this media id.
- session.notifyChildrenChanged(
- controller, anotherMediaId, testChildrenCount, null);
- }
- }
-
- @Override
- public List<MediaItem2> onGetChildren(MediaLibrarySession session,
- ControllerInfo controller, String parentId, int page, int pageSize,
- Bundle extras) {
- return TestUtils.createPlaylist(testChildrenCount);
- }
- };
- final BrowserCallback controllerCallbackProxy = new BrowserCallback() {
- @Override
- public void onChildrenChanged(MediaBrowser2 browser, String parentId,
- int itemCount, Bundle extras) {
- // Unexpected call.
- fail();
- }
- };
-
- TestServiceRegistry.getInstance().setSessionCallback(sessionCallback);
- final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
- final MediaBrowser2 browser = (MediaBrowser2) createController(
- token, true, controllerCallbackProxy);
- browser.subscribe(subscribedMediaId, null);
-
- // onChildrenChanged() should not be called.
- assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testBrowserCallback_onChildrenChangedIsCalledWhenSubscribed2()
- throws InterruptedException {
- // This test uses MediaLibrarySession.notifyChildrenChanged(ControllerInfo).
- prepareLooper();
- final String expectedParentId = "expectedParentId";
- final int testChildrenCount = 101;
- final Bundle testExtras = TestUtils.createTestBundle();
-
- final CountDownLatch latch = new CountDownLatch(1);
- final MediaLibrarySessionCallback sessionCallback = new MediaLibrarySessionCallback() {
- @Override
- public void onSubscribe(@NonNull MediaLibrarySession session,
- @NonNull ControllerInfo controller, @NonNull String parentId,
- @Nullable Bundle extras) {
- if (Process.myUid() == controller.getUid()) {
- // Should trigger onChildrenChanged() for the browser.
- session.notifyChildrenChanged(
- controller, expectedParentId, testChildrenCount, testExtras);
- }
- }
-
- @Override
- public List<MediaItem2> onGetChildren(MediaLibrarySession session,
- ControllerInfo controller, String parentId, int page, int pageSize,
- Bundle extras) {
- return TestUtils.createPlaylist(testChildrenCount);
- }
- };
- final BrowserCallback controllerCallbackProxy = new BrowserCallback() {
- @Override
- public void onChildrenChanged(MediaBrowser2 browser, String parentId,
- int itemCount, Bundle extras) {
- assertEquals(expectedParentId, parentId);
- assertEquals(testChildrenCount, itemCount);
- assertTrue(TestUtils.equals(testExtras, extras));
- latch.countDown();
- }
- };
-
- TestServiceRegistry.getInstance().setSessionCallback(sessionCallback);
- final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
- final MediaBrowser2 browser = (MediaBrowser2) createController(
- token, true, controllerCallbackProxy);
- browser.subscribe(expectedParentId, null);
-
- // onChildrenChanged() should be called.
- assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- }
-
public static class TestBrowserCallback extends BrowserCallback
implements TestControllerCallbackInterface {
private final ControllerCallback mCallbackProxy;
@@ -626,7 +504,7 @@
TestBrowserCallback(ControllerCallback callbackProxy) {
if (callbackProxy == null) {
- callbackProxy = new BrowserCallback() {};
+ throw new IllegalArgumentException("Callback proxy shouldn't be null. Test bug");
}
mCallbackProxy = callbackProxy;
}
@@ -812,9 +690,9 @@
private final BrowserCallback mCallback;
public TestMediaBrowser(@NonNull Context context, @NonNull SessionToken2 token,
- @NonNull BrowserCallback callback) {
- super(context, token, sHandlerExecutor, callback);
- mCallback = callback;
+ @NonNull ControllerCallback callback) {
+ super(context, token, sHandlerExecutor, (BrowserCallback) callback);
+ mCallback = (BrowserCallback) callback;
}
@Override
diff --git a/media/src/androidTest/java/androidx/media/MediaController2Test.java b/media/src/androidTest/java/androidx/media/MediaController2Test.java
index 072381e..75c9e50 100644
--- a/media/src/androidTest/java/androidx/media/MediaController2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaController2Test.java
@@ -25,7 +25,6 @@
import static org.junit.Assert.fail;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.net.Uri;
@@ -42,16 +41,15 @@
import androidx.annotation.NonNull;
import androidx.media.MediaController2.ControllerCallback;
-import androidx.media.MediaController2.PlaybackInfo;
import androidx.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
import androidx.media.MediaSession2.ControllerInfo;
import androidx.media.MediaSession2.SessionCallback;
import androidx.media.TestServiceRegistry.SessionServiceCallback;
import androidx.media.TestUtils.SyncHandler;
-import androidx.testutils.PollingCheck;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -67,7 +65,7 @@
// TODO(jaewan): Implement host-side test so controller and session can run in different processes.
// TODO(jaewan): Fix flaky failure -- see MediaController2Impl.getController()
// TODO(jaeawn): Revisit create/close session in the sHandler. It's no longer necessary.
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
@RunWith(AndroidJUnit4.class)
@SmallTest
@FlakyTest
@@ -79,7 +77,6 @@
MediaController2 mController;
MockPlayer mPlayer;
MockPlaylistAgent mMockAgent;
- AudioManager mAudioManager;
@Before
@Override
@@ -114,7 +111,6 @@
.setSessionActivity(mIntent)
.setId(TAG).build();
mController = createController(mSession.getToken());
- mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
TestServiceRegistry.getInstance().setHandler(sHandler);
}
@@ -211,12 +207,11 @@
@Test
public void testGettersAfterConnected() throws InterruptedException {
prepareLooper();
- final int state = MediaPlayerInterface.PLAYER_STATE_PLAYING;
- final int bufferingState = MediaPlayerInterface.BUFFERING_STATE_BUFFERING_COMPLETE;
+ final int state = MediaPlayerBase.PLAYER_STATE_PLAYING;
+ final int bufferingState = MediaPlayerBase.BUFFERING_STATE_BUFFERING_COMPLETE;
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;
@@ -226,60 +221,22 @@
mPlayer.mPlaybackSpeed = speed;
mMockAgent.mCurrentMediaItem = currentMediaItem;
+ long time1 = System.currentTimeMillis();
MediaController2 controller = createController(mSession.getToken());
- controller.setTimeDiff(timeDiff);
+ long time2 = System.currentTimeMillis();
assertEquals(state, controller.getPlayerState());
assertEquals(bufferedPosition, controller.getBufferedPosition());
assertEquals(speed, controller.getPlaybackSpeed(), 0.0f);
- assertEquals(position + (long) (speed * timeDiff), controller.getCurrentPosition());
+ 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(currentMediaItem, controller.getCurrentMediaItem());
}
@Test
- public void testUpdatePlayer() throws InterruptedException {
- prepareLooper();
- final int testState = MediaPlayerInterface.PLAYER_STATE_PLAYING;
- final List<MediaItem2> testPlaylist = TestUtils.createPlaylist(3);
- final AudioAttributesCompat testAudioAttributes = new AudioAttributesCompat.Builder()
- .setLegacyStreamType(AudioManager.STREAM_RING).build();
- final CountDownLatch latch = new CountDownLatch(3);
- mController = createController(mSession.getToken(), true, new ControllerCallback() {
- @Override
- public void onPlayerStateChanged(MediaController2 controller, int state) {
- assertEquals(mController, controller);
- assertEquals(testState, state);
- latch.countDown();
- }
-
- @Override
- public void onPlaylistChanged(MediaController2 controller, List<MediaItem2> list,
- MediaMetadata2 metadata) {
- assertEquals(mController, controller);
- assertEquals(testPlaylist, list);
- assertNull(metadata);
- latch.countDown();
- }
-
- @Override
- public void onPlaybackInfoChanged(MediaController2 controller, PlaybackInfo info) {
- assertEquals(mController, controller);
- assertEquals(testAudioAttributes, info.getAudioAttributes());
- latch.countDown();
- }
- });
-
- MockPlayer player = new MockPlayer(0);
- player.mLastPlayerState = testState;
- player.setAudioAttributes(testAudioAttributes);
-
- MockPlaylistAgent agent = new MockPlaylistAgent();
- agent.mPlaylist = testPlaylist;
-
- mSession.updatePlayer(player, agent, null);
- assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- }
-
- @Test
public void testGetSessionActivity() {
prepareLooper();
PendingIntent sessionActivity = mController.getSessionActivity();
@@ -463,77 +420,6 @@
}
}
-
- @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 = MediaPlayerInterface.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 = MediaPlayerInterface.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();
@@ -686,6 +572,7 @@
@Test
public void testSetVolumeTo() throws Exception {
+ // TODO(jaewan): Also test with local volume.
prepareLooper();
final int maxVolume = 100;
final int currentVolume = 23;
@@ -705,6 +592,7 @@
@Test
public void testAdjustVolume() throws Exception {
+ // TODO(jaewan): Also test with local volume.
prepareLooper();
final int maxVolume = 100;
final int currentVolume = 23;
@@ -723,87 +611,6 @@
}
@Test
- public void testSetVolumeWithLocalVolume() throws Exception {
- prepareLooper();
- if (Build.VERSION.SDK_INT >= 21 && mAudioManager.isVolumeFixed()) {
- // This test is not eligible for this device.
- return;
- }
-
- // Here, we intentionally choose STREAM_ALARM in order not to consider
- // 'Do Not Disturb' or 'Volume limit'.
- final int stream = AudioManager.STREAM_ALARM;
- final int maxVolume = mAudioManager.getStreamMaxVolume(stream);
- final int minVolume = 0;
- if (maxVolume <= minVolume) {
- return;
- }
-
- // Set stream of the session.
- AudioAttributesCompat attrs = new AudioAttributesCompat.Builder()
- .setLegacyStreamType(stream)
- .build();
- mPlayer.setAudioAttributes(attrs);
- mSession.updatePlayer(mPlayer, null, null);
-
- final int originalVolume = mAudioManager.getStreamVolume(stream);
- final int targetVolume = originalVolume == minVolume
- ? originalVolume + 1 : originalVolume - 1;
-
- mController.setVolumeTo(targetVolume, AudioManager.FLAG_SHOW_UI);
- new PollingCheck(WAIT_TIME_MS) {
- @Override
- protected boolean check() {
- return targetVolume == mAudioManager.getStreamVolume(stream);
- }
- }.run();
-
- // Set back to original volume.
- mAudioManager.setStreamVolume(stream, originalVolume, 0 /* flags */);
- }
-
- @Test
- public void testAdjustVolumeWithLocalVolume() throws Exception {
- prepareLooper();
- if (Build.VERSION.SDK_INT >= 21 && mAudioManager.isVolumeFixed()) {
- // This test is not eligible for this device.
- return;
- }
-
- // Here, we intentionally choose STREAM_ALARM in order not to consider
- // 'Do Not Disturb' or 'Volume limit'.
- final int stream = AudioManager.STREAM_ALARM;
- final int maxVolume = mAudioManager.getStreamMaxVolume(stream);
- final int minVolume = 0;
- if (maxVolume <= minVolume) {
- return;
- }
-
- // Set stream of the session.
- AudioAttributesCompat attrs = new AudioAttributesCompat.Builder()
- .setLegacyStreamType(stream)
- .build();
- mPlayer.setAudioAttributes(attrs);
- mSession.updatePlayer(mPlayer, null, null);
-
- final int originalVolume = mAudioManager.getStreamVolume(stream);
- final int direction = originalVolume == minVolume
- ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER;
- final int targetVolume = originalVolume + direction;
-
- mController.adjustVolume(direction, AudioManager.FLAG_SHOW_UI);
- new PollingCheck(WAIT_TIME_MS) {
- @Override
- protected boolean check() {
- return targetVolume == mAudioManager.getStreamVolume(stream);
- }
- }.run();
-
- // Set back to original volume.
- mAudioManager.setStreamVolume(stream, originalVolume, 0 /* flags */);
- }
-
- @Test
public void testGetPackageName() {
prepareLooper();
assertEquals(mContext.getPackageName(), mController.getSessionToken().getPackageName());
@@ -1172,7 +979,7 @@
testHandler.post(new Runnable() {
@Override
public void run() {
- final int state = MediaPlayerInterface.PLAYER_STATE_ERROR;
+ final int state = MediaPlayerBase.PLAYER_STATE_ERROR;
for (int i = 0; i < 100; i++) {
// triggers call from session to controller.
player.notifyPlaybackState(state);
@@ -1205,13 +1012,11 @@
}
});
}
-
- if (Build.VERSION.SDK_INT >= 18) {
+ if (sessionThread != null) {
sessionThread.quitSafely();
+ }
+ if (testThread != null) {
testThread.quitSafely();
- } else {
- sessionThread.quit();
- testThread.quit();
}
}
}
@@ -1260,29 +1065,30 @@
};
TestServiceRegistry.getInstance().setSessionCallback(sessionCallback);
- 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();
- }
- }
- }
- );
+ mController = createController(TestUtils.getServiceToken(mContext, id));
assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- // Test command from controller to session service.
+ // Test command from controller to session service
+ // TODO: Re enable when transport control works
+ /*
mController.play();
assertTrue(mPlayer.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
assertTrue(mPlayer.mPlayCalled);
+ */
- // Test command from session service to controller.
- mSession.sendCustomCommand(testCommand, null);
- assertTrue(controllerLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
+ // 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
@@ -1291,11 +1097,15 @@
testControllerAfterSessionIsClosed(mSession.getToken().getId());
}
+ // TODO(jaewan): Re-enable this test
+ @Ignore
@Test
public void testControllerAfterSessionIsClosed_sessionService() throws InterruptedException {
prepareLooper();
- testConnectToService(MockMediaSessionService2.ID);
+ /*
+ connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID));
testControllerAfterSessionIsClosed(MockMediaSessionService2.ID);
+ */
}
@Test
@@ -1382,12 +1192,14 @@
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/MediaMetadata2Test.java b/media/src/androidTest/java/androidx/media/MediaMetadata2Test.java
index d583e47..f000f02 100644
--- a/media/src/androidTest/java/androidx/media/MediaMetadata2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaMetadata2Test.java
@@ -19,9 +19,7 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
-import android.os.Build;
import android.os.Bundle;
-import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -30,7 +28,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
@RunWith(AndroidJUnit4.class)
@SmallTest
public class MediaMetadata2Test {
diff --git a/media/src/androidTest/java/androidx/media/MediaPlayer2Test.java b/media/src/androidTest/java/androidx/media/MediaPlayer2Test.java
index 0a35ddb..f565e8a 100644
--- a/media/src/androidTest/java/androidx/media/MediaPlayer2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaPlayer2Test.java
@@ -29,7 +29,6 @@
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;
@@ -37,13 +36,10 @@
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.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
-import androidx.media.MediaPlayerInterface.PlayerEventCallback;
import androidx.media.test.R;
import org.junit.After;
@@ -53,18 +49,14 @@
import java.io.BufferedReader;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.util.ArrayDeque;
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;
@@ -89,7 +81,7 @@
@Before
@Override
- public void setUp() throws Throwable {
+ public void setUp() throws Exception {
super.setUp();
mRecordedFilePath = new File(Environment.getExternalStorageDirectory(),
"mediaplayer_record.out").getAbsolutePath();
@@ -105,8 +97,61 @@
}
}
- @Test
- @MediumTest
+ // 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();
+ }
+ }
+
public void testPlayNullSourcePath() throws Exception {
final Monitor onSetDataSourceCalled = new Monitor();
MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
@@ -127,8 +172,6 @@
onSetDataSourceCalled.waitForSignal();
}
- @Test
- @LargeTest
public void testPlayAudioFromDataURI() throws Exception {
final int mp3Duration = 34909;
final int tolerance = 70;
@@ -177,12 +220,15 @@
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
.build();
mp.setAudioAttributes(attributes);
+ /* FIXME: ensure screen is on while testing.
+ mp.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+ */
- assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertFalse(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
onPlayCalled.reset();
mp.play();
onPlayCalled.waitForSignal();
- assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
/* FIXME: what's API for checking loop state?
assertFalse(mp.isLooping());
@@ -207,11 +253,11 @@
// test pause and restart
mp.pause();
Thread.sleep(SLEEP_TIME);
- assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertFalse(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
onPlayCalled.reset();
mp.play();
onPlayCalled.waitForSignal();
- assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// test stop and restart
mp.reset();
@@ -223,14 +269,14 @@
mp.prepare();
onPrepareCalled.waitForSignal();
- assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertFalse(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
onPlayCalled.reset();
mp.play();
onPlayCalled.waitForSignal();
- assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// waiting to complete
- while (mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
+ while (mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING) {
Thread.sleep(SLEEP_TIME);
}
} finally {
@@ -238,8 +284,6 @@
}
}
- @Test
- @LargeTest
public void testPlayAudio() throws Exception {
final int resid = R.raw.testmp3_2;
final int mp3Duration = 34909;
@@ -279,11 +323,11 @@
.build();
mp.setAudioAttributes(attributes);
- assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertFalse(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
onPlayCalled.reset();
mp.play();
onPlayCalled.waitForSignal();
- assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
//assertFalse(mp.isLooping());
onLoopCurrentCalled.reset();
@@ -304,11 +348,11 @@
// test pause and restart
mp.pause();
Thread.sleep(SLEEP_TIME);
- assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertFalse(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
onPlayCalled.reset();
mp.play();
onPlayCalled.waitForSignal();
- assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// test stop and restart
mp.reset();
@@ -323,14 +367,14 @@
onPrepareCalled.waitForSignal();
afd.close();
- assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertFalse(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
onPlayCalled.reset();
mp.play();
onPlayCalled.waitForSignal();
- assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// waiting to complete
- while (mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
+ while (mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING) {
Thread.sleep(SLEEP_TIME);
}
} catch (Exception e) {
@@ -370,6 +414,7 @@
.setInternalLegacyStreamType(AudioManager.STREAM_MUSIC)
.build();
mp.setAudioAttributes(attributes);
+ mp.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
assertFalse(mp.isPlaying());
onPlayCalled.reset();
@@ -400,8 +445,6 @@
}
*/
- @Test
- @LargeTest
public void testPlayAudioLooping() throws Exception {
final int resid = R.raw.testmp3;
@@ -419,10 +462,8 @@
@Override
public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd,
int what, int extra) {
- if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
- Log.i("@@@", "got oncompletion");
- onCompletionCalled.signal();
- }
+ Log.i("@@@", "got oncompletion");
+ onCompletionCalled.signal();
}
@Override
@@ -435,21 +476,21 @@
};
mp.setMediaPlayer2EventCallback(mExecutor, ecb);
- assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertFalse(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
onPlayCalled.reset();
mp.play();
onPlayCalled.waitForSignal();
- assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
long duration = mp.getDuration();
Thread.sleep(duration * 4); // allow for several loops
- assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
assertEquals("wrong number of completion signals", 0,
onCompletionCalled.getNumSignal());
mp.loopCurrent(false);
// wait for playback to finish
- while (mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
+ while (mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING) {
Thread.sleep(SLEEP_TIME);
}
assertEquals("wrong number of completion signals", 1,
@@ -459,8 +500,6 @@
}
}
- @Test
- @LargeTest
public void testPlayMidi() throws Exception {
final int resid = R.raw.midi8sec;
final int midiDuration = 8000;
@@ -629,7 +668,7 @@
mp.play();
Thread.sleep(SLEEP_TIME);
assertFalse("player was still playing after " + SLEEP_TIME + " ms",
- mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ mp.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
assertTrue("nothing heard while test ran", listener.heardSound());
listener.reset();
mp.seekTo(0, MediaPlayer2.SEEK_PREVIOUS_SYNC);
@@ -691,7 +730,7 @@
*/
// TODO: uncomment out line below when MediaPlayer2 can seek to requested position.
// assertEquals(posAfter, posBefore, tolerance);
- assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
Thread.sleep(SLEEP_TIME);
@@ -706,7 +745,7 @@
posAfter = mPlayer.getCurrentPosition();
// TODO: uncomment out line below when MediaPlayer2 can seek to requested position.
// assertEquals(posAfter, posBefore, tolerance);
- assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
Thread.sleep(SLEEP_TIME);
@@ -716,7 +755,7 @@
// TODO: uncomment out line below when MediaPlayer2 can seek to requested position.
// assertEquals(posAfter, posBefore, tolerance);
- assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
Thread.sleep(SLEEP_TIME);
}
@@ -828,19 +867,7 @@
assertEquals(Integer.parseInt(rotation), angle);
}
- @Test
- @LargeTest
- public void testSkipToNext() throws Exception {
- testPlaylist(true);
- }
-
- @Test
- @LargeTest
public void testPlaylist() throws Exception {
- testPlaylist(false);
- }
-
- private void testPlaylist(boolean skip) throws Exception {
if (!checkLoadResource(
R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz)) {
return; // skip
@@ -888,18 +915,9 @@
mPlayer.play();
- if (skip) {
- mPlayer.skipToNext();
- mPlayer.skipToNext();
- } else {
- mOnCompletionCalled.waitForSignal();
- onCompletion2Called.waitForSignal();
- }
+ mOnCompletionCalled.waitForSignal();
+ onCompletion2Called.waitForSignal();
onCompletion1Called.waitForSignal();
- if (skip) {
- assertFalse("first dsd completed", mOnCompletionCalled.isSignalled());
- assertFalse("second dsd completed", onCompletion2Called.isSignalled());
- }
mPlayer.reset();
}
@@ -1017,7 +1035,7 @@
playbackRate, pbp.getSpeed(),
FLOAT_TOLERANCE + playbackRate * sync.getTolerance());
assertTrue("MediaPlayer2 should still be playing",
- mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
long playedMediaDurationMs = mPlayer.getCurrentPosition();
int diff = Math.abs((int) (playedMediaDurationMs / playbackRate) - playTime);
@@ -1434,14 +1452,14 @@
}
}
- @Test
- @LargeTest
public void testDeselectTrackForSubtitleTracks() throws Throwable {
if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
return; // skip;
}
- mInstrumentation.waitForIdleSync();
+ /* FIXME: find out counter part of waitForIdleSync.
+ getInstrumentation().waitForIdleSync();
+ */
MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
@Override
@@ -1464,19 +1482,22 @@
mOnDeselectTrackCalled.signal();
}
}
-
- @Override
- public void onSubtitleData(
- MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) {
- if (data != null && data.getData() != null) {
- mOnSubtitleDataCalled.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) {
+ if (data != null && data.getData() != null) {
+ mOnSubtitleDataCalled.signal();
+ }
+ }
+ });
+ */
+
mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
mOnPrepareCalled.reset();
@@ -1486,7 +1507,7 @@
mOnPlayCalled.reset();
mPlayer.play();
mOnPlayCalled.waitForSignal();
- assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// Closed caption tracks are in-band.
// So, those tracks will be found after processing a number of frames.
@@ -1518,13 +1539,22 @@
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) {
@@ -1541,14 +1571,6 @@
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);
@@ -1563,7 +1585,7 @@
mOnPlayCalled.reset();
mPlayer.play();
mOnPlayCalled.waitForSignal();
- assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// Closed caption tracks are in-band.
// So, those tracks will be found after processing a number of frames.
@@ -1622,7 +1644,7 @@
mOnPlayCalled.reset();
mPlayer.play();
mOnPlayCalled.waitForSignal();
- assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// The media metadata will be changed while playing since closed caption tracks are in-band
// and those tracks will be found after processing a number of frames. These tracks will be
@@ -1638,77 +1660,10 @@
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)
@@ -1749,7 +1704,7 @@
// sleep long enough that we restart playback at least once, but no more
Thread.sleep(10000);
assertTrue("MediaPlayer2 should still be playing",
- mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
mPlayer.reset();
assertEquals("wrong number of repetitions", 1, mOnCompletionCalled.getNumSignal());
return 1;
@@ -1808,7 +1763,7 @@
mOnPlayCalled.reset();
mPlayer.play();
mOnPlayCalled.waitForSignal();
- while (mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
+ while (mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING) {
Log.i("@@@@", "position: " + mPlayer.getCurrentPosition());
Thread.sleep(500);
}
@@ -1879,10 +1834,10 @@
assertFalse(mOnCompletionCalled.isSignalled());
mPlayer.play();
mOnPlayCalled.waitForSignal();
- while (mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
+ while (mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING) {
Thread.sleep(SLEEP_TIME);
}
- assertFalse(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertFalse(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
mOnCompletionCalled.waitForSignal();
assertFalse(mOnErrorCalled.isSignalled());
mPlayer.reset();
@@ -1918,34 +1873,32 @@
mEventCallbacks.add(ecb);
}
- MediaPlayerInterface playerBase = mPlayer.getMediaPlayerInterface();
- assertEquals(MediaPlayerInterface.BUFFERING_STATE_UNKNOWN, playerBase.getBufferingState());
- assertEquals(MediaPlayerInterface.PLAYER_STATE_IDLE, playerBase.getPlayerState());
+ assertEquals(MediaPlayerBase.BUFFERING_STATE_UNKNOWN, mPlayer.getBufferingState());
+ assertEquals(MediaPlayerBase.PLAYER_STATE_IDLE, mPlayer.getPlayerState());
prepareCompleted.reset();
- playerBase.prepare();
+ mPlayer.prepare();
prepareCompleted.waitForSignal();
- assertEquals(MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
- playerBase.getBufferingState());
- assertEquals(MediaPlayerInterface.PLAYER_STATE_PAUSED, playerBase.getPlayerState());
- assertEquals(MediaPlayer2.MEDIAPLAYER2_STATE_PREPARED, mPlayer.getMediaPlayer2State());
+ assertEquals(MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
+ mPlayer.getBufferingState());
+ assertEquals(MediaPlayerBase.PLAYER_STATE_PAUSED, mPlayer.getPlayerState());
playCompleted.reset();
- playerBase.play();
+ mPlayer.play();
playCompleted.waitForSignal();
- assertEquals(MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
- playerBase.getBufferingState());
- assertEquals(MediaPlayerInterface.PLAYER_STATE_PLAYING, playerBase.getPlayerState());
+ assertEquals(MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
+ mPlayer.getBufferingState());
+ assertEquals(MediaPlayerBase.PLAYER_STATE_PLAYING, mPlayer.getPlayerState());
pauseCompleted.reset();
- playerBase.pause();
+ mPlayer.pause();
pauseCompleted.waitForSignal();
- assertEquals(MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
- playerBase.getBufferingState());
- assertEquals(MediaPlayerInterface.PLAYER_STATE_PAUSED, playerBase.getPlayerState());
+ assertEquals(MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
+ mPlayer.getBufferingState());
+ assertEquals(MediaPlayerBase.PLAYER_STATE_PAUSED, mPlayer.getPlayerState());
- playerBase.reset();
- assertEquals(MediaPlayerInterface.BUFFERING_STATE_UNKNOWN, playerBase.getBufferingState());
- assertEquals(MediaPlayerInterface.PLAYER_STATE_IDLE, playerBase.getPlayerState());
+ mPlayer.reset();
+ assertEquals(MediaPlayerBase.BUFFERING_STATE_UNKNOWN, mPlayer.getBufferingState());
+ assertEquals(MediaPlayerBase.PLAYER_STATE_IDLE, mPlayer.getPlayerState());
}
@Test
@@ -1956,13 +1909,9 @@
if (!checkLoadResource(R.raw.testvideo)) {
return; // skip;
}
- final DataSourceDesc dsd2 = createDataSourceDesc(
- R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz);
- mPlayer.setNextDataSource(dsd2);
mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
- final Monitor onDsdChangedCalled = new Monitor();
final Monitor onPrepareCalled = new Monitor();
final Monitor onSeekCompleteCalled = new Monitor();
final Monitor onPlayerStateChangedCalled = new Monitor();
@@ -1972,79 +1921,69 @@
final Monitor onPlaybackSpeedChanged = new Monitor();
final AtomicReference<Float> playbackSpeed = new AtomicReference<>();
- PlayerEventCallback callback = new PlayerEventCallback() {
+ MediaPlayerBase.PlayerEventCallback callback = new MediaPlayerBase.PlayerEventCallback() {
+ // TODO: implement and add test case for onCurrentDataSourceChanged() callback.
@Override
- public void onCurrentDataSourceChanged(MediaPlayerInterface mpb, DataSourceDesc dsd) {
- onDsdChangedCalled.signal();
- }
-
- @Override
- public void onMediaPrepared(MediaPlayerInterface mpb, DataSourceDesc dsd) {
+ public void onMediaPrepared(MediaPlayerBase mpb, DataSourceDesc dsd) {
onPrepareCalled.signal();
}
@Override
- public void onPlayerStateChanged(MediaPlayerInterface mpb, int state) {
+ public void onPlayerStateChanged(MediaPlayerBase mpb, int state) {
playerState.set(state);
onPlayerStateChangedCalled.signal();
}
@Override
- public void onBufferingStateChanged(MediaPlayerInterface mpb, DataSourceDesc dsd,
+ public void onBufferingStateChanged(MediaPlayerBase mpb, DataSourceDesc dsd,
int state) {
bufferingState.set(state);
onBufferingStateChangedCalled.signal();
}
@Override
- public void onPlaybackSpeedChanged(MediaPlayerInterface mpb, float speed) {
+ public void onPlaybackSpeedChanged(MediaPlayerBase mpb, float speed) {
playbackSpeed.set(speed);
onPlaybackSpeedChanged.signal();
}
@Override
- public void onSeekCompleted(MediaPlayerInterface mpb, long position) {
+ public void onSeekCompleted(MediaPlayerBase mpb, long position) {
onSeekCompleteCalled.signal();
}
};
- MediaPlayerInterface basePlayer = mPlayer.getMediaPlayerInterface();
ExecutorService executor = Executors.newFixedThreadPool(1);
- basePlayer.registerPlayerEventCallback(executor, callback);
+ mPlayer.registerPlayerEventCallback(executor, callback);
onPrepareCalled.reset();
onPlayerStateChangedCalled.reset();
onBufferingStateChangedCalled.reset();
- basePlayer.prepare();
+ mPlayer.prepare();
do {
assertTrue(onBufferingStateChangedCalled.waitForSignal(1000));
- } while (bufferingState.get()
- != MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_STARVED);
+ } while (bufferingState.get() != MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_STARVED);
assertTrue(onPrepareCalled.waitForSignal(1000));
do {
assertTrue(onPlayerStateChangedCalled.waitForSignal(1000));
- } while (playerState.get() != MediaPlayerInterface.PLAYER_STATE_PAUSED);
+ } while (playerState.get() != MediaPlayerBase.PLAYER_STATE_PAUSED);
do {
assertTrue(onBufferingStateChangedCalled.waitForSignal(1000));
- } while (bufferingState.get()
- != MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
+ } while (bufferingState.get() != MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
onSeekCompleteCalled.reset();
- basePlayer.seekTo(mp4Duration >> 1);
+ mPlayer.seekTo(mp4Duration >> 1, MediaPlayer2.SEEK_PREVIOUS_SYNC);
onSeekCompleteCalled.waitForSignal();
onPlaybackSpeedChanged.reset();
- basePlayer.setPlaybackSpeed(0.5f);
+ mPlayer.setPlaybackSpeed(0.5f);
do {
assertTrue(onPlaybackSpeedChanged.waitForSignal(1000));
} while (Math.abs(playbackSpeed.get() - 0.5f) > FLOAT_TOLERANCE);
- basePlayer.skipToNext();
- assertTrue(onDsdChangedCalled.waitForSignal(1000));
+ mPlayer.reset();
- basePlayer.reset();
-
- basePlayer.unregisterPlayerEventCallback(callback);
+ mPlayer.unregisterPlayerEventCallback(callback);
executor.shutdown();
}
@@ -2148,12 +2087,12 @@
.setDataSource(dataSource)
.build());
playLoadedVideo(null, null, -1);
- assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// Test pause and restart.
mPlayer.pause();
Thread.sleep(SLEEP_TIME);
- assertFalse(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertFalse(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
@Override
@@ -2175,7 +2114,7 @@
mOnPlayCalled.reset();
mPlayer.play();
mOnPlayCalled.waitForSignal();
- assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// Test reset.
mPlayer.reset();
@@ -2192,12 +2131,12 @@
mOnPlayCalled.reset();
mPlayer.play();
mOnPlayCalled.waitForSignal();
- assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
+ assertTrue(mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING);
// Test seek. Note: the seek position is cached and returned as the
// current position so there's no point in comparing them.
mPlayer.seekTo(duration - SLEEP_TIME, MediaPlayer2.SEEK_PREVIOUS_SYNC);
- while (mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
+ while (mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING) {
Thread.sleep(SLEEP_TIME);
}
}
@@ -2320,78 +2259,4 @@
mPlayer.play();
assertTrue(mOnErrorCalled.waitForSignal());
}
-
- @Test
- @SmallTest
- public void testClearPendingCommands() throws Exception {
- final Monitor readAllowed = new Monitor();
- Media2DataSource dataSource = new Media2DataSource() {
- @Override
- public int readAt(long position, byte[] buffer, int offset, int size)
- throws IOException {
- try {
- readAllowed.waitForSignal();
- } catch (InterruptedException e) {
- fail();
- }
- return -1;
- }
-
- @Override
- public long getSize() throws IOException {
- return -1; // Unknown size
- }
-
- @Override
- public void close() throws IOException {}
- };
- final ArrayDeque<Integer> commandsCompleted = new ArrayDeque<>();
- setOnErrorListener();
- MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
- @Override
- public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
- if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
- mOnPrepareCalled.signal();
- }
- }
-
- @Override
- public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
- commandsCompleted.add(what);
- }
-
- @Override
- public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
- mOnErrorCalled.signal();
- }
- };
- synchronized (mEventCbLock) {
- mEventCallbacks.add(ecb);
- }
-
- mOnPrepareCalled.reset();
- mOnErrorCalled.reset();
-
- mPlayer.setDataSource(new DataSourceDesc.Builder()
- .setDataSource(dataSource)
- .build());
-
- // prepare() will be pending until readAllowed is signaled.
- mPlayer.prepare();
-
- mPlayer.play();
- mPlayer.pause();
- mPlayer.play();
- mPlayer.pause();
- mPlayer.play();
- mPlayer.seekTo(1000);
-
- // Cause a failure on the pending prepare operation.
- readAllowed.signal();
- mOnErrorCalled.waitForSignal();
- assertEquals(0, mOnPrepareCalled.getNumSignal());
- assertEquals(1, commandsCompleted.size());
- assertEquals(MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE,
- (int) commandsCompleted.peekFirst());
- }
}
diff --git a/media/src/androidTest/java/androidx/media/MediaPlayer2TestBase.java b/media/src/androidTest/java/androidx/media/MediaPlayer2TestBase.java
index 77c5c04..215993a 100644
--- a/media/src/androidTest/java/androidx/media/MediaPlayer2TestBase.java
+++ b/media/src/androidTest/java/androidx/media/MediaPlayer2TestBase.java
@@ -15,29 +15,20 @@
*/
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;
@@ -50,7 +41,6 @@
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;
@@ -75,7 +65,6 @@
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;
@@ -86,35 +75,34 @@
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<>();
+ protected List<MediaPlayer2.MediaPlayer2EventCallback> mEventCallbacks =
+ new ArrayList<MediaPlayer2.MediaPlayer2EventCallback>();
protected final Object mEventCbLock2 = new Object();
- protected List<MediaPlayer2.MediaPlayer2EventCallback> mEventCallbacks2 = new ArrayList<>();
+ protected List<MediaPlayer2.MediaPlayer2EventCallback> mEventCallbacks2 =
+ new ArrayList<MediaPlayer2.MediaPlayer2EventCallback>();
@Rule
public ActivityTestRule<MediaStubActivity> mActivityRule =
new ActivityTestRule<>(MediaStubActivity.class);
- public PowerManager.WakeLock mScreenLock;
- private KeyguardManager mKeyguardManager;
// convenience functions to create MediaPlayer2
- protected MediaPlayer2 createMediaPlayer2(Context context, Uri uri) {
+ protected static MediaPlayer2 createMediaPlayer2(Context context, Uri uri) {
return createMediaPlayer2(context, uri, null);
}
- protected MediaPlayer2 createMediaPlayer2(Context context, Uri uri,
+ protected static 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 MediaPlayer2 createMediaPlayer2(Context context, Uri uri, SurfaceHolder holder,
+ protected static MediaPlayer2 createMediaPlayer2(Context context, Uri uri, SurfaceHolder holder,
AudioAttributesCompat audioAttributes, int audioSessionId) {
try {
- MediaPlayer2 mp = createMediaPlayer2OnUiThread();
+ MediaPlayer2 mp = MediaPlayer2.create();
final AudioAttributesCompat aa = audioAttributes != null ? audioAttributes :
new AudioAttributesCompat.Builder().build();
mp.setAudioAttributes(aa);
@@ -156,13 +144,13 @@
return null;
}
- protected MediaPlayer2 createMediaPlayer2(Context context, int resid) {
+ protected static 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 MediaPlayer2 createMediaPlayer2(Context context, int resid,
+ protected static MediaPlayer2 createMediaPlayer2(Context context, int resid,
AudioAttributesCompat audioAttributes, int audioSessionId) {
try {
AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
@@ -170,7 +158,7 @@
return null;
}
- MediaPlayer2 mp = createMediaPlayer2OnUiThread();
+ MediaPlayer2 mp = MediaPlayer2.create();
final AudioAttributesCompat aa = audioAttributes != null ? audioAttributes :
new AudioAttributesCompat.Builder().build();
@@ -216,20 +204,6 @@
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;
@@ -284,23 +258,8 @@
@Before
@CallSuper
- public void setUp() throws Throwable {
- mInstrumentation = InstrumentationRegistry.getInstrumentation();
- mKeyguardManager = (KeyguardManager)
- mInstrumentation.getTargetContext().getSystemService(KEYGUARD_SERVICE);
+ public void setUp() throws Exception {
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() {
@@ -385,11 +344,11 @@
}
@Override
- public void onMediaTimeDiscontinuity(MediaPlayer2 mp, DataSourceDesc dsd,
+ public void onMediaTimeChanged(MediaPlayer2 mp, DataSourceDesc dsd,
MediaTimestamp timestamp) {
synchronized (cbLock) {
for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
- ecb.onMediaTimeDiscontinuity(mp, dsd, timestamp);
+ ecb.onMediaTimeChanged(mp, dsd, timestamp);
}
}
}
@@ -402,15 +361,6 @@
}
}
}
- @Override
- public void onSubtitleData(MediaPlayer2 mp, DataSourceDesc dsd,
- final SubtitleData data) {
- synchronized (cbLock) {
- for (MediaPlayer2.MediaPlayer2EventCallback ecb : ecbs) {
- ecb.onSubtitleData(mp, dsd, data);
- }
- }
- }
});
}
@@ -540,7 +490,11 @@
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() {
@@ -605,49 +559,13 @@
if (playTime == -1) {
return;
} else if (playTime == 0) {
- while (mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
+ while (mPlayer.getPlayerState() == MediaPlayerBase.PLAYER_STATE_PLAYING) {
Thread.sleep(SLEEP_TIME);
}
} else {
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 adcba6b..5e7ed0e 100644
--- a/media/src/androidTest/java/androidx/media/MediaSession2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaSession2Test.java
@@ -65,7 +65,7 @@
/**
* Tests {@link MediaSession2}.
*/
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
@RunWith(AndroidJUnit4.class)
@SmallTest
public class MediaSession2Test extends MediaSession2TestBase {
@@ -125,7 +125,7 @@
@Test
public void testPlayerStateChange() throws Exception {
prepareLooper();
- final int targetState = MediaPlayerInterface.PLAYER_STATE_PLAYING;
+ final int targetState = MediaPlayerBase.PLAYER_STATE_PLAYING;
final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
sHandler.postAndSync(new Runnable() {
@Override
@@ -136,7 +136,7 @@
.setSessionCallback(sHandlerExecutor, new SessionCallback() {
@Override
public void onPlayerStateChanged(MediaSession2 session,
- MediaPlayerInterface player, int state) {
+ MediaPlayerBase player, int state) {
assertEquals(targetState, state);
latchForSessionCallback.countDown();
}
@@ -166,7 +166,7 @@
final List<MediaItem2> playlist = TestUtils.createPlaylist(5);
final MediaItem2 targetItem = playlist.get(3);
- final int targetBufferingState = MediaPlayerInterface.BUFFERING_STATE_BUFFERING_COMPLETE;
+ final int targetBufferingState = MediaPlayerBase.BUFFERING_STATE_BUFFERING_COMPLETE;
final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
sHandler.postAndSync(new Runnable() {
@Override
@@ -179,7 +179,7 @@
.setSessionCallback(sHandlerExecutor, new SessionCallback() {
@Override
public void onBufferingStateChanged(MediaSession2 session,
- MediaPlayerInterface player, MediaItem2 item, int state) {
+ MediaPlayerBase player, MediaItem2 item, int state) {
assertEquals(targetItem, item);
assertEquals(targetBufferingState, state);
latchForSessionCallback.countDown();
@@ -200,39 +200,13 @@
}
});
- mPlayer.notifyBufferingStateChanged(targetItem.getDataSourceDesc(), targetBufferingState);
+ mPlayer.notifyBufferingState(targetItem, 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, MediaPlayerInterface 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;
@@ -240,7 +214,9 @@
mMockAgent.setPlaylist(list, null);
final MediaItem2 currentItem = list.get(3);
- final CountDownLatch latchForSessionCallback = new CountDownLatch(2);
+ mMockAgent.mCurrentMediaItem = currentItem;
+
+ final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
try (MediaSession2 session = new MediaSession2.Builder(mContext)
.setPlayer(mPlayer)
.setPlaylistAgent(mMockAgent)
@@ -248,44 +224,27 @@
.setSessionCallback(sHandlerExecutor, new SessionCallback() {
@Override
public void onCurrentMediaItemChanged(MediaSession2 session,
- MediaPlayerInterface player, MediaItem2 item) {
- switch ((int) latchForSessionCallback.getCount()) {
- case 2:
- assertEquals(currentItem, item);
- break;
- case 1:
- assertNull(item);
- }
+ MediaPlayerBase player, MediaItem2 itemOut) {
+ assertSame(currentItem, itemOut);
latchForSessionCallback.countDown();
}
}).build()) {
- final CountDownLatch latchForControllerCallback = new CountDownLatch(2);
+ final CountDownLatch latchForControllerCallback = new CountDownLatch(1);
final MediaController2 controller =
createController(mSession.getToken(), true, new ControllerCallback() {
@Override
public void onCurrentMediaItemChanged(MediaController2 controller,
MediaItem2 item) {
- switch ((int) latchForControllerCallback.getCount()) {
- case 2:
- assertEquals(currentItem, item);
- break;
- case 1:
- assertNull(item);
- }
+ assertEquals(currentItem, item);
latchForControllerCallback.countDown();
}
});
- // Player notifies with the unknown dsd. Should be ignored.
- mPlayer.notifyCurrentDataSourceChanged(TestUtils.createMediaItemWithMetadata()
- .getDataSourceDesc());
- // Known DSD should be notified through the onCurrentMediaItemChanged.
mPlayer.notifyCurrentDataSourceChanged(currentItem.getDataSourceDesc());
- // Null DSD becomes null MediaItem2.
- mPlayer.notifyCurrentDataSourceChanged(null);
assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
assertTrue(latchForControllerCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
+ assertEquals(currentItem, controller.getCurrentMediaItem());
}
}
@@ -305,7 +264,7 @@
.setId("testMediaPrepared")
.setSessionCallback(sHandlerExecutor, new SessionCallback() {
@Override
- public void onMediaPrepared(MediaSession2 session, MediaPlayerInterface player,
+ public void onMediaPrepared(MediaSession2 session, MediaPlayerBase player,
MediaItem2 itemOut) {
assertSame(currentItem, itemOut);
latchForSessionCallback.countDown();
@@ -326,7 +285,7 @@
mMockAgent.setPlaylist(list, null);
final MediaItem2 currentItem = list.get(3);
- final int buffState = MediaPlayerInterface.BUFFERING_STATE_BUFFERING_COMPLETE;
+ final int buffState = MediaPlayerBase.BUFFERING_STATE_BUFFERING_COMPLETE;
final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
try (MediaSession2 session = new MediaSession2.Builder(mContext)
@@ -336,7 +295,7 @@
.setSessionCallback(sHandlerExecutor, new SessionCallback() {
@Override
public void onBufferingStateChanged(MediaSession2 session,
- MediaPlayerInterface player, MediaItem2 itemOut, int stateOut) {
+ MediaPlayerBase player, MediaItem2 itemOut, int stateOut) {
assertSame(currentItem, itemOut);
assertEquals(buffState, stateOut);
latchForSessionCallback.countDown();
@@ -366,7 +325,7 @@
.setSessionCallback(sHandlerExecutor, new SessionCallback() {
@Override
public void onPlaybackSpeedChanged(MediaSession2 session,
- MediaPlayerInterface player, float speedOut) {
+ MediaPlayerBase player, float speedOut) {
assertEquals(speed, speedOut, 0.0f);
latchForSessionCallback.countDown();
}
@@ -393,7 +352,7 @@
@Test
public void testUpdatePlayer() throws Exception {
prepareLooper();
- final int targetState = MediaPlayerInterface.PLAYER_STATE_PLAYING;
+ final int targetState = MediaPlayerBase.PLAYER_STATE_PLAYING;
final CountDownLatch latch = new CountDownLatch(1);
sHandler.postAndSync(new Runnable() {
@Override
@@ -403,7 +362,7 @@
.setSessionCallback(sHandlerExecutor, new SessionCallback() {
@Override
public void onPlayerStateChanged(MediaSession2 session,
- MediaPlayerInterface player, int state) {
+ MediaPlayerBase player, int state) {
assertEquals(targetState, state);
latch.countDown();
}
@@ -424,12 +383,12 @@
assertNotNull(mSession.getPlaylistAgent());
assertNotEquals(agent, mSession.getPlaylistAgent());
- player.notifyPlaybackState(MediaPlayerInterface.PLAYER_STATE_PLAYING);
+ player.notifyPlaybackState(MediaPlayerBase.PLAYER_STATE_PLAYING);
assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
}
@Test
- public void testUpdatePlayer_playbackInfo() throws Exception {
+ public void testSetPlayer_playbackInfo() throws Exception {
prepareLooper();
MockPlayer player = new MockPlayer(0);
final AudioAttributesCompat attrs = new AudioAttributesCompat.Builder()
@@ -523,47 +482,6 @@
}
@Test
- public void testGetDuration() throws Exception {
- prepareLooper();
- final long testDuration = 9999;
- mPlayer.mDuration = testDuration;
- assertEquals(testDuration, mSession.getDuration());
- }
-
- @Test
- public void testSessionCallback_onMediaPrepared() throws Exception {
- prepareLooper();
- final long testDuration = 9999;
- final List<MediaItem2> list = TestUtils.createPlaylist(2);
- final MediaItem2 testItem = list.get(1);
- final CountDownLatch latch = new CountDownLatch(1);
-
- mPlayer.mDuration = testDuration;
- mMockAgent.setPlaylist(list, null);
- mMockAgent.mCurrentMediaItem = testItem;
-
- final SessionCallback sessionCallback = new SessionCallback() {
- @Override
- public void onMediaPrepared(MediaSession2 session, MediaPlayerInterface player,
- MediaItem2 item) {
- assertEquals(testItem, item);
- assertEquals(testDuration,
- item.getMetadata().getLong(MediaMetadata2.METADATA_KEY_DURATION));
- latch.countDown();
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setPlaylistAgent(mMockAgent)
- .setId("testSessionCallback")
- .setSessionCallback(sHandlerExecutor, sessionCallback)
- .build()) {
- mPlayer.notifyMediaPrepared(testItem.getDataSourceDesc());
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
public void testSetPlaybackSpeed() throws Exception {
prepareLooper();
final float speed = 1.5f;
@@ -614,7 +532,7 @@
@Test
public void testGetPlayerState() {
prepareLooper();
- final int state = MediaPlayerInterface.PLAYER_STATE_PLAYING;
+ final int state = MediaPlayerBase.PLAYER_STATE_PLAYING;
mPlayer.mLastPlayerState = state;
assertEquals(state, mSession.getPlayerState());
}
@@ -622,7 +540,7 @@
@Test
public void testGetBufferingState() {
prepareLooper();
- final int bufferingState = MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE;
+ final int bufferingState = MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_PLAYABLE;
mPlayer.mLastBufferingState = bufferingState;
assertEquals(bufferingState, mSession.getBufferingState());
}
@@ -826,7 +744,7 @@
mSession.updatePlayer(player, null, null);
mSession.updatePlayer(mPlayer, null, null);
- player.notifyPlaybackState(MediaPlayerInterface.PLAYER_STATE_PAUSED);
+ player.notifyPlaybackState(MediaPlayerBase.PLAYER_STATE_PAUSED);
assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
}
@@ -839,7 +757,7 @@
@Override
public void unregisterPlayerEventCallback(
- @NonNull MediaPlayerInterface.PlayerEventCallback listener) {
+ @NonNull MediaPlayerBase.PlayerEventCallback listener) {
// No-op.
}
}
diff --git a/media/src/androidTest/java/androidx/media/MediaSession2TestBase.java b/media/src/androidTest/java/androidx/media/MediaSession2TestBase.java
index 9c9fa8e..745ef3a 100644
--- a/media/src/androidTest/java/androidx/media/MediaSession2TestBase.java
+++ b/media/src/androidTest/java/androidx/media/MediaSession2TestBase.java
@@ -20,7 +20,6 @@
import static junit.framework.Assert.assertTrue;
import android.content.Context;
-import android.os.Build;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Looper;
@@ -122,11 +121,7 @@
if (sHandler == null) {
return;
}
- if (Build.VERSION.SDK_INT >= 18) {
- sHandler.getLooper().quitSafely();
- } else {
- sHandler.getLooper().quit();
- }
+ sHandler.getLooper().quitSafely();
sHandler = null;
sHandlerExecutor = null;
}
diff --git a/media/src/androidTest/java/androidx/media/MediaSession2_PermissionTest.java b/media/src/androidTest/java/androidx/media/MediaSession2_PermissionTest.java
index 0bf93d4..3895ea5 100644
--- a/media/src/androidTest/java/androidx/media/MediaSession2_PermissionTest.java
+++ b/media/src/androidTest/java/androidx/media/MediaSession2_PermissionTest.java
@@ -48,11 +48,9 @@
import static org.junit.Assert.fail;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.support.test.filters.MediumTest;
-import android.support.test.filters.SdkSuppress;
import android.support.test.runner.AndroidJUnit4;
import androidx.annotation.NonNull;
@@ -70,7 +68,6 @@
/**
* Tests whether {@link MediaSession2} receives commands that hasn't allowed.
*/
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
@RunWith(AndroidJUnit4.class)
@MediumTest
public class MediaSession2_PermissionTest extends MediaSession2TestBase {
diff --git a/media/src/androidTest/java/androidx/media/MediaSessionManager_MediaSession2Test.java b/media/src/androidTest/java/androidx/media/MediaSessionManager_MediaSession2Test.java
index a0ce092..904b768 100644
--- a/media/src/androidTest/java/androidx/media/MediaSessionManager_MediaSession2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaSessionManager_MediaSession2Test.java
@@ -73,7 +73,7 @@
public void testGetMediaSession2Tokens_hasMediaController() throws InterruptedException {
prepareLooper();
final MockPlayer player = (MockPlayer) mSession.getPlayer();
- player.notifyPlaybackState(MediaPlayerInterface.PLAYER_STATE_IDLE);
+ player.notifyPlaybackState(MediaPlayerBase.PLAYER_STATE_IDLE);
MediaController2 controller = null;
// List<SessionToken2> tokens = mManager.getActiveSessionTokens();
@@ -89,7 +89,7 @@
// assertNotNull(controller);
//
// // Test if the found controller is correct one.
-// assertEquals(MediaPlayerInterface.PLAYER_STATE_IDLE, controller.getPlayerState());
+// assertEquals(MediaPlayerBase.PLAYER_STATE_IDLE, controller.getPlayerState());
// controller.play();
//
// assertTrue(player.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
diff --git a/media/src/androidTest/java/androidx/media/MockPlayer.java b/media/src/androidTest/java/androidx/media/MockPlayer.java
index e280ed8..49b1a19 100644
--- a/media/src/androidTest/java/androidx/media/MockPlayer.java
+++ b/media/src/androidTest/java/androidx/media/MockPlayer.java
@@ -16,17 +16,18 @@
package androidx.media;
+import android.util.ArrayMap;
+
import androidx.annotation.NonNull;
-import androidx.collection.ArrayMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
/**
- * A mock implementation of {@link MediaPlayerInterface} for testing.
+ * A mock implementation of {@link MediaPlayerBase} for testing.
*/
-public class MockPlayer extends MediaPlayerInterface {
+public class MockPlayer extends MediaPlayerBase {
public final CountDownLatch mCountDownLatch;
public boolean mPlayCalled;
@@ -41,7 +42,6 @@
public float mPlaybackSpeed = 1.0f;
public @PlayerState int mLastPlayerState;
public @BuffState int mLastBufferingState;
- public long mDuration;
public ArrayMap<PlayerEventCallback, Executor> mCallbacks = new ArrayMap<>();
@@ -128,11 +128,6 @@
}
@Override
- public long getDuration() {
- return mDuration;
- }
-
- @Override
public void registerPlayerEventCallback(@NonNull Executor executor,
@NonNull PlayerEventCallback callback) {
if (callback == null || executor == null) {
@@ -160,6 +155,21 @@
}
}
+ 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);
@@ -213,19 +223,6 @@
}
}
- 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/SessionToken2Test.java b/media/src/androidTest/java/androidx/media/SessionToken2Test.java
index bf96eb9..22881a8 100644
--- a/media/src/androidTest/java/androidx/media/SessionToken2Test.java
+++ b/media/src/androidTest/java/androidx/media/SessionToken2Test.java
@@ -20,10 +20,8 @@
import android.content.ComponentName;
import android.content.Context;
-import android.os.Build;
import android.os.Process;
import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -34,7 +32,6 @@
/**
* Tests {@link SessionToken2}.
*/
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SessionToken2Test {
diff --git a/media/src/androidTest/java/androidx/media/TestUtils.java b/media/src/androidTest/java/androidx/media/TestUtils.java
index 2b02b75..1e3ba9b 100644
--- a/media/src/androidTest/java/androidx/media/TestUtils.java
+++ b/media/src/androidTest/java/androidx/media/TestUtils.java
@@ -25,11 +25,10 @@
import android.os.Handler;
import android.os.Looper;
-import androidx.core.util.ObjectsCompat;
-
import java.io.FileDescriptor;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -69,29 +68,18 @@
* 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;
}
- for (String key : b.keySet()) {
- if (!ObjectsCompat.equals(a.get(key), b.get(key))) {
+ if (!a.keySet().containsAll(b.keySet())
+ || !b.keySet().containsAll(a.keySet())) {
+ return false;
+ }
+ for (String key : a.keySet()) {
+ if (!Objects.equals(a.get(key), b.get(key))) {
return false;
}
}
@@ -103,7 +91,7 @@
* <p>
* Caller's method name will be used for prefix of each media item's media id.
*
- * @param size list size
+ * @param size lits size
* @return the newly created playlist
*/
public static List<MediaItem2> createPlaylist(int size) {
@@ -112,7 +100,11 @@
for (int i = 0; i < size; i++) {
list.add(new MediaItem2.Builder(MediaItem2.FLAG_PLAYABLE)
.setMediaId(caller + "_item_" + (size + 1))
- .setDataSourceDesc(createDSD()).build());
+ .setDataSourceDesc(
+ new DataSourceDesc.Builder()
+ .setDataSource(new FileDescriptor())
+ .build())
+ .build());
}
return list;
}
@@ -125,7 +117,7 @@
*/
public static MediaItem2 createMediaItemWithMetadata() {
return new MediaItem2.Builder(MediaItem2.FLAG_PLAYABLE)
- .setMetadata(createMetadata()).setDataSourceDesc(createDSD()).build();
+ .setMetadata(createMetadata()).build();
}
/**
@@ -141,21 +133,6 @@
.putString(MediaMetadata2.METADATA_KEY_MEDIA_ID, mediaId).build();
}
- private static DataSourceDesc createDSD() {
- return new DataSourceDesc.Builder().setDataSource(new FileDescriptor()).build();
- }
-
- /**
- * Create a bundle for testing purpose.
- *
- * @return the newly created bundle.
- */
- public static Bundle createTestBundle() {
- Bundle bundle = new Bundle();
- bundle.putString("test_key", "test_value");
- return bundle;
- }
-
/**
* Handler that always waits until the Runnable finishes.
*/
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 aa039c3..a0e839bd 100644
--- a/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
+++ b/media/src/main/java/android/support/v4/media/MediaBrowserCompat.java
@@ -15,7 +15,6 @@
*/
package android.support.v4.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;
@@ -33,7 +32,6 @@
import static androidx.media.MediaBrowserProtocol.DATA_MEDIA_ITEM_ID;
import static androidx.media.MediaBrowserProtocol.DATA_MEDIA_ITEM_LIST;
import static androidx.media.MediaBrowserProtocol.DATA_MEDIA_SESSION_TOKEN;
-import static androidx.media.MediaBrowserProtocol.DATA_NOTIFY_CHILDREN_CHANGED_OPTIONS;
import static androidx.media.MediaBrowserProtocol.DATA_OPTIONS;
import static androidx.media.MediaBrowserProtocol.DATA_PACKAGE_NAME;
import static androidx.media.MediaBrowserProtocol.DATA_RESULT_RECEIVER;
@@ -430,20 +428,6 @@
}
/**
- * Gets the options which is passed to {@link MediaBrowserServiceCompat#notifyChildrenChanged(
- * String, Bundle)} call that triggered {@link SubscriptionCallback#onChildrenLoaded}.
- * This should be called inside of {@link SubscriptionCallback#onChildrenLoaded}.
- *
- * @return A bundle which is passed to {@link MediaBrowserServiceCompat#notifyChildrenChanged(
- * String, Bundle)}
- * @hide
- */
- @RestrictTo(LIBRARY)
- public @Nullable Bundle getNotifyChildrenChangedOptions() {
- return mImpl.getNotifyChildrenChangedOptions();
- }
-
- /**
* A class with information on a single media item for use in browsing/searching media.
* MediaItems are application dependent so we cannot guarantee that they contain the
* right values.
@@ -967,15 +951,13 @@
void search(@NonNull String query, Bundle extras, @NonNull SearchCallback callback);
void sendCustomAction(@NonNull String action, Bundle extras,
@Nullable CustomActionCallback callback);
- @Nullable Bundle getNotifyChildrenChangedOptions();
}
interface MediaBrowserServiceCallbackImpl {
void onServiceConnected(Messenger callback, String root, MediaSessionCompat.Token session,
Bundle extra);
void onConnectionFailed(Messenger callback);
- void onLoadChildren(Messenger callback, String parentId, List list, Bundle options,
- Bundle notifyChildrenChangedOptions);
+ void onLoadChildren(Messenger callback, String parentId, List list, Bundle options);
}
static class MediaBrowserImplBase
@@ -1000,7 +982,6 @@
private String mRootId;
private MediaSessionCompat.Token mMediaSessionToken;
private Bundle mExtras;
- private Bundle mNotifyChildrenChangedOptions;
public MediaBrowserImplBase(Context context, ComponentName serviceComponent,
ConnectionCallback callback, Bundle rootHints) {
@@ -1391,7 +1372,7 @@
@Override
public void onLoadChildren(final Messenger callback, final String parentId,
- final List list, final Bundle options, final Bundle notifyChildrenChangedOptions) {
+ final List list, final Bundle options) {
// Check that there hasn't been a disconnect or a different ServiceConnection.
if (!isCurrent(callback, "onLoadChildren")) {
return;
@@ -1417,27 +1398,18 @@
if (list == null) {
subscriptionCallback.onError(parentId);
} else {
- mNotifyChildrenChangedOptions = notifyChildrenChangedOptions;
subscriptionCallback.onChildrenLoaded(parentId, list);
- mNotifyChildrenChangedOptions = null;
}
} else {
if (list == null) {
subscriptionCallback.onError(parentId, options);
} else {
- mNotifyChildrenChangedOptions = notifyChildrenChangedOptions;
subscriptionCallback.onChildrenLoaded(parentId, list, options);
- mNotifyChildrenChangedOptions = null;
}
}
}
}
- @Override
- public Bundle getNotifyChildrenChangedOptions() {
- return mNotifyChildrenChangedOptions;
- }
-
/**
* For debugging.
*/
@@ -1617,7 +1589,6 @@
protected ServiceBinderWrapper mServiceBinderWrapper;
protected Messenger mCallbacksMessenger;
private MediaSessionCompat.Token mMediaSessionToken;
- private Bundle mNotifyChildrenChangedOptions;
MediaBrowserImplApi21(Context context, ComponentName serviceComponent,
ConnectionCallback callback, Bundle rootHints) {
@@ -1891,7 +1862,7 @@
mCallbacksMessenger = new Messenger(mHandler);
mHandler.setCallbacksMessenger(mCallbacksMessenger);
try {
- mServiceBinderWrapper.registerCallbackMessenger(mContext, mCallbacksMessenger);
+ mServiceBinderWrapper.registerCallbackMessenger(mCallbacksMessenger);
} catch (RemoteException e) {
Log.i(TAG, "Remote error registering client messenger." );
}
@@ -1930,8 +1901,7 @@
@Override
@SuppressWarnings("ReferenceEquality")
- public void onLoadChildren(Messenger callback, String parentId, List list, Bundle options,
- Bundle notifyChildrenChangedOptions) {
+ public void onLoadChildren(Messenger callback, String parentId, List list, Bundle options) {
if (mCallbacksMessenger != callback) {
return;
}
@@ -1952,26 +1922,17 @@
if (list == null) {
subscriptionCallback.onError(parentId);
} else {
- mNotifyChildrenChangedOptions = notifyChildrenChangedOptions;
subscriptionCallback.onChildrenLoaded(parentId, list);
- mNotifyChildrenChangedOptions = null;
}
} else {
if (list == null) {
subscriptionCallback.onError(parentId, options);
} else {
- mNotifyChildrenChangedOptions = notifyChildrenChangedOptions;
subscriptionCallback.onChildrenLoaded(parentId, list, options);
- mNotifyChildrenChangedOptions = null;
}
}
}
}
-
- @Override
- public Bundle getNotifyChildrenChangedOptions() {
- return mNotifyChildrenChangedOptions;
- }
}
@RequiresApi(23)
@@ -2116,8 +2077,7 @@
serviceCallback.onLoadChildren(callbacksMessenger,
data.getString(DATA_MEDIA_ITEM_ID),
data.getParcelableArrayList(DATA_MEDIA_ITEM_LIST),
- data.getBundle(DATA_OPTIONS),
- data.getBundle(DATA_NOTIFY_CHILDREN_CHANGED_OPTIONS));
+ data.getBundle(DATA_OPTIONS));
break;
default:
Log.w(TAG, "Unhandled message: " + msg
@@ -2187,10 +2147,8 @@
sendRequest(CLIENT_MSG_GET_MEDIA_ITEM, data, callbacksMessenger);
}
- void registerCallbackMessenger(Context context, Messenger callbackMessenger)
- throws RemoteException {
+ void registerCallbackMessenger(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 dd498be..1d78fc8 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
@@ -18,7 +18,6 @@
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-import static androidx.media.MediaSessionManager.RemoteUserInfo.LEGACY_CONTROLLER;
import android.app.Activity;
import android.app.PendingIntent;
@@ -32,10 +31,8 @@
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;
@@ -58,12 +55,9 @@
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;
@@ -389,11 +383,6 @@
// Maximum size of the bitmap in dp.
private static final int MAX_BITMAP_SIZE_IN_DP = 320;
- 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;
@@ -460,11 +449,7 @@
mbrIntent = PendingIntent.getBroadcast(context,
0/* requestCode, ignored */, mediaButtonIntent, 0/* flags */);
}
- 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) {
+ 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() {});
@@ -817,18 +802,6 @@
}
/**
- * 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)
- */
- 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.
@@ -1849,7 +1822,6 @@
Object getRemoteControlClient();
String getCallingPackage();
- RemoteUserInfo getCurrentControllerInfo();
}
static class MediaSessionImplBase implements MediaSessionImpl {
@@ -1946,19 +1918,30 @@
}
}
- void postToHandler(int what, int arg1, int arg2, Object obj, Bundle extras) {
+ 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) {
synchronized (mLock) {
if (mHandler != null) {
- 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();
+ mHandler.post(what, obj, arg1);
+ }
+ }
+ }
+
+ void postToHandler(int what, Object obj, Bundle extras) {
+ synchronized (mLock) {
+ if (mHandler != null) {
+ mHandler.post(what, obj, extras);
}
}
}
@@ -1976,7 +1959,6 @@
if (mVolumeProvider != null) {
mVolumeProvider.setCallback(null);
}
- mLocalStream = stream;
mVolumeType = MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL;
ParcelableVolumeInfo info = new ParcelableVolumeInfo(mVolumeType, mLocalStream,
VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
@@ -2300,16 +2282,6 @@
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;
@@ -2820,26 +2792,6 @@
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 {
@@ -2891,133 +2843,138 @@
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;
}
-
- 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);
+ 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());
}
- 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;
+ }
+ 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;
}
}
@@ -3071,10 +3028,6 @@
break;
}
}
-
- RemoteUserInfo getRemoteUserInfo() {
- return mRemoteUserInfo;
- }
}
}
@@ -3097,8 +3050,7 @@
new RemoteControlClient.OnPlaybackPositionUpdateListener() {
@Override
public void onPlaybackPositionUpdate(long newPositionMs) {
- postToHandler(
- MessageHandler.MSG_SEEK_TO, -1, -1, newPositionMs, null);
+ postToHandler(MessageHandler.MSG_SEEK_TO, newPositionMs);
}
};
mRcc.setPlaybackPositionUpdateListener(listener);
@@ -3183,8 +3135,8 @@
public void onMetadataUpdate(int key, Object newValue) {
if (key == MediaMetadataEditor.RATING_KEY_BY_USER
&& newValue instanceof Rating) {
- postToHandler(MessageHandler.MSG_RATE, -1, -1,
- RatingCompat.fromRating(newValue), null);
+ postToHandler(MessageHandler.MSG_RATE,
+ RatingCompat.fromRating(newValue));
}
}
};
@@ -3458,11 +3410,6 @@
}
}
- @Override
- public RemoteUserInfo getCurrentControllerInfo() {
- return null;
- }
-
class ExtraSession extends IMediaSession.Stub {
@Override
public void sendCommand(String command, Bundle args, ResultReceiverWrapper cb) {
@@ -3756,25 +3703,4 @@
}
}
}
-
- @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/AudioAttributesCompat.java b/media/src/main/java/androidx/media/AudioAttributesCompat.java
index 69ef117..1fbb7be0 100644
--- a/media/src/main/java/androidx/media/AudioAttributesCompat.java
+++ b/media/src/main/java/androidx/media/AudioAttributesCompat.java
@@ -21,7 +21,6 @@
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.os.Build;
-import android.os.Bundle;
import android.util.SparseIntArray;
import androidx.annotation.IntDef;
@@ -229,16 +228,6 @@
private static final int FLAG_ALL_PUBLIC =
(FLAG_AUDIBILITY_ENFORCED | FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY);
- /** Keys to convert to (or create from) Bundle. */
- private static final String AUDIO_ATTRIBUTES_FRAMEWORKS =
- "androidx.media.audio_attrs.FRAMEWORKS";
- private static final String AUDIO_ATTRIBUTES_USAGE = "androidx.media.audio_attrs.USAGE";
- private static final String AUDIO_ATTRIBUTES_CONTENT_TYPE =
- "androidx.media.audio_attrs.CONTENT_TYPE";
- private static final String AUDIO_ATTRIBUTES_FLAGS = "androidx.media.audio_attrs.FLAGS";
- private static final String AUDIO_ATTRIBUTES_LEGACY_STREAM_TYPE =
- "androidx.media.audio_attrs.LEGACY_STREAM_TYPE";
-
int mUsage = USAGE_UNKNOWN;
int mContentType = CONTENT_TYPE_UNKNOWN;
int mFlags = 0x0;
@@ -388,56 +377,6 @@
}
/**
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- public @NonNull Bundle toBundle() {
- Bundle bundle = new Bundle();
- if (Build.VERSION.SDK_INT >= 21) {
- bundle.putParcelable(AUDIO_ATTRIBUTES_FRAMEWORKS, mAudioAttributesWrapper.unwrap());
- } else {
- bundle.putInt(AUDIO_ATTRIBUTES_USAGE, mUsage);
- bundle.putInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, mContentType);
- bundle.putInt(AUDIO_ATTRIBUTES_FLAGS, mFlags);
- if (mLegacyStream != null) {
- bundle.putInt(AUDIO_ATTRIBUTES_LEGACY_STREAM_TYPE, mLegacyStream);
- }
- }
- return bundle;
- }
-
- /**
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- public static AudioAttributesCompat fromBundle(Bundle bundle) {
- if (bundle == null) {
- return null;
- }
-
- if (Build.VERSION.SDK_INT >= 21) {
- AudioAttributes frameworkAttrs = (AudioAttributes)
- bundle.getParcelable(AUDIO_ATTRIBUTES_FRAMEWORKS);
- return frameworkAttrs == null ? null : AudioAttributesCompat.wrap(frameworkAttrs);
- } else {
- int usage = bundle.getInt(AUDIO_ATTRIBUTES_USAGE, USAGE_UNKNOWN);
- int contentType = bundle.getInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, CONTENT_TYPE_UNKNOWN);
- int flags = bundle.getInt(AUDIO_ATTRIBUTES_FLAGS, 0);
-
- // Here, we do not use builder in order to 'copy' the exact state of the original one.
- // Builder class guesses the usage based on other value (contentType/legacyStream), and
- // overwrites it. So using builder cannot ensure the equality.
- AudioAttributesCompat attr = new AudioAttributesCompat();
- attr.mUsage = usage;
- attr.mContentType = contentType;
- attr.mFlags = flags;
- attr.mLegacyStream = bundle.containsKey(AUDIO_ATTRIBUTES_LEGACY_STREAM_TYPE)
- ? bundle.getInt(AUDIO_ATTRIBUTES_LEGACY_STREAM_TYPE) : null;
- return attr;
- }
- }
-
- /**
* Builder class for {@link AudioAttributesCompat} objects.
*
* <p>example:
diff --git a/media/src/main/java/androidx/media/Media2DataSource.java b/media/src/main/java/androidx/media/Media2DataSource.java
index 3855d56..4990259 100644
--- a/media/src/main/java/androidx/media/Media2DataSource.java
+++ b/media/src/main/java/androidx/media/Media2DataSource.java
@@ -17,10 +17,15 @@
package androidx.media;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import androidx.annotation.RestrictTo;
+
import java.io.Closeable;
import java.io.IOException;
/**
+ * @hide
* For supplying media data to the framework. Implement this if your app has
* special requirements for the way media data is obtained.
*
@@ -31,6 +36,7 @@
* Media2DataSource from another thread while it's being used by the framework.</p>
*
*/
+@RestrictTo(LIBRARY_GROUP)
public abstract class Media2DataSource implements Closeable {
/**
* Called to request data from the given position.
diff --git a/media/src/main/java/androidx/media/MediaBrowser2.java b/media/src/main/java/androidx/media/MediaBrowser2.java
index beadf1f..6ef7fcf 100644
--- a/media/src/main/java/androidx/media/MediaBrowser2.java
+++ b/media/src/main/java/androidx/media/MediaBrowser2.java
@@ -17,18 +17,13 @@
package androidx.media;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-import static androidx.media.MediaConstants2.ARGUMENT_EXTRAS;
-import static androidx.media.MediaConstants2.ARGUMENT_PAGE;
-import static androidx.media.MediaConstants2.ARGUMENT_PAGE_SIZE;
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;
import android.support.v4.media.MediaBrowserCompat.MediaItem;
import android.support.v4.media.MediaBrowserCompat.SubscriptionCallback;
-import android.util.Log;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
@@ -43,12 +38,11 @@
import java.util.concurrent.Executor;
/**
+ * @hide
* Browses media content offered by a {@link MediaLibraryService2}.
*/
+@RestrictTo(LIBRARY_GROUP)
public class MediaBrowser2 extends MediaController2 {
- static final String TAG = "MediaBrowser2";
- static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
/**
* @hide
*/
@@ -56,10 +50,11 @@
public static final String EXTRA_ITEM_COUNT = "android.media.browse.extra.ITEM_COUNT";
/**
+ * Key for Bundle version of {@link MediaSession2.ControllerInfo}.
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
- public static final String MEDIA_BROWSER2_SUBSCRIBE = "androidx.media.MEDIA_BROWSER2_SUBSCRIBE";
+ public static final String EXTRA_TARGET = "android.media.browse.extra.TARGET";
private final Object mLock = new Object();
@GuardedBy("mLock")
@@ -176,7 +171,7 @@
browser.disconnect();
}
mBrowserCompats.clear();
- // Ensure that ControllerCallback#onDisconnected() is called by super.close().
+ // TODO: Ensure that ControllerCallback#onDisconnected() is called by super.close().
super.close();
}
}
@@ -200,20 +195,13 @@
}
});
} else {
- 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();
- }
- });
+ MediaBrowserCompat newBrowser = new MediaBrowserCompat(getContext(),
+ getSessionToken().getComponentName(), new GetLibraryRootCallback(extras),
+ extras);
+ newBrowser.connect();
+ synchronized (mLock) {
+ mBrowserCompats.put(extras, newBrowser);
+ }
}
}
@@ -230,9 +218,15 @@
if (parentId == null) {
throw new IllegalArgumentException("parentId shouldn't be null");
}
- MediaBrowserCompat browser = getBrowserCompat();
- if (browser == null) {
- return;
+ // 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;
}
SubscribeCallback callback = new SubscribeCallback();
synchronized (mLock) {
@@ -243,11 +237,11 @@
}
list.add(callback);
}
-
- Bundle options = new Bundle();
- options.putBundle(ARGUMENT_EXTRAS, extras);
- options.putBoolean(MEDIA_BROWSER2_SUBSCRIBE, true);
- browser.subscribe(parentId, options, 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);
}
/**
@@ -263,10 +257,6 @@
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) {
@@ -274,6 +264,7 @@
if (list == null) {
return;
}
+ MediaBrowserCompat browser = getBrowserCompat();
for (int i = 0; i < list.size(); i++) {
browser.unsubscribe(parentId, list.get(i));
}
@@ -297,15 +288,12 @@
if (page < 1 || pageSize < 1) {
throw new IllegalArgumentException("Neither page nor pageSize should be less than 1");
}
- MediaBrowserCompat browser = getBrowserCompat();
- if (browser == null) {
- return;
- }
-
- Bundle options = MediaUtils2.createBundle(extras);
+ Bundle options = new Bundle(extras);
options.putInt(MediaBrowserCompat.EXTRA_PAGE, page);
options.putInt(MediaBrowserCompat.EXTRA_PAGE_SIZE, pageSize);
- browser.subscribe(parentId, options, new GetChildrenCallback(parentId, page, pageSize));
+ // TODO: Revisit using default browser is OK. See TODO in subscribe
+ getBrowserCompat().subscribe(parentId, options,
+ new GetChildrenCallback(parentId, page, pageSize));
}
/**
@@ -315,11 +303,8 @@
* @param mediaId media id for specifying the item
*/
public void getItem(@NonNull final String mediaId) {
- MediaBrowserCompat browser = getBrowserCompat();
- if (browser == null) {
- return;
- }
- browser.getItem(mediaId, new ItemCallback() {
+ // TODO: Revisit using default browser is OK. See TODO in subscribe
+ getBrowserCompat().getItem(mediaId, new ItemCallback() {
@Override
public void onItemLoaded(final MediaItem item) {
getCallbackExecutor().execute(new Runnable() {
@@ -353,28 +338,7 @@
* @param extras extra bundle
*/
public void search(@NonNull String query, @Nullable Bundle extras) {
- MediaBrowserCompat browser = getBrowserCompat();
- if (browser == null) {
- return;
- }
- browser.search(query, extras, new MediaBrowserCompat.SearchCallback() {
- @Override
- public void onSearchResult(final String query, final Bundle extras,
- final List<MediaItem> items) {
- getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- getCallback().onSearchResultChanged(
- MediaBrowser2.this, query, items.size(), extras);
- }
- });
- }
-
- @Override
- public void onError(final String query, final Bundle extras) {
- // Currently no way to tell failures in MediaBrowser2#search().
- }
- });
+ // TODO: Implement
}
/**
@@ -387,40 +351,9 @@
* @param pageSize page size. Should be greater or equal to {@code 1}
* @param extras extra bundle
*/
- public void getSearchResult(final @NonNull String query, final int page, final int pageSize,
- final @Nullable Bundle extras) {
- MediaBrowserCompat browser = getBrowserCompat();
- if (browser == null) {
- return;
- }
- Bundle options = MediaUtils2.createBundle(extras);
- options.putInt(ARGUMENT_PAGE, page);
- options.putInt(ARGUMENT_PAGE_SIZE, pageSize);
- browser.search(query, options, new MediaBrowserCompat.SearchCallback() {
- @Override
- public void onSearchResult(final String query, final Bundle extrasSent,
- final List<MediaItem> items) {
- getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- List<MediaItem2> item2List = MediaUtils2.toMediaItem2List(items);
- getCallback().onGetSearchResultDone(
- MediaBrowser2.this, query, page, pageSize, item2List, extras);
- }
- });
- }
-
- @Override
- public void onError(final String query, final Bundle extrasSent) {
- getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- getCallback().onGetSearchResultDone(
- MediaBrowser2.this, query, page, pageSize, null, extras);
- }
- });
- }
- });
+ public void getSearchResult(@NonNull String query, int page, int pageSize,
+ @Nullable Bundle extras) {
+ // TODO: Implement
}
@Override
@@ -434,20 +367,6 @@
}
}
- 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;
@@ -514,14 +433,11 @@
// Currently no way to tell failures in MediaBrowser2#subscribe().
return;
}
-
- final Bundle notifyChildrenChangedOptions =
- getBrowserCompat().getNotifyChildrenChangedOptions();
getCallbackExecutor().execute(new Runnable() {
@Override
public void run() {
getCallback().onChildrenChanged(MediaBrowser2.this, parentId, itemCount,
- notifyChildrenChangedOptions);
+ options);
}
});
}
@@ -556,7 +472,7 @@
@Override
public void onChildrenLoaded(final String parentId, List<MediaItem> children,
- Bundle options) {
+ final Bundle options) {
final List<MediaItem2> items;
if (children == null) {
items = null;
@@ -566,17 +482,12 @@
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, extras);
- browser.unsubscribe(mParentId, GetChildrenCallback.this);
+ items, options);
+ getBrowserCompat().unsubscribe(mParentId, GetChildrenCallback.this);
}
});
}
diff --git a/media/src/main/java/androidx/media/MediaBrowserCompatUtils.java b/media/src/main/java/androidx/media/MediaBrowserCompatUtils.java
index b9491b6..c553256 100644
--- a/media/src/main/java/androidx/media/MediaBrowserCompatUtils.java
+++ b/media/src/main/java/androidx/media/MediaBrowserCompatUtils.java
@@ -70,8 +70,12 @@
endIndex2 = startIndex2 + pageSize2 - 1;
}
- // For better readability, leaving the exclamation mark here.
- return !(endIndex1 < startIndex2 || endIndex2 < startIndex1);
+ if (startIndex1 <= startIndex2 && startIndex2 <= endIndex1) {
+ return true;
+ } else if (startIndex1 <= endIndex2 && endIndex2 <= endIndex1) {
+ return true;
+ }
+ return false;
}
private MediaBrowserCompatUtils() {
diff --git a/media/src/main/java/androidx/media/MediaBrowserProtocol.java b/media/src/main/java/androidx/media/MediaBrowserProtocol.java
index eb5b449..5c85880 100644
--- a/media/src/main/java/androidx/media/MediaBrowserProtocol.java
+++ b/media/src/main/java/androidx/media/MediaBrowserProtocol.java
@@ -15,7 +15,6 @@
*/
package androidx.media;
-import android.os.Bundle;
import android.support.v4.media.MediaBrowserCompat;
import androidx.annotation.RestrictTo;
@@ -30,13 +29,10 @@
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";
public static final String DATA_OPTIONS = "data_options";
- public static final String DATA_NOTIFY_CHILDREN_CHANGED_OPTIONS =
- "data_notify_children_changed_options";
public static final String DATA_PACKAGE_NAME = "data_package_name";
public static final String DATA_RESULT_RECEIVER = "data_result_receiver";
public static final String DATA_ROOT_HINTS = "data_root_hints";
@@ -98,9 +94,6 @@
* DATA_MEDIA_ITEM_LIST : An array list for the media item children
* DATA_OPTIONS : A bundle of service-specific arguments sent from the media browse to
* the media browser service
- * DATA_NOTIFY_CHILDREN_CHANGED_OPTIONS : A bundle of service-specific arguments sent from
- * the media browser service to the media browser by calling
- * {@link MediaBrowserServiceCompat#notifyChildrenChanged(String, Bundle)}
*/
public static final int SERVICE_MSG_ON_LOAD_CHILDREN = 3;
diff --git a/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java b/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
index 5da2287..8f24837 100644
--- a/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
+++ b/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
@@ -27,14 +27,12 @@
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;
import static androidx.media.MediaBrowserProtocol.DATA_MEDIA_ITEM_ID;
import static androidx.media.MediaBrowserProtocol.DATA_MEDIA_ITEM_LIST;
import static androidx.media.MediaBrowserProtocol.DATA_MEDIA_SESSION_TOKEN;
-import static androidx.media.MediaBrowserProtocol.DATA_NOTIFY_CHILDREN_CHANGED_OPTIONS;
import static androidx.media.MediaBrowserProtocol.DATA_OPTIONS;
import static androidx.media.MediaBrowserProtocol.DATA_PACKAGE_NAME;
import static androidx.media.MediaBrowserProtocol.DATA_RESULT_RECEIVER;
@@ -63,7 +61,6 @@
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;
@@ -79,7 +76,6 @@
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;
@@ -171,10 +167,9 @@
/** @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;
@@ -187,8 +182,6 @@
void setSessionToken(MediaSessionCompat.Token token);
void notifyChildrenChanged(final String parentId, final Bundle options);
Bundle getBrowserRootHints();
- RemoteUserInfo getCurrentBrowserInfo();
- List<RemoteUserInfo> getSubscribingBrowsers(String parentId);
}
class MediaBrowserServiceImplBase implements MediaBrowserServiceImpl {
@@ -213,7 +206,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,
@@ -240,8 +233,7 @@
for (Pair<IBinder, Bundle> callback : callbackList) {
if (MediaBrowserCompatUtils.hasDuplicatedItems(
options, callback.second)) {
- performLoadChildren(parentId, connection, callback.second,
- options);
+ performLoadChildren(parentId, connection, callback.second);
}
}
}
@@ -254,33 +246,10 @@
public Bundle getBrowserRootHints() {
if (mCurConnection == null) {
throw new IllegalStateException("This should be called inside of onLoadChildren,"
- + " onLoadItem, onSearch, or onCustomAction methods");
+ + " onLoadItem or onSearch 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;
- }
-
- @Override
- public List<RemoteUserInfo> getSubscribingBrowsers(String parentId) {
- List<RemoteUserInfo> result = new ArrayList<>();
- for (IBinder binder : mConnections.keySet()) {
- ConnectionRecord connection = mConnections.get(binder);
- List<Pair<IBinder, Bundle>> callbackList =
- connection.subscriptions.get(parentId);
- if (callbackList != null) {
- result.add(connection.browserInfo);
- }
- }
- return result;
- }
}
@RequiresApi(21)
@@ -329,6 +298,19 @@
}
@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;
@@ -346,13 +328,8 @@
mRootExtrasList.add(rootExtras);
}
}
- // We aren't sure whether this connection request would be accepted.
- // Temporarily set mCurConnection just to make getCurrentBrowserInfo() working.
- mCurConnection = new ConnectionRecord(clientPackageName, -1, clientUid, rootHints,
- null);
BrowserRoot root = MediaBrowserServiceCompat.this.onGetRoot(
clientPackageName, clientUid, rootHints);
- mCurConnection = null;
if (root == null) {
return null;
}
@@ -392,20 +369,6 @@
MediaBrowserServiceCompat.this.onLoadChildren(parentId, result);
}
- @Override
- public List<RemoteUserInfo> getSubscribingBrowsers(String parentId) {
- List<RemoteUserInfo> result = new ArrayList<>();
- for (IBinder binder : mConnections.keySet()) {
- ConnectionRecord connection = mConnections.get(binder);
- List<Pair<IBinder, Bundle>> callbackList =
- connection.subscriptions.get(parentId);
- if (callbackList != null) {
- result.add(connection.browserInfo);
- }
- }
- return result;
- }
-
void notifyChildrenChangedForFramework(final String parentId, final Bundle options) {
MediaBrowserServiceCompatApi21.notifyChildrenChanged(mServiceObj, parentId);
}
@@ -422,8 +385,7 @@
for (Pair<IBinder, Bundle> callback : callbackList) {
if (MediaBrowserCompatUtils.hasDuplicatedItems(
options, callback.second)) {
- performLoadChildren(parentId, connection, callback.second,
- options);
+ performLoadChildren(parentId, connection, callback.second);
}
}
}
@@ -431,28 +393,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 onGetRoot,"
- + " 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 onGetRoot,"
- + " onLoadChildren, onLoadItem, onSearch, or onCustomAction methods");
- }
- return mCurConnection.browserInfo;
- }
}
@RequiresApi(23)
@@ -529,7 +469,7 @@
@Override
public Bundle getBrowserRootHints() {
- // mCurConnection is not null when EXTRA_MESSENGER_BINDER is used.
+ // If EXTRA_MESSENGER_BINDER is used, mCurConnection is not null.
if (mCurConnection != null) {
return mCurConnection.rootHints == null ? null
: new Bundle(mCurConnection.rootHints);
@@ -548,21 +488,6 @@
}
}
- @RequiresApi(28)
- class MediaBrowserServiceImplApi28 extends MediaBrowserServiceImplApi26 {
- @Override
- public RemoteUserInfo getCurrentBrowserInfo() {
- // mCurConnection is not null when EXTRA_MESSENGER_BINDER is used.
- if (mCurConnection != null) {
- return mCurConnection.browserInfo;
- }
- 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();
@@ -575,8 +500,7 @@
switch (msg.what) {
case CLIENT_MSG_CONNECT:
mServiceBinderImpl.connect(data.getString(DATA_PACKAGE_NAME),
- data.getInt(DATA_CALLING_PID), data.getInt(DATA_CALLING_UID),
- data.getBundle(DATA_ROOT_HINTS),
+ data.getInt(DATA_CALLING_UID), data.getBundle(DATA_ROOT_HINTS),
new ServiceCallbacksCompat(msg.replyTo));
break;
case CLIENT_MSG_DISCONNECT:
@@ -600,8 +524,7 @@
break;
case CLIENT_MSG_REGISTER_CALLBACK_MESSENGER:
mServiceBinderImpl.registerCallbacks(new ServiceCallbacksCompat(msg.replyTo),
- data.getString(DATA_PACKAGE_NAME), data.getInt(DATA_CALLING_PID),
- data.getInt(DATA_CALLING_UID), data.getBundle(DATA_ROOT_HINTS));
+ data.getBundle(DATA_ROOT_HINTS));
break;
case CLIENT_MSG_UNREGISTER_CALLBACK_MESSENGER:
mServiceBinderImpl.unregisterCallbacks(new ServiceCallbacksCompat(msg.replyTo));
@@ -632,7 +555,6 @@
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);
}
@@ -649,23 +571,13 @@
* All the info about a connection.
*/
private class ConnectionRecord implements IBinder.DeathRecipient {
- 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;
+ String pkg;
+ Bundle rootHints;
+ ServiceCallbacks callbacks;
+ BrowserRoot root;
+ HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>();
- 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;
+ ConnectionRecord() {
}
@Override
@@ -828,7 +740,7 @@
ServiceBinderImpl() {
}
- public void connect(final String pkg, final int pid, final int uid, final Bundle rootHints,
+ public void connect(final String pkg, final int uid, final Bundle rootHints,
final ServiceCallbacks callbacks) {
if (!isValidPackage(pkg, uid)) {
@@ -844,11 +756,13 @@
// Clear out the old subscriptions. We are getting new ones.
mConnections.remove(b);
- final ConnectionRecord connection = new ConnectionRecord(pkg, pid, uid,
- rootHints, callbacks);
- mCurConnection = connection;
- connection.root = MediaBrowserServiceCompat.this.onGetRoot(pkg, uid, rootHints);
- mCurConnection = null;
+ final ConnectionRecord connection = new ConnectionRecord();
+ connection.pkg = pkg;
+ connection.rootHints = rootHints;
+ connection.callbacks = callbacks;
+
+ connection.root =
+ MediaBrowserServiceCompat.this.onGetRoot(pkg, uid, rootHints);
// If they didn't return something, don't allow this client.
if (connection.root == null) {
@@ -958,8 +872,7 @@
}
// Used when {@link MediaBrowserProtocol#EXTRA_MESSENGER_BINDER} is used.
- public void registerCallbacks(final ServiceCallbacks callbacks, final String pkg,
- final int pid, final int uid, final Bundle rootHints) {
+ public void registerCallbacks(final ServiceCallbacks callbacks, final Bundle rootHints) {
mHandler.postOrRun(new Runnable() {
@Override
public void run() {
@@ -967,8 +880,9 @@
// Clear out the old subscriptions. We are getting new ones.
mConnections.remove(b);
- final ConnectionRecord connection = new ConnectionRecord(pkg, pid, uid,
- rootHints, callbacks);
+ final ConnectionRecord connection = new ConnectionRecord();
+ connection.callbacks = callbacks;
+ connection.rootHints = rootHints;
mConnections.put(b, connection);
try {
b.linkToDeath(connection, 0);
@@ -1042,8 +956,8 @@
void onConnect(String root, MediaSessionCompat.Token session, Bundle extras)
throws RemoteException;
void onConnectFailed() throws RemoteException;
- void onLoadChildren(String mediaId, List<MediaBrowserCompat.MediaItem> list, Bundle options,
- Bundle notifyChildrenChangedOptions) throws RemoteException;
+ void onLoadChildren(String mediaId, List<MediaBrowserCompat.MediaItem> list, Bundle options)
+ throws RemoteException;
}
private static class ServiceCallbacksCompat implements ServiceCallbacks {
@@ -1079,11 +993,10 @@
@Override
public void onLoadChildren(String mediaId, List<MediaBrowserCompat.MediaItem> list,
- Bundle options, Bundle notifyChildrenChangedOptions) throws RemoteException {
+ Bundle options) throws RemoteException {
Bundle data = new Bundle();
data.putString(DATA_MEDIA_ITEM_ID, mediaId);
data.putBundle(DATA_OPTIONS, options);
- data.putBundle(DATA_NOTIFY_CHILDREN_CHANGED_OPTIONS, notifyChildrenChangedOptions);
if (list != null) {
data.putParcelableArrayList(DATA_MEDIA_ITEM_LIST,
list instanceof ArrayList ? (ArrayList) list : new ArrayList<>(list));
@@ -1118,9 +1031,7 @@
@Override
public void onCreate() {
super.onCreate();
- if (Build.VERSION.SDK_INT >= 28) {
- mImpl = new MediaBrowserServiceImplApi28();
- } else if (Build.VERSION.SDK_INT >= 26) {
+ if (Build.VERSION.SDK_INT >= 26) {
mImpl = new MediaBrowserServiceImplApi26();
} else if (Build.VERSION.SDK_INT >= 23) {
mImpl = new MediaBrowserServiceImplApi23();
@@ -1342,17 +1253,6 @@
}
/**
- * 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)
- */
- public final @NonNull RemoteUserInfo getCurrentBrowserInfo() {
- 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.
@@ -1389,18 +1289,6 @@
}
/**
- * Gets {@link RemoteUserInfo} of all browsers which are subscribing to the given parentId.
- * @hide
- */
- @RestrictTo(LIBRARY)
- public @NonNull List<RemoteUserInfo> getSubscribingBrowsers(@NonNull String parentId) {
- if (parentId == null) {
- throw new IllegalArgumentException("parentId cannot be null in getSubscribingBrowsers");
- }
- return mImpl.getSubscribingBrowsers(parentId);
- }
-
- /**
* Return whether the given package is one of the ones that is owned by the uid.
*/
boolean isValidPackage(String pkg, int uid) {
@@ -1437,7 +1325,7 @@
callbackList.add(new Pair<>(token, options));
connection.subscriptions.put(id, callbackList);
// send the results
- performLoadChildren(id, connection, options, null);
+ performLoadChildren(id, connection, options);
}
/**
@@ -1470,7 +1358,7 @@
* Callers must make sure that this connection is still connected.
*/
void performLoadChildren(final String parentId, final ConnectionRecord connection,
- final Bundle subscribeOptions, final Bundle notifyChildrenChangedOptions) {
+ final Bundle options) {
final Result<List<MediaBrowserCompat.MediaItem>> result
= new Result<List<MediaBrowserCompat.MediaItem>>(parentId) {
@Override
@@ -1485,10 +1373,9 @@
List<MediaBrowserCompat.MediaItem> filteredList =
(getFlags() & RESULT_FLAG_OPTION_NOT_HANDLED) != 0
- ? applyOptions(list, subscribeOptions) : list;
+ ? applyOptions(list, options) : list;
try {
- connection.callbacks.onLoadChildren(parentId, filteredList, subscribeOptions,
- notifyChildrenChangedOptions);
+ connection.callbacks.onLoadChildren(parentId, filteredList, options);
} catch (RemoteException ex) {
// The other side is in the process of crashing.
Log.w(TAG, "Calling onLoadChildren() failed for id=" + parentId
@@ -1498,10 +1385,10 @@
};
mCurConnection = connection;
- if (subscribeOptions == null) {
+ if (options == null) {
onLoadChildren(parentId, result);
} else {
- onLoadChildren(parentId, result, subscribeOptions);
+ onLoadChildren(parentId, result, options);
}
mCurConnection = null;
diff --git a/media/src/main/java/androidx/media/MediaConstants2.java b/media/src/main/java/androidx/media/MediaConstants2.java
index 1fec6db..68a9a19 100644
--- a/media/src/main/java/androidx/media/MediaConstants2.java
+++ b/media/src/main/java/androidx/media/MediaConstants2.java
@@ -33,10 +33,8 @@
"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_CHANGED =
+ static final String SESSION_EVENT_ON_BUFFERING_STATE_CHAGNED =
"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 =
@@ -47,10 +45,6 @@
"androidx.media.session.event.ON_PLAYLIST_METADATA_CHANGED";
static final String SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED =
"androidx.media.session.event.ON_ALLOWED_COMMANDS_CHANGED";
- static final String SESSION_EVENT_ON_CHILDREN_CHANGED =
- "androidx.media.session.event.ON_CHILDREN_CHANGED";
- static final String SESSION_EVENT_ON_SEARCH_RESULT_CHANGED =
- "androidx.media.session.event.ON_SEARCH_RESULT_CHANGED";
static final String SESSION_EVENT_SEND_CUSTOM_COMMAND =
"androidx.media.session.event.SEND_CUSTOM_COMMAND";
static final String SESSION_EVENT_SET_CUSTOM_LAYOUT =
@@ -95,9 +89,6 @@
static final String ARGUMENT_COMMAND_BUTTONS = "androidx.media.argument.COMMAND_BUTTONS";
static final String ARGUMENT_ROUTE_BUNDLE = "androidx.media.argument.ROUTE_BUNDLE";
static final String ARGUMENT_PLAYBACK_INFO = "androidx.media.argument.PLAYBACK_INFO";
- static final String ARGUMENT_ITEM_COUNT = "androidx.media.argument.ITEM_COUNT";
- static final String ARGUMENT_PAGE = "androidx.media.argument.PAGE";
- static final String ARGUMENT_PAGE_SIZE = "androidx.media.argument.PAGE_SIZE";
static final String ARGUMENT_ICONTROLLER_CALLBACK =
"androidx.media.argument.ICONTROLLER_CALLBACK";
diff --git a/media/src/main/java/androidx/media/MediaController2.java b/media/src/main/java/androidx/media/MediaController2.java
index 5d81cc2..1da552d 100644
--- a/media/src/main/java/androidx/media/MediaController2.java
+++ b/media/src/main/java/androidx/media/MediaController2.java
@@ -16,7 +16,93 @@
package androidx.media;
+import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DURATION;
+
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+import static androidx.media.MediaConstants2.ARGUMENT_ALLOWED_COMMANDS;
+import static androidx.media.MediaConstants2.ARGUMENT_ARGUMENTS;
+import static androidx.media.MediaConstants2.ARGUMENT_BUFFERING_STATE;
+import static androidx.media.MediaConstants2.ARGUMENT_COMMAND_BUTTONS;
+import static androidx.media.MediaConstants2.ARGUMENT_COMMAND_CODE;
+import static androidx.media.MediaConstants2.ARGUMENT_CUSTOM_COMMAND;
+import static androidx.media.MediaConstants2.ARGUMENT_ERROR_CODE;
+import static androidx.media.MediaConstants2.ARGUMENT_EXTRAS;
+import static androidx.media.MediaConstants2.ARGUMENT_ICONTROLLER_CALLBACK;
+import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ID;
+import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ITEM;
+import static androidx.media.MediaConstants2.ARGUMENT_PACKAGE_NAME;
+import static androidx.media.MediaConstants2.ARGUMENT_PID;
+import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_INFO;
+import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_SPEED;
+import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_STATE_COMPAT;
+import static androidx.media.MediaConstants2.ARGUMENT_PLAYER_STATE;
+import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST;
+import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST_INDEX;
+import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST_METADATA;
+import static androidx.media.MediaConstants2.ARGUMENT_QUERY;
+import static androidx.media.MediaConstants2.ARGUMENT_RATING;
+import static androidx.media.MediaConstants2.ARGUMENT_REPEAT_MODE;
+import static androidx.media.MediaConstants2.ARGUMENT_RESULT_RECEIVER;
+import static androidx.media.MediaConstants2.ARGUMENT_ROUTE_BUNDLE;
+import static androidx.media.MediaConstants2.ARGUMENT_SEEK_POSITION;
+import static androidx.media.MediaConstants2.ARGUMENT_SHUFFLE_MODE;
+import static androidx.media.MediaConstants2.ARGUMENT_UID;
+import static androidx.media.MediaConstants2.ARGUMENT_URI;
+import static androidx.media.MediaConstants2.ARGUMENT_VOLUME;
+import static androidx.media.MediaConstants2.ARGUMENT_VOLUME_DIRECTION;
+import static androidx.media.MediaConstants2.ARGUMENT_VOLUME_FLAGS;
+import static androidx.media.MediaConstants2.CONNECT_RESULT_CONNECTED;
+import static androidx.media.MediaConstants2.CONNECT_RESULT_DISCONNECTED;
+import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_BY_COMMAND_CODE;
+import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_BY_CUSTOM_COMMAND;
+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_CURRENT_MEDIA_ITEM_CHANGED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ERROR;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYBACK_SPEED_CHANGED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYER_STATE_CHANGED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYLIST_CHANGED;
+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_SHUFFLE_MODE_CHANGED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_SEND_CUSTOM_COMMAND;
+import static androidx.media.MediaConstants2.SESSION_EVENT_SET_CUSTOM_LAYOUT;
+import static androidx.media.MediaPlayerBase.BUFFERING_STATE_UNKNOWN;
+import static androidx.media.MediaPlayerBase.UNKNOWN_TIME;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_RESET;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_SEEK_TO;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_SET_SPEED;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_ADD_ITEM;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_TO_NEXT_ITEM;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM;
+import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_TO_PREV_ITEM;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_FAST_FORWARD;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_SEARCH;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_URI;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_URI;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_REWIND;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_SELECT_ROUTE;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_SET_RATING;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_SUBSCRIBE_ROUTES_INFO;
+import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_UNSUBSCRIBE_ROUTES_INFO;
+import static androidx.media.SessionCommand2.COMMAND_CODE_VOLUME_ADJUST_VOLUME;
+import static androidx.media.SessionCommand2.COMMAND_CODE_VOLUME_SET_VOLUME;
import android.annotation.TargetApi;
import android.app.PendingIntent;
@@ -25,14 +111,25 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.os.SystemClock;
import android.support.v4.media.MediaBrowserCompat;
+import android.support.v4.media.MediaMetadataCompat;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
+import android.util.Log;
+import androidx.annotation.GuardedBy;
import androidx.annotation.IntDef;
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;
@@ -45,9 +142,8 @@
import java.util.concurrent.Executor;
/**
- * Allows an app to interact with an active {@link MediaSession2} or a
- * {@link MediaSessionService2} in any status. Media buttons and other commands can be sent to
- * the session.
+ * Allows an app to interact with an active {@link MediaSession2} in any status. Media buttons and
+ * other commands can be sent to the session.
* <p>
* When you're done, use {@link #close()} to clean up resources. This also helps session service
* to be destroyed when there's no controller associated with it.
@@ -55,16 +151,9 @@
* When controlling {@link MediaSession2}, the controller will be available immediately after
* the creation.
* <p>
- * When controlling {@link MediaSessionService2}, the {@link MediaController2} would be
- * available only if the session service allows this controller by
- * {@link MediaSession2.SessionCallback#onConnect(MediaSession2, ControllerInfo)} for the service.
- * Wait {@link ControllerCallback#onConnected(MediaController2, SessionCommandGroup2)} or
- * {@link ControllerCallback#onDisconnected(MediaController2)} for the result.
- * <p>
* MediaController2 objects are thread-safe.
* <p>
* @see MediaSession2
- * @see MediaSessionService2
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public class MediaController2 implements AutoCloseable {
@@ -87,657 +176,6 @@
@Retention(RetentionPolicy.SOURCE)
public @interface VolumeFlags {}
- private final SupportLibraryImpl mImpl;
- // For testing.
- Long mTimeDiff;
-
- /**
- * Create a {@link MediaController2} from the {@link SessionToken2}.
- * This connects to the session and may wake up the service if it's not available.
- *
- * @param context Context
- * @param token token to connect to
- * @param executor executor to run callbacks on.
- * @param callback controller callback to receive changes in
- */
- public MediaController2(@NonNull Context context, @NonNull SessionToken2 token,
- @NonNull Executor executor, @NonNull ControllerCallback callback) {
- mImpl = new MediaController2ImplBase(context, token, executor, callback);
- mImpl.setInstance(this);
- }
-
- /**
- * Release this object, and disconnect from the session. After this, callbacks wouldn't be
- * received.
- */
- @Override
- public void close() {
- try {
- mImpl.close();
- } catch (Exception e) {
- // Should not be here.
- }
- }
-
- /**
- * @return token
- */
- public @NonNull SessionToken2 getSessionToken() {
- return mImpl.getSessionToken();
- }
-
- /**
- * Returns whether this class is connected to active {@link MediaSession2} or not.
- */
- public boolean isConnected() {
- return mImpl.isConnected();
- }
-
- /**
- * Requests that the player starts or resumes playback.
- */
- public void play() {
- mImpl.play();
- }
-
- /**
- * Requests that the player pauses playback.
- */
- public void pause() {
- mImpl.pause();
- }
-
- /**
- * Requests that the player be reset to its uninitialized state.
- */
- public void reset() {
- mImpl.reset();
- }
-
- /**
- * Request that the player prepare its playback. In other words, other sessions can continue
- * to play during the preparation of this session. This method can be used to speed up the
- * start of the playback. Once the preparation is done, the session will change its playback
- * state to {@link MediaPlayerInterface#PLAYER_STATE_PAUSED}. Afterwards, {@link #play} can be
- * called to start playback.
- */
- public void prepare() {
- mImpl.prepare();
- }
-
- /**
- * Start fast forwarding. If playback is already fast forwarding this
- * may increase the rate.
- */
- public void fastForward() {
- mImpl.fastForward();
- }
-
- /**
- * Start rewinding. If playback is already rewinding this may increase
- * the rate.
- */
- public void rewind() {
- mImpl.rewind();
- }
-
- /**
- * Move to a new location in the media stream.
- *
- * @param pos Position to move to, in milliseconds.
- */
- public void seekTo(long pos) {
- mImpl.seekTo(pos);
- }
-
- /**
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- public void skipForward() {
- // To match with KEYCODE_MEDIA_SKIP_FORWARD
- mImpl.skipForward();
- }
-
- /**
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- public void skipBackward() {
- // To match with KEYCODE_MEDIA_SKIP_BACKWARD
- mImpl.skipBackward();
- }
-
- /**
- * Request that the player start playback for a specific media id.
- *
- * @param mediaId The id of the requested media.
- * @param extras Optional extras that can include extra information about the media item
- * to be played.
- */
- public void playFromMediaId(@NonNull String mediaId, @Nullable Bundle extras) {
- mImpl.playFromMediaId(mediaId, extras);
- }
-
- /**
- * Request that the player start playback for a specific search query.
- *
- * @param query The search query. Should not be an empty string.
- * @param extras Optional extras that can include extra information about the query.
- */
- public void playFromSearch(@NonNull String query, @Nullable Bundle extras) {
- mImpl.playFromSearch(query, extras);
- }
-
- /**
- * Request that the player start playback for a specific {@link Uri}.
- *
- * @param uri The URI of the requested media.
- * @param extras Optional extras that can include extra information about the media item
- * to be played.
- */
- public void playFromUri(@NonNull Uri uri, @Nullable Bundle extras) {
- mImpl.playFromUri(uri, extras);
- }
-
- /**
- * Request that the player prepare playback for a specific media id. In other words, other
- * sessions can continue to play during the preparation of this session. This method can be
- * used to speed up the start of the playback. Once the preparation is done, the session
- * will change its playback state to {@link MediaPlayerInterface#PLAYER_STATE_PAUSED}.
- * Afterwards, {@link #play} can be called to start playback. If the preparation is not needed,
- * {@link #playFromMediaId} can be directly called without this method.
- *
- * @param mediaId The id of the requested media.
- * @param extras Optional extras that can include extra information about the media item
- * to be prepared.
- */
- public void prepareFromMediaId(@NonNull String mediaId, @Nullable Bundle extras) {
- mImpl.prepareFromMediaId(mediaId, extras);
- }
-
- /**
- * Request that the player prepare playback for a specific search query.
- * In other words, other sessions can continue to play during the preparation of this session.
- * This method can be used to speed up the start of the playback.
- * Once the preparation is done, the session will change its playback state to
- * {@link MediaPlayerInterface#PLAYER_STATE_PAUSED}. Afterwards,
- * {@link #play} can be called to start playback. If the preparation is not needed,
- * {@link #playFromSearch} can be directly called without this method.
- *
- * @param query The search query. Should not be an empty string.
- * @param extras Optional extras that can include extra information about the query.
- */
- public void prepareFromSearch(@NonNull String query, @Nullable Bundle extras) {
- mImpl.prepareFromSearch(query, extras);
- }
-
- /**
- * Request that the player prepare playback for a specific {@link Uri}. In other words,
- * other sessions can continue to play during the preparation of this session. This method
- * can be used to speed up the start of the playback. Once the preparation is done, the
- * session will change its playback state to {@link MediaPlayerInterface#PLAYER_STATE_PAUSED}.
- * Afterwards, {@link #play} can be called to start playback. If the preparation is not needed,
- * {@link #playFromUri} can be directly called without this method.
- *
- * @param uri The URI of the requested media.
- * @param extras Optional extras that can include extra information about the media item
- * to be prepared.
- */
- public void prepareFromUri(@NonNull Uri uri, @Nullable Bundle extras) {
- mImpl.prepareFromUri(uri, extras);
- }
-
- /**
- * Set the volume of the output this session is playing on. The command will be ignored if it
- * does not support {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}.
- * <p>
- * If the session is local playback, this changes the device's volume with the stream that
- * session's player is using. Flags will be specified for the {@link AudioManager}.
- * <p>
- * If the session is remote player (i.e. session has set volume provider), its volume provider
- * will receive this request instead.
- *
- * @see #getPlaybackInfo()
- * @param value The value to set it to, between 0 and the reported max.
- * @param flags flags from {@link AudioManager} to include with the volume request for local
- * playback
- */
- public void setVolumeTo(int value, @VolumeFlags int flags) {
- mImpl.setVolumeTo(value, flags);
- }
-
- /**
- * Adjust the volume of the output this session is playing on. The direction
- * must be one of {@link AudioManager#ADJUST_LOWER},
- * {@link AudioManager#ADJUST_RAISE}, or {@link AudioManager#ADJUST_SAME}.
- * <p>
- * The command will be ignored if the session does not support
- * {@link VolumeProviderCompat#VOLUME_CONTROL_RELATIVE} or
- * {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}.
- * <p>
- * If the session is local playback, this changes the device's volume with the stream that
- * session's player is using. Flags will be specified for the {@link AudioManager}.
- * <p>
- * If the session is remote player (i.e. session has set volume provider), its volume provider
- * will receive this request instead.
- *
- * @see #getPlaybackInfo()
- * @param direction The direction to adjust the volume in.
- * @param flags flags from {@link AudioManager} to include with the volume request for local
- * playback
- */
- public void adjustVolume(@VolumeDirection int direction, @VolumeFlags int flags) {
- mImpl.adjustVolume(direction, flags);
- }
-
- /**
- * Get an intent for launching UI associated with this session if one exists.
- *
- * @return A {@link PendingIntent} to launch UI or null.
- */
- public @Nullable PendingIntent getSessionActivity() {
- return mImpl.getSessionActivity();
- }
-
- /**
- * Get the lastly cached player state from
- * {@link ControllerCallback#onPlayerStateChanged(MediaController2, int)}.
- *
- * @return player state
- */
- public int getPlayerState() {
- return mImpl.getPlayerState();
- }
-
- /**
- * Gets the duration of the current media item, or {@link MediaPlayerInterface#UNKNOWN_TIME} if
- * unknown.
- * @return the duration in ms, or {@link MediaPlayerInterface#UNKNOWN_TIME}.
- */
- public long getDuration() {
- return mImpl.getDuration();
- }
-
- /**
- * Gets the current playback position.
- * <p>
- * This returns the calculated value of the position, based on the difference between the
- * update time and current time.
- *
- * @return position
- */
- public long getCurrentPosition() {
- return mImpl.getCurrentPosition();
- }
-
- /**
- * Get the lastly cached playback speed from
- * {@link ControllerCallback#onPlaybackSpeedChanged(MediaController2, float)}.
- *
- * @return speed the lastly cached playback speed, or 0.0f if unknown.
- */
- public float getPlaybackSpeed() {
- return mImpl.getPlaybackSpeed();
- }
-
- /**
- * Set the playback speed.
- */
- public void setPlaybackSpeed(float speed) {
- mImpl.setPlaybackSpeed(speed);
- }
-
- /**
- * Gets the current buffering state of the player.
- * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
- * buffered.
- * @return the buffering state.
- */
- public @MediaPlayerInterface.BuffState int getBufferingState() {
- return mImpl.getBufferingState();
- }
-
- /**
- * Gets the lastly cached buffered position from the session when
- * {@link ControllerCallback#onBufferingStateChanged(MediaController2, MediaItem2, int)} is
- * called.
- *
- * @return buffering position in millis, or {@link MediaPlayerInterface#UNKNOWN_TIME} if
- * unknown.
- */
- public long getBufferedPosition() {
- return mImpl.getBufferedPosition();
- }
-
- /**
- * Get the current playback info for this session.
- *
- * @return The current playback info or null.
- */
- public @Nullable PlaybackInfo getPlaybackInfo() {
- return mImpl.getPlaybackInfo();
- }
-
- /**
- * Rate the media. This will cause the rating to be set for the current user.
- * The rating style must follow the user rating style from the session.
- * You can get the rating style from the session through the
- * {@link MediaMetadata2#getRating(String)} with the key
- * {@link MediaMetadata2#METADATA_KEY_USER_RATING}.
- * <p>
- * If the user rating was {@code null}, the media item does not accept setting user rating.
- *
- * @param mediaId The id of the media
- * @param rating The rating to set
- */
- public void setRating(@NonNull String mediaId, @NonNull Rating2 rating) {
- mImpl.setRating(mediaId, rating);
- }
-
- /**
- * Send custom command to the session
- *
- * @param command custom command
- * @param args optional argument
- * @param cb optional result receiver
- */
- public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args,
- @Nullable ResultReceiver cb) {
- mImpl.sendCustomCommand(command, args, cb);
- }
-
- /**
- * Returns the cached playlist from {@link ControllerCallback#onPlaylistChanged}.
- * <p>
- * This list may differ with the list that was specified with
- * {@link #setPlaylist(List, MediaMetadata2)} depending on the {@link MediaPlaylistAgent}
- * implementation. Use media items returned here for other playlist agent APIs such as
- * {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)}.
- *
- * @return playlist. Can be {@code null} if the playlist hasn't set nor controller doesn't have
- * enough permission.
- * @see SessionCommand2#COMMAND_CODE_PLAYLIST_GET_LIST
- */
- public @Nullable List<MediaItem2> getPlaylist() {
- return mImpl.getPlaylist();
- }
-
- /**
- * Sets the playlist.
- * <p>
- * Even when the playlist is successfully set, use the playlist returned from
- * {@link #getPlaylist()} for playlist APIs such as {@link #skipToPlaylistItem(MediaItem2)}.
- * Otherwise the session in the remote process can't distinguish between media items.
- *
- * @param list playlist
- * @param metadata metadata of the playlist
- * @see #getPlaylist()
- * @see ControllerCallback#onPlaylistChanged
- */
- public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
- mImpl.setPlaylist(list, metadata);
- }
-
- /**
- * Updates the playlist metadata
- *
- * @param metadata metadata of the playlist
- */
- public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) {
- mImpl.updatePlaylistMetadata(metadata);
- }
-
- /**
- * Gets the lastly cached playlist playlist metadata either from
- * {@link ControllerCallback#onPlaylistMetadataChanged or
- * {@link ControllerCallback#onPlaylistChanged}.
- *
- * @return metadata metadata of the playlist, or null if none is set
- */
- public @Nullable MediaMetadata2 getPlaylistMetadata() {
- return mImpl.getPlaylistMetadata();
- }
-
- /**
- * Adds the media item to the playlist at position index. Index equals or greater than
- * the current playlist size (e.g. {@link Integer#MAX_VALUE}) will add the item at the end of
- * the playlist.
- * <p>
- * This will not change the currently playing media item.
- * If index is less than or equal to the current index of the playlist,
- * the current index of the playlist will be incremented correspondingly.
- *
- * @param index the index you want to add
- * @param item the media item you want to add
- */
- public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
- mImpl.addPlaylistItem(index, item);
- }
-
- /**
- * Removes the media item at index in the playlist.
- *<p>
- * If the item is the currently playing item of the playlist, current playback
- * will be stopped and playback moves to next source in the list.
- *
- * @param item the media item you want to add
- */
- public void removePlaylistItem(@NonNull MediaItem2 item) {
- mImpl.removePlaylistItem(item);
- }
-
- /**
- * Replace the media item at index in the playlist. This can be also used to update metadata of
- * an item.
- *
- * @param index the index of the item to replace
- * @param item the new item
- */
- public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
- mImpl.replacePlaylistItem(index, item);
- }
-
- /**
- * Get the lastly cached current item from
- * {@link ControllerCallback#onCurrentMediaItemChanged(MediaController2, MediaItem2)}.
- *
- * @return the currently playing item, or null if unknown.
- */
- public MediaItem2 getCurrentMediaItem() {
- return mImpl.getCurrentMediaItem();
- }
-
- /**
- * Skips to the previous item in the playlist.
- * <p>
- * This calls {@link MediaPlaylistAgent#skipToPreviousItem()}.
- */
- public void skipToPreviousItem() {
- mImpl.skipToPreviousItem();
- }
-
- /**
- * Skips to the next item in the playlist.
- * <p>
- * This calls {@link MediaPlaylistAgent#skipToNextItem()}.
- */
- public void skipToNextItem() {
- mImpl.skipToNextItem();
- }
-
- /**
- * Skips to the item in the playlist.
- * <p>
- * This calls {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)}.
- *
- * @param item The item in the playlist you want to play
- */
- public void skipToPlaylistItem(@NonNull MediaItem2 item) {
- mImpl.skipToPlaylistItem(item);
- }
-
- /**
- * Gets the cached repeat mode from the {@link ControllerCallback#onRepeatModeChanged}.
- *
- * @return repeat mode
- * @see MediaPlaylistAgent#REPEAT_MODE_NONE
- * @see MediaPlaylistAgent#REPEAT_MODE_ONE
- * @see MediaPlaylistAgent#REPEAT_MODE_ALL
- * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
- */
- public @RepeatMode int getRepeatMode() {
- return mImpl.getRepeatMode();
- }
-
- /**
- * Sets the repeat mode.
- *
- * @param repeatMode repeat mode
- * @see MediaPlaylistAgent#REPEAT_MODE_NONE
- * @see MediaPlaylistAgent#REPEAT_MODE_ONE
- * @see MediaPlaylistAgent#REPEAT_MODE_ALL
- * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
- */
- public void setRepeatMode(@RepeatMode int repeatMode) {
- mImpl.setRepeatMode(repeatMode);
- }
-
- /**
- * Gets the cached shuffle mode from the {@link ControllerCallback#onShuffleModeChanged}.
- *
- * @return The shuffle mode
- * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
- * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
- * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
- */
- public @ShuffleMode int getShuffleMode() {
- return mImpl.getShuffleMode();
- }
-
- /**
- * Sets the shuffle mode.
- *
- * @param shuffleMode The shuffle mode
- * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
- * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
- * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
- */
- public void setShuffleMode(@ShuffleMode int shuffleMode) {
- mImpl.setShuffleMode(shuffleMode);
- }
-
- /**
- * Queries for information about the routes currently known.
- */
- public void subscribeRoutesInfo() {
- mImpl.subscribeRoutesInfo();
- }
-
- /**
- * Unsubscribes for changes to the routes.
- * <p>
- * The {@link ControllerCallback#onRoutesInfoChanged callback} will no longer be invoked for
- * the routes once this method returns.
- * </p>
- */
- public void unsubscribeRoutesInfo() {
- mImpl.unsubscribeRoutesInfo();
- }
-
- /**
- * Selects the specified route.
- *
- * @param route The route to select.
- */
- public void selectRoute(@NonNull Bundle route) {
- mImpl.selectRoute(route);
- }
-
- @NonNull Context getContext() {
- return mImpl.getContext();
- }
-
- @NonNull ControllerCallback getCallback() {
- return mImpl.getCallback();
- }
-
- @NonNull Executor getCallbackExecutor() {
- return mImpl.getCallbackExecutor();
- }
-
- @Nullable MediaBrowserCompat getBrowserCompat() {
- return mImpl.getBrowserCompat();
- }
-
- /**
- * Sets the time diff forcefully when calculating current position.
- * @param timeDiff {@code null} for reset.
- */
- @VisibleForTesting
- void setTimeDiff(Long timeDiff) {
- mTimeDiff = timeDiff;
- }
-
- interface SupportLibraryImpl extends AutoCloseable {
- void setInstance(MediaController2 controller);
- SessionToken2 getSessionToken();
- boolean isConnected();
- void play();
- void pause();
- void reset();
- void prepare();
- void fastForward();
- void rewind();
- void seekTo(long pos);
- void skipForward();
- void skipBackward();
- void playFromMediaId(@NonNull String mediaId, @Nullable Bundle extras);
- void playFromSearch(@NonNull String query, @Nullable Bundle extras);
- void playFromUri(@NonNull Uri uri, @Nullable Bundle extras);
- void prepareFromMediaId(@NonNull String mediaId, @Nullable Bundle extras);
- void prepareFromSearch(@NonNull String query, @Nullable Bundle extras);
- void prepareFromUri(@NonNull Uri uri, @Nullable Bundle extras);
- void setVolumeTo(int value, @VolumeFlags int flags);
- void adjustVolume(@VolumeDirection int direction, @VolumeFlags int flags);
- @Nullable PendingIntent getSessionActivity();
- int getPlayerState();
- long getDuration();
- long getCurrentPosition();
- float getPlaybackSpeed();
- void setPlaybackSpeed(float speed);
- @MediaPlayerInterface.BuffState int getBufferingState();
- long getBufferedPosition();
- @Nullable PlaybackInfo getPlaybackInfo();
- void setRating(@NonNull String mediaId, @NonNull Rating2 rating);
- void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args,
- @Nullable ResultReceiver cb);
- @Nullable List<MediaItem2> getPlaylist();
- void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata);
- void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata);
- @Nullable MediaMetadata2 getPlaylistMetadata();
- void addPlaylistItem(int index, @NonNull MediaItem2 item);
- void removePlaylistItem(@NonNull MediaItem2 item);
- void replacePlaylistItem(int index, @NonNull MediaItem2 item);
- MediaItem2 getCurrentMediaItem();
- void skipToPreviousItem();
- void skipToNextItem();
- void skipToPlaylistItem(@NonNull MediaItem2 item);
- @RepeatMode int getRepeatMode();
- void setRepeatMode(@RepeatMode int repeatMode);
- @ShuffleMode int getShuffleMode();
- void setShuffleMode(@ShuffleMode int shuffleMode);
- void subscribeRoutesInfo();
- void unsubscribeRoutesInfo();
- void selectRoute(@NonNull Bundle route);
-
- // For MediaBrowser2
- @NonNull Context getContext();
- @NonNull ControllerCallback getCallback();
- @NonNull Executor getCallbackExecutor();
- @Nullable MediaBrowserCompat getBrowserCompat();
- }
-
/**
* Interface for listening to change in activeness of the {@link MediaSession2}. It's
* active if and only if it has set a player.
@@ -835,7 +273,7 @@
* @param state the new buffering state.
*/
public void onBufferingStateChanged(@NonNull MediaController2 controller,
- @NonNull MediaItem2 item, @MediaPlayerInterface.BuffState int state) { }
+ @NonNull MediaItem2 item, @MediaPlayerBase.BuffState int state) { }
/**
* Called to indicate that seeking is completed.
@@ -866,7 +304,7 @@
* @see #onBufferingStateChanged(MediaController2, MediaItem2, int)
*/
public void onCurrentMediaItemChanged(@NonNull MediaController2 controller,
- @Nullable MediaItem2 item) { }
+ @NonNull MediaItem2 item) { }
/**
* Called when a playlist is changed.
@@ -1023,7 +461,8 @@
bundle.putInt(KEY_MAX_VOLUME, mMaxVolume);
bundle.putInt(KEY_CURRENT_VOLUME, mCurrentVolume);
if (mAudioAttrsCompat != null) {
- bundle.putBundle(KEY_AUDIO_ATTRIBUTES, mAudioAttrsCompat.toBundle());
+ bundle.putParcelable(KEY_AUDIO_ATTRIBUTES,
+ MediaUtils2.toAudioAttributesBundle(mAudioAttrsCompat));
}
return bundle;
}
@@ -1041,10 +480,1291 @@
final int volumeControl = bundle.getInt(KEY_CONTROL_TYPE);
final int maxVolume = bundle.getInt(KEY_MAX_VOLUME);
final int currentVolume = bundle.getInt(KEY_CURRENT_VOLUME);
- final AudioAttributesCompat attrs = AudioAttributesCompat.fromBundle(
+ final AudioAttributesCompat attrs = MediaUtils2.fromAudioAttributesBundle(
bundle.getBundle(KEY_AUDIO_ATTRIBUTES));
return createPlaybackInfo(volumeType, attrs, volumeControl, maxVolume,
currentVolume);
}
}
+
+ private final class ControllerCompatCallback extends MediaControllerCompat.Callback {
+ @Override
+ public void onSessionReady() {
+ sendCommand(CONTROLLER_COMMAND_CONNECT, new ResultReceiver(mHandler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (!mHandlerThread.isAlive()) {
+ return;
+ }
+ switch (resultCode) {
+ case CONNECT_RESULT_CONNECTED:
+ onConnectedNotLocked(resultData);
+ break;
+ case CONNECT_RESULT_DISCONNECTED:
+ mCallback.onDisconnected(MediaController2.this);
+ close();
+ break;
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onSessionDestroyed() {
+ close();
+ }
+
+ @Override
+ public void onPlaybackStateChanged(PlaybackStateCompat state) {
+ synchronized (mLock) {
+ mPlaybackStateCompat = state;
+ }
+ }
+
+ @Override
+ public void onMetadataChanged(MediaMetadataCompat metadata) {
+ synchronized (mLock) {
+ mMediaMetadataCompat = metadata;
+ }
+ }
+
+ @Override
+ public void onSessionEvent(String event, Bundle extras) {
+ switch (event) {
+ case SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED: {
+ SessionCommandGroup2 allowedCommands = SessionCommandGroup2.fromBundle(
+ extras.getBundle(ARGUMENT_ALLOWED_COMMANDS));
+ synchronized (mLock) {
+ mAllowedCommands = allowedCommands;
+ }
+ mCallback.onAllowedCommandsChanged(MediaController2.this, allowedCommands);
+ break;
+ }
+ case SESSION_EVENT_ON_PLAYER_STATE_CHANGED: {
+ int playerState = extras.getInt(ARGUMENT_PLAYER_STATE);
+ synchronized (mLock) {
+ mPlayerState = playerState;
+ }
+ mCallback.onPlayerStateChanged(MediaController2.this, playerState);
+ break;
+ }
+ case SESSION_EVENT_ON_CURRENT_MEDIA_ITEM_CHANGED: {
+ MediaItem2 item = MediaItem2.fromBundle(extras.getBundle(ARGUMENT_MEDIA_ITEM));
+ if (item == null) {
+ return;
+ }
+ synchronized (mLock) {
+ mCurrentMediaItem = item;
+ }
+ mCallback.onCurrentMediaItemChanged(MediaController2.this, item);
+ break;
+ }
+ case SESSION_EVENT_ON_ERROR: {
+ int errorCode = extras.getInt(ARGUMENT_ERROR_CODE);
+ Bundle errorExtras = extras.getBundle(ARGUMENT_EXTRAS);
+ mCallback.onError(MediaController2.this, errorCode, errorExtras);
+ break;
+ }
+ case SESSION_EVENT_ON_ROUTES_INFO_CHANGED: {
+ List<Bundle> routes = MediaUtils2.toBundleList(
+ extras.getParcelableArray(ARGUMENT_ROUTE_BUNDLE));
+ mCallback.onRoutesInfoChanged(MediaController2.this, routes);
+ break;
+ }
+ case SESSION_EVENT_ON_PLAYLIST_CHANGED: {
+ MediaMetadata2 playlistMetadata = MediaMetadata2.fromBundle(
+ extras.getBundle(ARGUMENT_PLAYLIST_METADATA));
+ List<MediaItem2> playlist = MediaUtils2.fromMediaItem2ParcelableArray(
+ extras.getParcelableArray(ARGUMENT_PLAYLIST));
+ synchronized (mLock) {
+ mPlaylist = playlist;
+ mPlaylistMetadata = playlistMetadata;
+ }
+ mCallback.onPlaylistChanged(MediaController2.this, playlist, playlistMetadata);
+ break;
+ }
+ case SESSION_EVENT_ON_PLAYLIST_METADATA_CHANGED: {
+ MediaMetadata2 playlistMetadata = MediaMetadata2.fromBundle(
+ extras.getBundle(ARGUMENT_PLAYLIST_METADATA));
+ synchronized (mLock) {
+ mPlaylistMetadata = playlistMetadata;
+ }
+ mCallback.onPlaylistMetadataChanged(MediaController2.this, playlistMetadata);
+ break;
+ }
+ case SESSION_EVENT_ON_REPEAT_MODE_CHANGED: {
+ int repeatMode = extras.getInt(ARGUMENT_REPEAT_MODE);
+ synchronized (mLock) {
+ mRepeatMode = repeatMode;
+ }
+ mCallback.onRepeatModeChanged(MediaController2.this, repeatMode);
+ break;
+ }
+ case SESSION_EVENT_ON_SHUFFLE_MODE_CHANGED: {
+ int shuffleMode = extras.getInt(ARGUMENT_SHUFFLE_MODE);
+ synchronized (mLock) {
+ mShuffleMode = shuffleMode;
+ }
+ mCallback.onShuffleModeChanged(MediaController2.this, shuffleMode);
+ break;
+ }
+ case SESSION_EVENT_SEND_CUSTOM_COMMAND: {
+ Bundle commandBundle = extras.getBundle(ARGUMENT_CUSTOM_COMMAND);
+ if (commandBundle == null) {
+ return;
+ }
+ SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
+ Bundle args = extras.getBundle(ARGUMENT_ARGUMENTS);
+ ResultReceiver receiver = extras.getParcelable(ARGUMENT_RESULT_RECEIVER);
+ mCallback.onCustomCommand(MediaController2.this, command, args, receiver);
+ break;
+ }
+ case SESSION_EVENT_SET_CUSTOM_LAYOUT: {
+ List<CommandButton> layout = MediaUtils2.fromCommandButtonParcelableArray(
+ extras.getParcelableArray(ARGUMENT_COMMAND_BUTTONS));
+ if (layout == null) {
+ return;
+ }
+ mCallback.onCustomLayoutChanged(MediaController2.this, layout);
+ break;
+ }
+ case SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED: {
+ PlaybackInfo info = PlaybackInfo.fromBundle(
+ extras.getBundle(ARGUMENT_PLAYBACK_INFO));
+ if (info == null) {
+ return;
+ }
+ synchronized (mLock) {
+ mPlaybackInfo = info;
+ }
+ mCallback.onPlaybackInfoChanged(MediaController2.this, info);
+ break;
+ }
+ case SESSION_EVENT_ON_PLAYBACK_SPEED_CHANGED: {
+ PlaybackStateCompat state =
+ extras.getParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT);
+ if (state == null) {
+ return;
+ }
+ synchronized (mLock) {
+ mPlaybackStateCompat = state;
+ }
+ mCallback.onPlaybackSpeedChanged(
+ MediaController2.this, state.getPlaybackSpeed());
+ break;
+ }
+ case SESSION_EVENT_ON_BUFFERING_STATE_CHAGNED: {
+ MediaItem2 item = MediaItem2.fromBundle(extras.getBundle(ARGUMENT_MEDIA_ITEM));
+ int bufferingState = extras.getInt(ARGUMENT_BUFFERING_STATE);
+ if (item == null) {
+ return;
+ }
+ synchronized (mLock) {
+ mBufferingState = bufferingState;
+ }
+ mCallback.onBufferingStateChanged(MediaController2.this, item, bufferingState);
+ break;
+ }
+ }
+ }
+ }
+
+ private static final String TAG = "MediaController2";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ // Note: Using {@code null} doesn't helpful here because MediaBrowserServiceCompat always wraps
+ // the rootHints so it becomes non-null.
+ static final Bundle sDefaultRootExtras = new Bundle();
+ static {
+ sDefaultRootExtras.putBoolean(MediaConstants2.ROOT_EXTRA_DEFAULT, true);
+ }
+
+ private final Context mContext;
+ private final Object mLock = new Object();
+
+ private final SessionToken2 mToken;
+ private final ControllerCallback mCallback;
+ private final Executor mCallbackExecutor;
+ private final IBinder.DeathRecipient mDeathRecipient;
+
+ private final HandlerThread mHandlerThread;
+ private final Handler mHandler;
+
+ @GuardedBy("mLock")
+ private MediaBrowserCompat mBrowserCompat;
+ @GuardedBy("mLock")
+ private boolean mIsReleased;
+ @GuardedBy("mLock")
+ private List<MediaItem2> mPlaylist;
+ @GuardedBy("mLock")
+ private MediaMetadata2 mPlaylistMetadata;
+ @GuardedBy("mLock")
+ private @RepeatMode int mRepeatMode;
+ @GuardedBy("mLock")
+ private @ShuffleMode int mShuffleMode;
+ @GuardedBy("mLock")
+ private int mPlayerState;
+ @GuardedBy("mLock")
+ private MediaItem2 mCurrentMediaItem;
+ @GuardedBy("mLock")
+ private int mBufferingState;
+ @GuardedBy("mLock")
+ private PlaybackInfo mPlaybackInfo;
+ @GuardedBy("mLock")
+ private SessionCommandGroup2 mAllowedCommands;
+
+ // Media 1.0 variables
+ @GuardedBy("mLock")
+ private MediaControllerCompat mControllerCompat;
+ @GuardedBy("mLock")
+ private ControllerCompatCallback mControllerCompatCallback;
+ @GuardedBy("mLock")
+ private PlaybackStateCompat mPlaybackStateCompat;
+ @GuardedBy("mLock")
+ private MediaMetadataCompat mMediaMetadataCompat;
+
+ // Assignment should be used with the lock hold, but should be used without a lock to prevent
+ // potential deadlock.
+ @GuardedBy("mLock")
+ private volatile boolean mConnected;
+
+ /**
+ * Create a {@link MediaController2} from the {@link SessionToken2}.
+ * This connects to the session and may wake up the service if it's not available.
+ *
+ * @param context Context
+ * @param token token to connect to
+ * @param executor executor to run callbacks on.
+ * @param callback controller callback to receive changes in
+ */
+ public MediaController2(@NonNull Context context, @NonNull SessionToken2 token,
+ @NonNull Executor executor, @NonNull ControllerCallback callback) {
+ super();
+ if (context == null) {
+ throw new IllegalArgumentException("context shouldn't be null");
+ }
+ if (token == null) {
+ throw new IllegalArgumentException("token shouldn't be null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("callback shouldn't be null");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("executor shouldn't be null");
+ }
+ mContext = context;
+ mHandlerThread = new HandlerThread("MediaController2_Thread");
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ mToken = token;
+ mCallback = callback;
+ mCallbackExecutor = executor;
+ mDeathRecipient = new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ MediaController2.this.close();
+ }
+ };
+
+ initialize();
+ }
+
+ /**
+ * Release this object, and disconnect from the session. After this, callbacks wouldn't be
+ * received.
+ */
+ @Override
+ public void close() {
+ if (DEBUG) {
+ //Log.d(TAG, "release from " + mToken, new IllegalStateException());
+ }
+ synchronized (mLock) {
+ if (mIsReleased) {
+ // Prevent re-enterance from the ControllerCallback.onDisconnected()
+ return;
+ }
+ mHandler.removeCallbacksAndMessages(null);
+ mHandlerThread.quitSafely();
+
+ mIsReleased = true;
+
+ // Send command before the unregister callback to use mIControllerCallback in the
+ // callback.
+ sendCommand(CONTROLLER_COMMAND_DISCONNECT);
+ if (mControllerCompat != null) {
+ mControllerCompat.unregisterCallback(mControllerCompatCallback);
+ }
+ if (mBrowserCompat != null) {
+ mBrowserCompat.disconnect();
+ mBrowserCompat = null;
+ }
+ if (mControllerCompat != null) {
+ mControllerCompat.unregisterCallback(mControllerCompatCallback);
+ mControllerCompat = null;
+ }
+ mConnected = false;
+ }
+ mCallbackExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ mCallback.onDisconnected(MediaController2.this);
+ }
+ });
+ }
+
+ /**
+ * @return token
+ */
+ public @NonNull SessionToken2 getSessionToken() {
+ return mToken;
+ }
+
+ /**
+ * Returns whether this class is connected to active {@link MediaSession2} or not.
+ */
+ public boolean isConnected() {
+ synchronized (mLock) {
+ return mConnected;
+ }
+ }
+
+ /**
+ * Requests that the player starts or resumes playback.
+ */
+ public void play() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ sendCommand(COMMAND_CODE_PLAYBACK_PLAY);
+ }
+ }
+
+ /**
+ * Requests that the player pauses playback.
+ */
+ public void pause() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ sendCommand(COMMAND_CODE_PLAYBACK_PAUSE);
+ }
+ }
+
+ /**
+ * Requests that the player be reset to its uninitialized state.
+ */
+ public void reset() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ sendCommand(COMMAND_CODE_PLAYBACK_RESET);
+ }
+ }
+
+ /**
+ * Request that the player prepare its playback. In other words, other sessions can continue
+ * to play during the preparation of this session. This method can be used to speed up the
+ * start of the playback. Once the preparation is done, the session will change its playback
+ * state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards, {@link #play} can be called
+ * to start playback.
+ */
+ public void prepare() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ sendCommand(COMMAND_CODE_PLAYBACK_PREPARE);
+ }
+ }
+
+ /**
+ * Start fast forwarding. If playback is already fast forwarding this
+ * may increase the rate.
+ */
+ public void fastForward() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ sendCommand(COMMAND_CODE_SESSION_FAST_FORWARD);
+ }
+ }
+
+ /**
+ * Start rewinding. If playback is already rewinding this may increase
+ * the rate.
+ */
+ public void rewind() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ sendCommand(COMMAND_CODE_SESSION_REWIND);
+ }
+ }
+
+ /**
+ * Move to a new location in the media stream.
+ *
+ * @param pos Position to move to, in milliseconds.
+ */
+ public void seekTo(long pos) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putLong(ARGUMENT_SEEK_POSITION, pos);
+ sendCommand(COMMAND_CODE_PLAYBACK_SEEK_TO, args);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public void skipForward() {
+ // To match with KEYCODE_MEDIA_SKIP_FORWARD
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public void skipBackward() {
+ // To match with KEYCODE_MEDIA_SKIP_BACKWARD
+ }
+
+ /**
+ * Request that the player start playback for a specific media id.
+ *
+ * @param mediaId The id of the requested media.
+ * @param extras Optional extras that can include extra information about the media item
+ * to be played.
+ */
+ public void playFromMediaId(@NonNull String mediaId, @Nullable Bundle extras) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putString(ARGUMENT_MEDIA_ID, mediaId);
+ args.putBundle(ARGUMENT_EXTRAS, extras);
+ sendCommand(COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID, args);
+ }
+ }
+
+ /**
+ * Request that the player start playback for a specific search query.
+ *
+ * @param query The search query. Should not be an empty string.
+ * @param extras Optional extras that can include extra information about the query.
+ */
+ public void playFromSearch(@NonNull String query, @Nullable Bundle extras) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putString(ARGUMENT_QUERY, query);
+ args.putBundle(ARGUMENT_EXTRAS, extras);
+ sendCommand(COMMAND_CODE_SESSION_PLAY_FROM_SEARCH, args);
+ }
+ }
+
+ /**
+ * Request that the player start playback for a specific {@link Uri}.
+ *
+ * @param uri The URI of the requested media.
+ * @param extras Optional extras that can include extra information about the media item
+ * to be played.
+ */
+ public void playFromUri(@NonNull Uri uri, @Nullable Bundle extras) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putParcelable(ARGUMENT_URI, uri);
+ args.putBundle(ARGUMENT_EXTRAS, extras);
+ sendCommand(COMMAND_CODE_SESSION_PLAY_FROM_URI, args);
+ }
+ }
+
+ /**
+ * Request that the player prepare playback for a specific media id. In other words, other
+ * sessions can continue to play during the preparation of this session. This method can be
+ * used to speed up the start of the playback. Once the preparation is done, the session
+ * will change its playback state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards,
+ * {@link #play} can be called to start playback. If the preparation is not needed,
+ * {@link #playFromMediaId} can be directly called without this method.
+ *
+ * @param mediaId The id of the requested media.
+ * @param extras Optional extras that can include extra information about the media item
+ * to be prepared.
+ */
+ public void prepareFromMediaId(@NonNull String mediaId, @Nullable Bundle extras) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putString(ARGUMENT_MEDIA_ID, mediaId);
+ args.putBundle(ARGUMENT_EXTRAS, extras);
+ sendCommand(COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID, args);
+ }
+ }
+
+ /**
+ * Request that the player prepare playback for a specific search query.
+ * In other words, other sessions can continue to play during the preparation of this session.
+ * This method can be used to speed up the start of the playback.
+ * Once the preparation is done, the session will change its playback state to
+ * {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards,
+ * {@link #play} can be called to start playback. If the preparation is not needed,
+ * {@link #playFromSearch} can be directly called without this method.
+ *
+ * @param query The search query. Should not be an empty string.
+ * @param extras Optional extras that can include extra information about the query.
+ */
+ public void prepareFromSearch(@NonNull String query, @Nullable Bundle extras) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putString(ARGUMENT_QUERY, query);
+ args.putBundle(ARGUMENT_EXTRAS, extras);
+ sendCommand(COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH, args);
+ }
+ }
+
+ /**
+ * Request that the player prepare playback for a specific {@link Uri}. In other words,
+ * other sessions can continue to play during the preparation of this session. This method
+ * can be used to speed up the start of the playback. Once the preparation is done, the
+ * session will change its playback state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}.
+ * Afterwards, {@link #play} can be called to start playback. If the preparation is not needed,
+ * {@link #playFromUri} can be directly called without this method.
+ *
+ * @param uri The URI of the requested media.
+ * @param extras Optional extras that can include extra information about the media item
+ * to be prepared.
+ */
+ public void prepareFromUri(@NonNull Uri uri, @Nullable Bundle extras) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putParcelable(ARGUMENT_URI, uri);
+ args.putBundle(ARGUMENT_EXTRAS, extras);
+ sendCommand(COMMAND_CODE_SESSION_PREPARE_FROM_URI, args);
+ }
+ }
+
+ /**
+ * Set the volume of the output this session is playing on. The command will be ignored if it
+ * does not support {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}.
+ * <p>
+ * If the session is local playback, this changes the device's volume with the stream that
+ * session's player is using. Flags will be specified for the {@link AudioManager}.
+ * <p>
+ * If the session is remote player (i.e. session has set volume provider), its volume provider
+ * will receive this request instead.
+ *
+ * @see #getPlaybackInfo()
+ * @param value The value to set it to, between 0 and the reported max.
+ * @param flags flags from {@link AudioManager} to include with the volume request for local
+ * playback
+ */
+ public void setVolumeTo(int value, @VolumeFlags int flags) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putInt(ARGUMENT_VOLUME, value);
+ args.putInt(ARGUMENT_VOLUME_FLAGS, flags);
+ sendCommand(COMMAND_CODE_VOLUME_SET_VOLUME, args);
+ }
+ }
+
+ /**
+ * Adjust the volume of the output this session is playing on. The direction
+ * must be one of {@link AudioManager#ADJUST_LOWER},
+ * {@link AudioManager#ADJUST_RAISE}, or {@link AudioManager#ADJUST_SAME}.
+ * <p>
+ * The command will be ignored if the session does not support
+ * {@link VolumeProviderCompat#VOLUME_CONTROL_RELATIVE} or
+ * {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}.
+ * <p>
+ * If the session is local playback, this changes the device's volume with the stream that
+ * session's player is using. Flags will be specified for the {@link AudioManager}.
+ * <p>
+ * If the session is remote player (i.e. session has set volume provider), its volume provider
+ * will receive this request instead.
+ *
+ * @see #getPlaybackInfo()
+ * @param direction The direction to adjust the volume in.
+ * @param flags flags from {@link AudioManager} to include with the volume request for local
+ * playback
+ */
+ public void adjustVolume(@VolumeDirection int direction, @VolumeFlags int flags) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putInt(ARGUMENT_VOLUME_DIRECTION, direction);
+ args.putInt(ARGUMENT_VOLUME_FLAGS, flags);
+ sendCommand(COMMAND_CODE_VOLUME_ADJUST_VOLUME, args);
+ }
+ }
+
+ /**
+ * Get an intent for launching UI associated with this session if one exists.
+ *
+ * @return A {@link PendingIntent} to launch UI or null.
+ */
+ public @Nullable PendingIntent getSessionActivity() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return null;
+ }
+ return mControllerCompat.getSessionActivity();
+ }
+ }
+
+ /**
+ * Get the lastly cached player state from
+ * {@link ControllerCallback#onPlayerStateChanged(MediaController2, int)}.
+ *
+ * @return player state
+ */
+ public int getPlayerState() {
+ synchronized (mLock) {
+ return mPlayerState;
+ }
+ }
+
+ /**
+ * Gets the duration of the current media item, or {@link MediaPlayerBase#UNKNOWN_TIME} if
+ * unknown.
+ * @return the duration in ms, or {@link MediaPlayerBase#UNKNOWN_TIME}.
+ */
+ public long getDuration() {
+ synchronized (mLock) {
+ if (mMediaMetadataCompat != null
+ && mMediaMetadataCompat.containsKey(METADATA_KEY_DURATION)) {
+ return mMediaMetadataCompat.getLong(METADATA_KEY_DURATION);
+ }
+ }
+ return MediaPlayerBase.UNKNOWN_TIME;
+ }
+
+ /**
+ * Gets the current playback position.
+ * <p>
+ * This returns the calculated value of the position, based on the difference between the
+ * update time and current time.
+ *
+ * @return position
+ */
+ public long getCurrentPosition() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return UNKNOWN_TIME;
+ }
+ if (mPlaybackStateCompat != null) {
+ long timeDiff = SystemClock.elapsedRealtime()
+ - mPlaybackStateCompat.getLastPositionUpdateTime();
+ long expectedPosition = mPlaybackStateCompat.getPosition()
+ + (long) (mPlaybackStateCompat.getPlaybackSpeed() * timeDiff);
+ return Math.max(0, expectedPosition);
+ }
+ return UNKNOWN_TIME;
+ }
+ }
+
+ /**
+ * Get the lastly cached playback speed from
+ * {@link ControllerCallback#onPlaybackSpeedChanged(MediaController2, float)}.
+ *
+ * @return speed the lastly cached playback speed, or 0.0f if unknown.
+ */
+ public float getPlaybackSpeed() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return 0f;
+ }
+ return (mPlaybackStateCompat == null) ? 0f : mPlaybackStateCompat.getPlaybackSpeed();
+ }
+ }
+
+ /**
+ * Set the playback speed.
+ */
+ public void setPlaybackSpeed(float speed) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putFloat(ARGUMENT_PLAYBACK_SPEED, speed);
+ sendCommand(COMMAND_CODE_PLAYBACK_SET_SPEED, args);
+ }
+ }
+
+ /**
+ * Gets the current buffering state of the player.
+ * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
+ * buffered.
+ * @return the buffering state.
+ */
+ public @MediaPlayerBase.BuffState int getBufferingState() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return BUFFERING_STATE_UNKNOWN;
+ }
+ return mBufferingState;
+ }
+ }
+
+ /**
+ * Gets the lastly cached buffered position from the session when
+ * {@link ControllerCallback#onBufferingStateChanged(MediaController2, MediaItem2, int)} is
+ * called.
+ *
+ * @return buffering position in millis, or {@link MediaPlayerBase#UNKNOWN_TIME} if unknown.
+ */
+ public long getBufferedPosition() {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return UNKNOWN_TIME;
+ }
+ return (mPlaybackStateCompat == null) ? UNKNOWN_TIME
+ : mPlaybackStateCompat.getBufferedPosition();
+ }
+ }
+
+ /**
+ * Get the current playback info for this session.
+ *
+ * @return The current playback info or null.
+ */
+ public @Nullable PlaybackInfo getPlaybackInfo() {
+ synchronized (mLock) {
+ return mPlaybackInfo;
+ }
+ }
+
+ /**
+ * Rate the media. This will cause the rating to be set for the current user.
+ * The rating style must follow the user rating style from the session.
+ * You can get the rating style from the session through the
+ * {@link MediaMetadata2#getRating(String)} with the key
+ * {@link MediaMetadata2#METADATA_KEY_USER_RATING}.
+ * <p>
+ * If the user rating was {@code null}, the media item does not accept setting user rating.
+ *
+ * @param mediaId The id of the media
+ * @param rating The rating to set
+ */
+ public void setRating(@NonNull String mediaId, @NonNull Rating2 rating) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putString(ARGUMENT_MEDIA_ID, mediaId);
+ args.putBundle(ARGUMENT_RATING, rating.toBundle());
+ sendCommand(COMMAND_CODE_SESSION_SET_RATING, args);
+ }
+ }
+
+ /**
+ * Send custom command to the session
+ *
+ * @param command custom command
+ * @param args optional argument
+ * @param cb optional result receiver
+ */
+ public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args,
+ @Nullable ResultReceiver cb) {
+ synchronized (mLock) {
+ if (!mConnected) {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ return;
+ }
+ Bundle bundle = new Bundle();
+ bundle.putBundle(ARGUMENT_CUSTOM_COMMAND, command.toBundle());
+ bundle.putBundle(ARGUMENT_ARGUMENTS, args);
+ sendCommand(CONTROLLER_COMMAND_BY_CUSTOM_COMMAND, bundle, cb);
+ }
+ }
+
+ /**
+ * Returns the cached playlist from {@link ControllerCallback#onPlaylistChanged}.
+ * <p>
+ * This list may differ with the list that was specified with
+ * {@link #setPlaylist(List, MediaMetadata2)} depending on the {@link MediaPlaylistAgent}
+ * implementation. Use media items returned here for other playlist agent APIs such as
+ * {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)}.
+ *
+ * @return playlist. Can be {@code null} if the playlist hasn't set nor controller doesn't have
+ * enough permission.
+ * @see SessionCommand2#COMMAND_CODE_PLAYLIST_GET_LIST
+ */
+ public @Nullable List<MediaItem2> getPlaylist() {
+ synchronized (mLock) {
+ return mPlaylist;
+ }
+ }
+
+ /**
+ * Sets the playlist.
+ * <p>
+ * Even when the playlist is successfully set, use the playlist returned from
+ * {@link #getPlaylist()} for playlist APIs such as {@link #skipToPlaylistItem(MediaItem2)}.
+ * Otherwise the session in the remote process can't distinguish between media items.
+ *
+ * @param list playlist
+ * @param metadata metadata of the playlist
+ * @see #getPlaylist()
+ * @see ControllerCallback#onPlaylistChanged
+ */
+ public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
+ if (list == null) {
+ throw new IllegalArgumentException("list shouldn't be null");
+ }
+ Bundle args = new Bundle();
+ args.putParcelableArray(ARGUMENT_PLAYLIST, MediaUtils2.toMediaItem2ParcelableArray(list));
+ args.putBundle(ARGUMENT_PLAYLIST_METADATA, metadata == null ? null : metadata.toBundle());
+ sendCommand(COMMAND_CODE_PLAYLIST_SET_LIST, args);
+ }
+
+ /**
+ * Updates the playlist metadata
+ *
+ * @param metadata metadata of the playlist
+ */
+ public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) {
+ Bundle args = new Bundle();
+ args.putBundle(ARGUMENT_PLAYLIST_METADATA, metadata == null ? null : metadata.toBundle());
+ sendCommand(COMMAND_CODE_PLAYLIST_SET_LIST_METADATA, args);
+ }
+
+ /**
+ * Gets the lastly cached playlist playlist metadata either from
+ * {@link ControllerCallback#onPlaylistMetadataChanged or
+ * {@link ControllerCallback#onPlaylistChanged}.
+ *
+ * @return metadata metadata of the playlist, or null if none is set
+ */
+ public @Nullable MediaMetadata2 getPlaylistMetadata() {
+ synchronized (mLock) {
+ return mPlaylistMetadata;
+ }
+ }
+
+ /**
+ * Adds the media item to the playlist at position index. Index equals or greater than
+ * the current playlist size (e.g. {@link Integer#MAX_VALUE}) will add the item at the end of
+ * the playlist.
+ * <p>
+ * This will not change the currently playing media item.
+ * If index is less than or equal to the current index of the playlist,
+ * the current index of the playlist will be incremented correspondingly.
+ *
+ * @param index the index you want to add
+ * @param item the media item you want to add
+ */
+ public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
+ Bundle args = new Bundle();
+ args.putInt(ARGUMENT_PLAYLIST_INDEX, index);
+ args.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
+ sendCommand(COMMAND_CODE_PLAYLIST_ADD_ITEM, args);
+ }
+
+ /**
+ * Removes the media item at index in the playlist.
+ *<p>
+ * If the item is the currently playing item of the playlist, current playback
+ * will be stopped and playback moves to next source in the list.
+ *
+ * @param item the media item you want to add
+ */
+ public void removePlaylistItem(@NonNull MediaItem2 item) {
+ Bundle args = new Bundle();
+ args.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
+ sendCommand(COMMAND_CODE_PLAYLIST_REMOVE_ITEM, args);
+ }
+
+ /**
+ * Replace the media item at index in the playlist. This can be also used to update metadata of
+ * an item.
+ *
+ * @param index the index of the item to replace
+ * @param item the new item
+ */
+ public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
+ Bundle args = new Bundle();
+ args.putInt(ARGUMENT_PLAYLIST_INDEX, index);
+ args.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
+ sendCommand(COMMAND_CODE_PLAYLIST_REPLACE_ITEM, args);
+ }
+
+ /**
+ * Get the lastly cached current item from
+ * {@link ControllerCallback#onCurrentMediaItemChanged(MediaController2, MediaItem2)}.
+ *
+ * @return the currently playing item, or null if unknown.
+ */
+ public MediaItem2 getCurrentMediaItem() {
+ synchronized (mLock) {
+ return mCurrentMediaItem;
+ }
+ }
+
+ /**
+ * Skips to the previous item in the playlist.
+ * <p>
+ * This calls {@link MediaPlaylistAgent#skipToPreviousItem()}.
+ */
+ public void skipToPreviousItem() {
+ sendCommand(COMMAND_CODE_PLAYLIST_SKIP_TO_PREV_ITEM);
+ }
+
+ /**
+ * Skips to the next item in the playlist.
+ * <p>
+ * This calls {@link MediaPlaylistAgent#skipToNextItem()}.
+ */
+ public void skipToNextItem() {
+ sendCommand(COMMAND_CODE_PLAYLIST_SKIP_TO_NEXT_ITEM);
+ }
+
+ /**
+ * Skips to the item in the playlist.
+ * <p>
+ * This calls {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)}.
+ *
+ * @param item The item in the playlist you want to play
+ */
+ public void skipToPlaylistItem(@NonNull MediaItem2 item) {
+ Bundle args = new Bundle();
+ args.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
+ sendCommand(COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM, args);
+ }
+
+ /**
+ * Gets the cached repeat mode from the {@link ControllerCallback#onRepeatModeChanged}.
+ *
+ * @return repeat mode
+ * @see MediaPlaylistAgent#REPEAT_MODE_NONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ALL
+ * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
+ */
+ public @RepeatMode int getRepeatMode() {
+ synchronized (mLock) {
+ return mRepeatMode;
+ }
+ }
+
+ /**
+ * Sets the repeat mode.
+ *
+ * @param repeatMode repeat mode
+ * @see MediaPlaylistAgent#REPEAT_MODE_NONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ALL
+ * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
+ */
+ public void setRepeatMode(@RepeatMode int repeatMode) {
+ Bundle args = new Bundle();
+ args.putInt(ARGUMENT_REPEAT_MODE, repeatMode);
+ sendCommand(COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE, args);
+ }
+
+ /**
+ * Gets the cached shuffle mode from the {@link ControllerCallback#onShuffleModeChanged}.
+ *
+ * @return The shuffle mode
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
+ */
+ public @ShuffleMode int getShuffleMode() {
+ synchronized (mLock) {
+ return mShuffleMode;
+ }
+ }
+
+ /**
+ * Sets the shuffle mode.
+ *
+ * @param shuffleMode The shuffle mode
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
+ */
+ public void setShuffleMode(@ShuffleMode int shuffleMode) {
+ Bundle args = new Bundle();
+ args.putInt(ARGUMENT_SHUFFLE_MODE, shuffleMode);
+ sendCommand(COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE, args);
+ }
+
+ /**
+ * Queries for information about the routes currently known.
+ */
+ public void subscribeRoutesInfo() {
+ sendCommand(COMMAND_CODE_SESSION_SUBSCRIBE_ROUTES_INFO);
+ }
+
+ /**
+ * Unsubscribes for changes to the routes.
+ * <p>
+ * The {@link ControllerCallback#onRoutesInfoChanged callback} will no longer be invoked for
+ * the routes once this method returns.
+ * </p>
+ */
+ public void unsubscribeRoutesInfo() {
+ sendCommand(COMMAND_CODE_SESSION_UNSUBSCRIBE_ROUTES_INFO);
+ }
+
+ /**
+ * Selects the specified route.
+ *
+ * @param route The route to select.
+ */
+ public void selectRoute(@NonNull Bundle route) {
+ if (route == null) {
+ throw new IllegalArgumentException("route shouldn't be null");
+ }
+ Bundle args = new Bundle();
+ args.putBundle(ARGUMENT_ROUTE_BUNDLE, route);
+ sendCommand(COMMAND_CODE_SESSION_SELECT_ROUTE, args);
+ }
+
+ // Should be used without a lock to prevent potential deadlock.
+ void onConnectedNotLocked(Bundle data) {
+ // is enough or should we pass it while connecting?
+ final SessionCommandGroup2 allowedCommands = SessionCommandGroup2.fromBundle(
+ data.getBundle(ARGUMENT_ALLOWED_COMMANDS));
+ final int playerState = data.getInt(ARGUMENT_PLAYER_STATE);
+ final int bufferingState = data.getInt(ARGUMENT_BUFFERING_STATE);
+ final PlaybackStateCompat playbackStateCompat = data.getParcelable(
+ ARGUMENT_PLAYBACK_STATE_COMPAT);
+ final int repeatMode = data.getInt(ARGUMENT_REPEAT_MODE);
+ final int shuffleMode = data.getInt(ARGUMENT_SHUFFLE_MODE);
+ final List<MediaItem2> playlist = MediaUtils2.fromMediaItem2ParcelableArray(
+ data.getParcelableArray(ARGUMENT_PLAYLIST));
+ final MediaItem2 currentMediaItem = MediaItem2.fromBundle(
+ data.getBundle(ARGUMENT_MEDIA_ITEM));
+ final PlaybackInfo playbackInfo =
+ PlaybackInfo.fromBundle(data.getBundle(ARGUMENT_PLAYBACK_INFO));
+ final MediaMetadata2 metadata = MediaMetadata2.fromBundle(
+ data.getBundle(ARGUMENT_PLAYLIST_METADATA));
+ if (DEBUG) {
+ Log.d(TAG, "onConnectedNotLocked sessionCompatToken=" + mToken.getSessionCompatToken()
+ + ", allowedCommands=" + allowedCommands);
+ }
+ boolean close = false;
+ try {
+ synchronized (mLock) {
+ if (mIsReleased) {
+ return;
+ }
+ if (mConnected) {
+ Log.e(TAG, "Cannot be notified about the connection result many times."
+ + " Probably a bug or malicious app.");
+ close = true;
+ return;
+ }
+ mAllowedCommands = allowedCommands;
+ mPlayerState = playerState;
+ mBufferingState = bufferingState;
+ mPlaybackStateCompat = playbackStateCompat;
+ mRepeatMode = repeatMode;
+ mShuffleMode = shuffleMode;
+ mPlaylist = playlist;
+ mCurrentMediaItem = currentMediaItem;
+ mPlaylistMetadata = metadata;
+ mConnected = true;
+ mPlaybackInfo = playbackInfo;
+ }
+ mCallbackExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ // Note: We may trigger ControllerCallbacks with the initial values
+ // But it's hard to define the order of the controller callbacks
+ // Only notify about the
+ mCallback.onConnected(MediaController2.this, allowedCommands);
+ }
+ });
+ } finally {
+ if (close) {
+ // Trick to call release() without holding the lock, to prevent potential deadlock
+ // with the developer's custom lock within the ControllerCallback.onDisconnected().
+ close();
+ }
+ }
+ }
+
+ private void initialize() {
+ if (mToken.getType() == SessionToken2.TYPE_SESSION) {
+ synchronized (mLock) {
+ mBrowserCompat = null;
+ }
+ connectToSession(mToken.getSessionCompatToken());
+ } else {
+ connectToService();
+ }
+ }
+
+ private void connectToSession(MediaSessionCompat.Token sessionCompatToken) {
+ MediaControllerCompat controllerCompat = null;
+ try {
+ controllerCompat = new MediaControllerCompat(mContext, sessionCompatToken);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ synchronized (mLock) {
+ mControllerCompat = controllerCompat;
+ mControllerCompatCallback = new ControllerCompatCallback();
+ mControllerCompat.registerCallback(mControllerCompatCallback, mHandler);
+ }
+
+ if (controllerCompat.isSessionReady()) {
+ sendCommand(CONTROLLER_COMMAND_CONNECT, new ResultReceiver(mHandler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (!mHandlerThread.isAlive()) {
+ return;
+ }
+ switch (resultCode) {
+ case CONNECT_RESULT_CONNECTED:
+ onConnectedNotLocked(resultData);
+ break;
+ case CONNECT_RESULT_DISCONNECTED:
+ mCallback.onDisconnected(MediaController2.this);
+ close();
+ break;
+ }
+ }
+ });
+ }
+ }
+
+ private void connectToService() {
+ synchronized (mLock) {
+ mBrowserCompat = new MediaBrowserCompat(mContext, mToken.getComponentName(),
+ new ConnectionCallback(), sDefaultRootExtras);
+ mBrowserCompat.connect();
+ }
+ }
+
+ private void sendCommand(int commandCode) {
+ sendCommand(commandCode, null);
+ }
+
+ private void sendCommand(int commandCode, Bundle args) {
+ if (args == null) {
+ args = new Bundle();
+ }
+ args.putInt(ARGUMENT_COMMAND_CODE, commandCode);
+ sendCommand(CONTROLLER_COMMAND_BY_COMMAND_CODE, args, null);
+ }
+
+ private void sendCommand(String command) {
+ sendCommand(command, null, null);
+ }
+
+ private void sendCommand(String command, ResultReceiver receiver) {
+ sendCommand(command, null, receiver);
+ }
+
+ private void sendCommand(String command, Bundle args, ResultReceiver receiver) {
+ if (args == null) {
+ args = new Bundle();
+ }
+ MediaControllerCompat controller;
+ ControllerCompatCallback callback;
+ synchronized (mLock) {
+ controller = mControllerCompat;
+ callback = mControllerCompatCallback;
+ }
+ args.putBinder(ARGUMENT_ICONTROLLER_CALLBACK, callback.getIControllerCallback().asBinder());
+ args.putString(ARGUMENT_PACKAGE_NAME, mContext.getPackageName());
+ args.putInt(ARGUMENT_UID, Process.myUid());
+ args.putInt(ARGUMENT_PID, Process.myPid());
+ controller.sendCommand(command, args, receiver);
+ }
+
+ @NonNull Context getContext() {
+ return mContext;
+ }
+
+ @NonNull ControllerCallback getCallback() {
+ return mCallback;
+ }
+
+ @NonNull Executor getCallbackExecutor() {
+ return mCallbackExecutor;
+ }
+
+ @Nullable MediaBrowserCompat getBrowserCompat() {
+ synchronized (mLock) {
+ return mBrowserCompat;
+ }
+ }
+
+ private class ConnectionCallback extends MediaBrowserCompat.ConnectionCallback {
+ @Override
+ public void onConnected() {
+ MediaBrowserCompat browser = getBrowserCompat();
+ if (browser != null) {
+ connectToSession(browser.getSessionToken());
+ } else if (DEBUG) {
+ Log.d(TAG, "Controller is closed prematually", new IllegalStateException());
+ }
+ }
+
+ @Override
+ public void onConnectionSuspended() {
+ close();
+ }
+
+ @Override
+ public void onConnectionFailed() {
+ close();
+ }
+ }
}
diff --git a/media/src/main/java/androidx/media/MediaController2ImplBase.java b/media/src/main/java/androidx/media/MediaController2ImplBase.java
deleted file mode 100644
index 1bd0009..0000000
--- a/media/src/main/java/androidx/media/MediaController2ImplBase.java
+++ /dev/null
@@ -1,1283 +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.media;
-
-import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DURATION;
-
-import static androidx.media.MediaConstants2.ARGUMENT_ALLOWED_COMMANDS;
-import static androidx.media.MediaConstants2.ARGUMENT_ARGUMENTS;
-import static androidx.media.MediaConstants2.ARGUMENT_BUFFERING_STATE;
-import static androidx.media.MediaConstants2.ARGUMENT_COMMAND_BUTTONS;
-import static androidx.media.MediaConstants2.ARGUMENT_COMMAND_CODE;
-import static androidx.media.MediaConstants2.ARGUMENT_CUSTOM_COMMAND;
-import static androidx.media.MediaConstants2.ARGUMENT_ERROR_CODE;
-import static androidx.media.MediaConstants2.ARGUMENT_EXTRAS;
-import static androidx.media.MediaConstants2.ARGUMENT_ICONTROLLER_CALLBACK;
-import static androidx.media.MediaConstants2.ARGUMENT_ITEM_COUNT;
-import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ID;
-import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ITEM;
-import static androidx.media.MediaConstants2.ARGUMENT_PACKAGE_NAME;
-import static androidx.media.MediaConstants2.ARGUMENT_PID;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_INFO;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_SPEED;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_STATE_COMPAT;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYER_STATE;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST_INDEX;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST_METADATA;
-import static androidx.media.MediaConstants2.ARGUMENT_QUERY;
-import static androidx.media.MediaConstants2.ARGUMENT_RATING;
-import static androidx.media.MediaConstants2.ARGUMENT_REPEAT_MODE;
-import static androidx.media.MediaConstants2.ARGUMENT_RESULT_RECEIVER;
-import static androidx.media.MediaConstants2.ARGUMENT_ROUTE_BUNDLE;
-import static androidx.media.MediaConstants2.ARGUMENT_SEEK_POSITION;
-import static androidx.media.MediaConstants2.ARGUMENT_SHUFFLE_MODE;
-import static androidx.media.MediaConstants2.ARGUMENT_UID;
-import static androidx.media.MediaConstants2.ARGUMENT_URI;
-import static androidx.media.MediaConstants2.ARGUMENT_VOLUME;
-import static androidx.media.MediaConstants2.ARGUMENT_VOLUME_DIRECTION;
-import static androidx.media.MediaConstants2.ARGUMENT_VOLUME_FLAGS;
-import static androidx.media.MediaConstants2.CONNECT_RESULT_CONNECTED;
-import static androidx.media.MediaConstants2.CONNECT_RESULT_DISCONNECTED;
-import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_BY_COMMAND_CODE;
-import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_BY_CUSTOM_COMMAND;
-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_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_CHILDREN_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;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYBACK_SPEED_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYER_STATE_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYLIST_CHANGED;
-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_SEARCH_RESULT_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;
-import static androidx.media.MediaPlayerInterface.BUFFERING_STATE_UNKNOWN;
-import static androidx.media.MediaPlayerInterface.UNKNOWN_TIME;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_RESET;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_SEEK_TO;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_SET_SPEED;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_ADD_ITEM;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_TO_NEXT_ITEM;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_TO_PREV_ITEM;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_FAST_FORWARD;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_SEARCH;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_URI;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_URI;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_REWIND;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_SELECT_ROUTE;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_SET_RATING;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_SUBSCRIBE_ROUTES_INFO;
-import static androidx.media.SessionCommand2.COMMAND_CODE_SESSION_UNSUBSCRIBE_ROUTES_INFO;
-import static androidx.media.SessionCommand2.COMMAND_CODE_VOLUME_ADJUST_VOLUME;
-import static androidx.media.SessionCommand2.COMMAND_CODE_VOLUME_SET_VOLUME;
-
-import android.annotation.TargetApi;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.SystemClock;
-import android.support.v4.media.MediaBrowserCompat;
-import android.support.v4.media.MediaMetadataCompat;
-import android.support.v4.media.session.MediaControllerCompat;
-import android.support.v4.media.session.MediaSessionCompat;
-import android.support.v4.media.session.PlaybackStateCompat;
-import android.util.Log;
-
-import androidx.annotation.GuardedBy;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.app.BundleCompat;
-import androidx.media.MediaController2.ControllerCallback;
-import androidx.media.MediaController2.PlaybackInfo;
-import androidx.media.MediaController2.VolumeDirection;
-import androidx.media.MediaController2.VolumeFlags;
-import androidx.media.MediaPlaylistAgent.RepeatMode;
-import androidx.media.MediaPlaylistAgent.ShuffleMode;
-import androidx.media.MediaSession2.CommandButton;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
-class MediaController2ImplBase implements MediaController2.SupportLibraryImpl {
-
- private static final String TAG = "MC2ImplBase";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- // Note: Using {@code null} doesn't helpful here because MediaBrowserServiceCompat always wraps
- // the rootHints so it becomes non-null.
- static final Bundle sDefaultRootExtras = new Bundle();
- static {
- sDefaultRootExtras.putBoolean(MediaConstants2.ROOT_EXTRA_DEFAULT, true);
- }
-
- private final Context mContext;
- private final Object mLock = new Object();
-
- private final SessionToken2 mToken;
- private final ControllerCallback mCallback;
- private final Executor mCallbackExecutor;
- private final IBinder.DeathRecipient mDeathRecipient;
-
- private final HandlerThread mHandlerThread;
- private final Handler mHandler;
-
- private MediaController2 mInstance;
-
- @GuardedBy("mLock")
- private MediaBrowserCompat mBrowserCompat;
- @GuardedBy("mLock")
- private boolean mIsReleased;
- @GuardedBy("mLock")
- private List<MediaItem2> mPlaylist;
- @GuardedBy("mLock")
- private MediaMetadata2 mPlaylistMetadata;
- @GuardedBy("mLock")
- private @RepeatMode int mRepeatMode;
- @GuardedBy("mLock")
- private @ShuffleMode int mShuffleMode;
- @GuardedBy("mLock")
- private int mPlayerState;
- @GuardedBy("mLock")
- private MediaItem2 mCurrentMediaItem;
- @GuardedBy("mLock")
- private int mBufferingState;
- @GuardedBy("mLock")
- private PlaybackInfo mPlaybackInfo;
- @GuardedBy("mLock")
- private SessionCommandGroup2 mAllowedCommands;
-
- // Media 1.0 variables
- @GuardedBy("mLock")
- private MediaControllerCompat mControllerCompat;
- @GuardedBy("mLock")
- private ControllerCompatCallback mControllerCompatCallback;
- @GuardedBy("mLock")
- private PlaybackStateCompat mPlaybackStateCompat;
- @GuardedBy("mLock")
- private MediaMetadataCompat mMediaMetadataCompat;
-
- // Assignment should be used with the lock hold, but should be used without a lock to prevent
- // potential deadlock.
- @GuardedBy("mLock")
- private volatile boolean mConnected;
-
- MediaController2ImplBase(@NonNull Context context, @NonNull SessionToken2 token,
- @NonNull Executor executor, @NonNull ControllerCallback callback) {
- super();
- if (context == null) {
- throw new IllegalArgumentException("context shouldn't be null");
- }
- if (token == null) {
- throw new IllegalArgumentException("token shouldn't be null");
- }
- if (callback == null) {
- throw new IllegalArgumentException("callback shouldn't be null");
- }
- if (executor == null) {
- throw new IllegalArgumentException("executor shouldn't be null");
- }
- mContext = context;
- mHandlerThread = new HandlerThread("MediaController2_Thread");
- mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper());
- mToken = token;
- mCallback = callback;
- mCallbackExecutor = executor;
- mDeathRecipient = new IBinder.DeathRecipient() {
- @Override
- public void binderDied() {
- MediaController2ImplBase.this.close();
- }
- };
-
- initialize();
- }
-
- @Override
- public void setInstance(MediaController2 controller) {
- mInstance = controller;
- }
-
- @Override
- public void close() {
- if (DEBUG) {
- //Log.d(TAG, "release from " + mToken, new IllegalStateException());
- }
- synchronized (mLock) {
- if (mIsReleased) {
- // Prevent re-enterance from the ControllerCallback.onDisconnected()
- return;
- }
- mHandler.removeCallbacksAndMessages(null);
-
- if (Build.VERSION.SDK_INT >= 18) {
- mHandlerThread.quitSafely();
- } else {
- mHandlerThread.quit();
- }
-
- mIsReleased = true;
-
- // Send command before the unregister callback to use mIControllerCallback in the
- // callback.
- sendCommand(CONTROLLER_COMMAND_DISCONNECT);
- if (mControllerCompat != null) {
- mControllerCompat.unregisterCallback(mControllerCompatCallback);
- }
- if (mBrowserCompat != null) {
- mBrowserCompat.disconnect();
- mBrowserCompat = null;
- }
- if (mControllerCompat != null) {
- mControllerCompat.unregisterCallback(mControllerCompatCallback);
- mControllerCompat = null;
- }
- mConnected = false;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onDisconnected(mInstance);
- }
- });
- }
-
- @Override
- public @NonNull SessionToken2 getSessionToken() {
- return mToken;
- }
-
- @Override
- public boolean isConnected() {
- synchronized (mLock) {
- return mConnected;
- }
- }
-
- @Override
- public void play() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- sendCommand(COMMAND_CODE_PLAYBACK_PLAY);
- }
- }
-
- @Override
- public void pause() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- sendCommand(COMMAND_CODE_PLAYBACK_PAUSE);
- }
- }
-
- @Override
- public void reset() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- sendCommand(COMMAND_CODE_PLAYBACK_RESET);
- }
- }
-
- @Override
- public void prepare() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- sendCommand(COMMAND_CODE_PLAYBACK_PREPARE);
- }
- }
-
- @Override
- public void fastForward() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- sendCommand(COMMAND_CODE_SESSION_FAST_FORWARD);
- }
- }
-
- @Override
- public void rewind() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- sendCommand(COMMAND_CODE_SESSION_REWIND);
- }
- }
-
- @Override
- public void seekTo(long pos) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putLong(ARGUMENT_SEEK_POSITION, pos);
- sendCommand(COMMAND_CODE_PLAYBACK_SEEK_TO, args);
- }
- }
-
- @Override
- public void skipForward() {
- // To match with KEYCODE_MEDIA_SKIP_FORWARD
- }
-
- @Override
- public void skipBackward() {
- // To match with KEYCODE_MEDIA_SKIP_BACKWARD
- }
-
- @Override
- public void playFromMediaId(@NonNull String mediaId, @Nullable Bundle extras) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putString(ARGUMENT_MEDIA_ID, mediaId);
- args.putBundle(ARGUMENT_EXTRAS, extras);
- sendCommand(COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID, args);
- }
- }
-
- @Override
- public void playFromSearch(@NonNull String query, @Nullable Bundle extras) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putString(ARGUMENT_QUERY, query);
- args.putBundle(ARGUMENT_EXTRAS, extras);
- sendCommand(COMMAND_CODE_SESSION_PLAY_FROM_SEARCH, args);
- }
- }
-
- @Override
- public void playFromUri(@NonNull Uri uri, @Nullable Bundle extras) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(ARGUMENT_URI, uri);
- args.putBundle(ARGUMENT_EXTRAS, extras);
- sendCommand(COMMAND_CODE_SESSION_PLAY_FROM_URI, args);
- }
- }
-
- @Override
- public void prepareFromMediaId(@NonNull String mediaId, @Nullable Bundle extras) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putString(ARGUMENT_MEDIA_ID, mediaId);
- args.putBundle(ARGUMENT_EXTRAS, extras);
- sendCommand(COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID, args);
- }
- }
-
- @Override
- public void prepareFromSearch(@NonNull String query, @Nullable Bundle extras) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putString(ARGUMENT_QUERY, query);
- args.putBundle(ARGUMENT_EXTRAS, extras);
- sendCommand(COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH, args);
- }
- }
-
- @Override
- public void prepareFromUri(@NonNull Uri uri, @Nullable Bundle extras) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(ARGUMENT_URI, uri);
- args.putBundle(ARGUMENT_EXTRAS, extras);
- sendCommand(COMMAND_CODE_SESSION_PREPARE_FROM_URI, args);
- }
- }
-
- @Override
- public void setVolumeTo(int value, @VolumeFlags int flags) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putInt(ARGUMENT_VOLUME, value);
- args.putInt(ARGUMENT_VOLUME_FLAGS, flags);
- sendCommand(COMMAND_CODE_VOLUME_SET_VOLUME, args);
- }
- }
-
- @Override
- public void adjustVolume(@VolumeDirection int direction, @VolumeFlags int flags) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putInt(ARGUMENT_VOLUME_DIRECTION, direction);
- args.putInt(ARGUMENT_VOLUME_FLAGS, flags);
- sendCommand(COMMAND_CODE_VOLUME_ADJUST_VOLUME, args);
- }
- }
-
- @Override
- public @Nullable PendingIntent getSessionActivity() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return null;
- }
- return mControllerCompat.getSessionActivity();
- }
- }
-
- @Override
- public int getPlayerState() {
- synchronized (mLock) {
- return mPlayerState;
- }
- }
-
- @Override
- public long getDuration() {
- synchronized (mLock) {
- if (mMediaMetadataCompat != null
- && mMediaMetadataCompat.containsKey(METADATA_KEY_DURATION)) {
- return mMediaMetadataCompat.getLong(METADATA_KEY_DURATION);
- }
- }
- return MediaPlayerInterface.UNKNOWN_TIME;
- }
-
- @Override
- public long getCurrentPosition() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return UNKNOWN_TIME;
- }
- if (mPlaybackStateCompat != null) {
- long timeDiff = (mInstance.mTimeDiff != null) ? mInstance.mTimeDiff
- : SystemClock.elapsedRealtime()
- - mPlaybackStateCompat.getLastPositionUpdateTime();
- long expectedPosition = mPlaybackStateCompat.getPosition()
- + (long) (mPlaybackStateCompat.getPlaybackSpeed() * timeDiff);
- return Math.max(0, expectedPosition);
- }
- return UNKNOWN_TIME;
- }
- }
-
- @Override
- public float getPlaybackSpeed() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return 0f;
- }
- return (mPlaybackStateCompat == null) ? 0f : mPlaybackStateCompat.getPlaybackSpeed();
- }
- }
-
- @Override
- public void setPlaybackSpeed(float speed) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putFloat(ARGUMENT_PLAYBACK_SPEED, speed);
- sendCommand(COMMAND_CODE_PLAYBACK_SET_SPEED, args);
- }
- }
-
- @Override
- public @MediaPlayerInterface.BuffState int getBufferingState() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return BUFFERING_STATE_UNKNOWN;
- }
- return mBufferingState;
- }
- }
-
- @Override
- public long getBufferedPosition() {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return UNKNOWN_TIME;
- }
- return (mPlaybackStateCompat == null) ? UNKNOWN_TIME
- : mPlaybackStateCompat.getBufferedPosition();
- }
- }
-
- @Override
- public @Nullable PlaybackInfo getPlaybackInfo() {
- synchronized (mLock) {
- return mPlaybackInfo;
- }
- }
-
- @Override
- public void setRating(@NonNull String mediaId, @NonNull Rating2 rating) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle args = new Bundle();
- args.putString(ARGUMENT_MEDIA_ID, mediaId);
- args.putBundle(ARGUMENT_RATING, rating.toBundle());
- sendCommand(COMMAND_CODE_SESSION_SET_RATING, args);
- }
- }
-
- @Override
- public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args,
- @Nullable ResultReceiver cb) {
- synchronized (mLock) {
- if (!mConnected) {
- Log.w(TAG, "Session isn't active", new IllegalStateException());
- return;
- }
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_CUSTOM_COMMAND, command.toBundle());
- bundle.putBundle(ARGUMENT_ARGUMENTS, args);
- sendCommand(CONTROLLER_COMMAND_BY_CUSTOM_COMMAND, bundle, cb);
- }
- }
-
- @Override
- public @Nullable List<MediaItem2> getPlaylist() {
- synchronized (mLock) {
- return mPlaylist;
- }
- }
-
- @Override
- public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
- if (list == null) {
- throw new IllegalArgumentException("list shouldn't be null");
- }
- Bundle args = new Bundle();
- args.putParcelableArray(ARGUMENT_PLAYLIST, MediaUtils2.toMediaItem2ParcelableArray(list));
- args.putBundle(ARGUMENT_PLAYLIST_METADATA, metadata == null ? null : metadata.toBundle());
- sendCommand(COMMAND_CODE_PLAYLIST_SET_LIST, args);
- }
-
- @Override
- public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) {
- Bundle args = new Bundle();
- args.putBundle(ARGUMENT_PLAYLIST_METADATA, metadata == null ? null : metadata.toBundle());
- sendCommand(COMMAND_CODE_PLAYLIST_SET_LIST_METADATA, args);
- }
-
- @Override
- public @Nullable MediaMetadata2 getPlaylistMetadata() {
- synchronized (mLock) {
- return mPlaylistMetadata;
- }
- }
-
- @Override
- public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
- Bundle args = new Bundle();
- args.putInt(ARGUMENT_PLAYLIST_INDEX, index);
- args.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
- sendCommand(COMMAND_CODE_PLAYLIST_ADD_ITEM, args);
- }
-
- @Override
- public void removePlaylistItem(@NonNull MediaItem2 item) {
- Bundle args = new Bundle();
- args.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
- sendCommand(COMMAND_CODE_PLAYLIST_REMOVE_ITEM, args);
- }
-
- @Override
- public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
- Bundle args = new Bundle();
- args.putInt(ARGUMENT_PLAYLIST_INDEX, index);
- args.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
- sendCommand(COMMAND_CODE_PLAYLIST_REPLACE_ITEM, args);
- }
-
- @Override
- public MediaItem2 getCurrentMediaItem() {
- synchronized (mLock) {
- return mCurrentMediaItem;
- }
- }
-
- @Override
- public void skipToPreviousItem() {
- sendCommand(COMMAND_CODE_PLAYLIST_SKIP_TO_PREV_ITEM);
- }
-
- @Override
- public void skipToNextItem() {
- sendCommand(COMMAND_CODE_PLAYLIST_SKIP_TO_NEXT_ITEM);
- }
-
- @Override
- public void skipToPlaylistItem(@NonNull MediaItem2 item) {
- Bundle args = new Bundle();
- args.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
- sendCommand(COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM, args);
- }
-
- @Override
- public @RepeatMode int getRepeatMode() {
- synchronized (mLock) {
- return mRepeatMode;
- }
- }
-
- @Override
- public void setRepeatMode(@RepeatMode int repeatMode) {
- Bundle args = new Bundle();
- args.putInt(ARGUMENT_REPEAT_MODE, repeatMode);
- sendCommand(COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE, args);
- }
-
- @Override
- public @ShuffleMode int getShuffleMode() {
- synchronized (mLock) {
- return mShuffleMode;
- }
- }
-
- @Override
- public void setShuffleMode(@ShuffleMode int shuffleMode) {
- Bundle args = new Bundle();
- args.putInt(ARGUMENT_SHUFFLE_MODE, shuffleMode);
- sendCommand(COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE, args);
- }
-
- @Override
- public void subscribeRoutesInfo() {
- sendCommand(COMMAND_CODE_SESSION_SUBSCRIBE_ROUTES_INFO);
- }
-
- @Override
- public void unsubscribeRoutesInfo() {
- sendCommand(COMMAND_CODE_SESSION_UNSUBSCRIBE_ROUTES_INFO);
- }
-
- @Override
- public void selectRoute(@NonNull Bundle route) {
- if (route == null) {
- throw new IllegalArgumentException("route shouldn't be null");
- }
- Bundle args = new Bundle();
- args.putBundle(ARGUMENT_ROUTE_BUNDLE, route);
- sendCommand(COMMAND_CODE_SESSION_SELECT_ROUTE, args);
- }
-
- @Override
- public @NonNull Context getContext() {
- return mContext;
- }
-
- @Override
- public @NonNull ControllerCallback getCallback() {
- return mCallback;
- }
-
- @Override
- public @NonNull Executor getCallbackExecutor() {
- return mCallbackExecutor;
- }
-
- @Override
- public @Nullable MediaBrowserCompat getBrowserCompat() {
- synchronized (mLock) {
- return mBrowserCompat;
- }
- }
-
- // Should be used without a lock to prevent potential deadlock.
- void onConnectedNotLocked(Bundle data) {
- data.setClassLoader(MediaSession2.class.getClassLoader());
- // is enough or should we pass it while connecting?
- final SessionCommandGroup2 allowedCommands = SessionCommandGroup2.fromBundle(
- data.getBundle(ARGUMENT_ALLOWED_COMMANDS));
- final int playerState = data.getInt(ARGUMENT_PLAYER_STATE);
- final int bufferingState = data.getInt(ARGUMENT_BUFFERING_STATE);
- final PlaybackStateCompat playbackStateCompat = data.getParcelable(
- ARGUMENT_PLAYBACK_STATE_COMPAT);
- final int repeatMode = data.getInt(ARGUMENT_REPEAT_MODE);
- final int shuffleMode = data.getInt(ARGUMENT_SHUFFLE_MODE);
- final List<MediaItem2> playlist = MediaUtils2.fromMediaItem2ParcelableArray(
- data.getParcelableArray(ARGUMENT_PLAYLIST));
- final MediaItem2 currentMediaItem = MediaItem2.fromBundle(
- data.getBundle(ARGUMENT_MEDIA_ITEM));
- final PlaybackInfo playbackInfo =
- PlaybackInfo.fromBundle(data.getBundle(ARGUMENT_PLAYBACK_INFO));
- final MediaMetadata2 metadata = MediaMetadata2.fromBundle(
- data.getBundle(ARGUMENT_PLAYLIST_METADATA));
- if (DEBUG) {
- Log.d(TAG, "onConnectedNotLocked sessionCompatToken=" + mToken.getSessionCompatToken()
- + ", allowedCommands=" + allowedCommands);
- }
- boolean close = false;
- try {
- synchronized (mLock) {
- if (mIsReleased) {
- return;
- }
- if (mConnected) {
- Log.e(TAG, "Cannot be notified about the connection result many times."
- + " Probably a bug or malicious app.");
- close = true;
- return;
- }
- mAllowedCommands = allowedCommands;
- mPlayerState = playerState;
- mBufferingState = bufferingState;
- mPlaybackStateCompat = playbackStateCompat;
- mRepeatMode = repeatMode;
- mShuffleMode = shuffleMode;
- mPlaylist = playlist;
- mCurrentMediaItem = currentMediaItem;
- mPlaylistMetadata = metadata;
- mConnected = true;
- mPlaybackInfo = playbackInfo;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- // Note: We may trigger ControllerCallbacks with the initial values
- // But it's hard to define the order of the controller callbacks
- // Only notify about the
- mCallback.onConnected(mInstance, allowedCommands);
- }
- });
- } finally {
- if (close) {
- // Trick to call release() without holding the lock, to prevent potential deadlock
- // with the developer's custom lock within the ControllerCallback.onDisconnected().
- close();
- }
- }
- }
-
- private void initialize() {
- if (mToken.getType() == SessionToken2.TYPE_SESSION) {
- synchronized (mLock) {
- mBrowserCompat = null;
- }
- connectToSession(mToken.getSessionCompatToken());
- } else {
- connectToService();
- }
- }
-
- private void connectToSession(MediaSessionCompat.Token sessionCompatToken) {
- MediaControllerCompat controllerCompat = null;
- try {
- controllerCompat = new MediaControllerCompat(mContext, sessionCompatToken);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- synchronized (mLock) {
- mControllerCompat = controllerCompat;
- mControllerCompatCallback = new ControllerCompatCallback();
- mControllerCompat.registerCallback(mControllerCompatCallback, mHandler);
- }
-
- if (controllerCompat.isSessionReady()) {
- sendCommand(CONTROLLER_COMMAND_CONNECT, new ResultReceiver(mHandler) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (!mHandlerThread.isAlive()) {
- return;
- }
- switch (resultCode) {
- case CONNECT_RESULT_CONNECTED:
- onConnectedNotLocked(resultData);
- break;
- case CONNECT_RESULT_DISCONNECTED:
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onDisconnected(mInstance);
- }
- });
- close();
- break;
- }
- }
- });
- }
- }
-
- private void connectToService() {
- 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) {
- sendCommand(commandCode, null);
- }
-
- private void sendCommand(int commandCode, Bundle args) {
- if (args == null) {
- args = new Bundle();
- }
- args.putInt(ARGUMENT_COMMAND_CODE, commandCode);
- sendCommand(CONTROLLER_COMMAND_BY_COMMAND_CODE, args, null);
- }
-
- private void sendCommand(String command) {
- sendCommand(command, null, null);
- }
-
- private void sendCommand(String command, ResultReceiver receiver) {
- sendCommand(command, null, receiver);
- }
-
- private void sendCommand(String command, Bundle args, ResultReceiver receiver) {
- if (args == null) {
- args = new Bundle();
- }
- MediaControllerCompat controller;
- ControllerCompatCallback callback;
- synchronized (mLock) {
- controller = mControllerCompat;
- callback = mControllerCompatCallback;
- }
- BundleCompat.putBinder(args, ARGUMENT_ICONTROLLER_CALLBACK,
- callback.getIControllerCallback().asBinder());
- args.putString(ARGUMENT_PACKAGE_NAME, mContext.getPackageName());
- args.putInt(ARGUMENT_UID, Process.myUid());
- args.putInt(ARGUMENT_PID, Process.myPid());
- controller.sendCommand(command, args, receiver);
- }
-
- private class ConnectionCallback extends MediaBrowserCompat.ConnectionCallback {
- @Override
- public void onConnected() {
- MediaBrowserCompat browser = getBrowserCompat();
- if (browser != null) {
- connectToSession(browser.getSessionToken());
- } else if (DEBUG) {
- Log.d(TAG, "Controller is closed prematually", new IllegalStateException());
- }
- }
-
- @Override
- public void onConnectionSuspended() {
- close();
- }
-
- @Override
- public void onConnectionFailed() {
- close();
- }
- }
-
- private final class ControllerCompatCallback extends MediaControllerCompat.Callback {
- @Override
- public void onSessionReady() {
- sendCommand(CONTROLLER_COMMAND_CONNECT, new ResultReceiver(mHandler) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (!mHandlerThread.isAlive()) {
- return;
- }
- switch (resultCode) {
- case CONNECT_RESULT_CONNECTED:
- onConnectedNotLocked(resultData);
- break;
- case CONNECT_RESULT_DISCONNECTED:
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onDisconnected(mInstance);
- }
- });
- close();
- break;
- }
- }
- });
- }
-
- @Override
- public void onSessionDestroyed() {
- close();
- }
-
- @Override
- public void onPlaybackStateChanged(PlaybackStateCompat state) {
- synchronized (mLock) {
- mPlaybackStateCompat = state;
- }
- }
-
- @Override
- public void onMetadataChanged(MediaMetadataCompat metadata) {
- synchronized (mLock) {
- mMediaMetadataCompat = metadata;
- }
- }
-
- @Override
- public void onSessionEvent(String event, Bundle extras) {
- if (extras != null) {
- extras.setClassLoader(MediaSession2.class.getClassLoader());
- }
- switch (event) {
- case SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED: {
- final SessionCommandGroup2 allowedCommands = SessionCommandGroup2.fromBundle(
- extras.getBundle(ARGUMENT_ALLOWED_COMMANDS));
- synchronized (mLock) {
- mAllowedCommands = allowedCommands;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onAllowedCommandsChanged(mInstance, allowedCommands);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_PLAYER_STATE_CHANGED: {
- final 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;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onPlayerStateChanged(mInstance, playerState);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_CURRENT_MEDIA_ITEM_CHANGED: {
- final MediaItem2 item = MediaItem2.fromBundle(
- extras.getBundle(ARGUMENT_MEDIA_ITEM));
- synchronized (mLock) {
- mCurrentMediaItem = item;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onCurrentMediaItemChanged(mInstance, item);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_ERROR: {
- final int errorCode = extras.getInt(ARGUMENT_ERROR_CODE);
- final Bundle errorExtras = extras.getBundle(ARGUMENT_EXTRAS);
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onError(mInstance, errorCode, errorExtras);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_ROUTES_INFO_CHANGED: {
- final List<Bundle> routes = MediaUtils2.toBundleList(
- extras.getParcelableArray(ARGUMENT_ROUTE_BUNDLE));
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onRoutesInfoChanged(mInstance, routes);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_PLAYLIST_CHANGED: {
- final MediaMetadata2 playlistMetadata = MediaMetadata2.fromBundle(
- extras.getBundle(ARGUMENT_PLAYLIST_METADATA));
- final List<MediaItem2> playlist = MediaUtils2.fromMediaItem2ParcelableArray(
- extras.getParcelableArray(ARGUMENT_PLAYLIST));
- synchronized (mLock) {
- mPlaylist = playlist;
- mPlaylistMetadata = playlistMetadata;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onPlaylistChanged(mInstance, playlist, playlistMetadata);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_PLAYLIST_METADATA_CHANGED: {
- final MediaMetadata2 playlistMetadata = MediaMetadata2.fromBundle(
- extras.getBundle(ARGUMENT_PLAYLIST_METADATA));
- synchronized (mLock) {
- mPlaylistMetadata = playlistMetadata;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onPlaylistMetadataChanged(mInstance, playlistMetadata);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_REPEAT_MODE_CHANGED: {
- final int repeatMode = extras.getInt(ARGUMENT_REPEAT_MODE);
- synchronized (mLock) {
- mRepeatMode = repeatMode;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onRepeatModeChanged(mInstance, repeatMode);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_SHUFFLE_MODE_CHANGED: {
- final int shuffleMode = extras.getInt(ARGUMENT_SHUFFLE_MODE);
- synchronized (mLock) {
- mShuffleMode = shuffleMode;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onShuffleModeChanged(mInstance, shuffleMode);
- }
- });
- break;
- }
- case SESSION_EVENT_SEND_CUSTOM_COMMAND: {
- Bundle commandBundle = extras.getBundle(ARGUMENT_CUSTOM_COMMAND);
- if (commandBundle == null) {
- return;
- }
- final SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
- final Bundle args = extras.getBundle(ARGUMENT_ARGUMENTS);
- final ResultReceiver receiver = extras.getParcelable(ARGUMENT_RESULT_RECEIVER);
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onCustomCommand(mInstance, command, args, receiver);
- }
- });
- break;
- }
- case SESSION_EVENT_SET_CUSTOM_LAYOUT: {
- final List<CommandButton> layout = MediaUtils2.fromCommandButtonParcelableArray(
- extras.getParcelableArray(ARGUMENT_COMMAND_BUTTONS));
- if (layout == null) {
- return;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onCustomLayoutChanged(mInstance, layout);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED: {
- final PlaybackInfo info = PlaybackInfo.fromBundle(
- extras.getBundle(ARGUMENT_PLAYBACK_INFO));
- if (info == null) {
- return;
- }
- synchronized (mLock) {
- mPlaybackInfo = info;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onPlaybackInfoChanged(mInstance, info);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_PLAYBACK_SPEED_CHANGED: {
- final PlaybackStateCompat state =
- extras.getParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT);
- if (state == null) {
- return;
- }
- synchronized (mLock) {
- mPlaybackStateCompat = state;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onPlaybackSpeedChanged(mInstance, state.getPlaybackSpeed());
- }
- });
- break;
- }
- case SESSION_EVENT_ON_BUFFERING_STATE_CHANGED: {
- final MediaItem2 item = MediaItem2.fromBundle(
- extras.getBundle(ARGUMENT_MEDIA_ITEM));
- final int bufferingState = extras.getInt(ARGUMENT_BUFFERING_STATE);
- PlaybackStateCompat state =
- extras.getParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT);
- if (item == null || state == null) {
- return;
- }
- synchronized (mLock) {
- mBufferingState = bufferingState;
- mPlaybackStateCompat = state;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onBufferingStateChanged(mInstance, item, bufferingState);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_SEEK_COMPLETED: {
- final long position = extras.getLong(ARGUMENT_SEEK_POSITION);
- PlaybackStateCompat state =
- extras.getParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT);
- if (state == null) {
- return;
- }
- synchronized (mLock) {
- mPlaybackStateCompat = state;
- }
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onSeekCompleted(mInstance, position);
- }
- });
- break;
- }
- case SESSION_EVENT_ON_CHILDREN_CHANGED: {
- String parentId = extras.getString(ARGUMENT_MEDIA_ID);
- if (parentId == null || !(mInstance instanceof MediaBrowser2)) {
- return;
- }
- int itemCount = extras.getInt(ARGUMENT_ITEM_COUNT, -1);
- Bundle childrenExtras = extras.getBundle(ARGUMENT_EXTRAS);
- ((MediaBrowser2.BrowserCallback) mCallback).onChildrenChanged(
- (MediaBrowser2) mInstance, parentId, itemCount, childrenExtras);
- break;
- }
- case SESSION_EVENT_ON_SEARCH_RESULT_CHANGED: {
- final String query = extras.getString(ARGUMENT_QUERY);
- if (query == null || !(mInstance instanceof MediaBrowser2)) {
- return;
- }
- final int itemCount = extras.getInt(ARGUMENT_ITEM_COUNT, -1);
- final Bundle searchExtras = extras.getBundle(ARGUMENT_EXTRAS);
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- ((MediaBrowser2.BrowserCallback) mCallback).onSearchResultChanged(
- (MediaBrowser2) mInstance, query, itemCount, searchExtras);
- }
- });
- break;
- }
- }
- }
- }
-}
diff --git a/media/src/main/java/androidx/media/MediaLibraryService2.java b/media/src/main/java/androidx/media/MediaLibraryService2.java
index 9e3bfda..edd97c3 100644
--- a/media/src/main/java/androidx/media/MediaLibraryService2.java
+++ b/media/src/main/java/androidx/media/MediaLibraryService2.java
@@ -19,27 +19,28 @@
import static android.support.v4.media.MediaBrowserCompat.EXTRA_PAGE;
import static android.support.v4.media.MediaBrowserCompat.EXTRA_PAGE_SIZE;
-import static androidx.media.MediaConstants2.ARGUMENT_EXTRAS;
-import static androidx.media.MediaConstants2.ARGUMENT_PAGE;
-import static androidx.media.MediaConstants2.ARGUMENT_PAGE_SIZE;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import android.app.PendingIntent;
import android.content.Intent;
-import android.os.BadParcelableException;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.media.MediaBrowserCompat.MediaItem;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
import androidx.media.MediaLibraryService2.MediaLibrarySession.Builder;
import androidx.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
import androidx.media.MediaSession2.ControllerInfo;
+import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
/**
+ * @hide
* Base class for media library services.
* <p>
* Media library services enable applications to browse media content provided by an application
@@ -61,6 +62,7 @@
*
* @see MediaSessionService2
*/
+@RestrictTo(LIBRARY_GROUP)
public abstract class MediaLibraryService2 extends MediaSessionService2 {
/**
* This is the interface name that a service implementing a session service should say that it
@@ -68,6 +70,8 @@
*/
public static final String SERVICE_INTERFACE = "android.media.MediaLibraryService2";
+ // TODO: Revisit this value.
+
/**
* Session for the {@link MediaLibraryService2}. Build this object with
* {@link Builder} and return in {@link #onCreateSession(String)}.
@@ -166,6 +170,7 @@
* @param parentId parent id
* @see SessionCommand2#COMMAND_CODE_LIBRARY_UNSUBSCRIBE
*/
+ // TODO: Make this to be called.
public void onUnsubscribe(@NonNull MediaLibrarySession session,
@NonNull ControllerInfo controller, @NonNull String parentId) {
}
@@ -212,8 +217,6 @@
*/
// Override all methods just to show them with the type instead of generics in Javadoc.
// This workarounds javadoc issue described in the MediaSession2.BuilderBase.
- // Note: Don't override #setSessionCallback() because the callback can be set by the
- // constructor.
public static final class Builder extends MediaSession2.BuilderBase<MediaLibrarySession,
Builder, MediaLibrarySessionCallback> {
private MediaLibrarySessionImplBase.Builder mImpl;
@@ -232,7 +235,7 @@
}
@Override
- public @NonNull Builder setPlayer(@NonNull MediaPlayerInterface player) {
+ public @NonNull Builder setPlayer(@NonNull MediaPlayerBase player) {
return super.setPlayer(player);
}
@@ -258,6 +261,12 @@
}
@Override
+ public @NonNull Builder setSessionCallback(@NonNull Executor executor,
+ @NonNull MediaLibrarySessionCallback callback) {
+ return super.setSessionCallback(executor, callback);
+ }
+
+ @Override
public @NonNull MediaLibrarySession build() {
return super.build();
}
@@ -282,10 +291,9 @@
*/
public void notifyChildrenChanged(@NonNull ControllerInfo controller,
@NonNull String parentId, int itemCount, @Nullable Bundle extras) {
- List<MediaSessionManager.RemoteUserInfo> subscribingBrowsers =
- getServiceCompat().getSubscribingBrowsers(parentId);
- getImpl().notifyChildrenChanged(controller, parentId, itemCount, extras,
- subscribingBrowsers);
+ Bundle options = new Bundle(extras);
+ options.putInt(MediaBrowser2.EXTRA_ITEM_COUNT, itemCount);
+ options.putBundle(MediaBrowser2.EXTRA_TARGET, controller.toBundle());
}
/**
@@ -300,11 +308,9 @@
// This is for the backward compatibility.
public void notifyChildrenChanged(@NonNull String parentId, int itemCount,
@Nullable Bundle extras) {
- if (extras == null) {
- getServiceCompat().notifyChildrenChanged(parentId);
- } else {
- getServiceCompat().notifyChildrenChanged(parentId, extras);
- }
+ Bundle options = new Bundle(extras);
+ options.putInt(MediaBrowser2.EXTRA_ITEM_COUNT, itemCount);
+ getServiceCompat().notifyChildrenChanged(parentId, options);
}
/**
@@ -316,8 +322,8 @@
* @param extras extra bundle
*/
public void notifySearchResultChanged(@NonNull ControllerInfo controller,
- @NonNull String query, int itemCount, @Nullable Bundle extras) {
- getImpl().notifySearchResultChanged(controller, query, itemCount, extras);
+ @NonNull String query, int itemCount, @NonNull Bundle extras) {
+ // TODO: Implement
}
private MediaLibraryService2 getService() {
@@ -488,7 +494,10 @@
// controller.
return sDefaultBrowserRoot;
}
- final ControllerInfo controller = getController();
+ 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);
MediaLibrarySession session = getLibrarySession();
// Call onGetLibraryRoot() directly instead of execute on the executor. Here's the
// reason.
@@ -502,7 +511,7 @@
// Because of the reason, just call onGetLibraryRoot directly here. onGetLibraryRoot()
// has documentation that it may be called on the main thread.
LibraryRoot libraryRoot = session.getCallback().onGetLibraryRoot(
- session, controller, extras);
+ session, info, extras);
if (libraryRoot == null) {
return null;
}
@@ -517,47 +526,36 @@
@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() {
- if (options != null) {
- options.setClassLoader(MediaLibraryService2.this.getClassLoader());
- try {
- int page = options.getInt(EXTRA_PAGE);
- int pageSize = options.getInt(EXTRA_PAGE_SIZE);
- if (page > 0 && pageSize > 0) {
- // Requesting the list of children through pagination.
- List<MediaItem2> children = getLibrarySession().getCallback()
- .onGetChildren(getLibrarySession(), controller, parentId,
- page, pageSize, options);
- result.sendResult(MediaUtils2.fromMediaItem2List(children));
- return;
- } else if (options.containsKey(
- MediaBrowser2.MEDIA_BROWSER2_SUBSCRIBE)) {
- // This onLoadChildren() was triggered by MediaBrowser2.subscribe().
- options.remove(MediaBrowser2.MEDIA_BROWSER2_SUBSCRIBE);
- getLibrarySession().getCallback().onSubscribe(getLibrarySession(),
- controller, parentId, options.getBundle(ARGUMENT_EXTRAS));
- return;
+ 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)));
}
- } catch (BadParcelableException e) {
- // pass-through.
+ result.sendResult(list);
}
+ } else {
+ // Only wants to register callbacks
+ getLibrarySession().getCallback().onSubscribe(getLibrarySession(),
+ controller, parentId, options);
}
- List<MediaItem2> children = getLibrarySession().getCallback()
- .onGetChildren(getLibrarySession(), controller, parentId,
- 1 /* page */, Integer.MAX_VALUE /* pageSize*/,
- null /* extras */);
- result.sendResult(MediaUtils2.fromMediaItem2List(children));
}
});
}
@Override
public void onLoadItem(final String itemId, final Result<MediaItem> result) {
- result.detach();
final ControllerInfo controller = getController();
getLibrarySession().getCallbackExecutor().execute(new Runnable() {
@Override
@@ -565,7 +563,7 @@
MediaItem2 item = getLibrarySession().getCallback().onGetItem(
getLibrarySession(), controller, itemId);
if (item == null) {
- result.sendResult(null);
+ result.sendError(null);
} else {
result.sendResult(MediaUtils2.createMediaItem(item));
}
@@ -574,65 +572,17 @@
}
@Override
- public void onSearch(final String query, final Bundle extras,
- final Result<List<MediaItem>> result) {
- result.detach();
- final ControllerInfo controller = getController();
- extras.setClassLoader(MediaLibraryService2.this.getClassLoader());
- try {
- final int page = extras.getInt(ARGUMENT_PAGE);
- final int pageSize = extras.getInt(ARGUMENT_PAGE_SIZE);
- if (!(page > 0 && pageSize > 0)) {
- getLibrarySession().getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- getLibrarySession().getCallback().onSearch(
- getLibrarySession(), controller, query, extras);
- }
- });
- } else {
- getLibrarySession().getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- List<MediaItem2> searchResult = getLibrarySession().getCallback()
- .onGetSearchResult(getLibrarySession(), controller, query,
- page, pageSize, extras);
- if (searchResult == null) {
- result.sendResult(null);
- return;
- }
- result.sendResult(MediaUtils2.fromMediaItem2List(searchResult));
- }
- });
- }
- } catch (BadParcelableException e) {
- // Do nothing.
- }
+ public void onSearch(String query, Bundle extras, Result<List<MediaItem>> result) {
+ // TODO: Implement
}
@Override
public void onCustomAction(String action, Bundle extras, Result<Bundle> result) {
- // No-op. Library session will handle the custom action.
+ // TODO: Implement
}
private ControllerInfo getController() {
- MediaLibrarySession session = getLibrarySession();
- List<ControllerInfo> controllers = session.getConnectedControllers();
-
- MediaSessionManager.RemoteUserInfo info = getCurrentBrowserInfo();
- if (info == null) {
- return null;
- }
-
- for (int i = 0; i < controllers.size(); i++) {
- // Note: This cannot pick the right controller between two controllers in same
- // process.
- ControllerInfo controller = controllers.get(i);
- if (controller.getPackageName().equals(info.getPackageName())
- && controller.getUid() == info.getUid()) {
- return controller;
- }
- }
+ // TODO: Implement, by using getBrowserRootHints() / getCurrentBrowserInfo() / ...
return null;
}
}
diff --git a/media/src/main/java/androidx/media/MediaLibrarySessionImplBase.java b/media/src/main/java/androidx/media/MediaLibrarySessionImplBase.java
index dfaa98c..c21edd3 100644
--- a/media/src/main/java/androidx/media/MediaLibrarySessionImplBase.java
+++ b/media/src/main/java/androidx/media/MediaLibrarySessionImplBase.java
@@ -31,7 +31,7 @@
class MediaLibrarySessionImplBase extends MediaSession2ImplBase {
MediaLibrarySessionImplBase(Context context,
MediaSessionCompat sessionCompat, String id,
- MediaPlayerInterface player, MediaPlaylistAgent playlistAgent,
+ MediaPlayerBase player, MediaPlaylistAgent playlistAgent,
VolumeProviderCompat volumeProvider, PendingIntent sessionActivity,
Executor callbackExecutor,
MediaSession2.SessionCallback callback) {
@@ -39,11 +39,6 @@
callbackExecutor, callback);
}
- @Override
- MediaSession2 createInstance() {
- return new MediaLibrarySession(this);
- }
-
static final class Builder extends MediaSession2ImplBase.BuilderBase<
MediaLibrarySession, MediaLibrarySession.MediaLibrarySessionCallback> {
Builder(Context context) {
diff --git a/media/src/main/java/androidx/media/MediaPlayer2.java b/media/src/main/java/androidx/media/MediaPlayer2.java
index 4edb946..1864d72 100644
--- a/media/src/main/java/androidx/media/MediaPlayer2.java
+++ b/media/src/main/java/androidx/media/MediaPlayer2.java
@@ -28,7 +28,6 @@
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;
@@ -48,16 +47,27 @@
import java.util.UUID;
import java.util.concurrent.Executor;
+
/**
- * MediaPlayer2 class can be used to control playback of audio/video files and streams.
+ * @hide
+ * MediaPlayer2 class can be used to control playback
+ * of audio/video files and streams. An example on how to use the methods in
+ * this class can be found in {@link android.widget.VideoView}.
*
* <p>Topics covered here are:
* <ol>
* <li><a href="#StateDiagram">State Diagram</a>
+ * <li><a href="#Valid_and_Invalid_States">Valid and Invalid States</a>
* <li><a href="#Permissions">Permissions</a>
* <li><a href="#Callbacks">Register informational and error callbacks</a>
* </ol>
*
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about how to use MediaPlayer2, read the
+ * <a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a> developer guide.</p>
+ * </div>
+ *
* <a name="StateDiagram"></a>
* <h3>State Diagram</h3>
*
@@ -77,18 +87,18 @@
* <p>From this state diagram, one can see that a MediaPlayer2 object has the
* following states:</p>
* <ul>
- * <li>When a MediaPlayer2 object is just created using {@link #create()} or
- * after {@link #reset()} is called, it is in the <strong>Idle</strong> state; and Once
- * {@link #close()} is called, it can no longer be used and there is no way to bring it
- * back to any other state.
+ * <li>When a MediaPlayer2 object is just created using <code>create</code> or
+ * after {@link #reset()} is called, it is in the <em>Idle</em> state; and after
+ * {@link #close()} is called, it is in the <em>End</em> state. Between these
+ * two states is the life cycle of the MediaPlayer2 object.
* <ul>
- * <li>Calling {@link #setDataSource(DataSourceDesc)} and {@link #prepare()} transfers a
- * MediaPlayer2 object in the <strong>Idle</strong> state to the <strong>Paused</strong>
- * state. It is good programming practice to register a event callback for
- * {@link MediaPlayer2EventCallback#onCallCompleted} and
- * look out for {@link #CALL_STATUS_BAD_VALUE} and {@link #CALL_STATUS_ERROR_IO} that may be
- * caused from {@link #setDataSource}.
- * </li>
+ * <li> It is a programming error to invoke methods such
+ * as {@link #getCurrentPosition()},
+ * {@link #getDuration()}, {@link #getVideoHeight()},
+ * {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)},
+ * {@link #setPlayerVolume(float)}, {@link #pause()}, {@link #play()},
+ * {@link #seekTo(long, int)} or
+ * {@link #prepare()} in the <em>Idle</em> state.
* <li>It is also recommended that once
* a MediaPlayer2 object is no longer being used, call {@link #close()} immediately
* so that resources used by the internal player engine associated with the
@@ -96,7 +106,13 @@
* singleton resources such as hardware acceleration components and
* failure to call {@link #close()} may cause subsequent instances of
* MediaPlayer2 objects to fallback to software implementations or fail
- * altogether. </li>
+ * altogether. Once the MediaPlayer2
+ * object is in the <em>End</em> state, it can no longer be used and
+ * there is no way to bring it back to any other state. </li>
+ * <li>Furthermore,
+ * the MediaPlayer2 objects created using <code>new</code> is in the
+ * <em>Idle</em> state.
+ * </li>
* </ul>
* </li>
* <li>In general, some playback control operation may fail due to various
@@ -105,55 +121,71 @@
* Thus, error reporting and recovery is an important concern under
* these circumstances. Sometimes, due to programming errors, invoking a playback
* control operation in an invalid state may also occur. Under all these
- * error conditions, the player goes to <strong>Error</strong> state and invokes a user
- * supplied {@link MediaPlayer2EventCallback#onError}} method if an event callback has been
- * registered beforehand via {@link #setMediaPlayer2EventCallback}.
+ * error conditions, the internal player engine invokes a user supplied
+ * MediaPlayer2EventCallback.onError() method if an MediaPlayer2EventCallback has been
+ * registered beforehand via
+ * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.
* <ul>
* <li>It is important to note that once an error occurs, the
- * MediaPlayer2 object enters the <strong>Error</strong> state (except as noted
- * above), even if a callback has not been registered by the application.</li>
- * <li>In order to reuse a MediaPlayer2 object that is in the <strong>
- * Error</strong> state and recover from the error,
- * {@link #reset()} can be called to restore the object to its <strong>Idle</strong>
+ * MediaPlayer2 object enters the <em>Error</em> state (except as noted
+ * above), even if an error listener has not been registered by the application.</li>
+ * <li>In order to reuse a MediaPlayer2 object that is in the <em>
+ * Error</em> state and recover from the error,
+ * {@link #reset()} can be called to restore the object to its <em>Idle</em>
* state.</li>
* <li>It is good programming practice to have your application
- * register a {@link MediaPlayer2EventCallback} to look out for error callbacks from
+ * register a OnErrorListener to look out for error notifications from
* the internal player engine.</li>
- * <li> {@link MediaPlayer2EventCallback#onCallCompleted} is called with
- * {@link #CALL_STATUS_INVALID_OPERATION} on programming errors such as calling
- * {@link #prepare()} and {@link #setDataSource(DataSourceDesc)} methods in an invalid
- * state. </li>
+ * <li>IllegalStateException is
+ * thrown to prevent programming errors such as calling
+ * {@link #prepare()}, {@link #setDataSource(DataSourceDesc)}
+ * methods in an invalid state. </li>
* </ul>
* </li>
- * <li>A MediaPlayer2 object must first enter the <strong>Paused</strong> state
+ * <li>Calling
+ * {@link #setDataSource(DataSourceDesc)} transfers a
+ * MediaPlayer2 object in the <em>Idle</em> state to the
+ * <em>Initialized</em> state.
+ * <ul>
+ * <li>An IllegalStateException is thrown if
+ * setDataSource() is called in any other state.</li>
+ * <li>It is good programming
+ * practice to always look out for <code>IllegalArgumentException</code>
+ * and <code>IOException</code> that may be thrown from
+ * <code>setDataSource</code>.</li>
+ * </ul>
+ * </li>
+ * <li>A MediaPlayer2 object must first enter the <em>Prepared</em> state
* before playback can be started.
* <ul>
- * <li>The <strong>Paused</strong> state can be reached by calling {@link #prepare()}. Note
- * that {@link #prepare()} is asynchronous. When the preparation completes,
+ * <li>There are an asynchronous way that the <em>Prepared</em> state can be reached:
+ * a call to {@link #prepare()} (asynchronous) which
+ * first transfers the object to the <em>Preparing</em> state after the
+ * call returns (which occurs almost right way) while the internal
+ * player engine continues working on the rest of preparation work
+ * until the preparation work completes. When the preparation completes,
* the internal player engine then calls a user supplied callback method,
- * {@link MediaPlayer2EventCallback#onInfo} interface with {@link #MEDIA_INFO_PREPARED},
- * if a MediaPlayer2EventCallback is registered beforehand via
+ * onInfo() of the MediaPlayer2EventCallback interface with {@link #MEDIA_INFO_PREPARED},
+ * if an MediaPlayer2EventCallback is registered beforehand via
* {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.</li>
- * <li>The player also goes to <strong>Paused</strong> state when {@link #pause()} is called
- * to pause the ongoing playback. Note that {@link #pause()} is asynchronous. Once
- * {@link #pause()} is processed successfully by the internal media engine,
- * <strong>Paused</strong> state will be notified with
- * {@link MediaPlayerInterface.PlayerEventCallback#onPlayerStateChanged} callback.
- * In addition to the callback, {@link #getMediaPlayer2State()} can also be used to test
- * whether the MediaPlayer2 object is in the <strong>Paused</strong> state.
- * </li>
- * <li>While in the <em>Paused</em> state, properties such as audio/sound volume, looping
- * can be adjusted by invoking the corresponding set methods.</li>
+ * <li>It is important to note that
+ * the <em>Preparing</em> state is a transient state, and the behavior
+ * of calling any method with side effect while a MediaPlayer2 object is
+ * in the <em>Preparing</em> state is undefined.</li>
+ * <li>An IllegalStateException is
+ * thrown if {@link #prepare()} is called in
+ * any other state.</li>
+ * <li>While in the <em>Prepared</em> state, properties
+ * such as audio/sound volume, screenOnWhilePlaying, looping can be
+ * adjusted by invoking the corresponding set methods.</li>
* </ul>
* </li>
- * <li>To start the playback, {@link #play()} must be called. Once {@link #play()} is processed
- * successfully by the internal media engine, <strong>Playing</strong> state will be
- * notified with {@link MediaPlayerInterface.PlayerEventCallback#onPlayerStateChanged}
- * callback.
- * In addition to the callback, {@link #getMediaPlayer2State()} can be called to test
- * whether the MediaPlayer2 object is in the <strong>Started</strong> state.
+ * <li>To start the playback, {@link #play()} must be called. After
+ * {@link #play()} returns successfully, the MediaPlayer2 object is in the
+ * <em>Started</em> state. {@link #getPlayerState()} can be called to test
+ * whether the MediaPlayer2 object is in the <em>Started</em> state.
* <ul>
- * <li>While in the <strong>Playing</strong> state, the internal player engine calls
+ * <li>While in the <em>Started</em> state, the internal player engine calls
* a user supplied callback method MediaPlayer2EventCallback.onInfo() with
* {@link #MEDIA_INFO_BUFFERING_UPDATE} if an MediaPlayer2EventCallback has been
* registered beforehand via
@@ -161,21 +193,42 @@
* This callback allows applications to keep track of the buffering status
* while streaming audio/video.</li>
* <li>Calling {@link #play()} has not effect
- * on a MediaPlayer2 object that is already in the <strong>Playing</strong> state.</li>
+ * on a MediaPlayer2 object that is already in the <em>Started</em> state.</li>
* </ul>
* </li>
- * <li>The playback position can be adjusted with a call to {@link #seekTo}.
+ * <li>Playback can be paused and stopped, and the current playback position
+ * can be adjusted. Playback can be paused via {@link #pause()}. When the call to
+ * {@link #pause()} returns, the MediaPlayer2 object enters the
+ * <em>Paused</em> state. Note that the transition from the <em>Started</em>
+ * state to the <em>Paused</em> state and vice versa happens
+ * asynchronously in the player engine. It may take some time before
+ * the state is updated in calls to {@link #getPlayerState()}, and it can be
+ * a number of seconds in the case of streamed content.
* <ul>
- * <li>Although the asynchronous {@link #seekTo} call returns right away,
- * the actual seek operation may take a while to
+ * <li>Calling {@link #play()} to resume playback for a paused
+ * MediaPlayer2 object, and the resumed playback
+ * position is the same as where it was paused. When the call to
+ * {@link #play()} returns, the paused MediaPlayer2 object goes back to
+ * the <em>Started</em> state.</li>
+ * <li>Calling {@link #pause()} has no effect on
+ * a MediaPlayer2 object that is already in the <em>Paused</em> state.</li>
+ * </ul>
+ * </li>
+ * <li>The playback position can be adjusted with a call to
+ * {@link #seekTo(long, int)}.
+ * <ul>
+ * <li>Although the asynchronuous {@link #seekTo(long, int)}
+ * call returns right away, the actual seek operation may take a while to
* finish, especially for audio/video being streamed. When the actual
* seek operation completes, the internal player engine calls a user
* supplied MediaPlayer2EventCallback.onCallCompleted() with
* {@link #CALL_COMPLETED_SEEK_TO}
* if an MediaPlayer2EventCallback has been registered beforehand via
* {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.</li>
- * <li>Please note that {@link #seekTo(long, int)} can also be called in
- * <strong>Paused</strong> state. When {@link #seekTo(long, int)} is called in those states,
+ * <li>Please
+ * note that {@link #seekTo(long, int)} can also be called in the other states,
+ * such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
+ * </em> state. When {@link #seekTo(long, int)} is called in those states,
* one video frame will be displayed if the stream has video and the requested
* position is valid.
* </li>
@@ -188,20 +241,206 @@
* <li>When the playback reaches the end of stream, the playback completes.
* <ul>
* <li>If current source is set to loop by {@link #loopCurrent(boolean)},
- * the MediaPlayer2 object shall remain in the <strong>Playing</strong> state.</li>
+ * the MediaPlayer2 object shall remain in the <em>Started</em> state.</li>
* <li>If the looping mode was set to <var>false
* </var>, the player engine calls a user supplied callback method,
- * {@link MediaPlayer2EventCallback#onInfo} with {@link #MEDIA_INFO_PLAYBACK_COMPLETE},
- * if an MediaPlayer2EventCallback is registered beforehand via
+ * MediaPlayer2EventCallback.onCompletion(), if an MediaPlayer2EventCallback is
+ * registered beforehand via
* {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.
- * The invoke of the callback signals that the object is now in the <strong>Paused</strong>
- * state.</li>
- * <li>While in the <strong>Paused</strong> state, calling {@link #play()} can restart the
- * playback from the beginning of the audio/video source.</li>
+ * The invoke of the callback signals that the object is now in the <em>
+ * PlaybackCompleted</em> state.</li>
+ * <li>While in the <em>PlaybackCompleted</em>
+ * state, calling {@link #play()} can restart the playback from the
+ * beginning of the audio/video source.</li>
* </ul>
*
+ *
+ * <a name="Valid_and_Invalid_States"></a>
+ * <h3>Valid and invalid states</h3>
+ *
+ * <table border="0" cellspacing="0" cellpadding="0">
+ * <tr><td>Method Name </p></td>
+ * <td>Valid Sates </p></td>
+ * <td>Invalid States </p></td>
+ * <td>Comments </p></td></tr>
+ * <tr><td>attachAuxEffect </p></td>
+ * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
+ * <td>{Idle, Error} </p></td>
+ * <td>This method must be called after setDataSource.
+ * Calling it does not change the object state. </p></td></tr>
+ * <tr><td>getAudioSessionId </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change
+ * the object state. </p></td></tr>
+ * <tr><td>getCurrentPosition </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted} </p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object
+ * to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>getDuration </p></td>
+ * <td>{Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
+ * <td>{Idle, Initialized, Error} </p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object
+ * to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>getVideoHeight </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object
+ * to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>getVideoWidth </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change
+ * the state. Calling this method in an invalid state transfers the
+ * object to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>getPlayerState </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change
+ * the state. Calling this method in an invalid state transfers the
+ * object to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>pause </p></td>
+ * <td>{Started, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Prepared, Stopped, Error}</p></td>
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Paused</em> state. Calling this method in an
+ * invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+ * <tr><td>prepare </p></td>
+ * <td>{Initialized, Stopped} </p></td>
+ * <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Preparing</em> state. Calling this method in an
+ * invalid state throws an IllegalStateException.</p></td></tr>
+ * <tr><td>release </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>After {@link #close()}, the object is no longer available. </p></td></tr>
+ * <tr><td>reset </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted, Error}</p></td>
+ * <td>{}</p></td>
+ * <td>After {@link #reset()}, the object is like being just created.</p></td></tr>
+ * <tr><td>seekTo </p></td>
+ * <td>{Prepared, Started, Paused, PlaybackCompleted} </p></td>
+ * <td>{Idle, Initialized, Stopped, Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change
+ * the state. Calling this method in an invalid state transfers the
+ * object to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>setAudioAttributes </p></td>
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method does not change the state. In order for the
+ * target audio attributes type to become effective, this method must be called before
+ * prepare().</p></td></tr>
+ * <tr><td>setAudioSessionId </p></td>
+ * <td>{Idle} </p></td>
+ * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
+ * Error} </p></td>
+ * <td>This method must be called in idle state as the audio session ID must be known before
+ * calling setDataSource. Calling it does not change the object
+ * state. </p></td></tr>
+ * <tr><td>setAudioStreamType (deprecated)</p></td>
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method does not change the state. In order for the
+ * target audio stream type to become effective, this method must be called before
+ * prepare().</p></td></tr>
+ * <tr><td>setAuxEffectSendLevel </p></td>
+ * <td>any</p></td>
+ * <td>{} </p></td>
+ * <td>Calling this method does not change the object state. </p></td></tr>
+ * <tr><td>setDataSource </p></td>
+ * <td>{Idle} </p></td>
+ * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
+ * Error} </p></td>
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Initialized</em> state. Calling this method in an
+ * invalid state throws an IllegalStateException.</p></td></tr>
+ * <tr><td>setDisplay </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change
+ * the object state. </p></td></tr>
+ * <tr><td>setSurface </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change
+ * the object state. </p></td></tr>
+ * <tr><td>loopCurrent </p></td>
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change
+ * the state. Calling this method in an
+ * invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+ * <tr><td>isLooping </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change
+ * the object state. </p></td></tr>
+ * <tr><td>setDrmEventCallback </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change
+ * the object state. </p></td></tr>
+ * <tr><td>setMediaPlayer2EventCallback </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change
+ * the object state. </p></td></tr>
+ * <tr><td>setPlaybackParams</p></td>
+ * <td>{Initialized, Prepared, Started, Paused, PlaybackCompleted, Error}</p></td>
+ * <td>{Idle, Stopped} </p></td>
+ * <td>This method will change state in some cases, depending on when it's called.
+ * </p></td></tr>
+ * <tr><td>setPlayerVolume </p></td>
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.
+ * <tr><td>play </p></td>
+ * <td>{Prepared, Started, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Stopped, Error}</p></td>
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Started</em> state. Calling this method in an
+ * invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+ * <tr><td>stop </p></td>
+ * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Error}</p></td>
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Stopped</em> state. Calling this method in an
+ * invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+ * <tr><td>getTrackInfo </p></td>
+ * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.</p></td></tr>
+ * <tr><td>selectTrack </p></td>
+ * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.</p></td></tr>
+ * <tr><td>deselectTrack </p></td>
+ * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.</p></td></tr>
+ *
+ * </table>
+ *
* <a name="Permissions"></a>
* <h3>Permissions</h3>
+ * <p>One may need to declare a corresponding WAKE_LOCK permission {@link
+ * android.R.styleable#AndroidManifestUsesPermission <uses-permission>}
+ * element.
+ *
* <p>This class requires the {@link android.Manifest.permission#INTERNET} permission
* when used with network-based content.
*
@@ -221,7 +460,8 @@
*
*/
@TargetApi(Build.VERSION_CODES.P)
-public abstract class MediaPlayer2 {
+@RestrictTo(LIBRARY_GROUP)
+public abstract class MediaPlayer2 extends MediaPlayerBase {
/**
* Create a MediaPlayer2 object.
*
@@ -238,12 +478,6 @@
public MediaPlayer2() { }
/**
- * Returns a {@link MediaPlayerInterface} implementation which runs based on
- * this MediaPlayer2 instance.
- */
- public abstract MediaPlayerInterface getMediaPlayerInterface();
-
- /**
* Releases the resources held by this {@code MediaPlayer2} object.
*
* It is considered good practice to call this method when you're
@@ -261,8 +495,13 @@
* of the same codec are supported, some performance degradation
* may be expected when unnecessary multiple instances are used
* at the same time.
+ *
+ * {@code close()} may be safely called after a prior {@code close()}.
+ * This class implements the Java {@code AutoCloseable} interface and
+ * may be used with try-with-resources.
*/
// This is a synchronous call.
+ @Override
public abstract void close();
/**
@@ -274,6 +513,7 @@
*
*/
// This is an asynchronous call.
+ @Override
public abstract void play();
/**
@@ -284,18 +524,21 @@
*
*/
// This is an asynchronous call.
+ @Override
public abstract void prepare();
/**
* Pauses playback. Call play() to resume.
*/
// This is an asynchronous call.
+ @Override
public abstract void pause();
/**
* Tries to play next data source if applicable.
*/
// This is an asynchronous call.
+ @Override
public abstract void skipToNext();
/**
@@ -305,6 +548,7 @@
* @param msec the offset in milliseconds from the start to seek to
*/
// This is an asynchronous call.
+ @Override
public void seekTo(long msec) {
seekTo(msec, SEEK_PREVIOUS_SYNC /* mode */);
}
@@ -314,6 +558,7 @@
*
* @return the current position in milliseconds
*/
+ @Override
public abstract long getCurrentPosition();
/**
@@ -322,6 +567,7 @@
* @return the duration in milliseconds, if no duration is available
* (for example, if streaming live content), -1 is returned.
*/
+ @Override
public abstract long getDuration();
/**
@@ -333,14 +579,25 @@
*
* @return the current buffered media source position in milliseconds
*/
+ @Override
public abstract long getBufferedPosition();
/**
- * Gets the current MediaPlayer2 state.
+ * Gets the current player state.
*
- * @return the current MediaPlayer2 state.
+ * @return the current player state.
*/
- public abstract @MediaPlayer2State int getMediaPlayer2State();
+ @Override
+ public abstract @PlayerState int getPlayerState();
+
+ /**
+ * Gets the current buffering state of the player.
+ * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
+ * buffered.
+ * @return the buffering state, one of the following:
+ */
+ @Override
+ public abstract @BuffState int getBufferingState();
/**
* Sets the audio attributes for this MediaPlayer2.
@@ -350,12 +607,14 @@
* @param attributes a non-null set of audio attributes
*/
// This is an asynchronous call.
+ @Override
public abstract void setAudioAttributes(@NonNull AudioAttributesCompat attributes);
/**
* Gets the audio attributes for this MediaPlayer2.
* @return attributes a set of audio attributes
*/
+ @Override
public abstract @Nullable AudioAttributesCompat getAudioAttributes();
/**
@@ -364,6 +623,7 @@
* @param dsd the descriptor of data source you want to play
*/
// This is an asynchronous call.
+ @Override
public abstract void setDataSource(@NonNull DataSourceDesc dsd);
/**
@@ -373,6 +633,7 @@
* @param dsd the descriptor of data source you want to play after current one
*/
// This is an asynchronous call.
+ @Override
public abstract void setNextDataSource(@NonNull DataSourceDesc dsd);
/**
@@ -381,6 +642,7 @@
* @param dsds the list of data sources you want to play after current one
*/
// This is an asynchronous call.
+ @Override
public abstract void setNextDataSources(@NonNull List<DataSourceDesc> dsds);
/**
@@ -388,6 +650,7 @@
*
* @return the current DataSourceDesc
*/
+ @Override
public abstract @NonNull DataSourceDesc getCurrentDataSource();
/**
@@ -395,6 +658,7 @@
* @param loop true if the current data source is meant to loop.
*/
// This is an asynchronous call.
+ @Override
public abstract void loopCurrent(boolean loop);
/**
@@ -407,6 +671,7 @@
* @param speed the desired playback speed
*/
// This is an asynchronous call.
+ @Override
public abstract void setPlaybackSpeed(float speed);
/**
@@ -414,6 +679,7 @@
* Note that it may differ from the speed set in {@link #setPlaybackSpeed(float)}.
* @return the actual playback speed
*/
+ @Override
public float getPlaybackSpeed() {
return 1.0f;
}
@@ -424,6 +690,7 @@
* {@link #setPlaybackSpeed(float)}.
* @return true if reverse playback is supported.
*/
+ @Override
public boolean isReversePlaybackSupported() {
return false;
}
@@ -438,6 +705,7 @@
* @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
*/
// This is an asynchronous call.
+ @Override
public abstract void setPlayerVolume(float volume);
/**
@@ -445,16 +713,36 @@
* Note that it does not take into account the associated stream volume.
* @return the player volume.
*/
+ @Override
public abstract float getPlayerVolume();
/**
* @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
*/
+ @Override
public float getMaxPlayerVolume() {
return 1.0f;
}
/**
+ * Adds a callback to be notified of events for this player.
+ * @param e the {@link Executor} to be used for the events.
+ * @param cb the callback to receive the events.
+ */
+ // This is a synchronous call.
+ @Override
+ public abstract void registerPlayerEventCallback(@NonNull Executor e,
+ @NonNull PlayerEventCallback cb);
+
+ /**
+ * Removes a previously registered callback for player events
+ * @param cb the callback to remove
+ */
+ // This is a synchronous call.
+ @Override
+ public abstract void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb);
+
+ /**
* Insert a task in the command queue to help the client to identify whether a batch
* of commands has been finished. When this command is processed, a notification
* {@code MediaPlayer2EventCallback.onCommandLabelReached} will be fired with the
@@ -544,7 +832,10 @@
*
* 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();
/**
@@ -639,8 +930,7 @@
/**
* Moves the media to specified time position by considering the given mode.
* <p>
- * When seekTo is finished, the user will be notified via
- * {@link MediaPlayer2EventCallback#onInfo} with {@link #CALL_COMPLETED_SEEK_TO}.
+ * When seekTo is finished, the user will be notified via OnSeekComplete supplied by the user.
* There is at most one active seekTo processed at any time. If there is a to-be-completed
* seekTo, new seekTo requests will be queued in such a way that only the last request
* is kept. When current seekTo is completed, the queued request will be processed if
@@ -658,7 +948,7 @@
public abstract void seekTo(long msec, @SeekMode int mode);
/**
- * Gets current playback position as a {@link MediaTimestamp}.
+ * Get current playback position as a {@link MediaTimestamp}.
* <p>
* The MediaTimestamp represents how the media time correlates to the system time in
* a linear fashion using an anchor and a clock rate. During regular playback, the media
@@ -684,6 +974,7 @@
* data source and calling prepare().
*/
// This is a synchronous call.
+ @Override
public abstract void reset();
/**
@@ -818,9 +1109,8 @@
/**
* Selects a track.
* <p>
- * If a MediaPlayer2 is in invalid state, {@link #CALL_STATUS_INVALID_OPERATION} will be
- * reported with {@link MediaPlayer2EventCallback#onCallCompleted}.
- * If a MediaPlayer2 is in <em>Playing</em> state, the selected track is presented immediately.
+ * If a MediaPlayer2 is in invalid state, it throws an IllegalStateException exception.
+ * If a MediaPlayer2 is in <em>Started</em> state, the selected track is presented immediately.
* If a MediaPlayer2 is not in Started state, it just marks the track to be played.
* </p>
* <p>
@@ -834,10 +1124,13 @@
* </p>
* <p>
* Currently, only timed text tracks or audio tracks can be selected via this method.
+ * In addition, the support for selecting an audio track at runtime is pretty limited
+ * in that an audio track can only be selected in the <em>Prepared</em> state.
* </p>
* @param index the index of the track to be selected. The valid range of the index
* is 0..total number of track - 1. The total number of tracks as well as the type of
* each individual track can be found by calling {@link #getTrackInfo()} method.
+ * @throws IllegalStateException if called in an invalid state.
*
* @see MediaPlayer2#getTrackInfo
*/
@@ -845,7 +1138,7 @@
public abstract void selectTrack(int index);
/**
- * Deselects a track.
+ * Deselect a track.
* <p>
* Currently, the track must be a timed text track and no audio or video tracks can be
* deselected. If the timed text track identified by index has not been
@@ -854,6 +1147,7 @@
* @param index the index of the track to be deselected. The valid range of the index
* is 0..total number of tracks - 1. The total number of tracks as well as the type of
* each individual track can be found by calling {@link #getTrackInfo()} method.
+ * @throws IllegalStateException if called in an invalid state.
*
* @see MediaPlayer2#getTrackInfo
*/
@@ -935,26 +1229,13 @@
@CallStatus int status) { }
/**
- * 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>
+ * Called to indicate media clock has changed.
*
* @param mp the MediaPlayer2 the media time pertains to.
* @param dsd the DataSourceDesc of this data source
- * @param timestamp the timestamp that correlates media time, system time and clock rate,
- * or {@link MediaTimestamp#TIMESTAMP_UNKNOWN} in an error case.
+ * @param timestamp the new media clock.
*/
- public void onMediaTimeDiscontinuity(
+ public void onMediaTimeChanged(
MediaPlayer2 mp, DataSourceDesc dsd, MediaTimestamp timestamp) { }
/**
@@ -966,14 +1247,12 @@
*/
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, DataSourceDesc dsd, @NonNull SubtitleData data) { }
+ // public void onSubtitleData(MediaPlayer2 mp, @NonNull SubtitleData data) { }
}
/**
@@ -992,46 +1271,6 @@
// This is a synchronous call.
public abstract void clearMediaPlayer2EventCallback();
- /**
- * MediaPlayer2 has not been prepared or just has been reset.
- * In this state, MediaPlayer2 doesn't fetch data.
- */
- public static final int MEDIAPLAYER2_STATE_IDLE = 1001;
-
- /**
- * MediaPlayer2 has been just prepared.
- * In this state, MediaPlayer2 just fetches data from media source,
- * but doesn't actively render data.
- */
- public static final int MEDIAPLAYER2_STATE_PREPARED = 1002;
-
- /**
- * MediaPlayer2 is paused.
- * In this state, MediaPlayer2 doesn't actively render data.
- */
- public static final int MEDIAPLAYER2_STATE_PAUSED = 1003;
-
- /**
- * MediaPlayer2 is actively playing back data.
- */
- public static final int MEDIAPLAYER2_STATE_PLAYING = 1004;
-
- /**
- * MediaPlayer2 has hit some fatal error and cannot continue playback.
- */
- public static final int MEDIAPLAYER2_STATE_ERROR = 1005;
-
- /** @hide */
- @IntDef(flag = false, value = {
- MEDIAPLAYER2_STATE_IDLE,
- MEDIAPLAYER2_STATE_PREPARED,
- MEDIAPLAYER2_STATE_PAUSED,
- MEDIAPLAYER2_STATE_PLAYING,
- MEDIAPLAYER2_STATE_ERROR })
- @Retention(RetentionPolicy.SOURCE)
- @RestrictTo(LIBRARY_GROUP)
- public @interface MediaPlayer2State {}
-
/* Do not change these values without updating their counterparts
* in include/media/mediaplayer2.h!
*/
@@ -1092,9 +1331,7 @@
/** The player switched to this datas source because it is the
* next-to-be-played in the playlist.
* @see MediaPlayer2.MediaPlayer2EventCallback#onInfo
- * @hide
*/
- @RestrictTo(LIBRARY_GROUP)
public static final int MEDIA_INFO_STARTED_AS_NEXT = 2;
/** The player just pushed the very first video frame for rendering.
@@ -1275,6 +1512,16 @@
*/
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
*/
@@ -1362,6 +1609,8 @@
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,
@@ -1412,6 +1661,12 @@
*/
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
*/
@@ -1421,7 +1676,8 @@
CALL_STATUS_INVALID_OPERATION,
CALL_STATUS_BAD_VALUE,
CALL_STATUS_PERMISSION_DENIED,
- CALL_STATUS_ERROR_IO})
+ CALL_STATUS_ERROR_IO,
+ CALL_STATUS_NO_DRM_SCHEME})
@Retention(RetentionPolicy.SOURCE)
@RestrictTo(LIBRARY_GROUP)
public @interface CallStatus {}
@@ -1752,100 +2008,4 @@
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 3504876..3b3e119 100644
--- a/media/src/main/java/androidx/media/MediaPlayer2Impl.java
+++ b/media/src/main/java/androidx/media/MediaPlayer2Impl.java
@@ -28,7 +28,6 @@
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;
@@ -37,7 +36,9 @@
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Parcel;
+import android.os.Parcelable;
import android.os.PersistableBundle;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
import android.view.Surface;
@@ -46,11 +47,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
-import androidx.collection.ArrayMap;
import androidx.core.util.Preconditions;
-import androidx.media.MediaPlayerInterface.BuffState;
-import androidx.media.MediaPlayerInterface.PlayerEventCallback;
-import androidx.media.MediaPlayerInterface.PlayerState;
import java.io.IOException;
import java.nio.ByteOrder;
@@ -73,15 +70,13 @@
private static final String TAG = "MediaPlayer2Impl";
- 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 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 ArrayMap<Integer, Integer> sInfoEventMap;
private static ArrayMap<Integer, Integer> sErrorEventMap;
- private static ArrayMap<Integer, Integer> sPrepareDrmStatusMap;
- private static ArrayMap<Integer, Integer> sStateMap;
static {
sInfoEventMap = new ArrayMap<>();
@@ -111,29 +106,24 @@
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);
-
- sStateMap = new ArrayMap<>();
- sStateMap.put(MEDIAPLAYER2_STATE_IDLE, MediaPlayerInterface.PLAYER_STATE_IDLE);
- sStateMap.put(MEDIAPLAYER2_STATE_PREPARED, MediaPlayerInterface.PLAYER_STATE_PAUSED);
- sStateMap.put(MEDIAPLAYER2_STATE_PAUSED, MediaPlayerInterface.PLAYER_STATE_PAUSED);
- sStateMap.put(MEDIAPLAYER2_STATE_PLAYING, MediaPlayerInterface.PLAYER_STATE_PLAYING);
- sStateMap.put(MEDIAPLAYER2_STATE_ERROR, MediaPlayerInterface.PLAYER_STATE_ERROR);
}
- private MediaPlayerSourceQueue mPlayer;
+ 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 HandlerThread mHandlerThread;
private final Handler mTaskHandler;
@@ -145,6 +135,8 @@
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<>();
@@ -152,21 +144,8 @@
new ArrayMap<>();
private ArrayList<Pair<Executor, DrmEventCallback>> mDrmEventCallbackRecords =
new ArrayList<>();
- private MediaPlayerInterfaceImpl mMediaPlayerInterfaceImpl;
//--- 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()},
@@ -178,24 +157,10 @@
mHandlerThread.start();
Looper looper = mHandlerThread.getLooper();
mTaskHandler = new Handler(looper);
-
- // TODO: To make sure MediaPlayer1 listeners work, the caller thread should have a looper.
- // Fix the framework or document this behavior.
- mPlayer = new MediaPlayerSourceQueue();
- }
-
- /**
- * Returns a {@link MediaPlayerInterface} implementation which runs based on
- * this MediaPlayer2 instance.
- */
- @Override
- public MediaPlayerInterface getMediaPlayerInterface() {
- synchronized (mLock) {
- if (mMediaPlayerInterfaceImpl == null) {
- mMediaPlayerInterfaceImpl = new MediaPlayerInterfaceImpl();
- }
- return mMediaPlayerInterfaceImpl;
- }
+ mPlayer = new MediaPlayer();
+ mPlayerState = PLAYER_STATE_IDLE;
+ mBufferingState = BUFFERING_STATE_UNKNOWN;
+ setUpListeners();
}
/**
@@ -239,7 +204,8 @@
addTask(new Task(CALL_COMPLETED_PLAY, false) {
@Override
void process() {
- mPlayer.play();
+ mPlayer.start();
+ setPlayerState(PLAYER_STATE_PLAYING);
}
});
}
@@ -260,6 +226,7 @@
@Override
void process() throws IOException {
mPlayer.prepareAsync();
+ setBufferingState(BUFFERING_STATE_BUFFERING_AND_STARVED);
}
});
}
@@ -275,6 +242,7 @@
@Override
void process() {
mPlayer.pause();
+ setPlayerState(PLAYER_STATE_PAUSED);
}
});
}
@@ -289,7 +257,7 @@
addTask(new Task(CALL_COMPLETED_SKIP_TO_NEXT, false) {
@Override
void process() {
- mPlayer.skipToNext();
+ // TODO: switch to next data source and play
}
});
}
@@ -327,21 +295,14 @@
@Override
public long getBufferedPosition() {
// Use cached buffered percent for now.
- return mPlayer.getBufferedPosition();
+ return getDuration() * mBufferedPercentageCurrent.get() / 100;
}
- /**
- * Gets the current MediaPlayer2 state.
- *
- * @return the current MediaPlayer2 state.
- */
@Override
- public @MediaPlayer2State int getMediaPlayer2State() {
- return mPlayer.getMediaPlayer2State();
- }
-
- private @MediaPlayerInterface.PlayerState int getPlayerState() {
- return mPlayer.getPlayerState();
+ public @PlayerState int getPlayerState() {
+ synchronized (mLock) {
+ return mPlayerState;
+ }
}
/**
@@ -349,8 +310,11 @@
* During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
* buffered.
*/
- private @MediaPlayerInterface.BuffState int getBufferingState() {
- return mPlayer.getBufferingState();
+ @Override
+ public @BuffState int getBufferingState() {
+ synchronized (mLock) {
+ return mBufferingState;
+ }
}
/**
@@ -397,10 +361,13 @@
void process() {
Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
// TODO: setDataSource could update exist data source
- try {
- mPlayer.setFirst(dsd);
- } catch (IOException e) {
- Log.e(TAG, "process: setDataSource", e);
+ synchronized (mSrcLock) {
+ mCurrentDSD = dsd;
+ mCurrentSrcId = mSrcIdGenerator++;
+ try {
+ handleDataSource(true /* isCurrent */, dsd, mCurrentSrcId);
+ } catch (IOException e) {
+ }
}
}
});
@@ -420,7 +387,21 @@
@Override
void process() {
Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
- handleDataSourceError(mPlayer.setNext(dsd));
+ 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();
+ }
+ }
+ */
}
});
}
@@ -446,14 +427,30 @@
"DataSourceDesc in the source list cannot be null.");
}
}
- handleDataSourceError(mPlayer.setNextMultiple(dsds));
+
+ 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();
+ }
+ }
+ */
}
});
}
@Override
public @NonNull DataSourceDesc getCurrentDataSource() {
- return mPlayer.getFirst().getDSD();
+ synchronized (mSrcLock) {
+ return mCurrentDSD;
+ }
}
/**
@@ -524,7 +521,8 @@
addTask(new Task(CALL_COMPLETED_SET_PLAYER_VOLUME, false) {
@Override
void process() {
- mPlayer.setVolume(volume);
+ mVolume = volume;
+ mPlayer.setVolume(volume, volume);
}
});
}
@@ -536,7 +534,7 @@
*/
@Override
public float getPlayerVolume() {
- return mPlayer.getVolume();
+ return mVolume;
}
/**
@@ -552,7 +550,8 @@
* @param e the {@link Executor} to be used for the events.
* @param cb the callback to receive the events.
*/
- private void registerPlayerEventCallback(@NonNull Executor e,
+ @Override
+ public void registerPlayerEventCallback(@NonNull Executor e,
@NonNull PlayerEventCallback cb) {
if (cb == null) {
throw new IllegalArgumentException("Illegal null PlayerEventCallback");
@@ -570,7 +569,8 @@
* Removes a previously registered callback for player events
* @param cb the callback to remove
*/
- private void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb) {
+ @Override
+ public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb) {
if (cb == null) {
throw new IllegalArgumentException("Illegal null PlayerEventCallback");
}
@@ -628,9 +628,7 @@
*/
@Override
public void clearPendingCommands() {
- synchronized (mTaskLock) {
- mPendingTasks.clear();
- }
+ // TODO: implement this.
}
private void addTask(Task task) {
@@ -652,15 +650,14 @@
}
}
- private static void handleDataSource(MediaPlayerSource src)
+ private void handleDataSource(boolean isCurrent, @NonNull final DataSourceDesc dsd, long srcId)
throws IOException {
- final DataSourceDesc dsd = src.getDSD();
Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
- MediaPlayer player = src.mPlayer;
+ // TODO: handle the case isCurrent is false.
switch (dsd.getType()) {
case DataSourceDesc.TYPE_CALLBACK:
- player.setDataSource(new MediaDataSource() {
+ mPlayer.setDataSource(new MediaDataSource() {
Media2DataSource mDataSource = dsd.getMedia2DataSource();
@Override
public int readAt(long position, byte[] buffer, int offset, int size)
@@ -681,14 +678,14 @@
break;
case DataSourceDesc.TYPE_FD:
- player.setDataSource(
+ mPlayer.setDataSource(
dsd.getFileDescriptor(),
dsd.getFileDescriptorOffset(),
dsd.getFileDescriptorLength());
break;
case DataSourceDesc.TYPE_URI:
- player.setDataSource(
+ mPlayer.setDataSource(
dsd.getUriContext(),
dsd.getUri(),
dsd.getUriHeaders(),
@@ -874,12 +871,9 @@
@Override
public void reset() {
mPlayer.reset();
- synchronized (mLock) {
- mAudioAttributes = null;
- mMp2EventCallbackRecords.clear();
- mPlayerEventCallbackMap.clear();
- mDrmEventCallbackRecords.clear();
- }
+ setPlayerState(PLAYER_STATE_IDLE);
+ setBufferingState(BUFFERING_STATE_UNKNOWN);
+ /* FIXME: reset other internal variables. */
}
/**
@@ -1003,11 +997,45 @@
return null;
}
+ TrackInfoImpl(Parcel in) {
+ mTrackType = in.readInt();
+ // TODO: parcel in the full MediaFormat; currently we are using createSubtitleFormat
+ // even for audio/video tracks, meaning we only set the mime and language.
+ String mime = in.readString();
+ String language = in.readString();
+ mFormat = MediaFormat.createSubtitleFormat(mime, language);
+
+ if (mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
+ mFormat.setInteger(MediaFormat.KEY_IS_AUTOSELECT, in.readInt());
+ mFormat.setInteger(MediaFormat.KEY_IS_DEFAULT, in.readInt());
+ mFormat.setInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, in.readInt());
+ }
+ }
+
TrackInfoImpl(int type, MediaFormat format) {
mTrackType = type;
mFormat = format;
}
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ * May be 0 or {@link android.os.Parcelable#PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ /* package private */ void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mTrackType);
+ dest.writeString(getLanguage());
+
+ if (mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
+ dest.writeString(mFormat.getString(MediaFormat.KEY_MIME));
+ dest.writeInt(mFormat.getInteger(MediaFormat.KEY_IS_AUTOSELECT));
+ dest.writeInt(mFormat.getInteger(MediaFormat.KEY_IS_DEFAULT));
+ dest.writeInt(mFormat.getInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE));
+ }
+ }
+
@Override
public String toString() {
StringBuilder out = new StringBuilder(128);
@@ -1034,6 +1062,23 @@
out.append("}");
return out.toString();
}
+
+ /**
+ * Used to read a TrackInfoImpl from a Parcel.
+ */
+ /* package private */ static final Parcelable.Creator<TrackInfoImpl> CREATOR =
+ new Parcelable.Creator<TrackInfoImpl>() {
+ @Override
+ public TrackInfoImpl createFromParcel(Parcel in) {
+ return new TrackInfoImpl(in);
+ }
+
+ @Override
+ public TrackInfoImpl[] newArray(int size) {
+ return new TrackInfoImpl[size];
+ }
+ };
+
};
/**
@@ -1185,9 +1230,8 @@
mPlayer.setOnDrmConfigHelper(new MediaPlayer.OnDrmConfigHelper() {
@Override
public void onDrmConfig(MediaPlayer mp) {
- MediaPlayerSource src = mPlayer.getSourceForPlayer(mp);
- DataSourceDesc dsd = src == null ? null : src.getDSD();
- listener.onDrmConfig(MediaPlayer2Impl.this, dsd);
+ /** FIXME: pass the right DSD. */
+ listener.onDrmConfig(MediaPlayer2Impl.this, null);
}
});
}
@@ -1296,11 +1340,16 @@
*/
@Override
public void releaseDrm() throws NoDrmSchemeException {
- try {
- mPlayer.releaseDrm();
- } catch (MediaPlayer.NoDrmSchemeException e) {
- throw new NoDrmSchemeException(e.getMessage());
- }
+ 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());
+ }
+ }
+ });
}
@@ -1394,11 +1443,16 @@
@Override
public void restoreDrmKeys(@NonNull final byte[] keySetId)
throws NoDrmSchemeException {
- try {
- mPlayer.restoreKeys(keySetId);
- } catch (MediaPlayer.NoDrmSchemeException e) {
- throw new NoDrmSchemeException(e.getMessage());
- }
+ 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());
+ }
+ }
+ });
}
@@ -1450,16 +1504,46 @@
private void setPlaybackParamsInternal(final PlaybackParams params) {
PlaybackParams current = mPlayer.getPlaybackParams();
mPlayer.setPlaybackParams(params);
- if (current.getSpeed() != params.getSpeed()) {
+ if (Math.abs(current.getSpeed() - params.getSpeed()) > 0.0001f) {
notifyPlayerEvent(new PlayerEventNotifier() {
@Override
public void notify(PlayerEventCallback cb) {
- cb.onPlaybackSpeedChanged(mMediaPlayerInterfaceImpl, params.getSpeed());
+ cb.onPlaybackSpeedChanged(MediaPlayer2Impl.this, params.getSpeed());
}
});
}
}
+ 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) {
@@ -1493,21 +1577,6 @@
}
}
- 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);
}
@@ -1516,34 +1585,28 @@
void notify(PlayerEventCallback callback);
}
- private interface DrmEventNotifier {
- void notify(DrmEventCallback callback);
- }
-
- private void setUpListeners(final MediaPlayerSource src) {
- MediaPlayer p = src.mPlayer;
- p.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+ private void setUpListeners() {
+ mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
- handleDataSourceError(mPlayer.onPrepared(mp));
+ setPlayerState(PLAYER_STATE_PAUSED);
+ setBufferingState(BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
notifyMediaPlayer2Event(new Mp2EventNotifier() {
@Override
public void notify(MediaPlayer2EventCallback callback) {
- MediaPlayer2Impl mp2 = MediaPlayer2Impl.this;
- DataSourceDesc dsd = src.getDSD();
- callback.onInfo(mp2, dsd, MEDIA_INFO_PREPARED, 0);
+ callback.onInfo(MediaPlayer2Impl.this, mCurrentDSD, MEDIA_INFO_PREPARED, 0);
}
});
notifyPlayerEvent(new PlayerEventNotifier() {
@Override
public void notify(PlayerEventCallback cb) {
- cb.onMediaPrepared(mMediaPlayerInterfaceImpl, src.getDSD());
+ cb.onMediaPrepared(MediaPlayer2Impl.this, mCurrentDSD);
}
});
synchronized (mTaskLock) {
if (mCurrentTask != null
&& mCurrentTask.mMediaCallType == CALL_COMPLETED_PREPARE
- && mCurrentTask.mDSD == src.getDSD()
+ && mCurrentTask.mDSD == mCurrentDSD
&& mCurrentTask.mNeedToWaitForEventToComplete) {
mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
mCurrentTask = null;
@@ -1552,18 +1615,18 @@
}
}
});
- p.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
+ mPlayer.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, src.getDSD(), width, height);
+ cb.onVideoSizeChanged(MediaPlayer2Impl.this, mCurrentDSD, width, height);
}
});
}
});
- p.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+ mPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what) {
@@ -1571,52 +1634,50 @@
notifyMediaPlayer2Event(new Mp2EventNotifier() {
@Override
public void notify(MediaPlayer2EventCallback cb) {
- cb.onInfo(MediaPlayer2Impl.this, src.getDSD(),
+ cb.onInfo(MediaPlayer2Impl.this, mCurrentDSD,
MEDIA_INFO_VIDEO_RENDERING_START, 0);
}
});
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
- mPlayer.setBufferingState(
- mp, MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_STARVED);
+ setBufferingState(BUFFERING_STATE_BUFFERING_AND_STARVED);
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
- mPlayer.setBufferingState(
- mp, MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
+ setBufferingState(BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
break;
}
return false;
}
});
- p.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
- handleDataSourceError(mPlayer.onCompletion(mp));
+ setPlayerState(PLAYER_STATE_PAUSED);
notifyMediaPlayer2Event(new Mp2EventNotifier() {
@Override
public void notify(MediaPlayer2EventCallback cb) {
- MediaPlayer2Impl mp2 = MediaPlayer2Impl.this;
- DataSourceDesc dsd = src.getDSD();
- cb.onInfo(mp2, dsd, MEDIA_INFO_PLAYBACK_COMPLETE, 0);
+ cb.onInfo(MediaPlayer2Impl.this, mCurrentDSD, MEDIA_INFO_PLAYBACK_COMPLETE,
+ 0);
}
});
}
});
- p.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+ mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, final int what, final int extra) {
- mPlayer.onError(mp);
+ setPlayerState(PLAYER_STATE_ERROR);
+ setBufferingState(BUFFERING_STATE_UNKNOWN);
notifyMediaPlayer2Event(new Mp2EventNotifier() {
@Override
public void notify(MediaPlayer2EventCallback cb) {
int w = sErrorEventMap.getOrDefault(what, MEDIA_ERROR_UNKNOWN);
- cb.onError(MediaPlayer2Impl.this, src.getDSD(), w, extra);
+ cb.onError(MediaPlayer2Impl.this, mCurrentDSD, w, extra);
}
});
return true;
}
});
- p.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
+ mPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
synchronized (mTaskLock) {
@@ -1634,12 +1695,12 @@
public void notify(PlayerEventCallback cb) {
// TODO: The actual seeked position might be different from the
// requested position. Clarify which one is expected here.
- cb.onSeekCompleted(mMediaPlayerInterfaceImpl, seekPos);
+ cb.onSeekCompleted(MediaPlayer2Impl.this, seekPos);
}
});
}
});
- p.setOnTimedMetaDataAvailableListener(
+ mPlayer.setOnTimedMetaDataAvailableListener(
new MediaPlayer.OnTimedMetaDataAvailableListener() {
@Override
public void onTimedMetaDataAvailable(MediaPlayer mp, final TimedMetaData data) {
@@ -1647,91 +1708,40 @@
@Override
public void notify(MediaPlayer2EventCallback cb) {
cb.onTimedMetaDataAvailable(
- MediaPlayer2Impl.this, src.getDSD(), data);
+ MediaPlayer2Impl.this, mCurrentDSD, data);
}
});
}
});
- p.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+ mPlayer.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, src.getDSD(), w, extra);
+ cb.onInfo(MediaPlayer2Impl.this, mCurrentDSD, w, extra);
}
});
return true;
}
});
- p.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
+ mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, final int percent) {
if (percent >= 100) {
- mPlayer.setBufferingState(
- mp, MediaPlayerInterface.BUFFERING_STATE_BUFFERING_COMPLETE);
+ setBufferingState(BUFFERING_STATE_BUFFERING_COMPLETE);
}
- src.mBufferedPercentage.set(percent);
+ mBufferedPercentageCurrent.set(percent);
notifyMediaPlayer2Event(new Mp2EventNotifier() {
@Override
public void notify(MediaPlayer2EventCallback cb) {
- cb.onInfo(MediaPlayer2Impl.this, src.getDSD(),
+ cb.onInfo(MediaPlayer2Impl.this, mCurrentDSD,
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);
- }
- });
- }
- });
}
/**
@@ -1934,10 +1944,14 @@
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;
}
- mDSD = getCurrentDataSource();
+ synchronized (mSrcLock) {
+ mDSD = mCurrentDSD;
+ }
if (!mNeedToWaitForEventToComplete || status != CALL_STATUS_NO_ERROR) {
@@ -1965,590 +1979,4 @@
});
}
};
-
- 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;
- @MediaPlayer2State int mMp2State = MEDIAPLAYER2_STATE_IDLE;
- @BuffState int mBufferingState = MediaPlayerInterface.BUFFERING_STATE_UNKNOWN;
- @PlayerState int mPlayerState = MediaPlayerInterface.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 prepareAt(0);
- } else {
- mQueue.add(1, src);
- return prepareAt(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 prepareAt(0);
- } else {
- mQueue.addAll(1, sources);
- return prepareAt(1);
- }
- }
-
- synchronized void play() {
- MediaPlayerSource src = mQueue.get(0);
- if (src.mSourceState == SOURCE_STATE_PREPARED) {
- src.mPlayer.start();
- setMp2State(src.mPlayer, MEDIAPLAYER2_STATE_PLAYING);
- }
- }
-
- synchronized void prepare() {
- getCurrentPlayer().prepareAsync();
- }
-
- synchronized void release() {
- getCurrentPlayer().release();
- }
-
- synchronized void prepareAsync() {
- MediaPlayer mp = getCurrentPlayer();
- mp.prepareAsync();
- setBufferingState(mp, MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_STARVED);
- }
-
- synchronized void pause() {
- MediaPlayer mp = getCurrentPlayer();
- mp.pause();
- setMp2State(mp, MEDIAPLAYER2_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();
- setMp2State(src.mPlayer, MEDIAPLAYER2_STATE_PLAYING);
- } else {
- setMp2State(src.mPlayer, MEDIAPLAYER2_STATE_PREPARED);
- }
- }
- src.mSourceState = SOURCE_STATE_PREPARED;
- setBufferingState(src.mPlayer,
- MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
- return prepareAt(i + 1);
- }
- }
- return null;
- }
-
- synchronized DataSourceError onCompletion(MediaPlayer mp) {
- if (!mQueue.isEmpty() && mp == getCurrentPlayer()) {
- if (mQueue.size() == 1) {
- setMp2State(mp, MEDIAPLAYER2_STATE_PAUSED);
- return null;
- }
- moveToNext();
- }
- return playCurrent();
- }
-
- synchronized void moveToNext() {
- final MediaPlayerSource src1 = mQueue.remove(0);
- src1.mPlayer.release();
- if (mQueue.isEmpty()) {
- throw new IllegalStateException("player/source queue emptied");
- }
- final MediaPlayerSource src2 = mQueue.get(0);
- if (src1.mPlayerState != src2.mPlayerState) {
- notifyPlayerEvent(new PlayerEventNotifier() {
- @Override
- public void notify(PlayerEventCallback cb) {
- cb.onPlayerStateChanged(mMediaPlayerInterfaceImpl, src2.mPlayerState);
- }
- });
- }
- notifyPlayerEvent(new PlayerEventNotifier() {
- @Override
- public void notify(PlayerEventCallback cb) {
- cb.onCurrentDataSourceChanged(mMediaPlayerInterfaceImpl, src2.mDSD);
- }
- });
- }
-
- synchronized DataSourceError playCurrent() {
- 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 = prepareAt(0);
- }
- src.mPlayPending = true;
- }
- return err;
- }
-
- synchronized void onError(MediaPlayer mp) {
- setMp2State(mp, MEDIAPLAYER2_STATE_ERROR);
- setBufferingState(mp, MediaPlayerInterface.BUFFERING_STATE_UNKNOWN);
- }
-
- synchronized DataSourceError prepareAt(int n) {
- if (n >= mQueue.size()
- || mQueue.get(n).mSourceState != SOURCE_STATE_INIT
- || getPlayerState() == MediaPlayerInterface.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();
- setMp2State(src.mPlayer, MEDIAPLAYER2_STATE_ERROR);
- return new DataSourceError(dsd, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED);
- }
-
- }
-
- synchronized void skipToNext() {
- if (mQueue.size() <= 1) {
- throw new IllegalStateException("No next source available");
- }
- final MediaPlayerSource src = mQueue.get(0);
- moveToNext();
- if (src.mPlayerState == MediaPlayerInterface.PLAYER_STATE_PLAYING) {
- playCurrent();
- }
- }
-
- 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;
- setMp2State(src.mPlayer, MEDIAPLAYER2_STATE_IDLE);
- setBufferingState(src.mPlayer, MediaPlayerInterface.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 setMp2State(MediaPlayer mp, @MediaPlayer2State int mp2State) {
- for (final MediaPlayerSource src: mQueue) {
- if (src.mPlayer != mp) {
- continue;
- }
- if (src.mMp2State == mp2State) {
- return;
- }
- src.mMp2State = mp2State;
-
- final int playerState = sStateMap.get(mp2State);
- if (src.mPlayerState == playerState) {
- return;
- }
- src.mPlayerState = playerState;
- notifyPlayerEvent(new PlayerEventNotifier() {
- @Override
- public void notify(PlayerEventCallback cb) {
- cb.onPlayerStateChanged(mMediaPlayerInterfaceImpl, playerState);
- }
- });
- 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) {
- DataSourceDesc dsd = src.getDSD();
- cb.onBufferingStateChanged(mMediaPlayerInterfaceImpl, dsd, state);
- }
- });
- return;
- }
- }
-
- synchronized @MediaPlayer2State int getMediaPlayer2State() {
- return mQueue.get(0).mMp2State;
- }
-
- 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;
- }
- }
-
- private class MediaPlayerInterfaceImpl extends MediaPlayerInterface {
- @Override
- public void play() {
- MediaPlayer2Impl.this.play();
- }
-
- @Override
- public void prepare() {
- MediaPlayer2Impl.this.prepare();
- }
-
- @Override
- public void pause() {
- MediaPlayer2Impl.this.pause();
- }
-
- @Override
- public void reset() {
- MediaPlayer2Impl.this.reset();
- }
-
- @Override
- public void skipToNext() {
- MediaPlayer2Impl.this.skipToNext();
- }
-
- @Override
- public void seekTo(long pos) {
- MediaPlayer2Impl.this.seekTo(pos);
- }
-
- @Override
- public long getCurrentPosition() {
- return MediaPlayer2Impl.this.getCurrentPosition();
- }
-
- @Override
- public long getDuration() {
- return MediaPlayer2Impl.this.getDuration();
- }
-
- @Override
- public long getBufferedPosition() {
- return MediaPlayer2Impl.this.getBufferedPosition();
- }
-
- @Override
- public int getPlayerState() {
- return MediaPlayer2Impl.this.getPlayerState();
- }
-
- @Override
- public int getBufferingState() {
- return MediaPlayer2Impl.this.getBufferingState();
- }
-
- @Override
- public void setAudioAttributes(AudioAttributesCompat attributes) {
- MediaPlayer2Impl.this.setAudioAttributes(attributes);
- }
-
- @Override
- public AudioAttributesCompat getAudioAttributes() {
- return MediaPlayer2Impl.this.getAudioAttributes();
- }
-
- @Override
- public void setDataSource(DataSourceDesc dsd) {
- MediaPlayer2Impl.this.setDataSource(dsd);
- }
-
- @Override
- public void setNextDataSource(DataSourceDesc dsd) {
- MediaPlayer2Impl.this.setNextDataSource(dsd);
- }
-
- @Override
- public void setNextDataSources(List<DataSourceDesc> dsds) {
- MediaPlayer2Impl.this.setNextDataSources(dsds);
- }
-
- @Override
- public DataSourceDesc getCurrentDataSource() {
- return MediaPlayer2Impl.this.getCurrentDataSource();
- }
-
- @Override
- public void loopCurrent(boolean loop) {
- MediaPlayer2Impl.this.loopCurrent(loop);
- }
-
- @Override
- public void setPlaybackSpeed(float speed) {
- MediaPlayer2Impl.this.setPlaybackSpeed(speed);
- }
-
- @Override
- public float getPlaybackSpeed() {
- return MediaPlayer2Impl.this.getPlaybackSpeed();
- }
-
- @Override
- public void setPlayerVolume(float volume) {
- MediaPlayer2Impl.this.setPlayerVolume(volume);
- }
-
- @Override
- public float getPlayerVolume() {
- return MediaPlayer2Impl.this.getPlayerVolume();
- }
-
- @Override
- public void registerPlayerEventCallback(Executor e, final PlayerEventCallback cb) {
- MediaPlayer2Impl.this.registerPlayerEventCallback(e, cb);
- }
-
- @Override
- public void unregisterPlayerEventCallback(PlayerEventCallback cb) {
- MediaPlayer2Impl.this.unregisterPlayerEventCallback(cb);
- }
-
- @Override
- public void close() throws Exception {
- MediaPlayer2Impl.this.close();
- }
- }
}
diff --git a/media/src/main/java/androidx/media/MediaPlayerInterface.java b/media/src/main/java/androidx/media/MediaPlayerBase.java
similarity index 90%
rename from media/src/main/java/androidx/media/MediaPlayerInterface.java
rename to media/src/main/java/androidx/media/MediaPlayerBase.java
index 9d51609..de0e128 100644
--- a/media/src/main/java/androidx/media/MediaPlayerInterface.java
+++ b/media/src/main/java/androidx/media/MediaPlayerBase.java
@@ -32,10 +32,10 @@
import java.util.concurrent.Executor;
/**
- * Base interface for all media players that want media session.
+ * Base class for all media players that want media session.
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
-public abstract class MediaPlayerInterface implements AutoCloseable {
+public abstract class MediaPlayerBase implements AutoCloseable {
/**
* @hide
*/
@@ -111,9 +111,9 @@
/**
* Prepares the player for playback.
- * See {@link PlayerEventCallback#onMediaPrepared(MediaPlayerInterface, DataSourceDesc)} for
- * being notified when the preparation phase completed. During this time, the player may
- * allocate resources required to play, such as audio and video decoders.
+ * See {@link PlayerEventCallback#onMediaPrepared(MediaPlayerBase, DataSourceDesc)} for being
+ * notified when the preparation phase completed. During this time, the player may allocate
+ * resources required to play, such as audio and video decoders.
*/
public abstract void prepare();
@@ -123,7 +123,7 @@
public abstract void pause();
/**
- * Resets the MediaPlayerInterface to its uninitialized state.
+ * Resets the MediaPlayerBase to its uninitialized state.
*/
public abstract void reset();
@@ -166,7 +166,7 @@
/**
* Returns the current player state.
- * See also {@link PlayerEventCallback#onPlayerStateChanged(MediaPlayerInterface, int)} for
+ * See also {@link PlayerEventCallback#onPlayerStateChanged(MediaPlayerBase, int)} for
* notification of changes.
* @return the current player state
*/
@@ -294,8 +294,8 @@
/**
* A callback class to receive notifications for events on the media player.
- * See {@link MediaPlayerInterface#registerPlayerEventCallback(Executor, PlayerEventCallback)}
- * to register this callback.
+ * See {@link MediaPlayerBase#registerPlayerEventCallback(Executor, PlayerEventCallback)} to
+ * register this callback.
*/
public abstract static class PlayerEventCallback {
/**
@@ -304,7 +304,7 @@
* @param mpb the player whose data source changed.
* @param dsd the new current data source. null, if no more data sources available.
*/
- public void onCurrentDataSourceChanged(@NonNull MediaPlayerInterface mpb,
+ public void onCurrentDataSourceChanged(@NonNull MediaPlayerBase mpb,
@Nullable DataSourceDesc dsd) { }
/**
@@ -313,17 +313,16 @@
* @param mpb the player that is prepared.
* @param dsd the data source that the player is prepared to play.
*/
- public void onMediaPrepared(@NonNull MediaPlayerInterface mpb,
+ public void onMediaPrepared(@NonNull MediaPlayerBase mpb,
@NonNull DataSourceDesc dsd) { }
/**
* Called to indicate that the state of the player has changed.
- * See {@link MediaPlayerInterface#getPlayerState()} for polling the player state.
+ * See {@link MediaPlayerBase#getPlayerState()} for polling the player state.
* @param mpb the player whose state has changed.
* @param state the new state of the player.
*/
- public void onPlayerStateChanged(@NonNull MediaPlayerInterface mpb,
- @PlayerState int state) { }
+ public void onPlayerStateChanged(@NonNull MediaPlayerBase mpb, @PlayerState int state) { }
/**
* Called to report buffering events for a data source.
@@ -331,7 +330,7 @@
* @param dsd the data source for which buffering is happening.
* @param state the new buffering state.
*/
- public void onBufferingStateChanged(@NonNull MediaPlayerInterface mpb,
+ public void onBufferingStateChanged(@NonNull MediaPlayerBase mpb,
@NonNull DataSourceDesc dsd, @BuffState int state) { }
/**
@@ -339,7 +338,7 @@
* @param mpb the player that has changed the playback speed.
* @param speed the new playback speed.
*/
- public void onPlaybackSpeedChanged(@NonNull MediaPlayerInterface mpb, float speed) { }
+ public void onPlaybackSpeedChanged(@NonNull MediaPlayerBase mpb, float speed) { }
/**
* Called to indicate that {@link #seekTo(long)} is completed.
@@ -348,6 +347,6 @@
* @param position the previous seeking request.
* @see #seekTo(long)
*/
- public void onSeekCompleted(@NonNull MediaPlayerInterface mpb, long position) { }
+ public void onSeekCompleted(@NonNull MediaPlayerBase mpb, long position) { }
}
}
diff --git a/media/src/main/java/androidx/media/MediaPlaylistAgent.java b/media/src/main/java/androidx/media/MediaPlaylistAgent.java
index 4e1eee4..07838e8 100644
--- a/media/src/main/java/androidx/media/MediaPlaylistAgent.java
+++ b/media/src/main/java/androidx/media/MediaPlaylistAgent.java
@@ -377,12 +377,12 @@
/**
* Called by {@link MediaSession2} when it wants to translate {@link DataSourceDesc} from the
- * {@link MediaPlayerInterface.PlayerEventCallback} to the {@link MediaItem2}. Override this
- * method if you want to create {@link DataSourceDesc}s dynamically, instead of specifying them
- * with {@link #setPlaylist(List, MediaMetadata2)}.
+ * {@link MediaPlayerBase.PlayerEventCallback} to the {@link MediaItem2}. Override this method
+ * if you want to create {@link DataSourceDesc}s dynamically, instead of specifying them with
+ * {@link #setPlaylist(List, MediaMetadata2)}.
* <p>
* Session would throw an exception if this returns {@code null} for the dsd from the
- * {@link MediaPlayerInterface.PlayerEventCallback}.
+ * {@link MediaPlayerBase.PlayerEventCallback}.
* <p>
* Default implementation calls the {@link #getPlaylist()} and searches the {@link MediaItem2}
* with the {@param dsd}.
diff --git a/media/src/main/java/androidx/media/MediaSession2.java b/media/src/main/java/androidx/media/MediaSession2.java
index ce95078..909e979 100644
--- a/media/src/main/java/androidx/media/MediaSession2.java
+++ b/media/src/main/java/androidx/media/MediaSession2.java
@@ -27,9 +27,8 @@
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
-import android.os.RemoteException;
import android.os.ResultReceiver;
-import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.media.session.IMediaControllerCallback;
import android.support.v4.media.session.PlaybackStateCompat;
import androidx.annotation.IntDef;
@@ -37,8 +36,8 @@
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.media.MediaController2.PlaybackInfo;
-import androidx.media.MediaPlayerInterface.BuffState;
-import androidx.media.MediaPlayerInterface.PlayerState;
+import androidx.media.MediaPlayerBase.BuffState;
+import androidx.media.MediaPlayerBase.PlayerState;
import androidx.media.MediaPlaylistAgent.PlaylistEventCallback;
import androidx.media.MediaPlaylistAgent.RepeatMode;
import androidx.media.MediaPlaylistAgent.ShuffleMode;
@@ -61,10 +60,6 @@
* handle media keys. In general an app only needs one session for all playback, though multiple
* sessions can be created to provide finer grain controls of media.
* <p>
- * If you want to support background playback, {@link MediaSessionService2} is preferred
- * instead. With it, your playback can be revived even after playback is finished. See
- * {@link MediaSessionService2} for details.
- * <p>
* A session can be obtained by {@link Builder}. The owner of the session may pass its session token
* to other processes to allow them to create a {@link MediaController2} to interact with the
* session.
@@ -77,8 +72,6 @@
* and notify any controllers.
* <p>
* {@link MediaSession2} objects should be used on the thread on the looper.
- *
- * @see MediaSessionService2
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public class MediaSession2 extends MediaInterface2.SessionPlayer implements AutoCloseable {
@@ -161,594 +154,6 @@
*/
public static final int ERROR_CODE_SETUP_REQUIRED = 12;
- static final String TAG = "MediaSession2";
-
- private final SupportLibraryImpl mImpl;
-
- MediaSession2(SupportLibraryImpl impl) {
- mImpl = impl;
- }
-
- SupportLibraryImpl getImpl() {
- return mImpl;
- }
-
- /**
- * Sets the underlying {@link MediaPlayerInterface} and {@link MediaPlaylistAgent} for this
- * session to dispatch incoming event to.
- * <p>
- * When a {@link MediaPlaylistAgent} is specified here, the playlist agent should manage
- * {@link MediaPlayerInterface} for calling
- * {@link MediaPlayerInterface#setNextDataSources(List)}.
- * <p>
- * If the {@link MediaPlaylistAgent} isn't set, session will recreate the default playlist
- * agent.
- *
- * @param player a {@link MediaPlayerInterface} that handles actual media playback in your app
- * @param playlistAgent a {@link MediaPlaylistAgent} that manages playlist of the {@code player}
- * @param volumeProvider a {@link VolumeProviderCompat}. If {@code null}, system will adjust the
- * appropriate stream volume for this session's player.
- */
- public void updatePlayer(@NonNull MediaPlayerInterface player,
- @Nullable MediaPlaylistAgent playlistAgent,
- @Nullable VolumeProviderCompat volumeProvider) {
- mImpl.updatePlayer(player, playlistAgent, volumeProvider);
- }
-
- @Override
- public void close() {
- try {
- mImpl.close();
- } catch (Exception e) {
- // Should not be here.
- }
- }
-
- /**
- * @return player
- */
- public @NonNull MediaPlayerInterface getPlayer() {
- return mImpl.getPlayer();
- }
-
- /**
- * @return playlist agent
- */
- public @NonNull MediaPlaylistAgent getPlaylistAgent() {
- return mImpl.getPlaylistAgent();
- }
-
- /**
- * @return volume provider
- */
- public @Nullable VolumeProviderCompat getVolumeProvider() {
- return mImpl.getVolumeProvider();
- }
-
- /**
- * Returns the {@link SessionToken2} for creating {@link MediaController2}.
- */
- public @NonNull SessionToken2 getToken() {
- return mImpl.getToken();
- }
-
- @NonNull Context getContext() {
- return mImpl.getContext();
- }
-
- @NonNull Executor getCallbackExecutor() {
- return mImpl.getCallbackExecutor();
- }
-
- @NonNull SessionCallback getCallback() {
- return mImpl.getCallback();
- }
-
- /**
- * Returns the list of connected controller.
- *
- * @return list of {@link ControllerInfo}
- */
- public @NonNull List<ControllerInfo> getConnectedControllers() {
- return mImpl.getConnectedControllers();
- }
-
- /**
- * Set the {@link AudioFocusRequest} to obtain the audio focus
- *
- * @param afr the full request parameters
- */
- public void setAudioFocusRequest(@Nullable AudioFocusRequest afr) {
- mImpl.setAudioFocusRequest(afr);
- }
-
- /**
- * Sets ordered list of {@link CommandButton} for controllers to build UI with it.
- * <p>
- * It's up to controller's decision how to represent the layout in its own UI.
- * Here's the same way
- * (layout[i] means a CommandButton at index i in the given list)
- * For 5 icons row
- * layout[3] layout[1] layout[0] layout[2] layout[4]
- * For 3 icons row
- * layout[1] layout[0] layout[2]
- * For 5 icons row with overflow icon (can show +5 extra buttons with overflow button)
- * expanded row: layout[5] layout[6] layout[7] layout[8] layout[9]
- * main row: layout[3] layout[1] layout[0] layout[2] layout[4]
- * <p>
- * This API can be called in the
- * {@link SessionCallback#onConnect(MediaSession2, ControllerInfo)}.
- *
- * @param controller controller to specify layout.
- * @param layout ordered list of layout.
- */
- public void setCustomLayout(@NonNull ControllerInfo controller,
- @NonNull List<CommandButton> layout) {
- mImpl.setCustomLayout(controller, layout);
- }
-
- /**
- * Set the new allowed command group for the controller
- *
- * @param controller controller to change allowed commands
- * @param commands new allowed commands
- */
- public void setAllowedCommands(@NonNull ControllerInfo controller,
- @NonNull SessionCommandGroup2 commands) {
- mImpl.setAllowedCommands(controller, commands);
- }
-
- /**
- * Send custom command to all connected controllers.
- *
- * @param command a command
- * @param args optional argument
- */
- public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args) {
- mImpl.sendCustomCommand(command, args);
- }
-
- /**
- * Send custom command to a specific controller.
- *
- * @param command a command
- * @param args optional argument
- * @param receiver result receiver for the session
- */
- public void sendCustomCommand(@NonNull ControllerInfo controller,
- @NonNull SessionCommand2 command, @Nullable Bundle args,
- @Nullable ResultReceiver receiver) {
- mImpl.sendCustomCommand(controller, command, args, receiver);
- }
-
- /**
- * Play playback.
- * <p>
- * This calls {@link MediaPlayerInterface#play()}.
- */
- @Override
- public void play() {
- mImpl.play();
- }
-
- /**
- * Pause playback.
- * <p>
- * This calls {@link MediaPlayerInterface#pause()}.
- */
- @Override
- public void pause() {
- mImpl.pause();
- }
-
- /**
- * Stop playback, and reset the player to the initial state.
- * <p>
- * This calls {@link MediaPlayerInterface#reset()}.
- */
- @Override
- public void reset() {
- mImpl.reset();
- }
-
- /**
- * Request that the player prepare its playback. In other words, other sessions can continue
- * to play during the preparation of this session. This method can be used to speed up the
- * start of the playback. Once the preparation is done, the session will change its playback
- * state to {@link MediaPlayerInterface#PLAYER_STATE_PAUSED}. Afterwards, {@link #play} can be
- * called to start playback.
- * <p>
- * This calls {@link MediaPlayerInterface#reset()}.
- */
- @Override
- public void prepare() {
- mImpl.prepare();
- }
-
- /**
- * Move to a new location in the media stream.
- *
- * @param pos Position to move to, in milliseconds.
- */
- @Override
- public void seekTo(long pos) {
- mImpl.seekTo(pos);
- }
-
- /**
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void skipForward() {
- mImpl.skipForward();
- }
-
- /**
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- @Override
- public void skipBackward() {
- mImpl.skipBackward();
- }
-
- /**
- * Notify errors to the connected controllers
- *
- * @param errorCode error code
- * @param extras extras
- */
- @Override
- public void notifyError(@ErrorCode int errorCode, @Nullable Bundle extras) {
- mImpl.notifyError(errorCode, extras);
- }
-
- /**
- * Notify routes information to a connected controller
- *
- * @param controller controller information
- * @param routes The routes information. Each bundle should be from
- * MediaRouteDescritor.asBundle().
- */
- public void notifyRoutesInfoChanged(@NonNull ControllerInfo controller,
- @Nullable List<Bundle> routes) {
- mImpl.notifyRoutesInfoChanged(controller, routes);
- }
-
- /**
- * Gets the current player state.
- *
- * @return the current player state
- */
- @Override
- public @PlayerState int getPlayerState() {
- return mImpl.getPlayerState();
- }
-
- /**
- * Gets the current position.
- *
- * @return the current playback position in ms, or {@link MediaPlayerInterface#UNKNOWN_TIME} if
- * unknown.
- */
- @Override
- public long getCurrentPosition() {
- return mImpl.getCurrentPosition();
- }
-
- /**
- * Gets the duration of the currently playing media item.
- *
- * @return the duration of the current item from {@link MediaPlayerInterface#getDuration()}.
- */
- @Override
- public long getDuration() {
- return mImpl.getDuration();
- }
-
- /**
- * Gets the buffered position, or {@link MediaPlayerInterface#UNKNOWN_TIME} if unknown.
- *
- * @return the buffered position in ms, or {@link MediaPlayerInterface#UNKNOWN_TIME}.
- */
- @Override
- public long getBufferedPosition() {
- return mImpl.getBufferedPosition();
- }
-
- /**
- * Gets the current buffering state of the player.
- * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
- * buffered.
- *
- * @return the buffering state.
- */
- @Override
- public @BuffState int getBufferingState() {
- return mImpl.getBufferingState();
- }
-
- /**
- * Get the playback speed.
- *
- * @return speed
- */
- @Override
- public float getPlaybackSpeed() {
- return mImpl.getPlaybackSpeed();
- }
-
- /**
- * Set the playback speed.
- */
- @Override
- public void setPlaybackSpeed(float speed) {
- mImpl.setPlaybackSpeed(speed);
- }
-
- /**
- * Sets the data source missing helper. Helper will be used to provide default implementation of
- * {@link MediaPlaylistAgent} when it isn't set by developer.
- * <p>
- * Default implementation of the {@link MediaPlaylistAgent} will call helper when a
- * {@link MediaItem2} in the playlist doesn't have a {@link DataSourceDesc}. This may happen
- * when
- * <ul>
- * <li>{@link MediaItem2} specified by {@link #setPlaylist(List, MediaMetadata2)} doesn't
- * have {@link DataSourceDesc}</li>
- * <li>{@link MediaController2#addPlaylistItem(int, MediaItem2)} is called and accepted
- * by {@link SessionCallback#onCommandRequest(
- * MediaSession2, ControllerInfo, SessionCommand2)}.
- * In that case, an item would be added automatically without the data source.</li>
- * </ul>
- * <p>
- * If it's not set, playback wouldn't happen for the item without data source descriptor.
- * <p>
- * The helper will be run on the executor that was specified by
- * {@link Builder#setSessionCallback(Executor, SessionCallback)}.
- *
- * @param helper a data source missing helper.
- * @throws IllegalStateException when the helper is set when the playlist agent is set
- * @see #setPlaylist(List, MediaMetadata2)
- * @see SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)
- * @see SessionCommand2#COMMAND_CODE_PLAYLIST_ADD_ITEM
- * @see SessionCommand2#COMMAND_CODE_PLAYLIST_REPLACE_ITEM
- */
- @Override
- public void setOnDataSourceMissingHelper(@NonNull OnDataSourceMissingHelper helper) {
- mImpl.setOnDataSourceMissingHelper(helper);
- }
-
- /**
- * Clears the data source missing helper.
- *
- * @see #setOnDataSourceMissingHelper(OnDataSourceMissingHelper)
- */
- @Override
- public void clearOnDataSourceMissingHelper() {
- mImpl.clearOnDataSourceMissingHelper();
- }
-
- /**
- * Returns the playlist from the {@link MediaPlaylistAgent}.
- * <p>
- * This list may differ with the list that was specified with
- * {@link #setPlaylist(List, MediaMetadata2)} depending on the {@link MediaPlaylistAgent}
- * implementation. Use media items returned here for other playlist agent APIs such as
- * {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)}.
- *
- * @return playlist
- * @see MediaPlaylistAgent#getPlaylist()
- * @see SessionCallback#onPlaylistChanged(
- * MediaSession2, MediaPlaylistAgent, List, MediaMetadata2)
- */
- @Override
- public List<MediaItem2> getPlaylist() {
- return mImpl.getPlaylist();
- }
-
- /**
- * Sets a list of {@link MediaItem2} to the {@link MediaPlaylistAgent}. Ensure uniqueness of
- * each {@link MediaItem2} in the playlist so the session can uniquely identity individual
- * items.
- * <p>
- * This may be an asynchronous call, and {@link MediaPlaylistAgent} may keep the copy of the
- * list. Wait for {@link SessionCallback#onPlaylistChanged(MediaSession2, MediaPlaylistAgent,
- * List, MediaMetadata2)} to know the operation finishes.
- * <p>
- * You may specify a {@link MediaItem2} without {@link DataSourceDesc}. In that case,
- * {@link MediaPlaylistAgent} has responsibility to dynamically query {link DataSourceDesc}
- * when such media item is ready for preparation or play. Default implementation needs
- * {@link OnDataSourceMissingHelper} for such case.
- * <p>
- * It's recommended to fill {@link MediaMetadata2} in each {@link MediaItem2} especially for the
- * duration information with the key {@link MediaMetadata2#METADATA_KEY_DURATION}. Without the
- * duration information in the metadata, session will do extra work to get the duration and send
- * it to the controller.
- *
- * @param list A list of {@link MediaItem2} objects to set as a play list.
- * @throws IllegalArgumentException if given list is {@code null}, or has duplicated media
- * items.
- * @see MediaPlaylistAgent#setPlaylist(List, MediaMetadata2)
- * @see SessionCallback#onPlaylistChanged(
- * MediaSession2, MediaPlaylistAgent, List, MediaMetadata2)
- * @see #setOnDataSourceMissingHelper
- */
- @Override
- public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
- mImpl.setPlaylist(list, metadata);
- }
-
- /**
- * Skips to the item in the playlist.
- * <p>
- * This calls {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)} and the behavior depends
- * on the playlist agent implementation, especially with the shuffle/repeat mode.
- *
- * @param item The item in the playlist you want to play
- * @see #getShuffleMode()
- * @see #getRepeatMode()
- */
- @Override
- public void skipToPlaylistItem(@NonNull MediaItem2 item) {
- mImpl.skipToPlaylistItem(item);
- }
-
- /**
- * Skips to the previous item.
- * <p>
- * This calls {@link MediaPlaylistAgent#skipToPreviousItem()} and the behavior depends on the
- * playlist agent implementation, especially with the shuffle/repeat mode.
- *
- * @see #getShuffleMode()
- * @see #getRepeatMode()
- **/
- @Override
- public void skipToPreviousItem() {
- mImpl.skipToPreviousItem();
- }
-
- /**
- * Skips to the next item.
- * <p>
- * This calls {@link MediaPlaylistAgent#skipToNextItem()} and the behavior depends on the
- * playlist agent implementation, especially with the shuffle/repeat mode.
- *
- * @see #getShuffleMode()
- * @see #getRepeatMode()
- */
- @Override
- public void skipToNextItem() {
- mImpl.skipToNextItem();
- }
-
- /**
- * Gets the playlist metadata from the {@link MediaPlaylistAgent}.
- *
- * @return the playlist metadata
- */
- @Override
- public MediaMetadata2 getPlaylistMetadata() {
- return mImpl.getPlaylistMetadata();
- }
-
- /**
- * Adds the media item to the playlist at position index. Index equals or greater than
- * the current playlist size (e.g. {@link Integer#MAX_VALUE}) will add the item at the end of
- * the playlist.
- * <p>
- * This will not change the currently playing media item.
- * If index is less than or equal to the current index of the play list,
- * the current index of the play list will be incremented correspondingly.
- *
- * @param index the index you want to add
- * @param item the media item you want to add
- */
- @Override
- public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
- mImpl.addPlaylistItem(index, item);
- }
-
- /**
- * Removes the media item in the playlist.
- * <p>
- * If the item is the currently playing item of the playlist, current playback
- * will be stopped and playback moves to next source in the list.
- *
- * @param item the media item you want to add
- */
- @Override
- public void removePlaylistItem(@NonNull MediaItem2 item) {
- mImpl.removePlaylistItem(item);
- }
-
- /**
- * Replaces the media item at index in the playlist. This can be also used to update metadata of
- * an item.
- *
- * @param index the index of the item to replace
- * @param item the new item
- */
- @Override
- public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
- mImpl.replacePlaylistItem(index, item);
- }
-
- /**
- * Return currently playing media item.
- *
- * @return currently playing media item
- */
- @Override
- public MediaItem2 getCurrentMediaItem() {
- return mImpl.getCurrentMediaItem();
- }
-
- /**
- * Updates the playlist metadata to the {@link MediaPlaylistAgent}.
- *
- * @param metadata metadata of the playlist
- */
- @Override
- public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) {
- mImpl.updatePlaylistMetadata(metadata);
- }
-
- /**
- * Gets the repeat mode from the {@link MediaPlaylistAgent}.
- *
- * @return repeat mode
- * @see MediaPlaylistAgent#REPEAT_MODE_NONE
- * @see MediaPlaylistAgent#REPEAT_MODE_ONE
- * @see MediaPlaylistAgent#REPEAT_MODE_ALL
- * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
- */
- @Override
- public @RepeatMode int getRepeatMode() {
- return mImpl.getRepeatMode();
- }
-
- /**
- * Sets the repeat mode to the {@link MediaPlaylistAgent}.
- *
- * @param repeatMode repeat mode
- * @see MediaPlaylistAgent#REPEAT_MODE_NONE
- * @see MediaPlaylistAgent#REPEAT_MODE_ONE
- * @see MediaPlaylistAgent#REPEAT_MODE_ALL
- * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
- */
- @Override
- public void setRepeatMode(@RepeatMode int repeatMode) {
- mImpl.setRepeatMode(repeatMode);
- }
-
- /**
- * Gets the shuffle mode from the {@link MediaPlaylistAgent}.
- *
- * @return The shuffle mode
- * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
- * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
- * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
- */
- @Override
- public @ShuffleMode int getShuffleMode() {
- return mImpl.getShuffleMode();
- }
-
- /**
- * Sets the shuffle mode to the {@link MediaPlaylistAgent}.
- *
- * @param shuffleMode The shuffle mode
- * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
- * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
- * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
- */
- @Override
- public void setShuffleMode(@ShuffleMode int shuffleMode) {
- mImpl.setShuffleMode(shuffleMode);
- }
-
/**
* Interface definition of a callback to be invoked when a {@link MediaItem2} in the playlist
* didn't have a {@link DataSourceDesc} but it's needed now for preparing or playing it.
@@ -812,7 +217,7 @@
* Called when a controller sent a command which will be sent directly to one of the
* following:
* <ul>
- * <li> {@link MediaPlayerInterface} </li>
+ * <li> {@link MediaPlayerBase} </li>
* <li> {@link MediaPlaylistAgent} </li>
* <li> {@link android.media.AudioManager} or {@link VolumeProviderCompat} </li>
* </ul>
@@ -931,7 +336,7 @@
* <p>
* During the preparation, a session should not hold audio focus in order to allow other
* sessions play seamlessly. The state of playback should be updated to
- * {@link MediaPlayerInterface#PLAYER_STATE_PAUSED} after the preparation is done.
+ * {@link MediaPlayerBase#PLAYER_STATE_PAUSED} after the preparation is done.
* <p>
* The playback of the prepared content should start in the later calls of
* {@link MediaSession2#play()}.
@@ -956,9 +361,8 @@
* An empty query indicates that the app may prepare any music. The implementation should
* attempt to make a smart choice about what to play.
* <p>
- * The state of playback should be updated to
- * {@link MediaPlayerInterface#PLAYER_STATE_PAUSED} after the preparation is done.
- * The playback of the prepared content should start in the
+ * The state of playback should be updated to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}
+ * after the preparation is done. The playback of the prepared content should start in the
* later calls of {@link MediaSession2#play()}.
* <p>
* Override {@link #onPlayFromSearch} to handle requests for starting playback without
@@ -980,7 +384,7 @@
* <p>
* During the preparation, a session should not hold audio focus in order to allow
* other sessions play seamlessly. The state of playback should be updated to
- * {@link MediaPlayerInterface#PLAYER_STATE_PAUSED} after the preparation is done.
+ * {@link MediaPlayerBase#PLAYER_STATE_PAUSED} after the preparation is done.
* <p>
* The playback of the prepared content should start in the later calls of
* {@link MediaSession2#play()}.
@@ -1057,7 +461,7 @@
* @param item new item
*/
public void onCurrentMediaItemChanged(@NonNull MediaSession2 session,
- @NonNull MediaPlayerInterface player, @Nullable MediaItem2 item) { }
+ @NonNull MediaPlayerBase player, @NonNull MediaItem2 item) { }
/**
* Called when the player is <i>prepared</i>, i.e. it is ready to play the content
@@ -1066,18 +470,18 @@
* @param player the player for this event
* @param item the media item for which buffering is happening
*/
- public void onMediaPrepared(@NonNull MediaSession2 session,
- @NonNull MediaPlayerInterface player, @NonNull MediaItem2 item) { }
+ public void onMediaPrepared(@NonNull MediaSession2 session, @NonNull MediaPlayerBase player,
+ @NonNull MediaItem2 item) { }
/**
* Called to indicate that the state of the player has changed.
- * See {@link MediaPlayerInterface#getPlayerState()} for polling the player state.
+ * See {@link MediaPlayerBase#getPlayerState()} for polling the player state.
* @param session the session for this event
* @param player the player for this event
* @param state the new state of the player.
*/
public void onPlayerStateChanged(@NonNull MediaSession2 session,
- @NonNull MediaPlayerInterface player, @PlayerState int state) { }
+ @NonNull MediaPlayerBase player, @PlayerState int state) { }
/**
* Called to report buffering events for a data source.
@@ -1088,8 +492,7 @@
* @param state the new buffering state.
*/
public void onBufferingStateChanged(@NonNull MediaSession2 session,
- @NonNull MediaPlayerInterface player, @NonNull MediaItem2 item,
- @BuffState int state) { }
+ @NonNull MediaPlayerBase player, @NonNull MediaItem2 item, @BuffState int state) { }
/**
* Called to indicate that the playback speed has changed.
@@ -1098,18 +501,18 @@
* @param speed the new playback speed.
*/
public void onPlaybackSpeedChanged(@NonNull MediaSession2 session,
- @NonNull MediaPlayerInterface player, float speed) { }
+ @NonNull MediaPlayerBase player, float speed) { }
/**
* Called to indicate that {@link #seekTo(long)} is completed.
*
* @param session the session for this event.
- * @param player the player that has completed seeking.
+ * @param mpb the player that has completed seeking.
* @param position the previous seeking request.
* @see #seekTo(long)
*/
- public void onSeekCompleted(@NonNull MediaSession2 session,
- @NonNull MediaPlayerInterface player, long position) { }
+ public void onSeekCompleted(@NonNull MediaSession2 session, @NonNull MediaPlayerBase mpb,
+ long position) { }
/**
* Called when a playlist is changed from the {@link MediaPlaylistAgent}.
@@ -1168,6 +571,153 @@
}
/**
+ * Base builder class for MediaSession2 and its subclass. Any change in this class should be
+ * also applied to the subclasses {@link MediaSession2.Builder} and
+ * {@link MediaLibraryService2.MediaLibrarySession.Builder}.
+ * <p>
+ * APIs here should be package private, but should have documentations for developers.
+ * Otherwise, javadoc will generate documentation with the generic types such as follows.
+ * <pre>U extends BuilderBase<T, U, C> setSessionCallback(Executor executor, C callback)</pre>
+ * <p>
+ * This class is hidden to prevent from generating test stub, which fails with
+ * 'unexpected bound' because it tries to auto generate stub class as follows.
+ * <pre>abstract static class BuilderBase<
+ * T extends android.media.MediaSession2,
+ * U extends android.media.MediaSession2.BuilderBase<
+ * T, U, C extends android.media.MediaSession2.SessionCallback>, C></pre>
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ abstract static class BuilderBase
+ <T extends MediaSession2, U extends BuilderBase<T, U, C>, C extends SessionCallback> {
+ final Context mContext;
+ MediaSession2ImplBase.BuilderBase<T, C> mBaseImpl;
+ MediaPlayerBase mPlayer;
+ String mId;
+ Executor mCallbackExecutor;
+ C mCallback;
+ MediaPlaylistAgent mPlaylistAgent;
+ VolumeProviderCompat mVolumeProvider;
+ PendingIntent mSessionActivity;
+
+ BuilderBase(Context context) {
+ if (context == null) {
+ throw new IllegalArgumentException("context shouldn't be null");
+ }
+ mContext = context;
+ // Ensure non-null
+ mId = "";
+ }
+
+ /**
+ * Sets the underlying {@link MediaPlayerBase} for this session to dispatch incoming event
+ * to.
+ *
+ * @param player a {@link MediaPlayerBase} that handles actual media playback in your app.
+ */
+ @NonNull U setPlayer(@NonNull MediaPlayerBase player) {
+ if (player == null) {
+ throw new IllegalArgumentException("player shouldn't be null");
+ }
+ mBaseImpl.setPlayer(player);
+ return (U) this;
+ }
+
+ /**
+ * Sets the {@link MediaPlaylistAgent} for this session to manages playlist of the
+ * underlying {@link MediaPlayerBase}. The playlist agent should manage
+ * {@link MediaPlayerBase} for calling {@link MediaPlayerBase#setNextDataSources(List)}.
+ * <p>
+ * If the {@link MediaPlaylistAgent} isn't set, session will create the default playlist
+ * agent.
+ *
+ * @param playlistAgent a {@link MediaPlaylistAgent} that manages playlist of the
+ * {@code player}
+ */
+ U setPlaylistAgent(@NonNull MediaPlaylistAgent playlistAgent) {
+ if (playlistAgent == null) {
+ throw new IllegalArgumentException("playlistAgent shouldn't be null");
+ }
+ mBaseImpl.setPlaylistAgent(playlistAgent);
+ return (U) this;
+ }
+
+ /**
+ * Sets the {@link VolumeProviderCompat} for this session to handle volume events. If not
+ * set, system will adjust the appropriate stream volume for this session's player.
+ *
+ * @param volumeProvider The provider that will receive volume button events.
+ */
+ @NonNull U setVolumeProvider(@Nullable VolumeProviderCompat volumeProvider) {
+ mBaseImpl.setVolumeProvider(volumeProvider);
+ return (U) this;
+ }
+
+ /**
+ * Set an intent for launching UI for this Session. This can be used as a
+ * quick link to an ongoing media screen. The intent should be for an
+ * activity that may be started using {@link Context#startActivity(Intent)}.
+ *
+ * @param pi The intent to launch to show UI for this session.
+ */
+ @NonNull U setSessionActivity(@Nullable PendingIntent pi) {
+ mBaseImpl.setSessionActivity(pi);
+ return (U) this;
+ }
+
+ /**
+ * Set ID of the session. If it's not set, an empty string with used to create a session.
+ * <p>
+ * Use this if and only if your app supports multiple playback at the same time and also
+ * wants to provide external apps to have finer controls of them.
+ *
+ * @param id id of the session. Must be unique per package.
+ * @throws IllegalArgumentException if id is {@code null}
+ * @return
+ */
+ @NonNull U setId(@NonNull String id) {
+ if (id == null) {
+ throw new IllegalArgumentException("id shouldn't be null");
+ }
+ mBaseImpl.setId(id);
+ return (U) this;
+ }
+
+ /**
+ * Set callback for the session.
+ *
+ * @param executor callback executor
+ * @param callback session callback.
+ * @return
+ */
+ @NonNull U setSessionCallback(@NonNull Executor executor, @NonNull C callback) {
+ if (executor == null) {
+ throw new IllegalArgumentException("executor shouldn't be null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("callback shouldn't be null");
+ }
+ mBaseImpl.setSessionCallback(executor, callback);
+ return (U) this;
+ }
+
+ /**
+ * Build {@link MediaSession2}.
+ *
+ * @return a new session
+ * @throws IllegalStateException if the session with the same id is already exists for the
+ * package.
+ */
+ @NonNull T build() {
+ return mBaseImpl.build();
+ }
+
+ void setImpl(MediaSession2ImplBase.BuilderBase<T, C> impl) {
+ mBaseImpl = impl;
+ }
+ }
+
+ /**
* Builder for {@link MediaSession2}.
* <p>
* Any incoming event from the {@link MediaController2} will be handled on the thread
@@ -1183,7 +733,7 @@
}
@Override
- public @NonNull Builder setPlayer(@NonNull MediaPlayerInterface player) {
+ public @NonNull Builder setPlayer(@NonNull MediaPlayerBase player) {
return super.setPlayer(player);
}
@@ -1225,18 +775,20 @@
public static final class ControllerInfo {
private final int mUid;
private final String mPackageName;
+ // Note: IMediaControllerCallback should be used only for MediaSession2ImplBase
+ private final IMediaControllerCallback mIControllerCallback;
private final boolean mIsTrusted;
- private final ControllerCb mControllerCb;
/**
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
- ControllerInfo(@NonNull String packageName, int pid, int uid, @NonNull ControllerCb cb) {
+ public ControllerInfo(@NonNull Context context, int uid, int pid,
+ @NonNull String packageName, @NonNull IMediaControllerCallback callback) {
mUid = uid;
mPackageName = packageName;
+ mIControllerCallback = callback;
mIsTrusted = false;
- mControllerCb = cb;
}
/**
@@ -1266,9 +818,13 @@
return mIsTrusted;
}
+ IBinder getId() {
+ return mIControllerCallback.asBinder();
+ }
+
@Override
public int hashCode() {
- return mControllerCb.hashCode();
+ return mIControllerCallback.hashCode();
}
@Override
@@ -1277,7 +833,7 @@
return false;
}
ControllerInfo other = (ControllerInfo) obj;
- return mControllerCb.equals(other.mControllerCb);
+ return mIControllerCallback.asBinder().equals(other.mIControllerCallback.asBinder());
}
@Override
@@ -1285,12 +841,26 @@
return "ControllerInfo {pkg=" + mPackageName + ", uid=" + mUid + "})";
}
- @NonNull IBinder getId() {
- return mControllerCb.getId();
+ /**
+ * @hide
+ * @return Bundle
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public @NonNull Bundle toBundle() {
+ return new Bundle();
}
- @NonNull ControllerCb getControllerCb() {
- return mControllerCb;
+ /**
+ * @hide
+ * @return Bundle
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public static @NonNull ControllerInfo fromBundle(@NonNull Context context, Bundle bundle) {
+ return new ControllerInfo(context, -1, -1, "TODO", null);
+ }
+
+ IMediaControllerCallback getControllerBinder() {
+ return mIControllerCallback;
}
}
@@ -1490,60 +1060,12 @@
}
}
- abstract static class ControllerCb {
- @Override
- public int hashCode() {
- return getId().hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof ControllerCb)) {
- return false;
- }
- ControllerCb other = (ControllerCb) obj;
- return getId().equals(other.getId());
- }
-
- abstract @NonNull IBinder getId();
-
- // Mostly matched with the methods in MediaController2.ControllerCallback
- abstract void onCustomLayoutChanged(@NonNull List<CommandButton> layout)
- throws RemoteException;
- abstract void onPlaybackInfoChanged(@NonNull PlaybackInfo info) throws RemoteException;
- abstract void onAllowedCommandsChanged(@NonNull SessionCommandGroup2 commands)
- throws RemoteException;
- abstract void onCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args,
- @Nullable ResultReceiver receiver) throws RemoteException;
- abstract void onPlayerStateChanged(int playerState) throws RemoteException;
- abstract void onPlaybackSpeedChanged(float speed) throws RemoteException;
- abstract void onBufferingStateChanged(@NonNull MediaItem2 item,
- @MediaPlayerInterface.BuffState int state) throws RemoteException;
- abstract void onSeekCompleted(long position) throws RemoteException;
- abstract void onError(@ErrorCode int errorCode, @Nullable Bundle extras)
- throws RemoteException;
- abstract void onCurrentMediaItemChanged(@Nullable MediaItem2 item) throws RemoteException;
- abstract void onPlaylistChanged(@NonNull List<MediaItem2> playlist,
- @Nullable MediaMetadata2 metadata) throws RemoteException;
- abstract void onPlaylistMetadataChanged(@Nullable MediaMetadata2 metadata)
- throws RemoteException;
- abstract void onShuffleModeChanged(@MediaPlaylistAgent.ShuffleMode int shuffleMode)
- throws RemoteException;
- abstract void onRepeatModeChanged(@MediaPlaylistAgent.RepeatMode int repeatMode)
- throws RemoteException;
- abstract void onRoutesInfoChanged(@Nullable List<Bundle> routes) throws RemoteException;
- abstract void onChildrenChanged(@NonNull String parentId, int itemCount,
- @Nullable Bundle extras) throws RemoteException;
- abstract void onSearchResultChanged(@NonNull String query, int itemCount,
- @Nullable Bundle extras) throws RemoteException;
- }
-
abstract static class SupportLibraryImpl extends MediaInterface2.SessionPlayer
implements AutoCloseable {
- abstract void updatePlayer(@NonNull MediaPlayerInterface player,
+ abstract void updatePlayer(@NonNull MediaPlayerBase player,
@Nullable MediaPlaylistAgent playlistAgent,
@Nullable VolumeProviderCompat volumeProvider);
- abstract @NonNull MediaPlayerInterface getPlayer();
+ abstract @NonNull MediaPlayerBase getPlayer();
abstract @NonNull MediaPlaylistAgent getPlaylistAgent();
abstract @Nullable VolumeProviderCompat getVolumeProvider();
abstract @NonNull SessionToken2 getToken();
@@ -1561,17 +1083,9 @@
abstract void notifyRoutesInfoChanged(@NonNull ControllerInfo controller,
@Nullable List<Bundle> routes);
- // LibrarySession methods
- abstract void notifyChildrenChanged(@NonNull ControllerInfo controller,
- @NonNull String parentId, int itemCount, @Nullable Bundle extras,
- @NonNull List<MediaSessionManager.RemoteUserInfo> subscribingBrowsers);
- abstract void notifySearchResultChanged(@NonNull ControllerInfo controller,
- @NonNull String query, int itemCount, @Nullable Bundle extras);
-
// Internally used methods
- abstract MediaSession2 createInstance();
+ abstract void setInstance(MediaSession2 session);
abstract MediaSession2 getInstance();
- abstract MediaSessionCompat getSessionCompat();
abstract Context getContext();
abstract Executor getCallbackExecutor();
abstract SessionCallback getCallback();
@@ -1580,152 +1094,577 @@
abstract PlaybackInfo getPlaybackInfo();
}
+ static final String TAG = "MediaSession2";
+
+ private final SupportLibraryImpl mImpl;
+
+ MediaSession2(SupportLibraryImpl impl) {
+ mImpl = impl;
+ mImpl.setInstance(this);
+ }
+
/**
- * Base builder class for MediaSession2 and its subclass. Any change in this class should be
- * also applied to the subclasses {@link MediaSession2.Builder} and
- * {@link MediaLibraryService2.MediaLibrarySession.Builder}.
+ * Sets the underlying {@link MediaPlayerBase} and {@link MediaPlaylistAgent} for this session
+ * to dispatch incoming event to.
* <p>
- * APIs here should be package private, but should have documentations for developers.
- * Otherwise, javadoc will generate documentation with the generic types such as follows.
- * <pre>U extends BuilderBase<T, U, C> setSessionCallback(Executor executor, C callback)</pre>
+ * When a {@link MediaPlaylistAgent} is specified here, the playlist agent should manage
+ * {@link MediaPlayerBase} for calling {@link MediaPlayerBase#setNextDataSources(List)}.
* <p>
- * This class is hidden to prevent from generating test stub, which fails with
- * 'unexpected bound' because it tries to auto generate stub class as follows.
- * <pre>abstract static class BuilderBase<
- * T extends android.media.MediaSession2,
- * U extends android.media.MediaSession2.BuilderBase<
- * T, U, C extends android.media.MediaSession2.SessionCallback>, C></pre>
+ * If the {@link MediaPlaylistAgent} isn't set, session will recreate the default playlist
+ * agent.
+ *
+ * @param player a {@link MediaPlayerBase} that handles actual media playback in your app
+ * @param playlistAgent a {@link MediaPlaylistAgent} that manages playlist of the {@code player}
+ * @param volumeProvider a {@link VolumeProviderCompat}. If {@code null}, system will adjust the
+ * appropriate stream volume for this session's player.
+ */
+ public void updatePlayer(@NonNull MediaPlayerBase player,
+ @Nullable MediaPlaylistAgent playlistAgent,
+ @Nullable VolumeProviderCompat volumeProvider) {
+ mImpl.updatePlayer(player, playlistAgent, volumeProvider);
+ }
+
+ @Override
+ public void close() {
+ try {
+ mImpl.close();
+ } catch (Exception e) {
+ // Should not be here.
+ }
+ }
+
+ /**
+ * @return player
+ */
+ public @NonNull MediaPlayerBase getPlayer() {
+ return mImpl.getPlayer();
+ }
+
+ /**
+ * @return playlist agent
+ */
+ public @NonNull MediaPlaylistAgent getPlaylistAgent() {
+ return mImpl.getPlaylistAgent();
+ }
+
+ /**
+ * @return volume provider
+ */
+ public @Nullable VolumeProviderCompat getVolumeProvider() {
+ return mImpl.getVolumeProvider();
+ }
+
+ /**
+ * Returns the {@link SessionToken2} for creating {@link MediaController2}.
+ */
+ public @NonNull SessionToken2 getToken() {
+ return mImpl.getToken();
+ }
+
+ @NonNull Context getContext() {
+ return mImpl.getContext();
+ }
+
+ @NonNull Executor getCallbackExecutor() {
+ return mImpl.getCallbackExecutor();
+ }
+
+ @NonNull SessionCallback getCallback() {
+ return mImpl.getCallback();
+ }
+
+ /**
+ * Returns the list of connected controller.
+ *
+ * @return list of {@link ControllerInfo}
+ */
+ public @NonNull List<ControllerInfo> getConnectedControllers() {
+ return mImpl.getConnectedControllers();
+ }
+
+ /**
+ * Set the {@link AudioFocusRequest} to obtain the audio focus
+ *
+ * @param afr the full request parameters
+ */
+ public void setAudioFocusRequest(@Nullable AudioFocusRequest afr) {
+ mImpl.setAudioFocusRequest(afr);
+ }
+
+ /**
+ * Sets ordered list of {@link CommandButton} for controllers to build UI with it.
+ * <p>
+ * It's up to controller's decision how to represent the layout in its own UI.
+ * Here's the same way
+ * (layout[i] means a CommandButton at index i in the given list)
+ * For 5 icons row
+ * layout[3] layout[1] layout[0] layout[2] layout[4]
+ * For 3 icons row
+ * layout[1] layout[0] layout[2]
+ * For 5 icons row with overflow icon (can show +5 extra buttons with overflow button)
+ * expanded row: layout[5] layout[6] layout[7] layout[8] layout[9]
+ * main row: layout[3] layout[1] layout[0] layout[2] layout[4]
+ * <p>
+ * This API can be called in the
+ * {@link SessionCallback#onConnect(MediaSession2, ControllerInfo)}.
+ *
+ * @param controller controller to specify layout.
+ * @param layout ordered list of layout.
+ */
+ public void setCustomLayout(@NonNull ControllerInfo controller,
+ @NonNull List<CommandButton> layout) {
+ mImpl.setCustomLayout(controller, layout);
+ }
+
+ /**
+ * Set the new allowed command group for the controller
+ *
+ * @param controller controller to change allowed commands
+ * @param commands new allowed commands
+ */
+ public void setAllowedCommands(@NonNull ControllerInfo controller,
+ @NonNull SessionCommandGroup2 commands) {
+ mImpl.setAllowedCommands(controller, commands);
+ }
+
+ /**
+ * Send custom command to all connected controllers.
+ *
+ * @param command a command
+ * @param args optional argument
+ */
+ public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args) {
+ mImpl.sendCustomCommand(command, args);
+ }
+
+ /**
+ * Send custom command to a specific controller.
+ *
+ * @param command a command
+ * @param args optional argument
+ * @param receiver result receiver for the session
+ */
+ public void sendCustomCommand(@NonNull ControllerInfo controller,
+ @NonNull SessionCommand2 command, @Nullable Bundle args,
+ @Nullable ResultReceiver receiver) {
+ mImpl.sendCustomCommand(controller, command, args, receiver);
+ }
+
+ /**
+ * Play playback.
+ * <p>
+ * This calls {@link MediaPlayerBase#play()}.
+ */
+ @Override
+ public void play() {
+ mImpl.play();
+ }
+
+ /**
+ * Pause playback.
+ * <p>
+ * This calls {@link MediaPlayerBase#pause()}.
+ */
+ @Override
+ public void pause() {
+ mImpl.pause();
+ }
+
+ /**
+ * Stop playback, and reset the player to the initial state.
+ * <p>
+ * This calls {@link MediaPlayerBase#reset()}.
+ */
+ @Override
+ public void reset() {
+ mImpl.reset();
+ }
+
+ /**
+ * Request that the player prepare its playback. In other words, other sessions can continue
+ * to play during the preparation of this session. This method can be used to speed up the
+ * start of the playback. Once the preparation is done, the session will change its playback
+ * state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards, {@link #play} can be called
+ * to start playback.
+ * <p>
+ * This calls {@link MediaPlayerBase#reset()}.
+ */
+ @Override
+ public void prepare() {
+ mImpl.prepare();
+ }
+
+ /**
+ * Move to a new location in the media stream.
+ *
+ * @param pos Position to move to, in milliseconds.
+ */
+ @Override
+ public void seekTo(long pos) {
+ mImpl.seekTo(pos);
+ }
+
+ /**
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
- abstract static class BuilderBase
- <T extends MediaSession2, U extends BuilderBase<T, U, C>, C extends SessionCallback> {
- final Context mContext;
- MediaSession2ImplBase.BuilderBase<T, C> mBaseImpl;
- MediaPlayerInterface mPlayer;
- String mId;
- Executor mCallbackExecutor;
- C mCallback;
- MediaPlaylistAgent mPlaylistAgent;
- VolumeProviderCompat mVolumeProvider;
- PendingIntent mSessionActivity;
+ @Override
+ public void skipForward() {
+ mImpl.skipForward();
+ }
- BuilderBase(Context context) {
- if (context == null) {
- throw new IllegalArgumentException("context shouldn't be null");
- }
- mContext = context;
- // Ensure non-null
- mId = "";
- }
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ @Override
+ public void skipBackward() {
+ mImpl.skipBackward();
+ }
- /**
- * Sets the underlying {@link MediaPlayerInterface} for this session to dispatch incoming
- * event to.
- *
- * @param player a {@link MediaPlayerInterface} that handles actual media playback in your
- * app.
- */
- @NonNull U setPlayer(@NonNull MediaPlayerInterface player) {
- if (player == null) {
- throw new IllegalArgumentException("player shouldn't be null");
- }
- mBaseImpl.setPlayer(player);
- return (U) this;
- }
+ /**
+ * Notify errors to the connected controllers
+ *
+ * @param errorCode error code
+ * @param extras extras
+ */
+ @Override
+ public void notifyError(@ErrorCode int errorCode, @Nullable Bundle extras) {
+ mImpl.notifyError(errorCode, extras);
+ }
- /**
- * Sets the {@link MediaPlaylistAgent} for this session to manages playlist of the
- * underlying {@link MediaPlayerInterface}. The playlist agent should manage
- * {@link MediaPlayerInterface} for calling
- * {@link MediaPlayerInterface#setNextDataSources(List)}.
- * <p>
- * If the {@link MediaPlaylistAgent} isn't set, session will create the default playlist
- * agent.
- *
- * @param playlistAgent a {@link MediaPlaylistAgent} that manages playlist of the
- * {@code player}
- */
- U setPlaylistAgent(@NonNull MediaPlaylistAgent playlistAgent) {
- if (playlistAgent == null) {
- throw new IllegalArgumentException("playlistAgent shouldn't be null");
- }
- mBaseImpl.setPlaylistAgent(playlistAgent);
- return (U) this;
- }
+ /**
+ * Notify routes information to a connected controller
+ *
+ * @param controller controller information
+ * @param routes The routes information. Each bundle should be from
+ * MediaRouteDescritor.asBundle().
+ */
+ public void notifyRoutesInfoChanged(@NonNull ControllerInfo controller,
+ @Nullable List<Bundle> routes) {
+ mImpl.notifyRoutesInfoChanged(controller, routes);
+ }
- /**
- * Sets the {@link VolumeProviderCompat} for this session to handle volume events. If not
- * set, system will adjust the appropriate stream volume for this session's player.
- *
- * @param volumeProvider The provider that will receive volume button events.
- */
- @NonNull U setVolumeProvider(@Nullable VolumeProviderCompat volumeProvider) {
- mBaseImpl.setVolumeProvider(volumeProvider);
- return (U) this;
- }
+ /**
+ * Gets the current player state.
+ *
+ * @return the current player state
+ */
+ @Override
+ public @PlayerState int getPlayerState() {
+ return mImpl.getPlayerState();
+ }
- /**
- * Set an intent for launching UI for this Session. This can be used as a
- * quick link to an ongoing media screen. The intent should be for an
- * activity that may be started using {@link Context#startActivity(Intent)}.
- *
- * @param pi The intent to launch to show UI for this session.
- */
- @NonNull U setSessionActivity(@Nullable PendingIntent pi) {
- mBaseImpl.setSessionActivity(pi);
- return (U) this;
- }
+ /**
+ * Gets the current position.
+ *
+ * @return the current playback position in ms, or {@link MediaPlayerBase#UNKNOWN_TIME} if
+ * unknown.
+ */
+ @Override
+ public long getCurrentPosition() {
+ return mImpl.getCurrentPosition();
+ }
- /**
- * Set ID of the session. If it's not set, an empty string with used to create a session.
- * <p>
- * Use this if and only if your app supports multiple playback at the same time and also
- * wants to provide external apps to have finer controls of them.
- *
- * @param id id of the session. Must be unique per package.
- * @throws IllegalArgumentException if id is {@code null}
- * @return
- */
- @NonNull U setId(@NonNull String id) {
- if (id == null) {
- throw new IllegalArgumentException("id shouldn't be null");
- }
- mBaseImpl.setId(id);
- return (U) this;
- }
+ @Override
+ public long getDuration() {
+ return mImpl.getDuration();
+ }
- /**
- * Set callback for the session.
- *
- * @param executor callback executor
- * @param callback session callback.
- * @return
- */
- @NonNull U setSessionCallback(@NonNull Executor executor, @NonNull C callback) {
- if (executor == null) {
- throw new IllegalArgumentException("executor shouldn't be null");
- }
- if (callback == null) {
- throw new IllegalArgumentException("callback shouldn't be null");
- }
- mBaseImpl.setSessionCallback(executor, callback);
- return (U) this;
- }
+ /**
+ * Gets the buffered position, or {@link MediaPlayerBase#UNKNOWN_TIME} if unknown.
+ *
+ * @return the buffered position in ms, or {@link MediaPlayerBase#UNKNOWN_TIME}.
+ */
+ @Override
+ public long getBufferedPosition() {
+ return mImpl.getBufferedPosition();
+ }
- /**
- * Build {@link MediaSession2}.
- *
- * @return a new session
- * @throws IllegalStateException if the session with the same id is already exists for the
- * package.
- */
- @NonNull T build() {
- return mBaseImpl.build();
- }
+ /**
+ * Gets the current buffering state of the player.
+ * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
+ * buffered.
+ *
+ * @return the buffering state.
+ */
+ @Override
+ public @BuffState int getBufferingState() {
+ return mImpl.getBufferingState();
+ }
- void setImpl(MediaSession2ImplBase.BuilderBase<T, C> impl) {
- mBaseImpl = impl;
- }
+ /**
+ * Get the playback speed.
+ *
+ * @return speed
+ */
+ @Override
+ public float getPlaybackSpeed() {
+ return mImpl.getPlaybackSpeed();
+ }
+
+ /**
+ * Set the playback speed.
+ */
+ @Override
+ public void setPlaybackSpeed(float speed) {
+ mImpl.setPlaybackSpeed(speed);
+ }
+
+ /**
+ * Sets the data source missing helper. Helper will be used to provide default implementation of
+ * {@link MediaPlaylistAgent} when it isn't set by developer.
+ * <p>
+ * Default implementation of the {@link MediaPlaylistAgent} will call helper when a
+ * {@link MediaItem2} in the playlist doesn't have a {@link DataSourceDesc}. This may happen
+ * when
+ * <ul>
+ * <li>{@link MediaItem2} specified by {@link #setPlaylist(List, MediaMetadata2)} doesn't
+ * have {@link DataSourceDesc}</li>
+ * <li>{@link MediaController2#addPlaylistItem(int, MediaItem2)} is called and accepted
+ * by {@link SessionCallback#onCommandRequest(
+ * MediaSession2, ControllerInfo, SessionCommand2)}.
+ * In that case, an item would be added automatically without the data source.</li>
+ * </ul>
+ * <p>
+ * If it's not set, playback wouldn't happen for the item without data source descriptor.
+ * <p>
+ * The helper will be run on the executor that was specified by
+ * {@link Builder#setSessionCallback(Executor, SessionCallback)}.
+ *
+ * @param helper a data source missing helper.
+ * @throws IllegalStateException when the helper is set when the playlist agent is set
+ * @see #setPlaylist(List, MediaMetadata2)
+ * @see SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)
+ * @see SessionCommand2#COMMAND_CODE_PLAYLIST_ADD_ITEM
+ * @see SessionCommand2#COMMAND_CODE_PLAYLIST_REPLACE_ITEM
+ */
+ @Override
+ public void setOnDataSourceMissingHelper(@NonNull OnDataSourceMissingHelper helper) {
+ mImpl.setOnDataSourceMissingHelper(helper);
+ }
+
+ /**
+ * Clears the data source missing helper.
+ *
+ * @see #setOnDataSourceMissingHelper(OnDataSourceMissingHelper)
+ */
+ @Override
+ public void clearOnDataSourceMissingHelper() {
+ mImpl.clearOnDataSourceMissingHelper();
+ }
+
+ /**
+ * Returns the playlist from the {@link MediaPlaylistAgent}.
+ * <p>
+ * This list may differ with the list that was specified with
+ * {@link #setPlaylist(List, MediaMetadata2)} depending on the {@link MediaPlaylistAgent}
+ * implementation. Use media items returned here for other playlist agent APIs such as
+ * {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)}.
+ *
+ * @return playlist
+ * @see MediaPlaylistAgent#getPlaylist()
+ * @see SessionCallback#onPlaylistChanged(
+ * MediaSession2, MediaPlaylistAgent, List, MediaMetadata2)
+ */
+ @Override
+ public List<MediaItem2> getPlaylist() {
+ return mImpl.getPlaylist();
+ }
+
+ /**
+ * Sets a list of {@link MediaItem2} to the {@link MediaPlaylistAgent}. Ensure uniqueness of
+ * each {@link MediaItem2} in the playlist so the session can uniquely identity individual
+ * items.
+ * <p>
+ * This may be an asynchronous call, and {@link MediaPlaylistAgent} may keep the copy of the
+ * list. Wait for {@link SessionCallback#onPlaylistChanged(MediaSession2, MediaPlaylistAgent,
+ * List, MediaMetadata2)} to know the operation finishes.
+ * <p>
+ * You may specify a {@link MediaItem2} without {@link DataSourceDesc}. In that case,
+ * {@link MediaPlaylistAgent} has responsibility to dynamically query {link DataSourceDesc}
+ * when such media item is ready for preparation or play. Default implementation needs
+ * {@link OnDataSourceMissingHelper} for such case.
+ *
+ * @param list A list of {@link MediaItem2} objects to set as a play list.
+ * @throws IllegalArgumentException if given list is {@code null}, or has duplicated media
+ * items.
+ * @see MediaPlaylistAgent#setPlaylist(List, MediaMetadata2)
+ * @see SessionCallback#onPlaylistChanged(
+ * MediaSession2, MediaPlaylistAgent, List, MediaMetadata2)
+ * @see #setOnDataSourceMissingHelper
+ */
+ @Override
+ public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
+ mImpl.setPlaylist(list, metadata);
+ }
+
+ /**
+ * Skips to the item in the playlist.
+ * <p>
+ * This calls {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)} and the behavior depends
+ * on the playlist agent implementation, especially with the shuffle/repeat mode.
+ *
+ * @param item The item in the playlist you want to play
+ * @see #getShuffleMode()
+ * @see #getRepeatMode()
+ */
+ @Override
+ public void skipToPlaylistItem(@NonNull MediaItem2 item) {
+ mImpl.skipToPlaylistItem(item);
+ }
+
+ /**
+ * Skips to the previous item.
+ * <p>
+ * This calls {@link MediaPlaylistAgent#skipToPreviousItem()} and the behavior depends on the
+ * playlist agent implementation, especially with the shuffle/repeat mode.
+ *
+ * @see #getShuffleMode()
+ * @see #getRepeatMode()
+ **/
+ @Override
+ public void skipToPreviousItem() {
+ mImpl.skipToPreviousItem();
+ }
+
+ /**
+ * Skips to the next item.
+ * <p>
+ * This calls {@link MediaPlaylistAgent#skipToNextItem()} and the behavior depends on the
+ * playlist agent implementation, especially with the shuffle/repeat mode.
+ *
+ * @see #getShuffleMode()
+ * @see #getRepeatMode()
+ */
+ @Override
+ public void skipToNextItem() {
+ mImpl.skipToNextItem();
+ }
+
+ /**
+ * Gets the playlist metadata from the {@link MediaPlaylistAgent}.
+ *
+ * @return the playlist metadata
+ */
+ @Override
+ public MediaMetadata2 getPlaylistMetadata() {
+ return mImpl.getPlaylistMetadata();
+ }
+
+ /**
+ * Adds the media item to the playlist at position index. Index equals or greater than
+ * the current playlist size (e.g. {@link Integer#MAX_VALUE}) will add the item at the end of
+ * the playlist.
+ * <p>
+ * This will not change the currently playing media item.
+ * If index is less than or equal to the current index of the play list,
+ * the current index of the play list will be incremented correspondingly.
+ *
+ * @param index the index you want to add
+ * @param item the media item you want to add
+ */
+ @Override
+ public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
+ mImpl.addPlaylistItem(index, item);
+ }
+
+ /**
+ * Removes the media item in the playlist.
+ * <p>
+ * If the item is the currently playing item of the playlist, current playback
+ * will be stopped and playback moves to next source in the list.
+ *
+ * @param item the media item you want to add
+ */
+ @Override
+ public void removePlaylistItem(@NonNull MediaItem2 item) {
+ mImpl.removePlaylistItem(item);
+ }
+
+ /**
+ * Replaces the media item at index in the playlist. This can be also used to update metadata of
+ * an item.
+ *
+ * @param index the index of the item to replace
+ * @param item the new item
+ */
+ @Override
+ public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
+ mImpl.replacePlaylistItem(index, item);
+ }
+
+ /**
+ * Return currently playing media item.
+ *
+ * @return currently playing media item
+ */
+ @Override
+ public MediaItem2 getCurrentMediaItem() {
+ return mImpl.getCurrentMediaItem();
+ }
+
+ /**
+ * Updates the playlist metadata to the {@link MediaPlaylistAgent}.
+ *
+ * @param metadata metadata of the playlist
+ */
+ @Override
+ public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) {
+ mImpl.updatePlaylistMetadata(metadata);
+ }
+
+ /**
+ * Gets the repeat mode from the {@link MediaPlaylistAgent}.
+ *
+ * @return repeat mode
+ * @see MediaPlaylistAgent#REPEAT_MODE_NONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ALL
+ * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
+ */
+ @Override
+ public @RepeatMode int getRepeatMode() {
+ return mImpl.getRepeatMode();
+ }
+
+ /**
+ * Sets the repeat mode to the {@link MediaPlaylistAgent}.
+ *
+ * @param repeatMode repeat mode
+ * @see MediaPlaylistAgent#REPEAT_MODE_NONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ALL
+ * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
+ */
+ @Override
+ public void setRepeatMode(@RepeatMode int repeatMode) {
+ mImpl.setRepeatMode(repeatMode);
+ }
+
+ /**
+ * Gets the shuffle mode from the {@link MediaPlaylistAgent}.
+ *
+ * @return The shuffle mode
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
+ */
+ @Override
+ public @ShuffleMode int getShuffleMode() {
+ return mImpl.getShuffleMode();
+ }
+
+ /**
+ * Sets the shuffle mode to the {@link MediaPlaylistAgent}.
+ *
+ * @param shuffleMode The shuffle mode
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
+ */
+ @Override
+ public void setShuffleMode(@ShuffleMode int shuffleMode) {
+ mImpl.setShuffleMode(shuffleMode);
}
}
diff --git a/media/src/main/java/androidx/media/MediaSession2ImplBase.java b/media/src/main/java/androidx/media/MediaSession2ImplBase.java
index 1e768a0..e474b456 100644
--- a/media/src/main/java/androidx/media/MediaSession2ImplBase.java
+++ b/media/src/main/java/androidx/media/MediaSession2ImplBase.java
@@ -16,8 +16,7 @@
package androidx.media;
-import static androidx.media.MediaPlayerInterface.BUFFERING_STATE_UNKNOWN;
-import static androidx.media.MediaSession2.ControllerCb;
+import static androidx.media.MediaPlayerBase.BUFFERING_STATE_UNKNOWN;
import static androidx.media.MediaSession2.ControllerInfo;
import static androidx.media.MediaSession2.ErrorCode;
import static androidx.media.MediaSession2.OnDataSourceMissingHelper;
@@ -36,11 +35,9 @@
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
-import android.os.DeadObjectException;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
-import android.os.RemoteException;
import android.os.ResultReceiver;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
@@ -50,9 +47,8 @@
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.core.util.ObjectsCompat;
import androidx.media.MediaController2.PlaybackInfo;
-import androidx.media.MediaPlayerInterface.PlayerEventCallback;
+import androidx.media.MediaPlayerBase.PlayerEventCallback;
import androidx.media.MediaPlaylistAgent.PlaylistEventCallback;
import java.lang.ref.WeakReference;
@@ -72,19 +68,19 @@
private final HandlerThread mHandlerThread;
private final Handler mHandler;
private final MediaSessionCompat mSessionCompat;
- private final MediaSession2Stub mSession2Stub;
- private final MediaSessionLegacyStub mSessionLegacyStub;
+ private final MediaSession2StubImplBase mSession2Stub;
private final String mId;
private final Executor mCallbackExecutor;
private final SessionCallback mCallback;
private final SessionToken2 mSessionToken;
private final AudioManager mAudioManager;
- private final MediaPlayerInterface.PlayerEventCallback mPlayerEventCallback;
+ private final MediaPlayerBase.PlayerEventCallback mPlayerEventCallback;
private final MediaPlaylistAgent.PlaylistEventCallback mPlaylistEventCallback;
- private final MediaSession2 mInstance;
+
+ private WeakReference<MediaSession2> mInstance;
@GuardedBy("mLock")
- private MediaPlayerInterface mPlayer;
+ private MediaPlayerBase mPlayer;
@GuardedBy("mLock")
private MediaPlaylistAgent mPlaylistAgent;
@GuardedBy("mLock")
@@ -94,21 +90,21 @@
@GuardedBy("mLock")
private OnDataSourceMissingHelper mDsmHelper;
@GuardedBy("mLock")
+ private PlaybackStateCompat mPlaybackStateCompat;
+ @GuardedBy("mLock")
private PlaybackInfo mPlaybackInfo;
MediaSession2ImplBase(Context context, MediaSessionCompat sessionCompat, String id,
- MediaPlayerInterface player, MediaPlaylistAgent playlistAgent,
+ MediaPlayerBase player, MediaPlaylistAgent playlistAgent,
VolumeProviderCompat volumeProvider, PendingIntent sessionActivity,
Executor callbackExecutor, SessionCallback callback) {
mContext = context;
- mInstance = createInstance();
mHandlerThread = new HandlerThread("MediaController2_Thread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mSessionCompat = sessionCompat;
- mSession2Stub = new MediaSession2Stub(this);
- mSessionLegacyStub = new MediaSessionLegacyStub(this);
+ mSession2Stub = new MediaSession2StubImplBase(this);
mSessionCompat.setCallback(mSession2Stub, mHandler);
mSessionCompat.setSessionActivity(sessionActivity);
@@ -117,6 +113,7 @@
mCallbackExecutor = callbackExecutor;
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ // TODO: Set callback values properly
mPlayerEventCallback = new MyPlayerEventCallback(this);
mPlaylistEventCallback = new MyPlaylistEventCallback(this);
@@ -140,22 +137,16 @@
}
@Override
- public void updatePlayer(@NonNull MediaPlayerInterface player,
+ public void updatePlayer(@NonNull MediaPlayerBase player,
@Nullable MediaPlaylistAgent playlistAgent,
@Nullable VolumeProviderCompat volumeProvider) {
if (player == null) {
throw new IllegalArgumentException("player shouldn't be null");
}
- final boolean hasPlayerChanged;
- final boolean hasAgentChanged;
- final boolean hasPlaybackInfoChanged;
- final MediaPlayerInterface oldPlayer;
+ final MediaPlayerBase oldPlayer;
final MediaPlaylistAgent oldAgent;
final PlaybackInfo info = createPlaybackInfo(volumeProvider, player.getAudioAttributes());
synchronized (mLock) {
- hasPlayerChanged = (mPlayer != player);
- hasAgentChanged = (mPlaylistAgent != playlistAgent);
- hasPlaybackInfoChanged = (mPlaybackInfo != info);
oldPlayer = mPlayer;
oldAgent = mPlaylistAgent;
mPlayer = player;
@@ -170,10 +161,6 @@
mVolumeProvider = volumeProvider;
mPlaybackInfo = info;
}
- if (volumeProvider == null) {
- int stream = getLegacyStreamType(player.getAudioAttributes());
- mSessionCompat.setPlaybackToLocal(stream);
- }
if (player != oldPlayer) {
player.registerPlayerEventCallback(mCallbackExecutor, mPlayerEventCallback);
if (oldPlayer != null) {
@@ -184,40 +171,35 @@
if (playlistAgent != oldAgent) {
playlistAgent.registerPlaylistEventCallback(mCallbackExecutor, mPlaylistEventCallback);
if (oldAgent != null) {
- // Warning: Poorly implement agent may ignore this
+ // Warning: Poorly implement player may ignore this
oldAgent.unregisterPlaylistEventCallback(mPlaylistEventCallback);
}
}
if (oldPlayer != null) {
- // If it's not the first updatePlayer(), tell changes in the player, agent, and playback
- // info.
- if (hasAgentChanged) {
- // Update agent first. Otherwise current position may be changed off the current
- // media item's duration, and controller may consider it as a bug.
- notifyAgentUpdatedNotLocked(oldAgent);
- }
- if (hasPlayerChanged) {
- notifyPlayerUpdatedNotLocked(oldPlayer);
- }
- if (hasPlaybackInfoChanged) {
- // Currently hasPlaybackInfo is always true, but check this in case that we're
- // adding PlaybackInfo#equals().
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlaybackInfoChanged(info);
- }
- });
- }
+ mSession2Stub.notifyPlaybackInfoChanged(info);
+ notifyPlayerUpdatedNotLocked(oldPlayer);
}
+ // TODO(jaewan): Repeat the same thing for the playlist agent.
}
private PlaybackInfo createPlaybackInfo(VolumeProviderCompat volumeProvider,
AudioAttributesCompat attrs) {
PlaybackInfo info;
if (volumeProvider == null) {
- int stream = getLegacyStreamType(attrs);
+ int stream;
+ if (attrs == null) {
+ stream = AudioManager.STREAM_MUSIC;
+ } else {
+ stream = attrs.getVolumeControlStream();
+ if (stream == AudioManager.USE_DEFAULT_STREAM_TYPE) {
+ // It may happen if the AudioAttributes doesn't have usage.
+ // Change it to the STREAM_MUSIC because it's not supported by audio manager
+ // for querying volume level.
+ stream = AudioManager.STREAM_MUSIC;
+ }
+ }
+
int controlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
if (Build.VERSION.SDK_INT >= 21 && mAudioManager.isVolumeFixed()) {
controlType = VolumeProviderCompat.VOLUME_CONTROL_FIXED;
@@ -239,23 +221,6 @@
return info;
}
- private int getLegacyStreamType(@Nullable AudioAttributesCompat attrs) {
- int stream;
- if (attrs == null) {
- stream = AudioManager.STREAM_MUSIC;
- } else {
- stream = attrs.getLegacyStreamType();
- if (stream == AudioManager.USE_DEFAULT_STREAM_TYPE) {
- // Usually, AudioAttributesCompat#getLegacyStreamType() does not return
- // USE_DEFAULT_STREAM_TYPE unless the developer sets it with
- // AudioAttributesCompat.Builder#setLegacyStreamType().
- // But for safety, let's convert USE_DEFAULT_STREAM_TYPE to STREAM_MUSIC here.
- stream = AudioManager.STREAM_MUSIC;
- }
- }
- return stream;
- }
-
@Override
public void close() {
synchronized (mLock) {
@@ -267,17 +232,13 @@
mSessionCompat.release();
mHandler.removeCallbacksAndMessages(null);
if (mHandlerThread.isAlive()) {
- if (Build.VERSION.SDK_INT >= 18) {
- mHandlerThread.quitSafely();
- } else {
- mHandlerThread.quit();
- }
+ mHandlerThread.quitSafely();
}
}
}
@Override
- public @NonNull MediaPlayerInterface getPlayer() {
+ public @NonNull MediaPlayerBase getPlayer() {
synchronized (mLock) {
return mPlayer;
}
@@ -303,34 +264,31 @@
}
@Override
- public @NonNull List<ControllerInfo> getConnectedControllers() {
+ public @NonNull List<MediaSession2.ControllerInfo> getConnectedControllers() {
return mSession2Stub.getConnectedControllers();
}
@Override
public void setAudioFocusRequest(@Nullable AudioFocusRequest afr) {
+ // TODO(jaewan): implement this (b/72529899)
+ // mProvider.setAudioFocusRequest_impl(focusGain);
}
@Override
public void setCustomLayout(@NonNull ControllerInfo controller,
- @NonNull final List<MediaSession2.CommandButton> layout) {
+ @NonNull List<MediaSession2.CommandButton> layout) {
if (controller == null) {
throw new IllegalArgumentException("controller shouldn't be null");
}
if (layout == null) {
throw new IllegalArgumentException("layout shouldn't be null");
}
- notifyToController(controller, new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onCustomLayoutChanged(layout);
- }
- });
+ mSession2Stub.notifyCustomLayout(controller, layout);
}
@Override
public void setAllowedCommands(@NonNull ControllerInfo controller,
- @NonNull final SessionCommandGroup2 commands) {
+ @NonNull SessionCommandGroup2 commands) {
if (controller == null) {
throw new IllegalArgumentException("controller shouldn't be null");
}
@@ -338,49 +296,32 @@
throw new IllegalArgumentException("commands shouldn't be null");
}
mSession2Stub.setAllowedCommands(controller, commands);
- notifyToController(controller, new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onAllowedCommandsChanged(commands);
- }
- });
}
@Override
- public void sendCustomCommand(@NonNull final SessionCommand2 command,
- @Nullable final Bundle args) {
+ public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args) {
if (command == null) {
throw new IllegalArgumentException("command shouldn't be null");
}
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onCustomCommand(command, args, null);
- }
- });
+ mSession2Stub.sendCustomCommand(command, args);
}
@Override
public void sendCustomCommand(@NonNull ControllerInfo controller,
- @NonNull final SessionCommand2 command, @Nullable final Bundle args,
- @Nullable final ResultReceiver receiver) {
+ @NonNull SessionCommand2 command, @Nullable Bundle args,
+ @Nullable ResultReceiver receiver) {
if (controller == null) {
throw new IllegalArgumentException("controller shouldn't be null");
}
if (command == null) {
throw new IllegalArgumentException("command shouldn't be null");
}
- notifyToController(controller, new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onCustomCommand(command, args, receiver);
- }
- });
+ mSession2Stub.sendCustomCommand(controller, command, args, receiver);
}
@Override
public void play() {
- MediaPlayerInterface player;
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -393,7 +334,7 @@
@Override
public void pause() {
- MediaPlayerInterface player;
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -406,7 +347,7 @@
@Override
public void reset() {
- MediaPlayerInterface player;
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -419,7 +360,7 @@
@Override
public void prepare() {
- MediaPlayerInterface player;
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -432,7 +373,7 @@
@Override
public void seekTo(long pos) {
- MediaPlayerInterface player;
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -454,29 +395,19 @@
}
@Override
- public void notifyError(@ErrorCode final int errorCode, @Nullable final Bundle extras) {
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onError(errorCode, extras);
- }
- });
+ public void notifyError(@ErrorCode int errorCode, @Nullable Bundle extras) {
+ mSession2Stub.notifyError(errorCode, extras);
}
@Override
public void notifyRoutesInfoChanged(@NonNull ControllerInfo controller,
- @Nullable final List<Bundle> routes) {
- notifyToController(controller, new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onRoutesInfoChanged(routes);
- }
- });
+ @Nullable List<Bundle> routes) {
+ mSession2Stub.notifyRoutesInfoChanged(controller, routes);
}
@Override
- public @MediaPlayerInterface.PlayerState int getPlayerState() {
- MediaPlayerInterface player;
+ public @MediaPlayerBase.PlayerState int getPlayerState() {
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -485,12 +416,12 @@
} else if (DEBUG) {
Log.d(TAG, "API calls after the close()", new IllegalStateException());
}
- return MediaPlayerInterface.PLAYER_STATE_ERROR;
+ return MediaPlayerBase.PLAYER_STATE_ERROR;
}
@Override
public long getCurrentPosition() {
- MediaPlayerInterface player;
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -499,28 +430,18 @@
} else if (DEBUG) {
Log.d(TAG, "API calls after the close()", new IllegalStateException());
}
- return MediaPlayerInterface.UNKNOWN_TIME;
+ return MediaPlayerBase.UNKNOWN_TIME;
}
@Override
public long getDuration() {
- MediaPlayerInterface player;
- synchronized (mLock) {
- player = mPlayer;
- }
- if (player != null) {
- // Note: This should be the same as
- // getCurrentMediaItem().getMetadata().getLong(METADATA_KEY_DURATION)
- return player.getDuration();
- } else if (DEBUG) {
- Log.d(TAG, "API calls after the close()", new IllegalStateException());
- }
- return MediaPlayerInterface.UNKNOWN_TIME;
+ // TODO: implement
+ return 0;
}
@Override
public long getBufferedPosition() {
- MediaPlayerInterface player;
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -529,12 +450,12 @@
} else if (DEBUG) {
Log.d(TAG, "API calls after the close()", new IllegalStateException());
}
- return MediaPlayerInterface.UNKNOWN_TIME;
+ return MediaPlayerBase.UNKNOWN_TIME;
}
@Override
- public @MediaPlayerInterface.BuffState int getBufferingState() {
- MediaPlayerInterface player;
+ public @MediaPlayerBase.BuffState int getBufferingState() {
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -548,7 +469,7 @@
@Override
public float getPlaybackSpeed() {
- MediaPlayerInterface player;
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -562,7 +483,7 @@
@Override
public void setPlaybackSpeed(float speed) {
- MediaPlayerInterface player;
+ MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
}
@@ -819,63 +740,18 @@
}
///////////////////////////////////////////////////
- // LibrarySession Methods
- ///////////////////////////////////////////////////
-
- @Override
- void notifyChildrenChanged(ControllerInfo controller, final String parentId,
- final int itemCount, final Bundle extras,
- List<MediaSessionManager.RemoteUserInfo> subscribingBrowsers) {
- if (controller == null) {
- throw new IllegalArgumentException("controller shouldn't be null");
- }
- if (TextUtils.isEmpty(parentId)) {
- throw new IllegalArgumentException("query shouldn't be empty");
- }
-
- // Notify controller only if it has subscribed the parentId.
- for (MediaSessionManager.RemoteUserInfo info : subscribingBrowsers) {
- if (info.getPackageName().equals(controller.getPackageName())
- && info.getUid() == controller.getUid()) {
- notifyToController(controller, new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onChildrenChanged(parentId, itemCount, extras);
- }
- });
- return;
- }
- }
- }
-
- @Override
- void notifySearchResultChanged(ControllerInfo controller, final String query,
- final int itemCount, final Bundle extras) {
- if (controller == null) {
- throw new IllegalArgumentException("controller shouldn't be null");
- }
- if (TextUtils.isEmpty(query)) {
- throw new IllegalArgumentException("query shouldn't be empty");
- }
- notifyToController(controller, new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onSearchResultChanged(query, itemCount, extras);
- }
- });
- }
-
- ///////////////////////////////////////////////////
// package private and private methods
///////////////////////////////////////////////////
+
@Override
- MediaSession2 createInstance() {
- return new MediaSession2(this);
+ void setInstance(MediaSession2 session) {
+ mInstance = new WeakReference<>(session);
+
}
@Override
- @NonNull MediaSession2 getInstance() {
- return mInstance;
+ MediaSession2 getInstance() {
+ return mInstance.get();
}
@Override
@@ -894,11 +770,6 @@
}
@Override
- MediaSessionCompat getSessionCompat() {
- return mSessionCompat;
- }
-
- @Override
boolean isClosed() {
return !mHandlerThread.isAlive();
}
@@ -908,6 +779,12 @@
synchronized (mLock) {
int state = MediaUtils2.createPlaybackStateCompatState(getPlayerState(),
getBufferingState());
+ // TODO: Consider following missing stuff
+ // - setCustomAction(): Fill custom layout
+ // - setErrorMessage(): Fill error message when notifyError() is called.
+ // - setActiveQueueItemId(): Fill here with the current media item...
+ // - setExtra(): No idea at this moment.
+ // TODO: generate actions from the allowed commands.
long allActions = PlaybackStateCompat.ACTION_STOP | PlaybackStateCompat.ACTION_PAUSE
| PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_REWIND
| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
@@ -939,6 +816,11 @@
return mPlaybackInfo;
}
}
+
+ MediaSession2StubImplBase getSession2Stub() {
+ return mSession2Stub;
+ }
+
private static String getServiceName(Context context, String serviceAction, String id) {
PackageManager manager = context.getPackageManager();
Intent serviceIntent = new Intent(serviceAction);
@@ -964,203 +846,105 @@
return serviceName;
}
- private void notifyAgentUpdatedNotLocked(MediaPlaylistAgent oldAgent) {
- // Tells the playlist change first, to current item can change be notified with an item
- // within the playlist.
- List<MediaItem2> oldPlaylist = oldAgent.getPlaylist();
- final List<MediaItem2> newPlaylist = getPlaylist();
- if (!ObjectsCompat.equals(oldPlaylist, newPlaylist)) {
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlaylistChanged(
- newPlaylist, getPlaylistMetadata());
- }
- });
- } else {
- MediaMetadata2 oldMetadata = oldAgent.getPlaylistMetadata();
- final MediaMetadata2 newMetadata = getPlaylistMetadata();
- if (!ObjectsCompat.equals(oldMetadata, newMetadata)) {
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlaylistMetadataChanged(newMetadata);
- }
- });
- }
+ private void notifyPlayerUpdatedNotLocked(MediaPlayerBase oldPlayer) {
+ MediaPlayerBase player;
+ synchronized (mLock) {
+ player = mPlayer;
}
- MediaItem2 oldCurrentItem = oldAgent.getCurrentMediaItem();
- final MediaItem2 newCurrentItem = getCurrentMediaItem();
- if (!ObjectsCompat.equals(oldCurrentItem, newCurrentItem)) {
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onCurrentMediaItemChanged(newCurrentItem);
- }
- });
+ // TODO(jaewan): (Can be post-P) Find better way for player.getPlayerState() //
+ // In theory, Session.getXXX() may not be the same as Player.getXXX()
+ // and we should notify information of the session.getXXX() instead of
+ // player.getXXX()
+ // Notify to controllers as well.
+ final int state = player.getPlayerState();
+ if (state != oldPlayer.getPlayerState()) {
+ // TODO: implement
+ mSession2Stub.notifyPlayerStateChanged(state);
}
- final int repeatMode = getRepeatMode();
- if (oldAgent.getRepeatMode() != repeatMode) {
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onRepeatModeChanged(repeatMode);
- }
- });
- }
- final int shuffleMode = getShuffleMode();
- if (oldAgent.getShuffleMode() != shuffleMode) {
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onShuffleModeChanged(shuffleMode);
- }
- });
- }
- }
- private void notifyPlayerUpdatedNotLocked(MediaPlayerInterface oldPlayer) {
- // Always forcefully send the player state and buffered state to send the current position
- // and buffered position.
- final int playerState = getPlayerState();
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlayerStateChanged(playerState);
- }
- });
- final MediaItem2 item = getCurrentMediaItem();
- if (item != null) {
- final int bufferingState = getBufferingState();
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onBufferingStateChanged(item, bufferingState);
- }
- });
+ final long currentTimeMs = System.currentTimeMillis();
+ final long position = player.getCurrentPosition();
+ if (position != oldPlayer.getCurrentPosition()) {
+ // TODO: implement
+ //mSession2Stub.notifyPositionChangedNotLocked(currentTimeMs, position);
}
- final float speed = getPlaybackSpeed();
+
+ final float speed = player.getPlaybackSpeed();
if (speed != oldPlayer.getPlaybackSpeed()) {
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlaybackSpeedChanged(speed);
- }
- });
+ // TODO: implement
+ //mSession2Stub.notifyPlaybackSpeedChangedNotLocked(speed);
}
- // Note: AudioInfo is updated outside of this API.
+
+ final long bufferedPosition = player.getBufferedPosition();
+ if (bufferedPosition != oldPlayer.getBufferedPosition()) {
+ // TODO: implement
+ //mSession2Stub.notifyBufferedPositionChangedNotLocked(bufferedPosition);
+ }
}
private void notifyPlaylistChangedOnExecutor(MediaPlaylistAgent playlistAgent,
- final List<MediaItem2> list, final MediaMetadata2 metadata) {
+ List<MediaItem2> list, MediaMetadata2 metadata) {
synchronized (mLock) {
if (playlistAgent != mPlaylistAgent) {
// Ignore calls from the old agent.
return;
}
}
- mCallback.onPlaylistChanged(mInstance, playlistAgent, list, metadata);
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlaylistChanged(list, metadata);
- }
- });
+ MediaSession2 session2 = mInstance.get();
+ if (session2 != null) {
+ mCallback.onPlaylistChanged(session2, playlistAgent, list, metadata);
+ mSession2Stub.notifyPlaylistChanged(list, metadata);
+ }
}
private void notifyPlaylistMetadataChangedOnExecutor(MediaPlaylistAgent playlistAgent,
- final MediaMetadata2 metadata) {
+ MediaMetadata2 metadata) {
synchronized (mLock) {
if (playlistAgent != mPlaylistAgent) {
// Ignore calls from the old agent.
return;
}
}
- mCallback.onPlaylistMetadataChanged(mInstance, playlistAgent, metadata);
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlaylistMetadataChanged(metadata);
- }
- });
+ MediaSession2 session2 = mInstance.get();
+ if (session2 != null) {
+ mCallback.onPlaylistMetadataChanged(session2, playlistAgent, metadata);
+ mSession2Stub.notifyPlaylistMetadataChanged(metadata);
+ }
}
private void notifyRepeatModeChangedOnExecutor(MediaPlaylistAgent playlistAgent,
- final int repeatMode) {
+ int repeatMode) {
synchronized (mLock) {
if (playlistAgent != mPlaylistAgent) {
// Ignore calls from the old agent.
return;
}
}
- mCallback.onRepeatModeChanged(mInstance, playlistAgent, repeatMode);
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onRepeatModeChanged(repeatMode);
- }
- });
+ MediaSession2 session2 = mInstance.get();
+ if (session2 != null) {
+ mCallback.onRepeatModeChanged(session2, playlistAgent, repeatMode);
+ mSession2Stub.notifyRepeatModeChanged(repeatMode);
+ }
}
private void notifyShuffleModeChangedOnExecutor(MediaPlaylistAgent playlistAgent,
- final int shuffleMode) {
+ int shuffleMode) {
synchronized (mLock) {
if (playlistAgent != mPlaylistAgent) {
// Ignore calls from the old agent.
return;
}
}
- mCallback.onShuffleModeChanged(mInstance, playlistAgent, shuffleMode);
- notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onShuffleModeChanged(shuffleMode);
- }
- });
- }
-
- private void notifyToController(@NonNull final ControllerInfo controller,
- @NonNull NotifyRunnable runnable) {
- if (controller == null) {
- return;
- }
- try {
- runnable.run(controller.getControllerCb());
- } catch (DeadObjectException e) {
- if (DEBUG) {
- Log.d(TAG, controller.toString() + " is gone", e);
- }
- mSession2Stub.removeControllerInfo(controller);
- mCallbackExecutor.execute(new Runnable() {
- @Override
- public void run() {
- mCallback.onDisconnected(MediaSession2ImplBase.this.getInstance(), controller);
- }
- });
- } catch (RemoteException e) {
- // Currently it's TransactionTooLargeException or DeadSystemException.
- // We'd better to leave log for those cases because
- // - TransactionTooLargeException means that we may need to fix our code.
- // (e.g. add pagination or special way to deliver Bitmap)
- // - DeadSystemException means that errors around it can be ignored.
- Log.w(TAG, "Exception in " + controller.toString(), e);
- }
- }
-
- private void notifyToAllControllers(@NonNull NotifyRunnable runnable) {
- List<ControllerInfo> controllers = getConnectedControllers();
- for (int i = 0; i < controllers.size(); i++) {
- notifyToController(controllers.get(i), runnable);
+ MediaSession2 session2 = mInstance.get();
+ if (session2 != null) {
+ mCallback.onShuffleModeChanged(session2, playlistAgent, shuffleMode);
+ mSession2Stub.notifyShuffleModeChanged(shuffleMode);
}
}
///////////////////////////////////////////////////
// Inner classes
///////////////////////////////////////////////////
- @FunctionalInterface
- private interface NotifyRunnable {
- void run(ControllerCb callback) throws RemoteException;
- }
private static class MyPlayerEventCallback extends PlayerEventCallback {
private final WeakReference<MediaSession2ImplBase> mSession;
@@ -1170,41 +954,31 @@
}
@Override
- public void onCurrentDataSourceChanged(final MediaPlayerInterface player,
+ public void onCurrentDataSourceChanged(final MediaPlayerBase mpb,
final DataSourceDesc dsd) {
final MediaSession2ImplBase session = getSession();
- if (session == null) {
+ // TODO: handle properly when dsd == null
+ if (session == null || dsd == null) {
return;
}
session.getCallbackExecutor().execute(new Runnable() {
@Override
public void run() {
- final MediaItem2 item;
- if (dsd == null) {
- // This is OK because onCurrentDataSourceChanged() can be called with the
- // null dsd, so onCurrentMediaItemChanged() can be as well.
- item = null;
- } else {
- item = MyPlayerEventCallback.this.getMediaItem(session, dsd);
- if (item == null) {
- Log.w(TAG, "Cannot obtain media item from the dsd=" + dsd);
- return;
- }
+ MediaItem2 item = MyPlayerEventCallback.this.getMediaItem(session, dsd);
+ if (item == null) {
+ return;
}
- session.getCallback().onCurrentMediaItemChanged(session.getInstance(), player,
+ session.getCallback().onCurrentMediaItemChanged(session.getInstance(), mpb,
item);
- session.notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onCurrentMediaItemChanged(item);
- }
- });
+ if (item.equals(session.getCurrentMediaItem())) {
+ session.getSession2Stub().notifyCurrentMediaItemChanged(item);
+ }
}
});
}
@Override
- public void onMediaPrepared(final MediaPlayerInterface mpb, final DataSourceDesc dsd) {
+ public void onMediaPrepared(final MediaPlayerBase mpb, final DataSourceDesc dsd) {
final MediaSession2ImplBase session = getSession();
if (session == null || dsd == null) {
return;
@@ -1216,58 +990,14 @@
if (item == null) {
return;
}
- if (item.equals(session.getCurrentMediaItem())) {
- long duration = session.getDuration();
- if (duration < 0) {
- return;
- }
- MediaMetadata2 metadata = item.getMetadata();
- if (metadata != null) {
- if (!metadata.containsKey(MediaMetadata2.METADATA_KEY_DURATION)) {
- metadata = new MediaMetadata2.Builder(metadata).putLong(
- MediaMetadata2.METADATA_KEY_DURATION, duration).build();
- } else {
- long durationFromMetadata =
- metadata.getLong(MediaMetadata2.METADATA_KEY_DURATION);
- if (duration != durationFromMetadata) {
- // Warns developers about the mismatch. Don't log media item
- // here to keep metadata secure.
- Log.w(TAG, "duration mismatch for an item."
- + " duration from player=" + duration
- + " duration from metadata=" + durationFromMetadata
- + ". May be a timing issue?");
- }
- // Trust duration in the metadata set by developer.
- // In theory, duration may differ if the current item has been
- // changed before the getDuration(). So it's better not touch
- // duration set by developer.
- metadata = null;
- }
- } else {
- metadata = new MediaMetadata2.Builder()
- .putLong(MediaMetadata2.METADATA_KEY_DURATION, duration)
- .putString(MediaMetadata2.METADATA_KEY_MEDIA_ID,
- item.getMediaId())
- .build();
- }
- if (metadata != null) {
- item.setMetadata(metadata);
- session.notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlaylistChanged(
- session.getPlaylist(), session.getPlaylistMetadata());
- }
- });
- }
- }
session.getCallback().onMediaPrepared(session.getInstance(), mpb, item);
+ // TODO (jaewan): Notify controllers through appropriate callback. (b/74505936)
}
});
}
@Override
- public void onPlayerStateChanged(final MediaPlayerInterface player, final int state) {
+ public void onPlayerStateChanged(final MediaPlayerBase mpb, final int state) {
final MediaSession2ImplBase session = getSession();
if (session == null) {
return;
@@ -1275,21 +1005,15 @@
session.getCallbackExecutor().execute(new Runnable() {
@Override
public void run() {
- session.getCallback().onPlayerStateChanged(
- session.getInstance(), player, state);
- session.notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlayerStateChanged(state);
- }
- });
+ session.getCallback().onPlayerStateChanged(session.getInstance(), mpb, state);
+ session.getSession2Stub().notifyPlayerStateChanged(state);
}
});
}
@Override
- public void onBufferingStateChanged(final MediaPlayerInterface mpb,
- final DataSourceDesc dsd, final int state) {
+ public void onBufferingStateChanged(final MediaPlayerBase mpb, final DataSourceDesc dsd,
+ final int state) {
final MediaSession2ImplBase session = getSession();
if (session == null || dsd == null) {
return;
@@ -1297,24 +1021,19 @@
session.getCallbackExecutor().execute(new Runnable() {
@Override
public void run() {
- final MediaItem2 item = MyPlayerEventCallback.this.getMediaItem(session, dsd);
+ MediaItem2 item = MyPlayerEventCallback.this.getMediaItem(session, dsd);
if (item == null) {
return;
}
session.getCallback().onBufferingStateChanged(
session.getInstance(), mpb, item, state);
- session.notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onBufferingStateChanged(item, state);
- }
- });
+ session.getSession2Stub().notifyBufferingStateChanged(item, state);
}
});
}
@Override
- public void onPlaybackSpeedChanged(final MediaPlayerInterface mpb, final float speed) {
+ public void onPlaybackSpeedChanged(final MediaPlayerBase mpb, final float speed) {
final MediaSession2ImplBase session = getSession();
if (session == null) {
return;
@@ -1323,32 +1042,7 @@
@Override
public void run() {
session.getCallback().onPlaybackSpeedChanged(session.getInstance(), mpb, speed);
- session.notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onPlaybackSpeedChanged(speed);
- }
- });
- }
- });
- }
-
- @Override
- public void onSeekCompleted(final MediaPlayerInterface 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.notifyToAllControllers(new NotifyRunnable() {
- @Override
- public void run(ControllerCb callback) throws RemoteException {
- callback.onSeekCompleted(position);
- }
- });
+ session.getSession2Stub().notifyPlaybackSpeedChanged(speed);
}
});
}
@@ -1429,7 +1123,7 @@
abstract static class BuilderBase
<T extends MediaSession2, C extends SessionCallback> {
final Context mContext;
- MediaPlayerInterface mPlayer;
+ MediaPlayerBase mPlayer;
String mId;
Executor mCallbackExecutor;
C mCallback;
@@ -1446,7 +1140,7 @@
mId = TAG;
}
- void setPlayer(@NonNull MediaPlayerInterface player) {
+ void setPlayer(@NonNull MediaPlayerBase player) {
if (player == null) {
throw new IllegalArgumentException("player shouldn't be null");
}
diff --git a/media/src/main/java/androidx/media/MediaSession2Stub.java b/media/src/main/java/androidx/media/MediaSession2StubImplBase.java
similarity index 68%
rename from media/src/main/java/androidx/media/MediaSession2Stub.java
rename to media/src/main/java/androidx/media/MediaSession2StubImplBase.java
index 87b17cf..48e641e 100644
--- a/media/src/main/java/androidx/media/MediaSession2Stub.java
+++ b/media/src/main/java/androidx/media/MediaSession2StubImplBase.java
@@ -25,7 +25,6 @@
import static androidx.media.MediaConstants2.ARGUMENT_ERROR_CODE;
import static androidx.media.MediaConstants2.ARGUMENT_EXTRAS;
import static androidx.media.MediaConstants2.ARGUMENT_ICONTROLLER_CALLBACK;
-import static androidx.media.MediaConstants2.ARGUMENT_ITEM_COUNT;
import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ID;
import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ITEM;
import static androidx.media.MediaConstants2.ARGUMENT_PACKAGE_NAME;
@@ -56,8 +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_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_CHILDREN_CHANGED;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_BUFFERING_STATE_CHAGNED;
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;
@@ -67,12 +65,9 @@
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_SEARCH_RESULT_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;
-import static androidx.media.SessionCommand2.COMMAND_CODE_CUSTOM;
import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE;
import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY;
import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE;
@@ -111,22 +106,21 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.os.DeadObjectException;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.support.v4.media.session.IMediaControllerCallback;
import android.support.v4.media.session.MediaSessionCompat;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.collection.ArrayMap;
-import androidx.core.app.BundleCompat;
import androidx.media.MediaController2.PlaybackInfo;
import androidx.media.MediaSession2.CommandButton;
-import androidx.media.MediaSession2.ControllerCb;
import androidx.media.MediaSession2.ControllerInfo;
import java.util.ArrayList;
@@ -135,7 +129,7 @@
import java.util.Set;
@TargetApi(Build.VERSION_CODES.KITKAT)
-class MediaSession2Stub extends MediaSessionCompat.Callback {
+class MediaSession2StubImplBase extends MediaSessionCompat.Callback {
private static final String TAG = "MS2StubImplBase";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -167,16 +161,78 @@
private final ArrayMap<ControllerInfo, SessionCommandGroup2> mAllowedCommandGroupMap =
new ArrayMap<>();
- MediaSession2Stub(MediaSession2.SupportLibraryImpl session) {
+ MediaSession2StubImplBase(MediaSession2.SupportLibraryImpl session) {
mSession = session;
mContext = mSession.getContext();
}
@Override
+ public void onPrepare() {
+ mSession.getCallbackExecutor().execute(new Runnable() {
+ @Override
+ public void run() {
+ if (mSession.isClosed()) {
+ return;
+ }
+ mSession.prepare();
+ }
+ });
+ }
+
+ @Override
+ public void onPlay() {
+ mSession.getCallbackExecutor().execute(new Runnable() {
+ @Override
+ public void run() {
+ if (mSession.isClosed()) {
+ return;
+ }
+ mSession.play();
+ }
+ });
+ }
+
+ @Override
+ public void onPause() {
+ mSession.getCallbackExecutor().execute(new Runnable() {
+ @Override
+ public void run() {
+ if (mSession.isClosed()) {
+ return;
+ }
+ mSession.pause();
+ }
+ });
+ }
+
+ @Override
+ public void onStop() {
+ mSession.getCallbackExecutor().execute(new Runnable() {
+ @Override
+ public void run() {
+ if (mSession.isClosed()) {
+ return;
+ }
+ mSession.reset();
+ }
+ });
+ }
+
+ @Override
+ public void onSeekTo(final long pos) {
+ mSession.getCallbackExecutor().execute(new Runnable() {
+ @Override
+ public void run() {
+ if (mSession.isClosed()) {
+ return;
+ }
+ mSession.seekTo(pos);
+ }
+ });
+ }
+
+ @Override
public void onCommand(String command, final Bundle extras, final ResultReceiver cb) {
- if (extras != null) {
- extras.setClassLoader(MediaSession2.class.getClassLoader());
- }
switch (command) {
case CONTROLLER_COMMAND_CONNECT:
connect(extras, cb);
@@ -186,8 +242,8 @@
break;
case CONTROLLER_COMMAND_BY_COMMAND_CODE: {
final int commandCode = extras.getInt(ARGUMENT_COMMAND_CODE);
- IMediaControllerCallback caller = IMediaControllerCallback.Stub.asInterface(
- BundleCompat.getBinder(extras, ARGUMENT_ICONTROLLER_CALLBACK));
+ IMediaControllerCallback caller =
+ (IMediaControllerCallback) extras.getBinder(ARGUMENT_ICONTROLLER_CALLBACK);
if (caller == null) {
return;
}
@@ -276,10 +332,7 @@
int flags = extras.getInt(ARGUMENT_VOLUME_FLAGS);
VolumeProviderCompat vp = mSession.getVolumeProvider();
if (vp == null) {
- MediaSessionCompat sessionCompat = mSession.getSessionCompat();
- if (sessionCompat != null) {
- sessionCompat.getController().setVolumeTo(value, flags);
- }
+ // TODO: Revisit
} else {
vp.onSetVolumeTo(value);
}
@@ -290,11 +343,7 @@
int flags = extras.getInt(ARGUMENT_VOLUME_FLAGS);
VolumeProviderCompat vp = mSession.getVolumeProvider();
if (vp == null) {
- MediaSessionCompat sessionCompat = mSession.getSessionCompat();
- if (sessionCompat != null) {
- sessionCompat.getController().adjustVolume(
- direction, flags);
- }
+ // TODO: Revisit
} else {
vp.onAdjustVolume(direction);
}
@@ -389,8 +438,8 @@
case CONTROLLER_COMMAND_BY_CUSTOM_COMMAND: {
final SessionCommand2 customCommand =
SessionCommand2.fromBundle(extras.getBundle(ARGUMENT_CUSTOM_COMMAND));
- IMediaControllerCallback caller = IMediaControllerCallback.Stub.asInterface(
- BundleCompat.getBinder(extras, ARGUMENT_ICONTROLLER_CALLBACK));
+ IMediaControllerCallback caller =
+ (IMediaControllerCallback) extras.getBinder(ARGUMENT_ICONTROLLER_CALLBACK);
if (caller == null || customCommand == null) {
return;
}
@@ -418,10 +467,261 @@
return controllers;
}
+ void notifyCustomLayout(ControllerInfo controller, final List<CommandButton> layout) {
+ notifyInternal(controller, new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putParcelableArray(ARGUMENT_COMMAND_BUTTONS,
+ MediaUtils2.toCommandButtonParcelableArray(layout));
+ controller.getControllerBinder().onEvent(SESSION_EVENT_SET_CUSTOM_LAYOUT, bundle);
+ }
+ });
+ }
+
void setAllowedCommands(ControllerInfo controller, final SessionCommandGroup2 commands) {
synchronized (mLock) {
mAllowedCommandGroupMap.put(controller, commands);
}
+ notifyInternal(controller, new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putBundle(ARGUMENT_ALLOWED_COMMANDS, commands.toBundle());
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED, bundle);
+ }
+ });
+ }
+
+ public void sendCustomCommand(ControllerInfo controller, final SessionCommand2 command,
+ final Bundle args, final ResultReceiver receiver) {
+ if (receiver != null && controller == null) {
+ throw new IllegalArgumentException("Controller shouldn't be null if result receiver is"
+ + " specified");
+ }
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
+ notifyInternal(controller, new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ // TODO: Send this event through MediaSessionCompat.XXX()
+ Bundle bundle = new Bundle();
+ bundle.putBundle(ARGUMENT_CUSTOM_COMMAND, command.toBundle());
+ bundle.putBundle(ARGUMENT_ARGUMENTS, args);
+ bundle.putParcelable(ARGUMENT_RESULT_RECEIVER, receiver);
+ controller.getControllerBinder().onEvent(SESSION_EVENT_SEND_CUSTOM_COMMAND, bundle);
+ }
+ });
+ }
+
+ public void sendCustomCommand(final SessionCommand2 command, final Bundle args) {
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
+ final Bundle bundle = new Bundle();
+ bundle.putBundle(ARGUMENT_CUSTOM_COMMAND, command.toBundle());
+ bundle.putBundle(ARGUMENT_ARGUMENTS, args);
+ notifyAll(new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ controller.getControllerBinder().onEvent(SESSION_EVENT_SEND_CUSTOM_COMMAND, bundle);
+ }
+ });
+ }
+
+ void notifyCurrentMediaItemChanged(final MediaItem2 item) {
+ notifyAll(COMMAND_CODE_PLAYLIST_GET_CURRENT_MEDIA_ITEM, new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_CURRENT_MEDIA_ITEM_CHANGED, bundle);
+ }
+ });
+ }
+
+ void notifyPlaybackInfoChanged(final PlaybackInfo info) {
+ notifyAll(new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putBundle(ARGUMENT_PLAYBACK_INFO, info.toBundle());
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED, bundle);
+ }
+ });
+ }
+
+ void notifyPlayerStateChanged(final int state) {
+ notifyAll(new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putInt(ARGUMENT_PLAYER_STATE, state);
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_PLAYER_STATE_CHANGED, bundle);
+ }
+ });
+ }
+
+ void notifyPlaybackSpeedChanged(final float speed) {
+ notifyAll(new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(
+ ARGUMENT_PLAYBACK_STATE_COMPAT, mSession.getPlaybackStateCompat());
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_PLAYBACK_SPEED_CHANGED, bundle);
+ }
+ });
+ }
+
+ void notifyBufferingStateChanged(final MediaItem2 item, final int bufferingState) {
+ notifyAll(new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
+ bundle.putInt(ARGUMENT_BUFFERING_STATE, bufferingState);
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_BUFFERING_STATE_CHAGNED, bundle);
+ }
+ });
+ }
+
+ void notifyError(final int errorCode, final Bundle extras) {
+ notifyAll(new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putInt(ARGUMENT_ERROR_CODE, errorCode);
+ bundle.putBundle(ARGUMENT_EXTRAS, extras);
+ controller.getControllerBinder().onEvent(SESSION_EVENT_ON_ERROR, bundle);
+ }
+ });
+ }
+
+ void notifyRoutesInfoChanged(@NonNull final ControllerInfo controller,
+ @Nullable final List<Bundle> routes) {
+ notifyInternal(controller, new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = null;
+ if (routes != null) {
+ bundle = new Bundle();
+ bundle.putParcelableArray(ARGUMENT_ROUTE_BUNDLE, routes.toArray(new Bundle[0]));
+ }
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_ROUTES_INFO_CHANGED, bundle);
+ }
+ });
+ }
+
+ void notifyPlaylistChanged(final List<MediaItem2> playlist,
+ final MediaMetadata2 metadata) {
+ notifyAll(COMMAND_CODE_PLAYLIST_GET_LIST, new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putParcelableArray(ARGUMENT_PLAYLIST,
+ MediaUtils2.toMediaItem2ParcelableArray(playlist));
+ bundle.putBundle(ARGUMENT_PLAYLIST_METADATA,
+ metadata == null ? null : metadata.toBundle());
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_PLAYLIST_CHANGED, bundle);
+ }
+ });
+ }
+
+ void notifyPlaylistMetadataChanged(final MediaMetadata2 metadata) {
+ notifyAll(SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST_METADATA, new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putBundle(ARGUMENT_PLAYLIST_METADATA,
+ metadata == null ? null : metadata.toBundle());
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_PLAYLIST_METADATA_CHANGED, bundle);
+ }
+ });
+ }
+
+ void notifyRepeatModeChanged(final int repeatMode) {
+ notifyAll(new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putInt(ARGUMENT_REPEAT_MODE, repeatMode);
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_REPEAT_MODE_CHANGED, bundle);
+ }
+ });
+ }
+
+ void notifyShuffleModeChanged(final int shuffleMode) {
+ notifyAll(new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putInt(ARGUMENT_SHUFFLE_MODE, shuffleMode);
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_SHUFFLE_MODE_CHANGED, bundle);
+ }
+ });
+ }
+
+ private List<ControllerInfo> getControllers() {
+ ArrayList<ControllerInfo> controllers = new ArrayList<>();
+ synchronized (mLock) {
+ for (int i = 0; i < mControllers.size(); i++) {
+ controllers.add(mControllers.valueAt(i));
+ }
+ }
+ return controllers;
+ }
+
+ private void notifyAll(@NonNull Session2Runnable runnable) {
+ List<ControllerInfo> controllers = getControllers();
+ for (int i = 0; i < controllers.size(); i++) {
+ notifyInternal(controllers.get(i), runnable);
+ }
+ }
+
+ private void notifyAll(int commandCode, @NonNull Session2Runnable runnable) {
+ List<ControllerInfo> controllers = getControllers();
+ for (int i = 0; i < controllers.size(); i++) {
+ ControllerInfo controller = controllers.get(i);
+ if (isAllowedCommand(controller, commandCode)) {
+ notifyInternal(controller, runnable);
+ }
+ }
+ }
+
+ // TODO: Add a way to check permission from here.
+ private void notifyInternal(@NonNull ControllerInfo controller,
+ @NonNull Session2Runnable runnable) {
+ if (controller == null || controller.getControllerBinder() == null) {
+ return;
+ }
+ try {
+ runnable.run(controller);
+ } catch (DeadObjectException e) {
+ if (DEBUG) {
+ Log.d(TAG, controller.toString() + " is gone", e);
+ }
+ onControllerClosed(controller.getControllerBinder());
+ } catch (RemoteException e) {
+ // Currently it's TransactionTooLargeException or DeadSystemException.
+ // We'd better to leave log for those cases because
+ // - TransactionTooLargeException means that we may need to fix our code.
+ // (e.g. add pagination or special way to deliver Bitmap)
+ // - DeadSystemException means that errors around it can be ignored.
+ Log.w(TAG, "Exception in " + controller.toString(), e);
+ }
}
private boolean isAllowedCommand(ControllerInfo controller, SessionCommand2 command) {
@@ -442,17 +742,12 @@
private void onCommand2(@NonNull IBinder caller, final int commandCode,
@NonNull final Session2Runnable runnable) {
- onCommand2Internal(caller, null, commandCode, runnable);
+ // TODO: Prevent instantiation of SessionCommand2
+ onCommand2(caller, new SessionCommand2(commandCode), runnable);
}
private void onCommand2(@NonNull IBinder caller, @NonNull final SessionCommand2 sessionCommand,
@NonNull final Session2Runnable runnable) {
- onCommand2Internal(caller, sessionCommand, COMMAND_CODE_CUSTOM, runnable);
- }
-
- private void onCommand2Internal(@NonNull IBinder caller,
- @Nullable final SessionCommand2 sessionCommand, final int commandCode,
- @NonNull final Session2Runnable runnable) {
final ControllerInfo controller;
synchronized (mLock) {
controller = mControllers.get(caller);
@@ -463,25 +758,18 @@
mSession.getCallbackExecutor().execute(new Runnable() {
@Override
public void run() {
- SessionCommand2 command;
- if (sessionCommand != null) {
- if (!isAllowedCommand(controller, sessionCommand)) {
- return;
- }
- command = sCommandsForOnCommandRequest.get(sessionCommand.getCommandCode());
- } else {
- if (!isAllowedCommand(controller, commandCode)) {
- return;
- }
- command = sCommandsForOnCommandRequest.get(commandCode);
+ if (!isAllowedCommand(controller, sessionCommand)) {
+ return;
}
+ int commandCode = sessionCommand.getCommandCode();
+ SessionCommand2 command = sCommandsForOnCommandRequest.get(commandCode);
if (command != null) {
boolean accepted = mSession.getCallback().onCommandRequest(
mSession.getInstance(), controller, command);
if (!accepted) {
// Don't run rejected command.
if (DEBUG) {
- Log.d(TAG, "Command (" + command + ") from "
+ Log.d(TAG, "Command (code=" + commandCode + ") from "
+ controller + " was rejected by " + mSession);
}
return;
@@ -501,22 +789,35 @@
});
}
- void removeControllerInfo(ControllerInfo controller) {
+ private void onControllerClosed(IMediaControllerCallback iController) {
+ ControllerInfo controller;
synchronized (mLock) {
- controller = mControllers.remove(controller.getId());
+ controller = mControllers.remove(iController.asBinder());
if (DEBUG) {
Log.d(TAG, "releasing " + controller);
}
}
+ if (controller == null) {
+ return;
+ }
+ final ControllerInfo removedController = controller;
+ mSession.getCallbackExecutor().execute(new Runnable() {
+ @Override
+ public void run() {
+ mSession.getCallback().onDisconnected(mSession.getInstance(), removedController);
+ }
+ });
}
private ControllerInfo createControllerInfo(Bundle extras) {
IMediaControllerCallback callback = IMediaControllerCallback.Stub.asInterface(
- BundleCompat.getBinder(extras, ARGUMENT_ICONTROLLER_CALLBACK));
+ extras.getBinder(ARGUMENT_ICONTROLLER_CALLBACK));
String packageName = extras.getString(ARGUMENT_PACKAGE_NAME);
int uid = extras.getInt(ARGUMENT_UID);
int pid = extras.getInt(ARGUMENT_PID);
- return new ControllerInfo(packageName, pid, uid, new Controller2Cb(callback));
+ // TODO: sanity check for packageName, uid, and pid.
+
+ return new ControllerInfo(mContext, uid, pid, packageName, callback);
}
private void connect(Bundle extras, final ResultReceiver cb) {
@@ -625,173 +926,4 @@
private interface Session2Runnable {
void run(ControllerInfo controller) throws RemoteException;
}
-
- final class Controller2Cb extends ControllerCb {
- private final IMediaControllerCallback mIControllerCallback;
-
- Controller2Cb(@NonNull IMediaControllerCallback callback) {
- mIControllerCallback = callback;
- }
-
- @Override
- @NonNull IBinder getId() {
- return mIControllerCallback.asBinder();
- }
-
- @Override
- void onCustomLayoutChanged(List<CommandButton> layout) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putParcelableArray(ARGUMENT_COMMAND_BUTTONS,
- MediaUtils2.toCommandButtonParcelableArray(layout));
- mIControllerCallback.onEvent(SESSION_EVENT_SET_CUSTOM_LAYOUT, bundle);
- }
-
- @Override
- void onPlaybackInfoChanged(PlaybackInfo info) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_PLAYBACK_INFO, info.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED, bundle);
-
- }
-
- @Override
- void onAllowedCommandsChanged(SessionCommandGroup2 commands) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_ALLOWED_COMMANDS, commands.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED, bundle);
- }
-
- @Override
- void onCustomCommand(SessionCommand2 command, Bundle args, ResultReceiver receiver)
- throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_CUSTOM_COMMAND, command.toBundle());
- bundle.putBundle(ARGUMENT_ARGUMENTS, args);
- bundle.putParcelable(ARGUMENT_RESULT_RECEIVER, receiver);
- mIControllerCallback.onEvent(SESSION_EVENT_SEND_CUSTOM_COMMAND, bundle);
- }
-
- @Override
- void onPlayerStateChanged(int playerState)
- throws RemoteException {
- // Note: current position should be also sent to the controller here for controller
- // to calculate the position more correctly.
- Bundle bundle = new Bundle();
- bundle.putInt(ARGUMENT_PLAYER_STATE, playerState);
- bundle.putParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT, mSession.getPlaybackStateCompat());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYER_STATE_CHANGED, bundle);
- }
-
- @Override
- void onPlaybackSpeedChanged(float speed) throws RemoteException {
- // Note: current position should be also sent to the controller here for controller
- // to calculate the position more correctly.
- Bundle bundle = new Bundle();
- bundle.putParcelable(
- ARGUMENT_PLAYBACK_STATE_COMPAT, mSession.getPlaybackStateCompat());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYBACK_SPEED_CHANGED, bundle);
- }
-
- @Override
- void onBufferingStateChanged(MediaItem2 item, int state) throws RemoteException {
- // Note: buffered position should be also sent to the controller here. It's to
- // follow the behavior of MediaPlayerInterface.PlayerEventCallback.
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
- bundle.putInt(ARGUMENT_BUFFERING_STATE, state);
- bundle.putParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT,
- mSession.getPlaybackStateCompat());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_BUFFERING_STATE_CHANGED, bundle);
-
- }
-
- @Override
- void onSeekCompleted(long position) throws RemoteException {
- // Note: current position should be also sent to the controller here because the
- // position here may refer to the parameter of the previous seek() API calls.
- Bundle bundle = new Bundle();
- bundle.putLong(ARGUMENT_SEEK_POSITION, position);
- bundle.putParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT,
- mSession.getPlaybackStateCompat());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_SEEK_COMPLETED, bundle);
- }
-
- @Override
- void onError(int errorCode, Bundle extras) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putInt(ARGUMENT_ERROR_CODE, errorCode);
- bundle.putBundle(ARGUMENT_EXTRAS, extras);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_ERROR, bundle);
- }
-
- @Override
- void onCurrentMediaItemChanged(MediaItem2 item) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_MEDIA_ITEM, (item == null) ? null : item.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_CURRENT_MEDIA_ITEM_CHANGED, bundle);
- }
-
- @Override
- void onPlaylistChanged(List<MediaItem2> playlist, MediaMetadata2 metadata)
- throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putParcelableArray(ARGUMENT_PLAYLIST,
- MediaUtils2.toMediaItem2ParcelableArray(playlist));
- bundle.putBundle(ARGUMENT_PLAYLIST_METADATA,
- metadata == null ? null : metadata.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYLIST_CHANGED, bundle);
- }
-
- @Override
- void onPlaylistMetadataChanged(MediaMetadata2 metadata) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_PLAYLIST_METADATA,
- metadata == null ? null : metadata.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYLIST_METADATA_CHANGED, bundle);
- }
-
- @Override
- void onShuffleModeChanged(int shuffleMode) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putInt(ARGUMENT_SHUFFLE_MODE, shuffleMode);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_SHUFFLE_MODE_CHANGED, bundle);
- }
-
- @Override
- void onRepeatModeChanged(int repeatMode) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putInt(ARGUMENT_REPEAT_MODE, repeatMode);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_REPEAT_MODE_CHANGED, bundle);
- }
-
- @Override
- void onRoutesInfoChanged(List<Bundle> routes) throws RemoteException {
- Bundle bundle = null;
- if (routes != null) {
- bundle = new Bundle();
- bundle.putParcelableArray(ARGUMENT_ROUTE_BUNDLE, routes.toArray(new Bundle[0]));
- }
- mIControllerCallback.onEvent(SESSION_EVENT_ON_ROUTES_INFO_CHANGED, bundle);
- }
-
- @Override
- void onChildrenChanged(String parentId, int itemCount, Bundle extras)
- throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putString(ARGUMENT_MEDIA_ID, parentId);
- bundle.putInt(ARGUMENT_ITEM_COUNT, itemCount);
- bundle.putBundle(ARGUMENT_EXTRAS, extras);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_CHILDREN_CHANGED, bundle);
- }
-
- @Override
- void onSearchResultChanged(String query, int itemCount, Bundle extras)
- throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putString(ARGUMENT_QUERY, query);
- bundle.putInt(ARGUMENT_ITEM_COUNT, itemCount);
- bundle.putBundle(ARGUMENT_EXTRAS, extras);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_SEARCH_RESULT_CHANGED, bundle);
- }
- }
}
diff --git a/media/src/main/java/androidx/media/MediaSessionLegacyStub.java b/media/src/main/java/androidx/media/MediaSessionLegacyStub.java
deleted file mode 100644
index 2e0f945..0000000
--- a/media/src/main/java/androidx/media/MediaSessionLegacyStub.java
+++ /dev/null
@@ -1,583 +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.media;
-
-import static androidx.media.MediaConstants2.ARGUMENT_ALLOWED_COMMANDS;
-import static androidx.media.MediaConstants2.ARGUMENT_ARGUMENTS;
-import static androidx.media.MediaConstants2.ARGUMENT_BUFFERING_STATE;
-import static androidx.media.MediaConstants2.ARGUMENT_COMMAND_BUTTONS;
-import static androidx.media.MediaConstants2.ARGUMENT_CUSTOM_COMMAND;
-import static androidx.media.MediaConstants2.ARGUMENT_ERROR_CODE;
-import static androidx.media.MediaConstants2.ARGUMENT_EXTRAS;
-import static androidx.media.MediaConstants2.ARGUMENT_ICONTROLLER_CALLBACK;
-import static androidx.media.MediaConstants2.ARGUMENT_ITEM_COUNT;
-import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ID;
-import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ITEM;
-import static androidx.media.MediaConstants2.ARGUMENT_PACKAGE_NAME;
-import static androidx.media.MediaConstants2.ARGUMENT_PID;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_INFO;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_STATE_COMPAT;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYER_STATE;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST;
-import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST_METADATA;
-import static androidx.media.MediaConstants2.ARGUMENT_QUERY;
-import static androidx.media.MediaConstants2.ARGUMENT_REPEAT_MODE;
-import static androidx.media.MediaConstants2.ARGUMENT_RESULT_RECEIVER;
-import static androidx.media.MediaConstants2.ARGUMENT_ROUTE_BUNDLE;
-import static androidx.media.MediaConstants2.ARGUMENT_SEEK_POSITION;
-import static androidx.media.MediaConstants2.ARGUMENT_SHUFFLE_MODE;
-import static androidx.media.MediaConstants2.ARGUMENT_UID;
-import static androidx.media.MediaConstants2.CONNECT_RESULT_CONNECTED;
-import static androidx.media.MediaConstants2.CONNECT_RESULT_DISCONNECTED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_BUFFERING_STATE_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_CHILDREN_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;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYBACK_SPEED_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYER_STATE_CHANGED;
-import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYLIST_CHANGED;
-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_SEARCH_RESULT_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;
-import static androidx.media.SessionCommand2.COMMAND_CODE_CUSTOM;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_GET_CURRENT_MEDIA_ITEM;
-import static androidx.media.SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.support.v4.media.session.IMediaControllerCallback;
-import android.support.v4.media.session.MediaSessionCompat;
-import android.util.Log;
-import android.util.SparseArray;
-
-import androidx.annotation.GuardedBy;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.collection.ArrayMap;
-import androidx.core.app.BundleCompat;
-import androidx.media.MediaController2.PlaybackInfo;
-import androidx.media.MediaSession2.CommandButton;
-import androidx.media.MediaSession2.ControllerCb;
-import androidx.media.MediaSession2.ControllerInfo;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-@TargetApi(Build.VERSION_CODES.KITKAT)
-class MediaSessionLegacyStub extends MediaSessionCompat.Callback {
-
- private static final String TAG = "MS2StubImplBase";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private static final SparseArray<SessionCommand2> sCommandsForOnCommandRequest =
- new SparseArray<>();
-
- static {
- SessionCommandGroup2 group = new SessionCommandGroup2();
- group.addAllPlaybackCommands();
- group.addAllPlaylistCommands();
- group.addAllVolumeCommands();
- Set<SessionCommand2> commands = group.getCommands();
- for (SessionCommand2 command : commands) {
- sCommandsForOnCommandRequest.append(command.getCommandCode(), command);
- }
- }
-
- private final Object mLock = new Object();
-
- final MediaSession2.SupportLibraryImpl mSession;
- final Context mContext;
-
- @GuardedBy("mLock")
- private final ArrayMap<IBinder, ControllerInfo> mControllers = new ArrayMap<>();
- @GuardedBy("mLock")
- private final Set<IBinder> mConnectingControllers = new HashSet<>();
- @GuardedBy("mLock")
- private final ArrayMap<ControllerInfo, SessionCommandGroup2> mAllowedCommandGroupMap =
- new ArrayMap<>();
-
- MediaSessionLegacyStub(MediaSession2.SupportLibraryImpl session) {
- mSession = session;
- mContext = mSession.getContext();
- }
-
- @Override
- public void onPrepare() {
- mSession.getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- if (mSession.isClosed()) {
- return;
- }
- mSession.prepare();
- }
- });
- }
-
- @Override
- public void onPlay() {
- mSession.getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- if (mSession.isClosed()) {
- return;
- }
- mSession.play();
- }
- });
- }
-
- @Override
- public void onPause() {
- mSession.getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- if (mSession.isClosed()) {
- return;
- }
- mSession.pause();
- }
- });
- }
-
- @Override
- public void onStop() {
- mSession.getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- if (mSession.isClosed()) {
- return;
- }
- mSession.reset();
- }
- });
- }
-
- @Override
- public void onSeekTo(final long pos) {
- mSession.getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- if (mSession.isClosed()) {
- return;
- }
- mSession.seekTo(pos);
- }
- });
- }
-
- List<ControllerInfo> getConnectedControllers() {
- ArrayList<ControllerInfo> controllers = new ArrayList<>();
- synchronized (mLock) {
- for (int i = 0; i < mControllers.size(); i++) {
- controllers.add(mControllers.valueAt(i));
- }
- }
- return controllers;
- }
-
- void setAllowedCommands(ControllerInfo controller, final SessionCommandGroup2 commands) {
- synchronized (mLock) {
- mAllowedCommandGroupMap.put(controller, commands);
- }
- }
-
- private boolean isAllowedCommand(ControllerInfo controller, SessionCommand2 command) {
- SessionCommandGroup2 allowedCommands;
- synchronized (mLock) {
- allowedCommands = mAllowedCommandGroupMap.get(controller);
- }
- return allowedCommands != null && allowedCommands.hasCommand(command);
- }
-
- private boolean isAllowedCommand(ControllerInfo controller, int commandCode) {
- SessionCommandGroup2 allowedCommands;
- synchronized (mLock) {
- allowedCommands = mAllowedCommandGroupMap.get(controller);
- }
- return allowedCommands != null && allowedCommands.hasCommand(commandCode);
- }
-
- private void onCommand2(@NonNull IBinder caller, final int commandCode,
- @NonNull final Session2Runnable runnable) {
- onCommand2Internal(caller, null, commandCode, runnable);
- }
-
- private void onCommand2(@NonNull IBinder caller, @NonNull final SessionCommand2 sessionCommand,
- @NonNull final Session2Runnable runnable) {
- onCommand2Internal(caller, sessionCommand, COMMAND_CODE_CUSTOM, runnable);
- }
-
- private void onCommand2Internal(@NonNull IBinder caller,
- @Nullable final SessionCommand2 sessionCommand, final int commandCode,
- @NonNull final Session2Runnable runnable) {
- final ControllerInfo controller;
- synchronized (mLock) {
- controller = mControllers.get(caller);
- }
- if (mSession == null || controller == null) {
- return;
- }
- mSession.getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- SessionCommand2 command;
- if (sessionCommand != null) {
- if (!isAllowedCommand(controller, sessionCommand)) {
- return;
- }
- command = sCommandsForOnCommandRequest.get(sessionCommand.getCommandCode());
- } else {
- if (!isAllowedCommand(controller, commandCode)) {
- return;
- }
- command = sCommandsForOnCommandRequest.get(commandCode);
- }
- if (command != null) {
- boolean accepted = mSession.getCallback().onCommandRequest(
- mSession.getInstance(), controller, command);
- if (!accepted) {
- // Don't run rejected command.
- if (DEBUG) {
- Log.d(TAG, "Command (" + command + ") from "
- + controller + " was rejected by " + mSession);
- }
- return;
- }
- }
- try {
- runnable.run(controller);
- } catch (RemoteException e) {
- // Currently it's TransactionTooLargeException or DeadSystemException.
- // We'd better to leave log for those cases because
- // - TransactionTooLargeException means that we may need to fix our code.
- // (e.g. add pagination or special way to deliver Bitmap)
- // - DeadSystemException means that errors around it can be ignored.
- Log.w(TAG, "Exception in " + controller.toString(), e);
- }
- }
- });
- }
-
- void removeControllerInfo(ControllerInfo controller) {
- synchronized (mLock) {
- controller = mControllers.remove(controller.getId());
- if (DEBUG) {
- Log.d(TAG, "releasing " + controller);
- }
- }
- }
-
- private ControllerInfo createControllerInfo(Bundle extras) {
- IMediaControllerCallback callback = IMediaControllerCallback.Stub.asInterface(
- BundleCompat.getBinder(extras, ARGUMENT_ICONTROLLER_CALLBACK));
- String packageName = extras.getString(ARGUMENT_PACKAGE_NAME);
- int uid = extras.getInt(ARGUMENT_UID);
- int pid = extras.getInt(ARGUMENT_PID);
- return new ControllerInfo(packageName, pid, uid, new ControllerLegacyCb(callback));
- }
-
- private void connect(Bundle extras, final ResultReceiver cb) {
- final ControllerInfo controllerInfo = createControllerInfo(extras);
- mSession.getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- if (mSession.isClosed()) {
- return;
- }
- synchronized (mLock) {
- // Keep connecting controllers.
- // This helps sessions to call APIs in the onConnect()
- // (e.g. setCustomLayout()) instead of pending them.
- mConnectingControllers.add(controllerInfo.getId());
- }
- SessionCommandGroup2 allowedCommands = mSession.getCallback().onConnect(
- mSession.getInstance(), controllerInfo);
- // Don't reject connection for the request from trusted app.
- // Otherwise server will fail to retrieve session's information to dispatch
- // media keys to.
- boolean accept = allowedCommands != null || controllerInfo.isTrusted();
- if (accept) {
- if (DEBUG) {
- Log.d(TAG, "Accepting connection, controllerInfo=" + controllerInfo
- + " allowedCommands=" + allowedCommands);
- }
- if (allowedCommands == null) {
- // For trusted apps, send non-null allowed commands to keep
- // connection.
- allowedCommands = new SessionCommandGroup2();
- }
- synchronized (mLock) {
- mConnectingControllers.remove(controllerInfo.getId());
- mControllers.put(controllerInfo.getId(), controllerInfo);
- mAllowedCommandGroupMap.put(controllerInfo, allowedCommands);
- }
- // If connection is accepted, notify the current state to the
- // controller. It's needed because we cannot call synchronous calls
- // between session/controller.
- // Note: We're doing this after the onConnectionChanged(), but there's
- // no guarantee that events here are notified after the
- // onConnected() because IMediaController2 is oneway (i.e. async
- // call) and Stub will use thread poll for incoming calls.
- final Bundle resultData = new Bundle();
- resultData.putBundle(ARGUMENT_ALLOWED_COMMANDS,
- allowedCommands.toBundle());
- resultData.putInt(ARGUMENT_PLAYER_STATE, mSession.getPlayerState());
- resultData.putInt(ARGUMENT_BUFFERING_STATE, mSession.getBufferingState());
- resultData.putParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT,
- mSession.getPlaybackStateCompat());
- resultData.putInt(ARGUMENT_REPEAT_MODE, mSession.getRepeatMode());
- resultData.putInt(ARGUMENT_SHUFFLE_MODE, mSession.getShuffleMode());
- final List<MediaItem2> playlist = allowedCommands.hasCommand(
- COMMAND_CODE_PLAYLIST_GET_LIST) ? mSession.getPlaylist() : null;
- if (playlist != null) {
- resultData.putParcelableArray(ARGUMENT_PLAYLIST,
- MediaUtils2.toMediaItem2ParcelableArray(playlist));
- }
- final MediaItem2 currentMediaItem =
- allowedCommands.hasCommand(COMMAND_CODE_PLAYLIST_GET_CURRENT_MEDIA_ITEM)
- ? mSession.getCurrentMediaItem() : null;
- if (currentMediaItem != null) {
- resultData.putBundle(ARGUMENT_MEDIA_ITEM, currentMediaItem.toBundle());
- }
- resultData.putBundle(ARGUMENT_PLAYBACK_INFO,
- mSession.getPlaybackInfo().toBundle());
- final MediaMetadata2 playlistMetadata = mSession.getPlaylistMetadata();
- if (playlistMetadata != null) {
- resultData.putBundle(ARGUMENT_PLAYLIST_METADATA,
- playlistMetadata.toBundle());
- }
- // Double check if session is still there, because close() can be
- // called in another thread.
- if (mSession.isClosed()) {
- return;
- }
- cb.send(CONNECT_RESULT_CONNECTED, resultData);
- } else {
- synchronized (mLock) {
- mConnectingControllers.remove(controllerInfo.getId());
- }
- if (DEBUG) {
- Log.d(TAG, "Rejecting connection, controllerInfo=" + controllerInfo);
- }
- cb.send(CONNECT_RESULT_DISCONNECTED, null);
- }
- }
- });
- }
-
- private void disconnect(Bundle extras) {
- final ControllerInfo controllerInfo = createControllerInfo(extras);
- mSession.getCallbackExecutor().execute(new Runnable() {
- @Override
- public void run() {
- if (mSession.isClosed()) {
- return;
- }
- mSession.getCallback().onDisconnected(mSession.getInstance(), controllerInfo);
- }
- });
- }
-
- @FunctionalInterface
- private interface Session2Runnable {
- void run(ControllerInfo controller) throws RemoteException;
- }
-
- final class ControllerLegacyCb extends ControllerCb {
- private final IMediaControllerCallback mIControllerCallback;
-
- ControllerLegacyCb(@NonNull IMediaControllerCallback callback) {
- mIControllerCallback = callback;
- }
-
- @Override
- @NonNull IBinder getId() {
- return mIControllerCallback.asBinder();
- }
-
- @Override
- void onCustomLayoutChanged(List<CommandButton> layout) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putParcelableArray(ARGUMENT_COMMAND_BUTTONS,
- MediaUtils2.toCommandButtonParcelableArray(layout));
- mIControllerCallback.onEvent(SESSION_EVENT_SET_CUSTOM_LAYOUT, bundle);
- }
-
- @Override
- void onPlaybackInfoChanged(PlaybackInfo info) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_PLAYBACK_INFO, info.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED, bundle);
-
- }
-
- @Override
- void onAllowedCommandsChanged(SessionCommandGroup2 commands) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_ALLOWED_COMMANDS, commands.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED, bundle);
- }
-
- @Override
- void onCustomCommand(SessionCommand2 command, Bundle args, ResultReceiver receiver)
- throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_CUSTOM_COMMAND, command.toBundle());
- bundle.putBundle(ARGUMENT_ARGUMENTS, args);
- bundle.putParcelable(ARGUMENT_RESULT_RECEIVER, receiver);
- mIControllerCallback.onEvent(SESSION_EVENT_SEND_CUSTOM_COMMAND, bundle);
- }
-
- @Override
- void onPlayerStateChanged(int playerState)
- throws RemoteException {
- // Note: current position should be also sent to the controller here for controller
- // to calculate the position more correctly.
- Bundle bundle = new Bundle();
- bundle.putInt(ARGUMENT_PLAYER_STATE, playerState);
- bundle.putParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT, mSession.getPlaybackStateCompat());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYER_STATE_CHANGED, bundle);
- }
-
- @Override
- void onPlaybackSpeedChanged(float speed) throws RemoteException {
- // Note: current position should be also sent to the controller here for controller
- // to calculate the position more correctly.
- Bundle bundle = new Bundle();
- bundle.putParcelable(
- ARGUMENT_PLAYBACK_STATE_COMPAT, mSession.getPlaybackStateCompat());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYBACK_SPEED_CHANGED, bundle);
- }
-
- @Override
- void onBufferingStateChanged(MediaItem2 item, int state) throws RemoteException {
- // Note: buffered position should be also sent to the controller here. It's to
- // follow the behavior of MediaPlayerInterface.PlayerEventCallback.
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_MEDIA_ITEM, item.toBundle());
- bundle.putInt(ARGUMENT_BUFFERING_STATE, state);
- bundle.putParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT,
- mSession.getPlaybackStateCompat());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_BUFFERING_STATE_CHANGED, bundle);
-
- }
-
- @Override
- void onSeekCompleted(long position) throws RemoteException {
- // Note: current position should be also sent to the controller here because the
- // position here may refer to the parameter of the previous seek() API calls.
- Bundle bundle = new Bundle();
- bundle.putLong(ARGUMENT_SEEK_POSITION, position);
- bundle.putParcelable(ARGUMENT_PLAYBACK_STATE_COMPAT,
- mSession.getPlaybackStateCompat());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_SEEK_COMPLETED, bundle);
- }
-
- @Override
- void onError(int errorCode, Bundle extras) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putInt(ARGUMENT_ERROR_CODE, errorCode);
- bundle.putBundle(ARGUMENT_EXTRAS, extras);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_ERROR, bundle);
- }
-
- @Override
- void onCurrentMediaItemChanged(MediaItem2 item) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_MEDIA_ITEM, (item == null) ? null : item.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_CURRENT_MEDIA_ITEM_CHANGED, bundle);
- }
-
- @Override
- void onPlaylistChanged(List<MediaItem2> playlist, MediaMetadata2 metadata)
- throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putParcelableArray(ARGUMENT_PLAYLIST,
- MediaUtils2.toMediaItem2ParcelableArray(playlist));
- bundle.putBundle(ARGUMENT_PLAYLIST_METADATA,
- metadata == null ? null : metadata.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYLIST_CHANGED, bundle);
- }
-
- @Override
- void onPlaylistMetadataChanged(MediaMetadata2 metadata) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putBundle(ARGUMENT_PLAYLIST_METADATA,
- metadata == null ? null : metadata.toBundle());
- mIControllerCallback.onEvent(SESSION_EVENT_ON_PLAYLIST_METADATA_CHANGED, bundle);
- }
-
- @Override
- void onShuffleModeChanged(int shuffleMode) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putInt(ARGUMENT_SHUFFLE_MODE, shuffleMode);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_SHUFFLE_MODE_CHANGED, bundle);
- }
-
- @Override
- void onRepeatModeChanged(int repeatMode) throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putInt(ARGUMENT_REPEAT_MODE, repeatMode);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_REPEAT_MODE_CHANGED, bundle);
- }
-
- @Override
- void onRoutesInfoChanged(List<Bundle> routes) throws RemoteException {
- Bundle bundle = null;
- if (routes != null) {
- bundle = new Bundle();
- bundle.putParcelableArray(ARGUMENT_ROUTE_BUNDLE, routes.toArray(new Bundle[0]));
- }
- mIControllerCallback.onEvent(SESSION_EVENT_ON_ROUTES_INFO_CHANGED, bundle);
- }
-
- @Override
- void onChildrenChanged(String parentId, int itemCount, Bundle extras)
- throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putString(ARGUMENT_MEDIA_ID, parentId);
- bundle.putInt(ARGUMENT_ITEM_COUNT, itemCount);
- bundle.putBundle(ARGUMENT_EXTRAS, extras);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_CHILDREN_CHANGED, bundle);
- }
-
- @Override
- void onSearchResultChanged(String query, int itemCount, Bundle extras)
- throws RemoteException {
- Bundle bundle = new Bundle();
- bundle.putString(ARGUMENT_QUERY, query);
- bundle.putInt(ARGUMENT_ITEM_COUNT, itemCount);
- bundle.putBundle(ARGUMENT_EXTRAS, extras);
- mIControllerCallback.onEvent(SESSION_EVENT_ON_SEARCH_RESULT_CHANGED, bundle);
- }
- }
-}
diff --git a/media/src/main/java/androidx/media/MediaSessionManager.java b/media/src/main/java/androidx/media/MediaSessionManager.java
deleted file mode 100644
index 8c11228..0000000
--- a/media/src/main/java/androidx/media/MediaSessionManager.java
+++ /dev/null
@@ -1,164 +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.media;
-
-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.Nullable;
-import androidx.core.os.BuildCompat;
-
-/**
- * Provides support for interacting with {@link MediaSessionCompat media sessions} that
- * applications have published to express their ongoing media playback state.
- *
- * @see MediaSessionCompat
- * @see MediaControllerCompat
- */
-public final class MediaSessionManager {
- static final String TAG = "MediaSessionManager";
- static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private static final Object sLock = new Object();
- private static volatile 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 @NonNull MediaSessionManager getSessionManager(@NonNull Context context) {
- MediaSessionManager manager = sSessionManager;
- if (manager == null) {
- synchronized (sLock) {
- manager = sSessionManager;
- if (manager == null) {
- sSessionManager = new MediaSessionManager(context.getApplicationContext());
- manager = sSessionManager;
- }
- }
- }
- return manager;
- }
-
- 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(@NonNull 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 @NonNull 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(@Nullable 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
deleted file mode 100644
index 4fefe70..0000000
--- a/media/src/main/java/androidx/media/MediaSessionManagerImplApi21.java
+++ /dev/null
@@ -1,48 +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.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
deleted file mode 100644
index 48344fa..0000000
--- a/media/src/main/java/androidx/media/MediaSessionManagerImplApi28.java
+++ /dev/null
@@ -1,64 +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.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
deleted file mode 100644
index 3fc21f1..0000000
--- a/media/src/main/java/androidx/media/MediaSessionManagerImplBase.java
+++ /dev/null
@@ -1,163 +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.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 PERMISSION_MEDIA_CONTENT_CONTROL =
- "android.permission.MEDIA_CONTENT_CONTROL";
- 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 isPermissionGranted(userInfo, PERMISSION_STATUS_BAR_SERVICE)
- || isPermissionGranted(userInfo, PERMISSION_MEDIA_CONTENT_CONTROL)
- || userInfo.getUid() == Process.SYSTEM_UID
- || isEnabledNotificationListener(userInfo);
- }
-
- private boolean isPermissionGranted(MediaSessionManager.RemoteUserInfoImpl userInfo,
- String permission) {
- if (userInfo.getPid() < 0) {
- // This may happen for the MediaBrowserServiceCompat#onGetRoot().
- return mContext.getPackageManager().checkPermission(
- permission, userInfo.getPackageName()) == PackageManager.PERMISSION_GRANTED;
- }
- return mContext.checkPermission(permission, userInfo.getPid(), userInfo.getUid())
- == PackageManager.PERMISSION_GRANTED;
- }
-
- /**
- * 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 03bb086..7bad65c 100644
--- a/media/src/main/java/androidx/media/MediaSessionService2.java
+++ b/media/src/main/java/androidx/media/MediaSessionService2.java
@@ -16,6 +16,8 @@
package androidx.media;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
@@ -29,6 +31,7 @@
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
import androidx.media.MediaBrowserServiceCompat.BrowserRoot;
import androidx.media.MediaSession2.ControllerInfo;
import androidx.media.SessionToken2.TokenType;
@@ -36,6 +39,7 @@
import java.util.List;
/**
+ * @hide
* Base class for media session services, which is the service version of the {@link MediaSession2}.
* <p>
* It's highly recommended for an app to use this instead of {@link MediaSession2} if it wants
@@ -93,6 +97,7 @@
* <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.
@@ -101,9 +106,6 @@
* 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>
@@ -111,7 +113,10 @@
* the session service accepted the connection request through
* {@link MediaSession2.SessionCallback#onConnect(MediaSession2, ControllerInfo)}.
*/
+@RestrictTo(LIBRARY_GROUP)
public abstract class MediaSessionService2 extends Service {
+ //private final MediaSessionService2Provider mProvider;
+
/**
* This is the interface name that a service implementing a session service should say that it
* support -- that is, this is the action it uses for its intent filter.
@@ -311,6 +316,8 @@
// 2. MediaSessionService2 is defined as the simplified version of the library
// service with no browsing feature, so shouldn't allow MediaBrowserServiceCompat
// specific operations.
+ // TODO: Revisit here API not to return stub root here. The fake media ID here may be
+ // used by the browser service for real.
return sDefaultBrowserRoot;
}
diff --git a/media/src/main/java/androidx/media/MediaUtils2.java b/media/src/main/java/androidx/media/MediaUtils2.java
index 6a011f2..657e24d 100644
--- a/media/src/main/java/androidx/media/MediaUtils2.java
+++ b/media/src/main/java/androidx/media/MediaUtils2.java
@@ -16,6 +16,8 @@
package androidx.media;
+import static androidx.media.AudioAttributesCompat.CONTENT_TYPE_UNKNOWN;
+import static androidx.media.AudioAttributesCompat.USAGE_UNKNOWN;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_DESCRIPTION;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_ICON;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_ICON_URI;
@@ -42,7 +44,9 @@
import java.util.List;
class MediaUtils2 {
- static final String TAG = "MediaUtils2";
+ static final String AUDIO_ATTRIBUTES_USAGE = "androidx.media.audio_attrs.USAGE";
+ static final String AUDIO_ATTRIBUTES_CONTENT_TYPE = "androidx.media.audio_attrs.CONTENT_TYPE";
+ static final String AUDIO_ATTRIBUTES_FLAGS = "androidx.media.audio_attrs.FLAGS";
private MediaUtils2() {
}
@@ -112,28 +116,6 @@
.build();
}
- static List<MediaItem> fromMediaItem2List(List<MediaItem2> items) {
- if (items == null) {
- return null;
- }
- List<MediaItem> result = new ArrayList<>();
- for (int i = 0; i < items.size(); i++) {
- result.add(createMediaItem(items.get(i)));
- }
- return result;
- }
-
- static List<MediaItem2> toMediaItem2List(List<MediaItem> items) {
- if (items == null) {
- return null;
- }
- List<MediaItem2> result = new ArrayList<>();
- for (int i = 0; i < items.size(); i++) {
- result.add(createMediaItem2(items.get(i)));
- }
- return result;
- }
-
/**
* Creates a {@link MediaMetadata2} from the {@link MediaDescriptionCompat}.
*
@@ -369,6 +351,28 @@
return layout;
}
+ static Bundle toAudioAttributesBundle(AudioAttributesCompat attrs) {
+ if (attrs == null) {
+ return null;
+ }
+ Bundle bundle = new Bundle();
+ bundle.putInt(AUDIO_ATTRIBUTES_USAGE, attrs.getUsage());
+ bundle.putInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, attrs.getContentType());
+ bundle.putInt(AUDIO_ATTRIBUTES_FLAGS, attrs.getFlags());
+ return bundle;
+ }
+
+ static AudioAttributesCompat fromAudioAttributesBundle(Bundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+ return new AudioAttributesCompat.Builder()
+ .setUsage(bundle.getInt(AUDIO_ATTRIBUTES_USAGE, USAGE_UNKNOWN))
+ .setContentType(bundle.getInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, CONTENT_TYPE_UNKNOWN))
+ .setFlags(bundle.getInt(AUDIO_ATTRIBUTES_FLAGS, 0))
+ .build();
+ }
+
static List<Bundle> toBundleList(Parcelable[] array) {
if (array == null) {
return null;
@@ -382,17 +386,17 @@
static int createPlaybackStateCompatState(int playerState, int bufferingState) {
switch (playerState) {
- case MediaPlayerInterface.PLAYER_STATE_PLAYING:
+ case MediaPlayerBase.PLAYER_STATE_PLAYING:
switch (bufferingState) {
- case MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_STARVED:
+ case MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_STARVED:
return PlaybackStateCompat.STATE_BUFFERING;
}
return PlaybackStateCompat.STATE_PLAYING;
- case MediaPlayerInterface.PLAYER_STATE_PAUSED:
+ case MediaPlayerBase.PLAYER_STATE_PAUSED:
return PlaybackStateCompat.STATE_PAUSED;
- case MediaPlayerInterface.PLAYER_STATE_IDLE:
+ case MediaPlayerBase.PLAYER_STATE_IDLE:
return PlaybackStateCompat.STATE_NONE;
- case MediaPlayerInterface.PLAYER_STATE_ERROR:
+ case MediaPlayerBase.PLAYER_STATE_ERROR:
return PlaybackStateCompat.STATE_ERROR;
}
// For unknown value
@@ -402,13 +406,13 @@
static int toPlayerState(int playbackStateCompatState) {
switch (playbackStateCompatState) {
case PlaybackStateCompat.STATE_ERROR:
- return MediaPlayerInterface.PLAYER_STATE_ERROR;
+ return MediaPlayerBase.PLAYER_STATE_ERROR;
case PlaybackStateCompat.STATE_NONE:
- return MediaPlayerInterface.PLAYER_STATE_IDLE;
+ return MediaPlayerBase.PLAYER_STATE_IDLE;
case PlaybackStateCompat.STATE_PAUSED:
case PlaybackStateCompat.STATE_STOPPED:
case PlaybackStateCompat.STATE_BUFFERING: // means paused for buffering.
- return MediaPlayerInterface.PLAYER_STATE_PAUSED;
+ return MediaPlayerBase.PLAYER_STATE_PAUSED;
case PlaybackStateCompat.STATE_FAST_FORWARDING:
case PlaybackStateCompat.STATE_PLAYING:
case PlaybackStateCompat.STATE_REWINDING:
@@ -416,16 +420,12 @@
case PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS:
case PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM:
case PlaybackStateCompat.STATE_CONNECTING: // Note: there's no perfect match for this.
- return MediaPlayerInterface.PLAYER_STATE_PLAYING;
+ return MediaPlayerBase.PLAYER_STATE_PLAYING;
}
- return MediaPlayerInterface.PLAYER_STATE_ERROR;
+ return MediaPlayerBase.PLAYER_STATE_ERROR;
}
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/SessionCommand2.java b/media/src/main/java/androidx/media/SessionCommand2.java
index 353688a..f017941 100644
--- a/media/src/main/java/androidx/media/SessionCommand2.java
+++ b/media/src/main/java/androidx/media/SessionCommand2.java
@@ -276,38 +276,52 @@
public static final int COMMAND_CODE_SESSION_SELECT_ROUTE = 38;
/**
+ * @hide
* Command code for {@link MediaBrowser2#getChildren(String, int, int, Bundle)}.
*/
+ @RestrictTo(LIBRARY_GROUP)
public static final int COMMAND_CODE_LIBRARY_GET_CHILDREN = 29;
/**
+ * @hide
* Command code for {@link MediaBrowser2#getItem(String)}.
*/
+ @RestrictTo(LIBRARY_GROUP)
public static final int COMMAND_CODE_LIBRARY_GET_ITEM = 30;
/**
+ * @hide
* Command code for {@link MediaBrowser2#getLibraryRoot(Bundle)}.
*/
+ @RestrictTo(LIBRARY_GROUP)
public static final int COMMAND_CODE_LIBRARY_GET_LIBRARY_ROOT = 31;
/**
+ * @hide
* Command code for {@link MediaBrowser2#getSearchResult(String, int, int, Bundle)}.
*/
+ @RestrictTo(LIBRARY_GROUP)
public static final int COMMAND_CODE_LIBRARY_GET_SEARCH_RESULT = 32;
/**
+ * @hide
* Command code for {@link MediaBrowser2#search(String, Bundle)}.
*/
+ @RestrictTo(LIBRARY_GROUP)
public static final int COMMAND_CODE_LIBRARY_SEARCH = 33;
/**
+ * @hide
* Command code for {@link MediaBrowser2#subscribe(String, Bundle)}.
*/
+ @RestrictTo(LIBRARY_GROUP)
public static final int COMMAND_CODE_LIBRARY_SUBSCRIBE = 34;
/**
+ * @hide
* Command code for {@link MediaBrowser2#unsubscribe(String)}.
*/
+ @RestrictTo(LIBRARY_GROUP)
public static final int COMMAND_CODE_LIBRARY_UNSUBSCRIBE = 35;
/**
diff --git a/media/src/main/java/androidx/media/SessionCommandGroup2.java b/media/src/main/java/androidx/media/SessionCommandGroup2.java
index db15bb3..691eb70 100644
--- a/media/src/main/java/androidx/media/SessionCommandGroup2.java
+++ b/media/src/main/java/androidx/media/SessionCommandGroup2.java
@@ -42,7 +42,7 @@
private static final String KEY_COMMANDS = "android.media.mediasession2.commandgroup.commands";
// Prefix for all command codes
private static final String PREFIX_COMMAND_CODE = "COMMAND_CODE_";
- // Prefix for command codes that will be sent directly to the MediaPlayerInterface
+ // Prefix for command codes that will be sent directly to the MediaPlayerBase
private static final String PREFIX_COMMAND_CODE_PLAYBACK = "COMMAND_CODE_PLAYBACK_";
// Prefix for command codes that will be sent directly to the MediaPlaylistAgent
private static final String PREFIX_COMMAND_CODE_PLAYLIST = "COMMAND_CODE_PLAYLIST_";
diff --git a/media/src/main/java/androidx/media/SessionPlaylistAgentImplBase.java b/media/src/main/java/androidx/media/SessionPlaylistAgentImplBase.java
index 2cdc9ab..431b188 100644
--- a/media/src/main/java/androidx/media/SessionPlaylistAgentImplBase.java
+++ b/media/src/main/java/androidx/media/SessionPlaylistAgentImplBase.java
@@ -18,13 +18,13 @@
import android.annotation.TargetApi;
import android.os.Build;
+import android.util.ArrayMap;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import androidx.collection.ArrayMap;
-import androidx.media.MediaPlayerInterface.PlayerEventCallback;
+import androidx.media.MediaPlayerBase.PlayerEventCallback;
import androidx.media.MediaSession2.OnDataSourceMissingHelper;
import java.util.ArrayList;
@@ -46,7 +46,7 @@
private final MyPlayerEventCallback mPlayerCallback;
@GuardedBy("mLock")
- private MediaPlayerInterface mPlayer;
+ private MediaPlayerBase mPlayer;
@GuardedBy("mLock")
private OnDataSourceMissingHelper mDsmHelper;
// TODO: Check if having the same item is okay (b/74090741)
@@ -68,7 +68,7 @@
// Called on session callback executor.
private class MyPlayerEventCallback extends PlayerEventCallback {
@Override
- public void onCurrentDataSourceChanged(@NonNull MediaPlayerInterface mpb,
+ public void onCurrentDataSourceChanged(@NonNull MediaPlayerBase mpb,
@Nullable DataSourceDesc dsd) {
synchronized (mLock) {
if (mPlayer != mpb) {
@@ -133,7 +133,7 @@
}
SessionPlaylistAgentImplBase(@NonNull MediaSession2ImplBase session,
- @NonNull MediaPlayerInterface player) {
+ @NonNull MediaPlayerBase player) {
super();
if (session == null) {
throw new IllegalArgumentException("sessionImpl shouldn't be null");
@@ -147,7 +147,7 @@
mPlayer.registerPlayerEventCallback(mSession.getCallbackExecutor(), mPlayerCallback);
}
- public void setPlayer(@NonNull MediaPlayerInterface player) {
+ public void setPlayer(@NonNull MediaPlayerBase player) {
if (player == null) {
throw new IllegalArgumentException("player shouldn't be null");
}
diff --git a/media/src/main/java/androidx/media/SessionToken2.java b/media/src/main/java/androidx/media/SessionToken2.java
index cae6c9b..eb42297 100644
--- a/media/src/main/java/androidx/media/SessionToken2.java
+++ b/media/src/main/java/androidx/media/SessionToken2.java
@@ -23,6 +23,7 @@
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;
@@ -37,8 +38,7 @@
import java.util.List;
/**
- * Represents an ongoing {@link MediaSession2} or a {@link MediaSessionService2}.
- * If it's representing a session service, it may not be ongoing.
+ * Represents an ongoing {@link MediaSession2}.
* <p>
* This may be passed to apps by the session owner to allow them to create a
* {@link MediaController2} to communicate with the session.
@@ -65,13 +65,15 @@
public static final int TYPE_SESSION = 0;
/**
- * Type for {@link MediaSessionService2}.
+ * @hide
*/
+ @RestrictTo(LIBRARY_GROUP)
public static final int TYPE_SESSION_SERVICE = 1;
/**
- * Type for {@link MediaLibraryService2}.
+ * @hide
*/
+ @RestrictTo(LIBRARY_GROUP)
public static final int TYPE_LIBRARY_SERVICE = 2;
//private final SessionToken2Provider mProvider;
@@ -95,12 +97,14 @@
private final ComponentName mComponentName;
/**
+ * @hide
* Constructor for the token. You can only create token for session service or library service
* to use by {@link MediaController2} or {@link MediaBrowser2}.
*
* @param context The context.
* @param serviceComponent The component name of the media browser service.
*/
+ @RestrictTo(LIBRARY_GROUP)
public SessionToken2(@NonNull Context context, @NonNull ComponentName serviceComponent) {
this(context, serviceComponent, UID_UNKNOWN);
}
@@ -238,8 +242,6 @@
/**
* @return type of the token
* @see #TYPE_SESSION
- * @see #TYPE_SESSION_SERVICE
- * @see #TYPE_LIBRARY_SERVICE
*/
public @TokenType int getType() {
return mType;
diff --git a/media/src/main/java/androidx/media/subtitle/Cea608CCParser.java b/media/src/main/java/androidx/media/subtitle/Cea608CCParser.java
deleted file mode 100644
index 9205fba..0000000
--- a/media/src/main/java/androidx/media/subtitle/Cea608CCParser.java
+++ /dev/null
@@ -1,987 +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.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
deleted file mode 100644
index 90ff516f..0000000
--- a/media/src/main/java/androidx/media/subtitle/ClosedCaptionRenderer.java
+++ /dev/null
@@ -1,402 +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.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
deleted file mode 100644
index a3d3e47..0000000
--- a/media/src/main/java/androidx/media/subtitle/ClosedCaptionWidget.java
+++ /dev/null
@@ -1,167 +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.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
deleted file mode 100644
index b6f0a14..0000000
--- a/media/src/main/java/androidx/media/subtitle/MediaTimeProvider.java
+++ /dev/null
@@ -1,100 +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.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
deleted file mode 100644
index b6dfc2b..0000000
--- a/media/src/main/java/androidx/media/subtitle/SubtitleController.java
+++ /dev/null
@@ -1,534 +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.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
deleted file mode 100644
index 30c1316..0000000
--- a/media/src/main/java/androidx/media/subtitle/SubtitleTrack.java
+++ /dev/null
@@ -1,715 +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.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
deleted file mode 100644
index be50378..0000000
--- a/media/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<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/client/src/androidTest/java/androidx/media/test/client/MediaController2Test_copied.java b/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MediaController2Test_copied.java
deleted file mode 100644
index a096160..0000000
--- a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MediaController2Test_copied.java
+++ /dev/null
@@ -1,1512 +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.media.test.client;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Process;
-import android.os.ResultReceiver;
-import android.support.mediacompat.testlib.util.PollingCheck;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import androidx.annotation.NonNull;
-import androidx.media.AudioAttributesCompat;
-import androidx.media.MediaController2;
-import androidx.media.MediaController2.ControllerCallback;
-import androidx.media.MediaController2.PlaybackInfo;
-import androidx.media.MediaItem2;
-import androidx.media.MediaMetadata2;
-import androidx.media.MediaPlayerInterface;
-import androidx.media.MediaPlaylistAgent;
-import androidx.media.MediaSession2;
-import androidx.media.MediaSession2.ControllerInfo;
-import androidx.media.MediaSession2.SessionCallback;
-import androidx.media.Rating2;
-import androidx.media.SessionCommand2;
-import androidx.media.SessionCommandGroup2;
-import androidx.media.VolumeProviderCompat;
-import androidx.media.test.client.TestUtils.SyncHandler;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Tests {@link MediaController2}.
- */
-// TODO(jaewan): Implement host-side test so controller and session can run in different processes.
-// TODO(jaewan): Fix flaky failure -- see MediaController2Impl.getController()
-// TODO(jaeawn): Revisit create/close session in the sHandler. It's no longer necessary.
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-@FlakyTest
-@Ignore
-public class MediaController2Test_copied extends MediaSession2TestBase {
- private static final String TAG = "MediaController2Test_copied";
-
- PendingIntent mIntent;
- MediaSession2 mSession;
- MediaController2 mController;
- MockPlayer mPlayer;
- MockPlaylistAgent mMockAgent;
- AudioManager mAudioManager;
-
- @Before
- @Override
- public void setUp() throws Exception {
- super.setUp();
- final Intent sessionActivity = new Intent(mContext, MockActivity.class);
- // Create this test specific MediaSession2 to use our own Handler.
- mIntent = PendingIntent.getActivity(mContext, 0, sessionActivity, 0);
-
- mPlayer = new MockPlayer(1);
- mMockAgent = new MockPlaylistAgent();
- mSession = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setPlaylistAgent(mMockAgent)
- .setSessionCallback(sHandlerExecutor, new SessionCallback() {
- @Override
- public SessionCommandGroup2 onConnect(MediaSession2 session,
- ControllerInfo controller) {
- if (Process.myUid() == controller.getUid()) {
- return super.onConnect(session, controller);
- }
- return null;
- }
-
- @Override
- public void onPlaylistMetadataChanged(MediaSession2 session,
- MediaPlaylistAgent playlistAgent,
- MediaMetadata2 metadata) {
- super.onPlaylistMetadataChanged(session, playlistAgent, metadata);
- }
- })
- .setSessionActivity(mIntent)
- .setId(TAG).build();
- mController = createController(mSession.getToken());
- mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
- TestServiceRegistry.getInstance().setHandler(sHandler);
- }
-
- @After
- @Override
- public void cleanUp() throws Exception {
- super.cleanUp();
- if (mSession != null) {
- mSession.close();
- }
- TestServiceRegistry.getInstance().cleanUp();
- }
-
- /**
- * Test if the {@link MediaSession2TestBase.TestControllerCallback} wraps the callback proxy
- * without missing any method.
- */
- @Test
- public void testTestControllerCallback() {
- prepareLooper();
- Method[] methods = TestControllerCallback.class.getMethods();
- assertNotNull(methods);
- for (int i = 0; i < methods.length; i++) {
- // For any methods in the controller callback, TestControllerCallback should have
- // overriden the method and call matching API in the callback proxy.
- assertNotEquals("TestControllerCallback should override " + methods[i]
- + " and call callback proxy",
- ControllerCallback.class, methods[i].getDeclaringClass());
- }
- }
-
- @Test
- public void testPlay() {
- prepareLooper();
- mController.play();
- try {
- assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail(e.getMessage());
- }
- assertTrue(mPlayer.mPlayCalled);
- }
-
- @Test
- public void testPause() {
- prepareLooper();
- mController.pause();
- try {
- assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail(e.getMessage());
- }
- assertTrue(mPlayer.mPauseCalled);
- }
-
- @Test
- public void testReset() {
- prepareLooper();
- mController.reset();
- try {
- assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail(e.getMessage());
- }
- assertTrue(mPlayer.mResetCalled);
- }
-
- @Test
- public void testPrepare() {
- prepareLooper();
- mController.prepare();
- try {
- assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail(e.getMessage());
- }
- assertTrue(mPlayer.mPrepareCalled);
- }
-
- @Test
- public void testSeekTo() {
- prepareLooper();
- final long seekPosition = 12125L;
- mController.seekTo(seekPosition);
- try {
- assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail(e.getMessage());
- }
- assertTrue(mPlayer.mSeekToCalled);
- assertEquals(seekPosition, mPlayer.mSeekPosition);
- }
-
- @Test
- public void testGettersAfterConnected() throws InterruptedException {
- prepareLooper();
- final int state = MediaPlayerInterface.PLAYER_STATE_PLAYING;
- final int bufferingState = MediaPlayerInterface.BUFFERING_STATE_BUFFERING_COMPLETE;
- 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;
- mPlayer.mLastBufferingState = bufferingState;
- mPlayer.mCurrentPosition = position;
- mPlayer.mBufferedPosition = bufferedPosition;
- mPlayer.mPlaybackSpeed = speed;
- mMockAgent.mCurrentMediaItem = currentMediaItem;
-
- MediaController2 controller = createController(mSession.getToken());
- // setTimeDiff is package-private, so cannot be called here.
-// controller.setTimeDiff(timeDiff);
- assertEquals(state, controller.getPlayerState());
- assertEquals(bufferedPosition, controller.getBufferedPosition());
- assertEquals(speed, controller.getPlaybackSpeed(), 0.0f);
- assertEquals(position + (long) (speed * timeDiff), controller.getCurrentPosition());
- assertEquals(currentMediaItem, controller.getCurrentMediaItem());
- }
-
- @Test
- public void testUpdatePlayer() throws InterruptedException {
- prepareLooper();
- final int testState = MediaPlayerInterface.PLAYER_STATE_PLAYING;
- final List<MediaItem2> testPlaylist = TestUtils.createPlaylist(3);
- final AudioAttributesCompat testAudioAttributes = new AudioAttributesCompat.Builder()
- .setLegacyStreamType(AudioManager.STREAM_RING).build();
- final CountDownLatch latch = new CountDownLatch(3);
- mController = createController(mSession.getToken(), true, new ControllerCallback() {
- @Override
- public void onPlayerStateChanged(MediaController2 controller, int state) {
- assertEquals(mController, controller);
- assertEquals(testState, state);
- latch.countDown();
- }
-
- @Override
- public void onPlaylistChanged(MediaController2 controller, List<MediaItem2> list,
- MediaMetadata2 metadata) {
- assertEquals(mController, controller);
- assertEquals(testPlaylist, list);
- assertNull(metadata);
- latch.countDown();
- }
-
- @Override
- public void onPlaybackInfoChanged(MediaController2 controller, PlaybackInfo info) {
- assertEquals(mController, controller);
- assertEquals(testAudioAttributes, info.getAudioAttributes());
- latch.countDown();
- }
- });
-
- MockPlayer player = new MockPlayer(0);
- player.mLastPlayerState = testState;
- player.setAudioAttributes(testAudioAttributes);
-
- MockPlaylistAgent agent = new MockPlaylistAgent();
- agent.mPlaylist = testPlaylist;
-
- mSession.updatePlayer(player, agent, null);
- assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testGetSessionActivity() {
- prepareLooper();
- PendingIntent sessionActivity = mController.getSessionActivity();
- assertEquals(mContext.getPackageName(), sessionActivity.getCreatorPackage());
- assertEquals(Process.myUid(), sessionActivity.getCreatorUid());
- }
-
- @Test
- public void testSetPlaylist() throws InterruptedException {
- prepareLooper();
- final List<MediaItem2> list = TestUtils.createPlaylist(2);
- mController.setPlaylist(list, null /* Metadata */);
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertTrue(mMockAgent.mSetPlaylistCalled);
- assertNull(mMockAgent.mMetadata);
-
- assertNotNull(mMockAgent.mPlaylist);
- assertEquals(list.size(), mMockAgent.mPlaylist.size());
- for (int i = 0; i < list.size(); i++) {
- // MediaController2.setPlaylist does not ensure the equality of the items.
- assertEquals(list.get(i).getMediaId(), mMockAgent.mPlaylist.get(i).getMediaId());
- }
- }
-
- /**
- * This also tests {@link ControllerCallback#onPlaylistChanged(
- * MediaController2, List, MediaMetadata2)}.
- */
- @Test
- public void testGetPlaylist() throws InterruptedException {
- prepareLooper();
- final List<MediaItem2> testList = TestUtils.createPlaylist(2);
- final AtomicReference<List<MediaItem2>> listFromCallback = new AtomicReference<>();
- final CountDownLatch latch = new CountDownLatch(1);
- final ControllerCallback callback = new ControllerCallback() {
- @Override
- public void onPlaylistChanged(MediaController2 controller,
- List<MediaItem2> playlist, MediaMetadata2 metadata) {
- assertNotNull(playlist);
- assertEquals(testList.size(), playlist.size());
- for (int i = 0; i < playlist.size(); i++) {
- assertEquals(testList.get(i).getMediaId(), playlist.get(i).getMediaId());
- }
- listFromCallback.set(playlist);
- latch.countDown();
- }
- };
- final MediaPlaylistAgent agent = new MockPlaylistAgent() {
- @Override
- public List<MediaItem2> getPlaylist() {
- return testList;
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setId("testControllerCallback_onPlaylistChanged")
- .setSessionCallback(sHandlerExecutor, new SessionCallback() {})
- .setPlaylistAgent(agent)
- .build()) {
- MediaController2 controller = createController(
- session.getToken(), true, callback);
- agent.notifyPlaylistChanged();
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(listFromCallback.get(), controller.getPlaylist());
- }
- }
-
- @Test
- public void testUpdatePlaylistMetadata() throws InterruptedException {
- prepareLooper();
- final MediaMetadata2 testMetadata = TestUtils.createMetadata();
- mController.updatePlaylistMetadata(testMetadata);
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertTrue(mMockAgent.mUpdatePlaylistMetadataCalled);
- assertNotNull(mMockAgent.mMetadata);
- assertEquals(testMetadata.getMediaId(), mMockAgent.mMetadata.getMediaId());
- }
-
- @Test
- public void testGetPlaylistMetadata() throws InterruptedException {
- prepareLooper();
- final MediaMetadata2 testMetadata = TestUtils.createMetadata();
- final AtomicReference<MediaMetadata2> metadataFromCallback = new AtomicReference<>();
- final CountDownLatch latch = new CountDownLatch(1);
- final ControllerCallback callback = new ControllerCallback() {
- @Override
- public void onPlaylistMetadataChanged(MediaController2 controller,
- MediaMetadata2 metadata) {
- assertNotNull(testMetadata);
- assertEquals(testMetadata.getMediaId(), metadata.getMediaId());
- metadataFromCallback.set(metadata);
- latch.countDown();
- }
- };
- final MediaPlaylistAgent agent = new MockPlaylistAgent() {
- @Override
- public MediaMetadata2 getPlaylistMetadata() {
- return testMetadata;
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setId("testGetPlaylistMetadata")
- .setSessionCallback(sHandlerExecutor, new SessionCallback() {})
- .setPlaylistAgent(agent)
- .build()) {
- MediaController2 controller = createController(session.getToken(), true, callback);
- agent.notifyPlaylistMetadataChanged();
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(metadataFromCallback.get().getMediaId(),
- controller.getPlaylistMetadata().getMediaId());
- }
- }
-
- @Test
- public void testSetPlaybackSpeed() throws Exception {
- prepareLooper();
- final float speed = 1.5f;
- mController.setPlaybackSpeed(speed);
- assertTrue(mPlayer.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(speed, mPlayer.mPlaybackSpeed, 0.0f);
- }
-
- /**
- * Test whether {@link MediaSession2#setPlaylist(List, MediaMetadata2)} is notified
- * through the
- * {@link ControllerCallback#onPlaylistMetadataChanged(MediaController2, MediaMetadata2)}
- * if the controller doesn't have {@link SessionCommand2#COMMAND_CODE_PLAYLIST_GET_LIST} but
- * {@link SessionCommand2#COMMAND_CODE_PLAYLIST_GET_LIST_METADATA}.
- */
- @Test
- public void testControllerCallback_onPlaylistMetadataChanged() throws InterruptedException {
- prepareLooper();
- final MediaItem2 item = TestUtils.createMediaItemWithMetadata();
- final List<MediaItem2> list = TestUtils.createPlaylist(2);
- final CountDownLatch latch = new CountDownLatch(1);
- final ControllerCallback callback = new ControllerCallback() {
- @Override
- public void onPlaylistMetadataChanged(MediaController2 controller,
- MediaMetadata2 metadata) {
- assertNotNull(metadata);
- assertEquals(item.getMediaId(), metadata.getMediaId());
- latch.countDown();
- }
- };
- final SessionCallback sessionCallback = new SessionCallback() {
- @Override
- public SessionCommandGroup2 onConnect(MediaSession2 session,
- ControllerInfo controller) {
- if (Process.myUid() == controller.getUid()) {
- SessionCommandGroup2 commands = new SessionCommandGroup2();
- commands.addCommand(new SessionCommand2(
- SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST_METADATA));
- return commands;
- }
- return super.onConnect(session, controller);
- }
- };
- final MediaPlaylistAgent agent = new MockPlaylistAgent() {
- @Override
- public MediaMetadata2 getPlaylistMetadata() {
- return item.getMetadata();
- }
-
- @Override
- public List<MediaItem2> getPlaylist() {
- return list;
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setId("testControllerCallback_onPlaylistMetadataChanged")
- .setSessionCallback(sHandlerExecutor, sessionCallback)
- .setPlaylistAgent(agent)
- .build()) {
- MediaController2 controller = createController(session.getToken(), true, callback);
- agent.notifyPlaylistMetadataChanged();
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
-
- @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) {
- // setTimeDiff is package-private, so cannot be called here.
-// 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 = MediaPlayerInterface.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) {
- // setTimeDiff is package-private, so cannot be called here.
-// 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 = MediaPlayerInterface.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) {
- // setTimeDiff is package-private, so cannot be called here.
-// 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();
- final int testIndex = 12;
- final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
- mController.addPlaylistItem(testIndex, testMediaItem);
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertTrue(mMockAgent.mAddPlaylistItemCalled);
- assertEquals(testIndex, mMockAgent.mIndex);
- // MediaController2.addPlaylistItem does not ensure the equality of the items.
- assertEquals(testMediaItem.getMediaId(), mMockAgent.mItem.getMediaId());
- }
-
- @Test
- public void testRemovePlaylistItem() throws InterruptedException {
- prepareLooper();
- mMockAgent.mPlaylist = TestUtils.createPlaylist(2);
-
- // Recreate controller for sending removePlaylistItem.
- // It's easier to ensure that MediaController2.getPlaylist() returns the playlist from the
- // agent.
- MediaController2 controller = createController(mSession.getToken());
- MediaItem2 targetItem = controller.getPlaylist().get(0);
- controller.removePlaylistItem(targetItem);
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertTrue(mMockAgent.mRemovePlaylistItemCalled);
- assertEquals(targetItem, mMockAgent.mItem);
- }
-
- @Test
- public void testReplacePlaylistItem() throws InterruptedException {
- prepareLooper();
- final int testIndex = 12;
- final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
- mController.replacePlaylistItem(testIndex, testMediaItem);
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertTrue(mMockAgent.mReplacePlaylistItemCalled);
- // MediaController2.replacePlaylistItem does not ensure the equality of the items.
- assertEquals(testMediaItem.getMediaId(), mMockAgent.mItem.getMediaId());
- }
-
- @Test
- public void testSkipToPreviousItem() throws InterruptedException {
- prepareLooper();
- mController.skipToPreviousItem();
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertTrue(mMockAgent.mSkipToPreviousItemCalled);
- }
-
- @Test
- public void testSkipToNextItem() throws InterruptedException {
- prepareLooper();
- mController.skipToNextItem();
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertTrue(mMockAgent.mSkipToNextItemCalled);
- }
-
- @Test
- public void testSkipToPlaylistItem() throws InterruptedException {
- prepareLooper();
- MediaController2 controller = createController(mSession.getToken());
- MediaItem2 targetItem = TestUtils.createMediaItemWithMetadata();
- controller.skipToPlaylistItem(targetItem);
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertTrue(mMockAgent.mSkipToPlaylistItemCalled);
- assertEquals(targetItem, mMockAgent.mItem);
- }
-
- /**
- * This also tests {@link ControllerCallback#onShuffleModeChanged(MediaController2, int)}.
- */
- @Test
- public void testGetShuffleMode() throws InterruptedException {
- prepareLooper();
- final int testShuffleMode = MediaPlaylistAgent.SHUFFLE_MODE_GROUP;
- final MediaPlaylistAgent agent = new MockPlaylistAgent() {
- @Override
- public int getShuffleMode() {
- return testShuffleMode;
- }
- };
- final CountDownLatch latch = new CountDownLatch(1);
- final ControllerCallback callback = new ControllerCallback() {
- @Override
- public void onShuffleModeChanged(MediaController2 controller, int shuffleMode) {
- assertEquals(testShuffleMode, shuffleMode);
- latch.countDown();
- }
- };
- mSession.updatePlayer(mPlayer, agent, null);
- MediaController2 controller = createController(mSession.getToken(), true, callback);
- agent.notifyShuffleModeChanged();
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(testShuffleMode, controller.getShuffleMode());
- }
-
- @Test
- public void testSetShuffleMode() throws InterruptedException {
- prepareLooper();
- final int testShuffleMode = MediaPlaylistAgent.SHUFFLE_MODE_GROUP;
- mController.setShuffleMode(testShuffleMode);
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertTrue(mMockAgent.mSetShuffleModeCalled);
- assertEquals(testShuffleMode, mMockAgent.mShuffleMode);
- }
-
- /**
- * This also tests {@link ControllerCallback#onRepeatModeChanged(MediaController2, int)}.
- */
- @Test
- public void testGetRepeatMode() throws InterruptedException {
- prepareLooper();
- final int testRepeatMode = MediaPlaylistAgent.REPEAT_MODE_GROUP;
- final MediaPlaylistAgent agent = new MockPlaylistAgent() {
- @Override
- public int getRepeatMode() {
- return testRepeatMode;
- }
- };
- final CountDownLatch latch = new CountDownLatch(1);
- final ControllerCallback callback = new ControllerCallback() {
- @Override
- public void onRepeatModeChanged(MediaController2 controller, int repeatMode) {
- assertEquals(testRepeatMode, repeatMode);
- latch.countDown();
- }
- };
- mSession.updatePlayer(mPlayer, agent, null);
- MediaController2 controller = createController(mSession.getToken(), true, callback);
- agent.notifyRepeatModeChanged();
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(testRepeatMode, controller.getRepeatMode());
- }
-
- @Test
- public void testSetRepeatMode() throws InterruptedException {
- prepareLooper();
- final int testRepeatMode = MediaPlaylistAgent.REPEAT_MODE_GROUP;
- mController.setRepeatMode(testRepeatMode);
- assertTrue(mMockAgent.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertTrue(mMockAgent.mSetRepeatModeCalled);
- assertEquals(testRepeatMode, mMockAgent.mRepeatMode);
- }
-
- @Test
- public void testSetVolumeTo() throws Exception {
- prepareLooper();
- final int maxVolume = 100;
- final int currentVolume = 23;
- final int volumeControlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
- TestVolumeProvider volumeProvider =
- new TestVolumeProvider(volumeControlType, maxVolume, currentVolume);
-
- mSession.updatePlayer(new MockPlayer(0), null, volumeProvider);
- final MediaController2 controller = createController(mSession.getToken(), true, null);
-
- final int targetVolume = 50;
- controller.setVolumeTo(targetVolume, 0 /* flags */);
- assertTrue(volumeProvider.mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- assertTrue(volumeProvider.mSetVolumeToCalled);
- assertEquals(targetVolume, volumeProvider.mVolume);
- }
-
- @Test
- public void testAdjustVolume() throws Exception {
- prepareLooper();
- final int maxVolume = 100;
- final int currentVolume = 23;
- final int volumeControlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
- TestVolumeProvider volumeProvider =
- new TestVolumeProvider(volumeControlType, maxVolume, currentVolume);
-
- mSession.updatePlayer(new MockPlayer(0), null, volumeProvider);
- final MediaController2 controller = createController(mSession.getToken(), true, null);
-
- final int direction = AudioManager.ADJUST_RAISE;
- controller.adjustVolume(direction, 0 /* flags */);
- assertTrue(volumeProvider.mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- assertTrue(volumeProvider.mAdjustVolumeCalled);
- assertEquals(direction, volumeProvider.mDirection);
- }
-
- @Test
- public void testSetVolumeWithLocalVolume() throws Exception {
- prepareLooper();
- if (Build.VERSION.SDK_INT >= 21 && mAudioManager.isVolumeFixed()) {
- // This test is not eligible for this device.
- return;
- }
-
- // Here, we intentionally choose STREAM_ALARM in order not to consider
- // 'Do Not Disturb' or 'Volume limit'.
- final int stream = AudioManager.STREAM_ALARM;
- final int maxVolume = mAudioManager.getStreamMaxVolume(stream);
- final int minVolume = 0;
- if (maxVolume <= minVolume) {
- return;
- }
-
- // Set stream of the session.
- AudioAttributesCompat attrs = new AudioAttributesCompat.Builder()
- .setLegacyStreamType(stream)
- .build();
- mPlayer.setAudioAttributes(attrs);
- mSession.updatePlayer(mPlayer, null, null);
-
- final int originalVolume = mAudioManager.getStreamVolume(stream);
- final int targetVolume = originalVolume == minVolume
- ? originalVolume + 1 : originalVolume - 1;
-
- mController.setVolumeTo(targetVolume, AudioManager.FLAG_SHOW_UI);
- new PollingCheck(WAIT_TIME_MS) {
- @Override
- protected boolean check() {
- return targetVolume == mAudioManager.getStreamVolume(stream);
- }
- }.run();
-
- // Set back to original volume.
- mAudioManager.setStreamVolume(stream, originalVolume, 0 /* flags */);
- }
-
- @Test
- public void testAdjustVolumeWithLocalVolume() throws Exception {
- prepareLooper();
- if (Build.VERSION.SDK_INT >= 21 && mAudioManager.isVolumeFixed()) {
- // This test is not eligible for this device.
- return;
- }
-
- // Here, we intentionally choose STREAM_ALARM in order not to consider
- // 'Do Not Disturb' or 'Volume limit'.
- final int stream = AudioManager.STREAM_ALARM;
- final int maxVolume = mAudioManager.getStreamMaxVolume(stream);
- final int minVolume = 0;
- if (maxVolume <= minVolume) {
- return;
- }
-
- // Set stream of the session.
- AudioAttributesCompat attrs = new AudioAttributesCompat.Builder()
- .setLegacyStreamType(stream)
- .build();
- mPlayer.setAudioAttributes(attrs);
- mSession.updatePlayer(mPlayer, null, null);
-
- final int originalVolume = mAudioManager.getStreamVolume(stream);
- final int direction = originalVolume == minVolume
- ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER;
- final int targetVolume = originalVolume + direction;
-
- mController.adjustVolume(direction, AudioManager.FLAG_SHOW_UI);
- new PollingCheck(WAIT_TIME_MS) {
- @Override
- protected boolean check() {
- return targetVolume == mAudioManager.getStreamVolume(stream);
- }
- }.run();
-
- // Set back to original volume.
- mAudioManager.setStreamVolume(stream, originalVolume, 0 /* flags */);
- }
-
- @Test
- public void testGetPackageName() {
- prepareLooper();
- assertEquals(mContext.getPackageName(), mController.getSessionToken().getPackageName());
- }
-
- @Test
- public void testSendCustomCommand() throws InterruptedException {
- prepareLooper();
- // TODO(jaewan): Need to revisit with the permission.
- final SessionCommand2 testCommand =
- new SessionCommand2(SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE);
- final Bundle testArgs = new Bundle();
- testArgs.putString("args", "testSendCustomCommand");
-
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onCustomCommand(MediaSession2 session, ControllerInfo controller,
- SessionCommand2 customCommand, Bundle args, ResultReceiver cb) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- assertEquals(testCommand, customCommand);
- assertTrue(TestUtils.equals(testArgs, args));
- assertNull(cb);
- latch.countDown();
- }
- };
- mSession.close();
- mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback).setId(TAG).build();
- final MediaController2 controller = createController(mSession.getToken());
- controller.sendCustomCommand(testCommand, testArgs, null);
- assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testControllerCallback_onConnected() throws InterruptedException {
- prepareLooper();
- // createController() uses controller callback to wait until the controller becomes
- // available.
- MediaController2 controller = createController(mSession.getToken());
- assertNotNull(controller);
- }
-
- @Test
- public void testControllerCallback_sessionRejects() throws InterruptedException {
- prepareLooper();
- final MediaSession2.SessionCallback sessionCallback = new SessionCallback() {
- @Override
- public SessionCommandGroup2 onConnect(MediaSession2 session,
- ControllerInfo controller) {
- return null;
- }
- };
- sHandler.postAndSync(new Runnable() {
- @Override
- public void run() {
- mSession.close();
- mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, sessionCallback).build();
- }
- });
- MediaController2 controller =
- createController(mSession.getToken(), false, null);
- assertNotNull(controller);
- waitForConnect(controller, false);
- waitForDisconnect(controller, true);
- }
-
- @Test
- public void testControllerCallback_releaseSession() throws InterruptedException {
- prepareLooper();
- mSession.close();
- waitForDisconnect(mController, true);
- }
-
- @Test
- public void testControllerCallback_close() throws InterruptedException {
- prepareLooper();
- mController.close();
- waitForDisconnect(mController, true);
- }
-
- @Test
- public void testFastForward() throws InterruptedException {
- prepareLooper();
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onFastForward(MediaSession2 session, ControllerInfo controller) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- latch.countDown();
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback)
- .setId("testFastForward").build()) {
- MediaController2 controller = createController(session.getToken());
- controller.fastForward();
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
- public void testRewind() throws InterruptedException {
- prepareLooper();
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onRewind(MediaSession2 session, ControllerInfo controller) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- latch.countDown();
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback)
- .setId("testRewind").build()) {
- MediaController2 controller = createController(session.getToken());
- controller.rewind();
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
- public void testPlayFromSearch() throws InterruptedException {
- prepareLooper();
- final String request = "random query";
- final Bundle bundle = new Bundle();
- bundle.putString("key", "value");
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onPlayFromSearch(MediaSession2 session, ControllerInfo controller,
- String query, Bundle extras) {
- super.onPlayFromSearch(session, controller, query, extras);
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- assertEquals(request, query);
- assertTrue(TestUtils.equals(bundle, extras));
- latch.countDown();
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback)
- .setId("testPlayFromSearch").build()) {
- MediaController2 controller = createController(session.getToken());
- controller.playFromSearch(request, bundle);
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
- public void testPlayFromUri() throws InterruptedException {
- prepareLooper();
- final Uri request = Uri.parse("foo://boo");
- final Bundle bundle = new Bundle();
- bundle.putString("key", "value");
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onPlayFromUri(MediaSession2 session, ControllerInfo controller, Uri uri,
- Bundle extras) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- assertEquals(request, uri);
- assertTrue(TestUtils.equals(bundle, extras));
- latch.countDown();
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback)
- .setId("testPlayFromUri").build()) {
- MediaController2 controller = createController(session.getToken());
- controller.playFromUri(request, bundle);
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
- public void testPlayFromMediaId() throws InterruptedException {
- prepareLooper();
- final String request = "media_id";
- final Bundle bundle = new Bundle();
- bundle.putString("key", "value");
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onPlayFromMediaId(MediaSession2 session, ControllerInfo controller,
- String mediaId, Bundle extras) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- assertEquals(request, mediaId);
- assertTrue(TestUtils.equals(bundle, extras));
- latch.countDown();
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback)
- .setId("testPlayFromMediaId").build()) {
- MediaController2 controller = createController(session.getToken());
- controller.playFromMediaId(request, bundle);
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
- public void testPrepareFromSearch() throws InterruptedException {
- prepareLooper();
- final String request = "random query";
- final Bundle bundle = new Bundle();
- bundle.putString("key", "value");
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onPrepareFromSearch(MediaSession2 session, ControllerInfo controller,
- String query, Bundle extras) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- assertEquals(request, query);
- assertTrue(TestUtils.equals(bundle, extras));
- latch.countDown();
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback)
- .setId("testPrepareFromSearch").build()) {
- MediaController2 controller = createController(session.getToken());
- controller.prepareFromSearch(request, bundle);
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
- public void testPrepareFromUri() throws InterruptedException {
- prepareLooper();
- final Uri request = Uri.parse("foo://boo");
- final Bundle bundle = new Bundle();
- bundle.putString("key", "value");
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onPrepareFromUri(MediaSession2 session, ControllerInfo controller, Uri uri,
- Bundle extras) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- assertEquals(request, uri);
- assertTrue(TestUtils.equals(bundle, extras));
- latch.countDown();
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback)
- .setId("testPrepareFromUri").build()) {
- MediaController2 controller = createController(session.getToken());
- controller.prepareFromUri(request, bundle);
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
- public void testPrepareFromMediaId() throws InterruptedException {
- prepareLooper();
- final String request = "media_id";
- final Bundle bundle = new Bundle();
- bundle.putString("key", "value");
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onPrepareFromMediaId(MediaSession2 session, ControllerInfo controller,
- String mediaId, Bundle extras) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- assertEquals(request, mediaId);
- assertTrue(TestUtils.equals(bundle, extras));
- latch.countDown();
- }
- };
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback)
- .setId("testPrepareFromMediaId").build()) {
- MediaController2 controller = createController(session.getToken());
- controller.prepareFromMediaId(request, bundle);
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
- public void testSetRating() throws InterruptedException {
- prepareLooper();
- final int ratingType = Rating2.RATING_5_STARS;
- final float ratingValue = 3.5f;
- final Rating2 rating = Rating2.newStarRating(ratingType, ratingValue);
- final String mediaId = "media_id";
-
- final CountDownLatch latch = new CountDownLatch(1);
- final SessionCallback callback = new SessionCallback() {
- @Override
- public void onSetRating(MediaSession2 session, ControllerInfo controller,
- String mediaIdOut, Rating2 ratingOut) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- assertEquals(mediaId, mediaIdOut);
- assertEquals(rating, ratingOut);
- latch.countDown();
- }
- };
-
- try (MediaSession2 session = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback)
- .setId("testSetRating").build()) {
- MediaController2 controller = createController(session.getToken());
- controller.setRating(mediaId, rating);
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Test
- public void testIsConnected() throws InterruptedException {
- prepareLooper();
- assertTrue(mController.isConnected());
- sHandler.postAndSync(new Runnable() {
- @Override
- public void run() {
- mSession.close();
- }
- });
- waitForDisconnect(mController, true);
- assertFalse(mController.isConnected());
- }
-
- /**
- * Test potential deadlock for calls between controller and session.
- */
- @Test
- public void testDeadlock() throws InterruptedException {
- prepareLooper();
- sHandler.postAndSync(new Runnable() {
- @Override
- public void run() {
- mSession.close();
- mSession = null;
- }
- });
-
- // Two more threads are needed not to block test thread nor test wide thread (sHandler).
- final HandlerThread sessionThread = new HandlerThread("testDeadlock_session");
- final HandlerThread testThread = new HandlerThread("testDeadlock_test");
- sessionThread.start();
- testThread.start();
- final SyncHandler sessionHandler = new SyncHandler(sessionThread.getLooper());
- final Handler testHandler = new Handler(testThread.getLooper());
- final CountDownLatch latch = new CountDownLatch(1);
- try {
- final MockPlayer player = new MockPlayer(0);
- sessionHandler.postAndSync(new Runnable() {
- @Override
- public void run() {
- mSession = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, new SessionCallback() {})
- .setId("testDeadlock").build();
- }
- });
- final MediaController2 controller = createController(mSession.getToken());
- testHandler.post(new Runnable() {
- @Override
- public void run() {
- final int state = MediaPlayerInterface.PLAYER_STATE_ERROR;
- for (int i = 0; i < 100; i++) {
- // triggers call from session to controller.
- player.notifyPlaybackState(state);
- // triggers call from controller to session.
- controller.play();
-
- // Repeat above
- player.notifyPlaybackState(state);
- controller.pause();
- player.notifyPlaybackState(state);
- controller.reset();
- player.notifyPlaybackState(state);
- controller.skipToNextItem();
- player.notifyPlaybackState(state);
- controller.skipToPreviousItem();
- }
- // This may hang if deadlock happens.
- latch.countDown();
- }
- });
- assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- } finally {
- if (mSession != null) {
- sessionHandler.postAndSync(new Runnable() {
- @Override
- public void run() {
- // Clean up here because sessionHandler will be removed afterwards.
- mSession.close();
- mSession = null;
- }
- });
- }
-
- if (Build.VERSION.SDK_INT >= 18) {
- sessionThread.quitSafely();
- testThread.quitSafely();
- } else {
- sessionThread.quit();
- testThread.quit();
- }
- }
- }
-
- // Temporaily commenting out, since we don't have the Mock services yet.
-// @Test
-// public void testGetServiceToken() {
-// prepareLooper();
-// SessionToken2 token = TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID);
-// assertNotNull(token);
-// assertEquals(mContext.getPackageName(), token.getPackageName());
-// assertEquals(MockMediaSessionService2.ID, token.getId());
-// assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
-// }
-//
-// @Test
-// public void testConnectToService_sessionService() throws InterruptedException {
-// prepareLooper();
-// testConnectToService(MockMediaSessionService2.ID);
-// }
-//
-// @Test
-// public void testConnectToService_libraryService() throws InterruptedException {
-// prepareLooper();
-// testConnectToService(MockMediaLibraryService2.ID);
-// }
-//
-// public void testConnectToService(String id) throws InterruptedException {
-// prepareLooper();
-// final CountDownLatch latch = new CountDownLatch(1);
-// final MediaLibrarySessionCallback sessionCallback = new MediaLibrarySessionCallback() {
-// @Override
-// public SessionCommandGroup2 onConnect(@NonNull MediaSession2 session,
-// @NonNull ControllerInfo controller) {
-// if (Process.myUid() == controller.getUid()) {
-// if (mSession != null) {
-// mSession.close();
-// }
-// mSession = session;
-// mPlayer = (MockPlayer) session.getPlayer();
-// assertEquals(mContext.getPackageName(), controller.getPackageName());
-// assertFalse(controller.isTrusted());
-// latch.countDown();
-// }
-// return super.onConnect(session, controller);
-// }
-// };
-// TestServiceRegistry.getInstance().setSessionCallback(sessionCallback);
-//
-// 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.
-// mController.play();
-// assertTrue(mPlayer.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-// assertTrue(mPlayer.mPlayCalled);
-//
-// // Test command from session service to controller.
-// mSession.sendCustomCommand(testCommand, null);
-// assertTrue(controllerLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-// }
-
- @Test
- public void testControllerAfterSessionIsGone_session() throws InterruptedException {
- prepareLooper();
- testControllerAfterSessionIsClosed(mSession.getToken().getId());
- }
-
- // Temporaily commenting out, since we don't have the Mock services yet.
-// @Test
-// public void testControllerAfterSessionIsClosed_sessionService() throws InterruptedException {
-// prepareLooper();
-// testConnectToService(MockMediaSessionService2.ID);
-// testControllerAfterSessionIsClosed(MockMediaSessionService2.ID);
-// }
-
- @Test
- public void testSubscribeRouteInfo() throws InterruptedException {
- prepareLooper();
- final TestSessionCallback callback = new TestSessionCallback() {
- @Override
- public void onSubscribeRoutesInfo(@NonNull MediaSession2 session,
- @NonNull ControllerInfo controller) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- mLatch.countDown();
- }
-
- @Override
- public void onUnsubscribeRoutesInfo(@NonNull MediaSession2 session,
- @NonNull ControllerInfo controller) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- mLatch.countDown();
- }
- };
- mSession.close();
- mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback).setId(TAG).build();
- final MediaController2 controller = createController(mSession.getToken());
-
- callback.resetLatchCount(1);
- controller.subscribeRoutesInfo();
- assertTrue(callback.mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- callback.resetLatchCount(1);
- controller.unsubscribeRoutesInfo();
- assertTrue(callback.mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testSelectRouteInfo() throws InterruptedException {
- prepareLooper();
- final Bundle testRoute = new Bundle();
- testRoute.putString("id", "testRoute");
- final TestSessionCallback callback = new TestSessionCallback() {
- @Override
- public void onSelectRoute(@NonNull MediaSession2 session,
- @NonNull ControllerInfo controller, @NonNull Bundle route) {
- assertEquals(mContext.getPackageName(), controller.getPackageName());
- assertTrue(TestUtils.equals(route, testRoute));
- mLatch.countDown();
- }
- };
- mSession.close();
- mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, callback).setId(TAG).build();
- final MediaController2 controller = createController(mSession.getToken());
-
- callback.resetLatchCount(1);
- controller.selectRoute(testRoute);
- assertTrue(callback.mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testClose_beforeConnected() throws InterruptedException {
- prepareLooper();
- MediaController2 controller =
- createController(mSession.getToken(), false, null);
- controller.close();
- }
-
- @Test
- public void testClose_twice() {
- prepareLooper();
- mController.close();
- mController.close();
- }
-
- @Test
- public void testClose_session() throws InterruptedException {
- prepareLooper();
- final String id = mSession.getToken().getId();
- mController.close();
- // close is done immediately for session.
- testNoInteraction();
-
- // Test whether the controller is notified about later close of the session or
- // re-creation.
- testControllerAfterSessionIsClosed(id);
- }
-
- // Temporaily commenting out, since we don't have the Mock services yet.
-// @Test
-// public void testClose_sessionService() throws InterruptedException {
-// prepareLooper();
-// testCloseFromService(MockMediaSessionService2.ID);
-// }
-//
-// @Test
-// public void testClose_libraryService() throws InterruptedException {
-// prepareLooper();
-// testCloseFromService(MockMediaLibraryService2.ID);
-// }
-//
-// private void testCloseFromService(String id) throws InterruptedException {
-// final CountDownLatch latch = new CountDownLatch(1);
-// TestServiceRegistry.getInstance().setSessionServiceCallback(new SessionServiceCallback() {
-// @Override
-// public void onCreated() {
-// // Do nothing.
-// }
-//
-// @Override
-// public void onDestroyed() {
-// latch.countDown();
-// }
-// });
-// mController = createController(TestUtils.getServiceToken(mContext, id));
-// mController.close();
-// // Wait until close triggers onDestroy() of the session service.
-// assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-// assertNull(TestServiceRegistry.getInstance().getServiceInstance());
-// testNoInteraction();
-//
-// // Test whether the controller is notified about later close of the session or
-// // re-creation.
-// testControllerAfterSessionIsClosed(id);
-// }
-
- private void testControllerAfterSessionIsClosed(final String id) throws InterruptedException {
- // This cause session service to be died.
- mSession.close();
- waitForDisconnect(mController, true);
- testNoInteraction();
-
- // Ensure that the controller cannot use newly create session with the same ID.
- // Recreated session has different session stub, so previously created controller
- // shouldn't be available.
- mSession = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(sHandlerExecutor, new SessionCallback() {})
- .setId(id).build();
- testNoInteraction();
- }
-
- // Test that mSession and mController doesn't interact.
- // Note that this method can be called after the mSession is died, so mSession may not have
- // valid player.
- private void testNoInteraction() throws InterruptedException {
- // TODO: check that calls from the controller to session shouldn't be delivered.
-
- // Calls from the session to controller shouldn't be delivered.
- final CountDownLatch latch = new CountDownLatch(1);
- setRunnableForOnCustomCommand(mController, new Runnable() {
- @Override
- public void run() {
- latch.countDown();
- }
- });
- SessionCommand2 customCommand = new SessionCommand2("testNoInteraction", null);
- mSession.sendCustomCommand(customCommand, null);
- assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- setRunnableForOnCustomCommand(mController, null);
- }
-
- // TODO(jaewan): Add test for service connect rejection, when we differentiate session
- // active/inactive and connection accept/refuse
-
- class TestVolumeProvider extends VolumeProviderCompat {
- final CountDownLatch mLatch = new CountDownLatch(1);
- boolean mSetVolumeToCalled;
- boolean mAdjustVolumeCalled;
- int mVolume;
- int mDirection;
-
- TestVolumeProvider(int controlType, int maxVolume, int currentVolume) {
- super(controlType, maxVolume, currentVolume);
- }
-
- @Override
- public void onSetVolumeTo(int volume) {
- mSetVolumeToCalled = true;
- mVolume = volume;
- mLatch.countDown();
- }
-
- @Override
- public void onAdjustVolume(int direction) {
- mAdjustVolumeCalled = true;
- mDirection = direction;
- mLatch.countDown();
- }
- }
-
- class TestSessionCallback extends SessionCallback {
- CountDownLatch mLatch;
-
- void resetLatchCount(int count) {
- mLatch = new CountDownLatch(count);
- }
- }
-}
diff --git a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MediaSession2TestBase.java b/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MediaSession2TestBase.java
deleted file mode 100644
index a8da0b1..0000000
--- a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MediaSession2TestBase.java
+++ /dev/null
@@ -1,375 +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.media.test.client;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.content.Context;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.ResultReceiver;
-import android.support.test.InstrumentationRegistry;
-
-import androidx.annotation.CallSuper;
-import androidx.annotation.GuardedBy;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.media.MediaController2;
-import androidx.media.MediaController2.ControllerCallback;
-import androidx.media.MediaItem2;
-import androidx.media.MediaMetadata2;
-import androidx.media.MediaSession2.CommandButton;
-import androidx.media.SessionCommand2;
-import androidx.media.SessionCommandGroup2;
-import androidx.media.SessionToken2;
-import androidx.media.test.client.TestUtils.SyncHandler;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Base class for session test.
- * <p>
- * For all subclasses, all individual tests should begin with the {@link #prepareLooper()}. See
- * {@link #prepareLooper} for details.
- */
-abstract class MediaSession2TestBase {
- // Expected success
- static final int WAIT_TIME_MS = 1000;
-
- // Expected timeout
- static final int TIMEOUT_MS = 500;
-
- static SyncHandler sHandler;
- static Executor sHandlerExecutor;
-
- Context mContext;
- private List<MediaController2> mControllers = new ArrayList<>();
-
- interface TestControllerInterface {
- ControllerCallback getCallback();
- }
-
- interface TestControllerCallbackInterface {
- void waitForConnect(boolean expect) throws InterruptedException;
- void waitForDisconnect(boolean expect) throws InterruptedException;
- void setRunnableForOnCustomCommand(Runnable runnable);
- }
-
- /**
- * All tests methods should start with this.
- * <p>
- * MediaControllerCompat, which is wrapped by the MediaSession2, can be only created by the
- * thread whose Looper is prepared. However, when the presubmit tests runs on the server,
- * test runs with the {@link org.junit.internal.runners.statements.FailOnTimeout} which creates
- * dedicated thread for running test methods while methods annotated with @After or @Before
- * runs on the different thread. This ensures that the current Looper is prepared.
- * <p>
- * To address the issue .
- */
- public static void prepareLooper() {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- }
-
- @BeforeClass
- public static void setUpThread() {
- synchronized (MediaSession2TestBase.class) {
- if (sHandler != null) {
- return;
- }
- prepareLooper();
- HandlerThread handlerThread = new HandlerThread("MediaSession2TestBase");
- handlerThread.start();
- sHandler = new SyncHandler(handlerThread.getLooper());
- sHandlerExecutor = new Executor() {
- @Override
- public void execute(Runnable runnable) {
- SyncHandler handler;
- synchronized (MediaSession2TestBase.class) {
- handler = sHandler;
- }
- if (handler != null) {
- handler.post(runnable);
- }
- }
- };
- }
- }
-
- @AfterClass
- public static void cleanUpThread() {
- synchronized (MediaSession2TestBase.class) {
- if (sHandler == null) {
- return;
- }
- if (Build.VERSION.SDK_INT >= 18) {
- sHandler.getLooper().quitSafely();
- } else {
- sHandler.getLooper().quit();
- }
- sHandler = null;
- sHandlerExecutor = null;
- }
- }
-
- @CallSuper
- public void setUp() throws Exception {
- mContext = InstrumentationRegistry.getTargetContext();
- }
-
- @CallSuper
- public void cleanUp() throws Exception {
- for (int i = 0; i < mControllers.size(); i++) {
- mControllers.get(i).close();
- }
- }
-
- final MediaController2 createController(SessionToken2 token) throws InterruptedException {
- return createController(token, true, null);
- }
-
- final MediaController2 createController(@NonNull SessionToken2 token,
- boolean waitForConnect, @Nullable ControllerCallback callback)
- throws InterruptedException {
- TestControllerInterface instance = onCreateController(token, callback);
- if (!(instance instanceof MediaController2)) {
- throw new RuntimeException("Test has a bug. Expected MediaController2 but returned "
- + instance);
- }
- MediaController2 controller = (MediaController2) instance;
- mControllers.add(controller);
- if (waitForConnect) {
- waitForConnect(controller, true);
- }
- return controller;
- }
-
- private static TestControllerCallbackInterface getTestControllerCallbackInterface(
- MediaController2 controller) {
- if (!(controller instanceof TestControllerInterface)) {
- throw new RuntimeException("Test has a bug. Expected controller implemented"
- + " TestControllerInterface but got " + controller);
- }
- ControllerCallback callback = ((TestControllerInterface) controller).getCallback();
- if (!(callback instanceof TestControllerCallbackInterface)) {
- throw new RuntimeException("Test has a bug. Expected controller with callback "
- + " implemented TestControllerCallbackInterface but got " + controller);
- }
- return (TestControllerCallbackInterface) callback;
- }
-
- public static void waitForConnect(MediaController2 controller, boolean expected)
- throws InterruptedException {
- getTestControllerCallbackInterface(controller).waitForConnect(expected);
- }
-
- public static void waitForDisconnect(MediaController2 controller, boolean expected)
- throws InterruptedException {
- getTestControllerCallbackInterface(controller).waitForDisconnect(expected);
- }
-
- public static void setRunnableForOnCustomCommand(MediaController2 controller,
- Runnable runnable) {
- getTestControllerCallbackInterface(controller).setRunnableForOnCustomCommand(runnable);
- }
-
- TestControllerInterface onCreateController(final @NonNull SessionToken2 token,
- @Nullable ControllerCallback callback) throws InterruptedException {
- final ControllerCallback controllerCallback =
- callback != null ? callback : new ControllerCallback() {};
- final AtomicReference<TestControllerInterface> controller = new AtomicReference<>();
- sHandler.postAndSync(new Runnable() {
- @Override
- public void run() {
- // Create controller on the test handler, for changing MediaBrowserCompat's Handler
- // 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 TestMediaController(
- mContext, token, new TestControllerCallback(controllerCallback)));
- }
- });
- return controller.get();
- }
-
- // TODO(jaewan): (Can be Post-P): Deprecate this
- public static class TestControllerCallback extends MediaController2.ControllerCallback
- implements TestControllerCallbackInterface {
- public final ControllerCallback mCallbackProxy;
- public final CountDownLatch connectLatch = new CountDownLatch(1);
- public final CountDownLatch disconnectLatch = new CountDownLatch(1);
- @GuardedBy("this")
- private Runnable mOnCustomCommandRunnable;
-
- TestControllerCallback(@NonNull ControllerCallback callbackProxy) {
- if (callbackProxy == null) {
- throw new IllegalArgumentException("Callback proxy shouldn't be null. Test bug");
- }
- mCallbackProxy = callbackProxy;
- }
-
- @CallSuper
- @Override
- public void onConnected(MediaController2 controller, SessionCommandGroup2 commands) {
- connectLatch.countDown();
- }
-
- @CallSuper
- @Override
- public void onDisconnected(MediaController2 controller) {
- disconnectLatch.countDown();
- }
-
- @Override
- public void waitForConnect(boolean expect) throws InterruptedException {
- if (expect) {
- assertTrue(connectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- } else {
- assertFalse(connectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Override
- public void waitForDisconnect(boolean expect) throws InterruptedException {
- if (expect) {
- assertTrue(disconnectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- } else {
- assertFalse(disconnectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- }
- }
-
- @Override
- public void onCustomCommand(MediaController2 controller, SessionCommand2 command,
- Bundle args, ResultReceiver receiver) {
- mCallbackProxy.onCustomCommand(controller, command, args, receiver);
- synchronized (this) {
- if (mOnCustomCommandRunnable != null) {
- mOnCustomCommandRunnable.run();
- }
- }
- }
-
- @Override
- public void onPlaybackInfoChanged(MediaController2 controller,
- MediaController2.PlaybackInfo info) {
- mCallbackProxy.onPlaybackInfoChanged(controller, info);
- }
-
- @Override
- public void onCustomLayoutChanged(MediaController2 controller, List<CommandButton> layout) {
- mCallbackProxy.onCustomLayoutChanged(controller, layout);
- }
-
- @Override
- public void onAllowedCommandsChanged(MediaController2 controller,
- SessionCommandGroup2 commands) {
- mCallbackProxy.onAllowedCommandsChanged(controller, commands);
- }
-
- @Override
- public void onPlayerStateChanged(MediaController2 controller, int state) {
- mCallbackProxy.onPlayerStateChanged(controller, state);
- }
-
- @Override
- public void onSeekCompleted(MediaController2 controller, long position) {
- mCallbackProxy.onSeekCompleted(controller, position);
- }
-
- @Override
- public void onPlaybackSpeedChanged(MediaController2 controller, float speed) {
- mCallbackProxy.onPlaybackSpeedChanged(controller, speed);
- }
-
- @Override
- public void onBufferingStateChanged(MediaController2 controller, MediaItem2 item,
- int state) {
- mCallbackProxy.onBufferingStateChanged(controller, item, state);
- }
-
- @Override
- public void onError(MediaController2 controller, int errorCode, Bundle extras) {
- mCallbackProxy.onError(controller, errorCode, extras);
- }
-
- @Override
- public void onCurrentMediaItemChanged(MediaController2 controller, MediaItem2 item) {
- mCallbackProxy.onCurrentMediaItemChanged(controller, item);
- }
-
- @Override
- public void onPlaylistChanged(MediaController2 controller,
- List<MediaItem2> list, MediaMetadata2 metadata) {
- mCallbackProxy.onPlaylistChanged(controller, list, metadata);
- }
-
- @Override
- public void onPlaylistMetadataChanged(MediaController2 controller,
- MediaMetadata2 metadata) {
- mCallbackProxy.onPlaylistMetadataChanged(controller, metadata);
- }
-
- @Override
- public void onShuffleModeChanged(MediaController2 controller, int shuffleMode) {
- mCallbackProxy.onShuffleModeChanged(controller, shuffleMode);
- }
-
- @Override
- public void onRepeatModeChanged(MediaController2 controller, int repeatMode) {
- mCallbackProxy.onRepeatModeChanged(controller, repeatMode);
- }
-
- @Override
- public void setRunnableForOnCustomCommand(Runnable runnable) {
- synchronized (this) {
- mOnCustomCommandRunnable = runnable;
- }
- }
-
- @Override
- public void onRoutesInfoChanged(@NonNull MediaController2 controller,
- @Nullable List<Bundle> routes) {
- mCallbackProxy.onRoutesInfoChanged(controller, routes);
- }
- }
-
- public class TestMediaController extends MediaController2 implements TestControllerInterface {
- private final ControllerCallback mCallback;
-
- TestMediaController(@NonNull Context context, @NonNull SessionToken2 token,
- @NonNull ControllerCallback callback) {
- super(context, token, sHandlerExecutor, callback);
- mCallback = callback;
- }
-
- @Override
- public ControllerCallback getCallback() {
- return mCallback;
- }
- }
-}
diff --git a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MockActivity.java b/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MockActivity.java
deleted file mode 100644
index 1bcb93a..0000000
--- a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MockActivity.java
+++ /dev/null
@@ -1,22 +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.media.test.client;
-
-import android.app.Activity;
-
-public class MockActivity extends Activity {
-}
diff --git a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MockPlayer.java b/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MockPlayer.java
deleted file mode 100644
index 7a61184..0000000
--- a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MockPlayer.java
+++ /dev/null
@@ -1,296 +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.media.test.client;
-
-import androidx.annotation.NonNull;
-import androidx.collection.ArrayMap;
-import androidx.media.AudioAttributesCompat;
-import androidx.media.DataSourceDesc;
-import androidx.media.MediaPlayerInterface;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-
-/**
- * A mock implementation of {@link MediaPlayerInterface} for testing.
- */
-public class MockPlayer extends MediaPlayerInterface {
- public final CountDownLatch mCountDownLatch;
-
- public boolean mPlayCalled;
- public boolean mPauseCalled;
- public boolean mResetCalled;
- public boolean mPrepareCalled;
- public boolean mSeekToCalled;
- public boolean mSetPlaybackSpeedCalled;
- public long mSeekPosition;
- public long mCurrentPosition;
- public long mBufferedPosition;
- public float mPlaybackSpeed = 1.0f;
- public @PlayerState int mLastPlayerState;
- public @BuffState int mLastBufferingState;
- public long mDuration;
-
- public ArrayMap<PlayerEventCallback, Executor> mCallbacks = new ArrayMap<>();
-
- private AudioAttributesCompat mAudioAttributes;
-
- public MockPlayer(int count) {
- mCountDownLatch = (count > 0) ? new CountDownLatch(count) : null;
- }
-
- @Override
- public void close() {
- // no-op
- }
-
- @Override
- public void reset() {
- mResetCalled = true;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void play() {
- mPlayCalled = true;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void pause() {
- mPauseCalled = true;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void prepare() {
- mPrepareCalled = true;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void seekTo(long pos) {
- mSeekToCalled = true;
- mSeekPosition = pos;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void skipToNext() {
- // No-op. This skipToNext() means 'skip to next item in the setNextDataSources()'
- }
-
- @Override
- public int getPlayerState() {
- return mLastPlayerState;
- }
-
- @Override
- public long getCurrentPosition() {
- return mCurrentPosition;
- }
-
- @Override
- public long getBufferedPosition() {
- return mBufferedPosition;
- }
-
- @Override
- public float getPlaybackSpeed() {
- return mPlaybackSpeed;
- }
-
- @Override
- public int getBufferingState() {
- return mLastBufferingState;
- }
-
- @Override
- public long getDuration() {
- return mDuration;
- }
-
- @Override
- public void registerPlayerEventCallback(@NonNull Executor executor,
- @NonNull PlayerEventCallback callback) {
- if (callback == null || executor == null) {
- throw new IllegalArgumentException("callback=" + callback + " executor=" + executor);
- }
- mCallbacks.put(callback, executor);
- }
-
- @Override
- public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback callback) {
- mCallbacks.remove(callback);
- }
-
- public void notifyPlaybackState(final int state) {
- mLastPlayerState = state;
- 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.onPlayerStateChanged(MockPlayer.this, state);
- }
- });
- }
- }
-
- public void notifyCurrentDataSourceChanged(final DataSourceDesc dsd) {
- 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.onCurrentDataSourceChanged(MockPlayer.this, dsd);
- }
- });
- }
- }
-
- public void notifyMediaPrepared(final DataSourceDesc dsd) {
- 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.onMediaPrepared(MockPlayer.this, dsd);
- }
- });
- }
- }
-
- public void notifyBufferingStateChanged(final DataSourceDesc dsd,
- final @BuffState int buffState) {
- 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, dsd, buffState);
- }
- });
- }
- }
-
- public void notifyPlaybackSpeedChanged(final float speed) {
- 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.onPlaybackSpeedChanged(MockPlayer.this, speed);
- }
- });
- }
- }
-
- 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);
- final Executor executor = mCallbacks.valueAt(i);
- // TODO: Uncomment or remove
- //executor.execute(() -> callback.onError(null, what, 0));
- }
- }
-
- @Override
- public void setAudioAttributes(AudioAttributesCompat attributes) {
- mAudioAttributes = attributes;
- }
-
- @Override
- public AudioAttributesCompat getAudioAttributes() {
- return mAudioAttributes;
- }
-
- @Override
- public void setDataSource(@NonNull DataSourceDesc dsd) {
- // TODO: Implement this
- }
-
- @Override
- public void setNextDataSource(@NonNull DataSourceDesc dsd) {
- // TODO: Implement this
- }
-
- @Override
- public void setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
- // TODO: Implement this
- }
-
- @Override
- public DataSourceDesc getCurrentDataSource() {
- // TODO: Implement this
- return null;
- }
-
- @Override
- public void loopCurrent(boolean loop) {
- // TODO: implement this
- }
-
- @Override
- public void setPlaybackSpeed(float speed) {
- mSetPlaybackSpeedCalled = true;
- mPlaybackSpeed = speed;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void setPlayerVolume(float volume) {
- // TODO: implement this
- }
-
- @Override
- public float getPlayerVolume() {
- // TODO: implement this
- return -1;
- }
-}
diff --git a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MockPlaylistAgent.java b/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MockPlaylistAgent.java
deleted file mode 100644
index 1ed6cd7..0000000
--- a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/MockPlaylistAgent.java
+++ /dev/null
@@ -1,149 +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.media.test.client;
-
-import androidx.media.MediaItem2;
-import androidx.media.MediaMetadata2;
-import androidx.media.MediaPlaylistAgent;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * A mock implementation of {@link MediaPlaylistAgent} for testing.
- * <p>
- * Do not use mockito for {@link MediaPlaylistAgent}. Instead, use this.
- * Mocks created from mockito should not be shared across different threads.
- */
-public class MockPlaylistAgent extends MediaPlaylistAgent {
- public final CountDownLatch mCountDownLatch = new CountDownLatch(1);
-
- public List<MediaItem2> mPlaylist;
- public MediaMetadata2 mMetadata;
- public MediaItem2 mCurrentMediaItem;
- public MediaItem2 mItem;
- public int mIndex = -1;
- public @RepeatMode int mRepeatMode = -1;
- public @ShuffleMode int mShuffleMode = -1;
-
- public boolean mSetPlaylistCalled;
- public boolean mUpdatePlaylistMetadataCalled;
- public boolean mAddPlaylistItemCalled;
- public boolean mRemovePlaylistItemCalled;
- public boolean mReplacePlaylistItemCalled;
- public boolean mSkipToPlaylistItemCalled;
- public boolean mSkipToPreviousItemCalled;
- public boolean mSkipToNextItemCalled;
- public boolean mSetRepeatModeCalled;
- public boolean mSetShuffleModeCalled;
-
- @Override
- public List<MediaItem2> getPlaylist() {
- return mPlaylist;
- }
-
- @Override
- public void setPlaylist(List<MediaItem2> list, MediaMetadata2 metadata) {
- mSetPlaylistCalled = true;
- mPlaylist = list;
- mMetadata = metadata;
- mCountDownLatch.countDown();
- }
-
- @Override
- public MediaMetadata2 getPlaylistMetadata() {
- return mMetadata;
- }
-
- @Override
- public void updatePlaylistMetadata(MediaMetadata2 metadata) {
- mUpdatePlaylistMetadataCalled = true;
- mMetadata = metadata;
- mCountDownLatch.countDown();
- }
-
- @Override
- public MediaItem2 getCurrentMediaItem() {
- return mCurrentMediaItem;
- }
-
- @Override
- public void addPlaylistItem(int index, MediaItem2 item) {
- mAddPlaylistItemCalled = true;
- mIndex = index;
- mItem = item;
- mCountDownLatch.countDown();
- }
-
- @Override
- public void removePlaylistItem(MediaItem2 item) {
- mRemovePlaylistItemCalled = true;
- mItem = item;
- mCountDownLatch.countDown();
- }
-
- @Override
- public void replacePlaylistItem(int index, MediaItem2 item) {
- mReplacePlaylistItemCalled = true;
- mIndex = index;
- mItem = item;
- mCountDownLatch.countDown();
- }
-
- @Override
- public void skipToPlaylistItem(MediaItem2 item) {
- mSkipToPlaylistItemCalled = true;
- mItem = item;
- mCountDownLatch.countDown();
- }
-
- @Override
- public void skipToPreviousItem() {
- mSkipToPreviousItemCalled = true;
- mCountDownLatch.countDown();
- }
-
- @Override
- public void skipToNextItem() {
- mSkipToNextItemCalled = true;
- mCountDownLatch.countDown();
- }
-
- @Override
- public int getRepeatMode() {
- return mRepeatMode;
- }
-
- @Override
- public void setRepeatMode(int repeatMode) {
- mSetRepeatModeCalled = true;
- mRepeatMode = repeatMode;
- mCountDownLatch.countDown();
- }
-
- @Override
- public int getShuffleMode() {
- return mShuffleMode;
- }
-
- @Override
- public void setShuffleMode(int shuffleMode) {
- mSetShuffleModeCalled = true;
- mShuffleMode = shuffleMode;
- mCountDownLatch.countDown();
- }
-}
diff --git a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestHelper.java b/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestHelper.java
deleted file mode 100644
index 76c7758..0000000
--- a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestHelper.java
+++ /dev/null
@@ -1,117 +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.media.test.client;
-
-import static androidx.media.test.lib.TestHelperUtil.ACTION_TEST_HELPER;
-import static androidx.media.test.lib.TestHelperUtil.SERVICE_TEST_HELPER_COMPONENT_NAME;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.support.mediacompat.testlib.ITestHelperForServiceApp;
-import android.util.Log;
-
-import androidx.media.MediaSession2;
-import androidx.media.SessionToken2;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Interacts with service app's TestHelperService.
- */
-public class TestHelper {
-
- private static final String TAG = "TestHelper";
-
- private Context mContext;
- private ServiceConnection mServiceConnection;
- private ITestHelperForServiceApp mBinder;
-
- private CountDownLatch mCountDownLatch;
-
- public TestHelper(Context context) {
- mContext = context;
- mCountDownLatch = new CountDownLatch(1);
- }
-
- /**
- * Connects to service app's TestHelperService. Should NOT be called in main thread.
- *
- * @return true if connected successfully, false if failed to connect.
- */
- public boolean connect(int timeoutMs) {
- mServiceConnection = new MyServiceConnection();
-
- final Intent intent = new Intent(ACTION_TEST_HELPER);
- intent.setComponent(SERVICE_TEST_HELPER_COMPONENT_NAME);
-
- boolean bound = false;
- try {
- bound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
- } catch (Exception ex) {
- Log.e(TAG, "Failed binding to the test helper service of service app");
- }
-
- if (bound) {
- try {
- mCountDownLatch.await(timeoutMs, TimeUnit.MILLISECONDS);
- } catch (InterruptedException ex) {
- Log.e(TAG, "InterruptedException while waiting for onServiceConnected.", ex);
- }
- }
- return mBinder != null;
- }
-
- /**
- * Create a session2 in the service app, and gets its token.
- *
- * @return A {@link SessionToken2} object if succeeded, {@code null} if failed.
- */
- public SessionToken2 getSessionToken2(String testName) {
- SessionToken2 token = null;
- try {
- Bundle bundle = mBinder.getSessionToken2(testName);
- if (bundle != null) {
- bundle.setClassLoader(MediaSession2.class.getClassLoader());
- }
- token = SessionToken2.fromBundle(bundle);
- } catch (RemoteException ex) {
- Log.e(TAG, "Failed to get session token. testName=" + testName);
- }
- return token;
- }
-
- // These methods will run on main thread.
- class MyServiceConnection implements ServiceConnection {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- Log.d(TAG, "Connected to service app's TestHelperService.");
- mBinder = ITestHelperForServiceApp.Stub.asInterface(service);
- mCountDownLatch.countDown();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- Log.d(TAG, "Disconnected from the service.");
- }
- }
-}
diff --git a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestHelperTest.java b/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestHelperTest.java
deleted file mode 100644
index af5b1ed..0000000
--- a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestHelperTest.java
+++ /dev/null
@@ -1,95 +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.media.test.client;
-
-import static android.support.mediacompat.testlib.VersionConstants.KEY_SERVICE_VERSION;
-import static android.support.mediacompat.testlib.VersionConstants.VERSION_TOT;
-import static android.support.mediacompat.testlib.util.IntentUtil.SERVICE_PACKAGE_NAME;
-import static android.support.test.InstrumentationRegistry.getArguments;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.os.Looper;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import androidx.media.MediaController2;
-import androidx.media.SessionToken2;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.Executor;
-
-/** Test {@link TestHelper}. */
-@RunWith(AndroidJUnit4.class)
-public class TestHelperTest {
- private static final int TIME_OUT_MS = 3000;
-
- private Context mContext;
- private TestHelper mTestHelper;
- private String mServiceVersion;
-
- @Before
- public void setUp() {
- // The version of the service app is provided through the instrumentation arguments.
- mServiceVersion = getArguments().getString(KEY_SERVICE_VERSION, "");
- if (!VERSION_TOT.equals(mServiceVersion)) {
- return;
- }
-
- mContext = InstrumentationRegistry.getTargetContext();
- mTestHelper = new TestHelper(mContext);
- boolean connected = mTestHelper.connect(TIME_OUT_MS);
- if (!connected) {
- fail("Failed to connect to Test helper service.");
- }
- }
-
- @Test
- @SmallTest
- public void testGettingToken() {
- if (!VERSION_TOT.equals(mServiceVersion)) {
- return;
- }
- SessionToken2 token = mTestHelper.getSessionToken2("testGettingToken");
- assertNotNull(token);
- assertEquals(SERVICE_PACKAGE_NAME, token.getPackageName());
- }
-
- @Test
- @SmallTest
- public void testCreatingController() {
- if (!VERSION_TOT.equals(mServiceVersion)) {
- return;
- }
- Looper.prepare();
- SessionToken2 token = mTestHelper.getSessionToken2("testCreatingController");
- assertNotNull(token);
- MediaController2 controller = new MediaController2(mContext, token, new Executor() {
- @Override
- public void execute(Runnable command) {
- command.run();
- }
- }, new MediaController2.ControllerCallback() {});
- }
-}
diff --git a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestServiceRegistry.java b/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestServiceRegistry.java
deleted file mode 100644
index 8c87073..0000000
--- a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestServiceRegistry.java
+++ /dev/null
@@ -1,133 +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.media.test.client;
-
-import static org.junit.Assert.fail;
-
-import android.os.Handler;
-
-import androidx.annotation.GuardedBy;
-import androidx.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
-import androidx.media.MediaSessionService2;
-import androidx.media.test.client.TestUtils.SyncHandler;
-
-/**
- * Keeps the instance of currently running {@link MockMediaSessionService2}. And also provides
- * a way to control them in one place.
- * <p>
- * It only support only one service at a time.
- */
-public class TestServiceRegistry {
- @GuardedBy("TestServiceRegistry.class")
- private static TestServiceRegistry sInstance;
- @GuardedBy("TestServiceRegistry.class")
- private MediaSessionService2 mService;
- @GuardedBy("TestServiceRegistry.class")
- private SyncHandler mHandler;
- @GuardedBy("TestServiceRegistry.class")
- private MediaLibrarySessionCallback mSessionCallback;
- @GuardedBy("TestServiceRegistry.class")
- private SessionServiceCallback mSessionServiceCallback;
-
- /**
- * Callback for session service's lifecyle (onCreate() / onDestroy())
- */
- public interface SessionServiceCallback {
- void onCreated();
- void onDestroyed();
- }
-
- public static TestServiceRegistry getInstance() {
- synchronized (TestServiceRegistry.class) {
- if (sInstance == null) {
- sInstance = new TestServiceRegistry();
- }
- return sInstance;
- }
- }
-
- public void setHandler(Handler handler) {
- synchronized (TestServiceRegistry.class) {
- mHandler = new SyncHandler(handler.getLooper());
- }
- }
-
- public Handler getHandler() {
- synchronized (TestServiceRegistry.class) {
- return mHandler;
- }
- }
-
- public void setSessionServiceCallback(SessionServiceCallback sessionServiceCallback) {
- synchronized (TestServiceRegistry.class) {
- mSessionServiceCallback = sessionServiceCallback;
- }
- }
-
- public void setSessionCallback(MediaLibrarySessionCallback sessionCallback) {
- synchronized (TestServiceRegistry.class) {
- mSessionCallback = sessionCallback;
- }
- }
-
- public MediaLibrarySessionCallback getSessionCallback() {
- synchronized (TestServiceRegistry.class) {
- return mSessionCallback;
- }
- }
-
- public void setServiceInstance(MediaSessionService2 service) {
- synchronized (TestServiceRegistry.class) {
- if (mService != null) {
- fail("Previous service instance is still running. Clean up manually to ensure"
- + " previoulsy running service doesn't break current test");
- }
- mService = service;
- if (mSessionServiceCallback != null) {
- mSessionServiceCallback.onCreated();
- }
- }
- }
-
- public MediaSessionService2 getServiceInstance() {
- synchronized (TestServiceRegistry.class) {
- return mService;
- }
- }
-
- public void cleanUp() {
- synchronized (TestServiceRegistry.class) {
- if (mService != null) {
- // TODO(jaewan): Remove this, and override SessionService#onDestroy() to do this
- mService.getSession().close();
- // stopSelf() would not kill service while the binder connection established by
- // bindService() exists, and close() above will do the job instead.
- // So stopSelf() isn't really needed, but just for sure.
- mService.stopSelf();
- mService = null;
- }
- if (mHandler != null) {
- mHandler.removeCallbacksAndMessages(null);
- }
- mSessionCallback = null;
- if (mSessionServiceCallback != null) {
- mSessionServiceCallback.onDestroyed();
- mSessionServiceCallback = null;
- }
- }
- }
-}
diff --git a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestUtils.java b/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestUtils.java
deleted file mode 100644
index 3cd7f68..0000000
--- a/media/version-compat-tests/current/client/src/androidTest/java/androidx/media/test/client/TestUtils.java
+++ /dev/null
@@ -1,184 +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.media.test.client;
-
-import static org.junit.Assert.assertTrue;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-
-import androidx.core.util.ObjectsCompat;
-import androidx.media.DataSourceDesc;
-import androidx.media.MediaItem2;
-import androidx.media.MediaMetadata2;
-
-import java.io.FileDescriptor;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Utilities for tests.
- */
-public final class TestUtils {
- private static final int WAIT_TIME_MS = 1000;
- private static final int WAIT_SERVICE_TIME_MS = 5000;
-
- // Temporaily commenting out, since we don't have the Mock services yet.
-// /**
-// * Finds the session with id in this test package.
-// *
-// * @param context
-// * @param id
-// * @return
-// */
-// public static SessionToken2 getServiceToken(Context context, String id) {
-// switch (id) {
-// case MockMediaSessionService2.ID:
-// return new SessionToken2(context, new ComponentName(
-// context.getPackageName(), MockMediaSessionService2.class.getName()));
-// case MockMediaLibraryService2.ID:
-// return new SessionToken2(context, new ComponentName(
-// context.getPackageName(), MockMediaLibraryService2.class.getName()));
-// }
-// fail("Unknown id=" + id);
-// return null;
-// }
-
- /**
- * Compares contents of two bundles.
- *
- * @param a a bundle
- * @param b another bundle
- * @return {@code true} if two bundles are the same. {@code false} otherwise. This may be
- * 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;
- }
- for (String key : b.keySet()) {
- if (!ObjectsCompat.equals(a.get(key), b.get(key))) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Create a playlist for testing purpose
- * <p>
- * Caller's method name will be used for prefix of each media item's media id.
- *
- * @param size list size
- * @return the newly created playlist
- */
- public static List<MediaItem2> createPlaylist(int size) {
- final List<MediaItem2> list = new ArrayList<>();
- String caller = Thread.currentThread().getStackTrace()[1].getMethodName();
- for (int i = 0; i < size; i++) {
- list.add(new MediaItem2.Builder(MediaItem2.FLAG_PLAYABLE)
- .setMediaId(caller + "_item_" + (size + 1))
- .setDataSourceDesc(createDSD()).build());
- }
- return list;
- }
-
- /**
- * Create a media item with the metadata for testing purpose.
- *
- * @return the newly created media item
- * @see #createMetadata()
- */
- public static MediaItem2 createMediaItemWithMetadata() {
- return new MediaItem2.Builder(MediaItem2.FLAG_PLAYABLE)
- .setMetadata(createMetadata()).setDataSourceDesc(createDSD()).build();
- }
-
- /**
- * Create a media metadata for testing purpose.
- * <p>
- * Caller's method name will be used for the media id.
- *
- * @return the newly created media item
- */
- public static MediaMetadata2 createMetadata() {
- String mediaId = Thread.currentThread().getStackTrace()[1].getMethodName();
- return new MediaMetadata2.Builder()
- .putString(MediaMetadata2.METADATA_KEY_MEDIA_ID, mediaId).build();
- }
-
- private static DataSourceDesc createDSD() {
- return new DataSourceDesc.Builder().setDataSource(new FileDescriptor()).build();
- }
-
- /**
- * Create a bundle for testing purpose.
- *
- * @return the newly created bundle.
- */
- public static Bundle createTestBundle() {
- Bundle bundle = new Bundle();
- bundle.putString("test_key", "test_value");
- return bundle;
- }
-
- /**
- * Handler that always waits until the Runnable finishes.
- */
- public static class SyncHandler extends Handler {
- public SyncHandler(Looper looper) {
- super(looper);
- }
-
- public void postAndSync(final Runnable runnable) throws InterruptedException {
- if (getLooper() == Looper.myLooper()) {
- runnable.run();
- } else {
- final CountDownLatch latch = new CountDownLatch(1);
- post(new Runnable() {
- @Override
- public void run() {
- runnable.run();
- latch.countDown();
- }
- });
- assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
- }
- }
- }
-}
diff --git a/media/version-compat-tests/current/service/src/androidTest/AndroidManifest.xml b/media/version-compat-tests/current/service/src/androidTest/AndroidManifest.xml
index 0ca78fc..13c22ae 100644
--- a/media/version-compat-tests/current/service/src/androidTest/AndroidManifest.xml
+++ b/media/version-compat-tests/current/service/src/androidTest/AndroidManifest.xml
@@ -41,12 +41,5 @@
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
-
- <service android:name="androidx.media.test.service.TestHelperService">
- <intent-filter>
- <!-- Keep sync with TestHelperUtil.java -->
- <action android:name="androidx.media.test.action.TEST_HELPER"/>
- </intent-filter>
- </service>
</application>
</manifest>
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 82e55ed..3519f2f 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
@@ -85,7 +85,6 @@
import android.os.Parcel;
import android.os.ResultReceiver;
import android.os.SystemClock;
-import android.support.mediacompat.testlib.util.PollingCheck;
import android.support.test.filters.MediumTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -723,80 +722,7 @@
@Test
@SmallTest
- public void testSetVolumeWithLocalVolume() throws Exception {
- if (Build.VERSION.SDK_INT >= 21 && mAudioManager.isVolumeFixed()) {
- // This test is not eligible for this device.
- return;
- }
-
- // Here, we intentionally choose STREAM_ALARM in order not to consider
- // 'Do Not Disturb' or 'Volume limit'.
- final int stream = AudioManager.STREAM_ALARM;
- final int maxVolume = mAudioManager.getStreamMaxVolume(stream);
- final int minVolume = 0;
- if (maxVolume <= minVolume) {
- return;
- }
-
- mSession.setPlaybackToLocal(stream);
-
- final int originalVolume = mAudioManager.getStreamVolume(stream);
- final int targetVolume = originalVolume == minVolume
- ? originalVolume + 1 : originalVolume - 1;
-
- callMediaControllerMethod(SET_VOLUME_TO, targetVolume, getContext(),
- mSession.getSessionToken());
- new PollingCheck(TIME_OUT_MS) {
- @Override
- protected boolean check() {
- return targetVolume == mAudioManager.getStreamVolume(stream);
- }
- }.run();
-
- // Set back to original volume.
- mAudioManager.setStreamVolume(stream, originalVolume, 0 /* flags */);
- }
-
- @Test
- @SmallTest
- public void testAdjustVolumeWithLocalVolume() throws Exception {
- if (Build.VERSION.SDK_INT >= 21 && mAudioManager.isVolumeFixed()) {
- // This test is not eligible for this device.
- return;
- }
-
- // Here, we intentionally choose STREAM_ALARM in order not to consider
- // 'Do Not Disturb' or 'Volume limit'.
- final int stream = AudioManager.STREAM_ALARM;
- final int maxVolume = mAudioManager.getStreamMaxVolume(stream);
- final int minVolume = 0;
- if (maxVolume <= minVolume) {
- return;
- }
-
- mSession.setPlaybackToLocal(stream);
-
- final int originalVolume = mAudioManager.getStreamVolume(stream);
- final int direction = originalVolume == minVolume
- ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER;
- final int targetVolume = originalVolume + direction;
-
- callMediaControllerMethod(ADJUST_VOLUME, direction, getContext(),
- mSession.getSessionToken());
- new PollingCheck(TIME_OUT_MS) {
- @Override
- protected boolean check() {
- return targetVolume == mAudioManager.getStreamVolume(stream);
- }
- }.run();
-
- // Set back to original volume.
- mAudioManager.setStreamVolume(stream, originalVolume, 0 /* flags */);
- }
-
- @Test
- @SmallTest
- public void testRemoteVolumeControl() throws Exception {
+ public void testVolumeControl() throws Exception {
if (android.os.Build.VERSION.SDK_INT < 27) {
// This test causes an Exception on System UI in API < 27.
return;
diff --git a/media/version-compat-tests/current/service/src/androidTest/java/androidx/media/test/service/MockPlayer.java b/media/version-compat-tests/current/service/src/androidTest/java/androidx/media/test/service/MockPlayer.java
deleted file mode 100644
index 14f1a96..0000000
--- a/media/version-compat-tests/current/service/src/androidTest/java/androidx/media/test/service/MockPlayer.java
+++ /dev/null
@@ -1,296 +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.media.test.service;
-
-import androidx.annotation.NonNull;
-import androidx.collection.ArrayMap;
-import androidx.media.AudioAttributesCompat;
-import androidx.media.DataSourceDesc;
-import androidx.media.MediaPlayerInterface;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-
-/**
- * A mock implementation of {@link MediaPlayerInterface} for testing.
- */
-public class MockPlayer extends MediaPlayerInterface {
- public final CountDownLatch mCountDownLatch;
-
- public boolean mPlayCalled;
- public boolean mPauseCalled;
- public boolean mResetCalled;
- public boolean mPrepareCalled;
- public boolean mSeekToCalled;
- public boolean mSetPlaybackSpeedCalled;
- public long mSeekPosition;
- public long mCurrentPosition;
- public long mBufferedPosition;
- public float mPlaybackSpeed = 1.0f;
- public @PlayerState int mLastPlayerState;
- public @BuffState int mLastBufferingState;
- public long mDuration;
-
- public ArrayMap<PlayerEventCallback, Executor> mCallbacks = new ArrayMap<>();
-
- private AudioAttributesCompat mAudioAttributes;
-
- public MockPlayer(int count) {
- mCountDownLatch = (count > 0) ? new CountDownLatch(count) : null;
- }
-
- @Override
- public void close() {
- // no-op
- }
-
- @Override
- public void reset() {
- mResetCalled = true;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void play() {
- mPlayCalled = true;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void pause() {
- mPauseCalled = true;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void prepare() {
- mPrepareCalled = true;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void seekTo(long pos) {
- mSeekToCalled = true;
- mSeekPosition = pos;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void skipToNext() {
- // No-op. This skipToNext() means 'skip to next item in the setNextDataSources()'
- }
-
- @Override
- public int getPlayerState() {
- return mLastPlayerState;
- }
-
- @Override
- public long getCurrentPosition() {
- return mCurrentPosition;
- }
-
- @Override
- public long getBufferedPosition() {
- return mBufferedPosition;
- }
-
- @Override
- public float getPlaybackSpeed() {
- return mPlaybackSpeed;
- }
-
- @Override
- public int getBufferingState() {
- return mLastBufferingState;
- }
-
- @Override
- public long getDuration() {
- return mDuration;
- }
-
- @Override
- public void registerPlayerEventCallback(@NonNull Executor executor,
- @NonNull PlayerEventCallback callback) {
- if (callback == null || executor == null) {
- throw new IllegalArgumentException("callback=" + callback + " executor=" + executor);
- }
- mCallbacks.put(callback, executor);
- }
-
- @Override
- public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback callback) {
- mCallbacks.remove(callback);
- }
-
- public void notifyPlaybackState(final int state) {
- mLastPlayerState = state;
- 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.onPlayerStateChanged(MockPlayer.this, state);
- }
- });
- }
- }
-
- public void notifyCurrentDataSourceChanged(final DataSourceDesc dsd) {
- 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.onCurrentDataSourceChanged(MockPlayer.this, dsd);
- }
- });
- }
- }
-
- public void notifyMediaPrepared(final DataSourceDesc dsd) {
- 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.onMediaPrepared(MockPlayer.this, dsd);
- }
- });
- }
- }
-
- public void notifyBufferingStateChanged(final DataSourceDesc dsd,
- final @BuffState int buffState) {
- 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, dsd, buffState);
- }
- });
- }
- }
-
- public void notifyPlaybackSpeedChanged(final float speed) {
- 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.onPlaybackSpeedChanged(MockPlayer.this, speed);
- }
- });
- }
- }
-
- 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);
- final Executor executor = mCallbacks.valueAt(i);
- // TODO: Uncomment or remove
- //executor.execute(() -> callback.onError(null, what, 0));
- }
- }
-
- @Override
- public void setAudioAttributes(AudioAttributesCompat attributes) {
- mAudioAttributes = attributes;
- }
-
- @Override
- public AudioAttributesCompat getAudioAttributes() {
- return mAudioAttributes;
- }
-
- @Override
- public void setDataSource(@NonNull DataSourceDesc dsd) {
- // TODO: Implement this
- }
-
- @Override
- public void setNextDataSource(@NonNull DataSourceDesc dsd) {
- // TODO: Implement this
- }
-
- @Override
- public void setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
- // TODO: Implement this
- }
-
- @Override
- public DataSourceDesc getCurrentDataSource() {
- // TODO: Implement this
- return null;
- }
-
- @Override
- public void loopCurrent(boolean loop) {
- // TODO: implement this
- }
-
- @Override
- public void setPlaybackSpeed(float speed) {
- mSetPlaybackSpeedCalled = true;
- mPlaybackSpeed = speed;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- @Override
- public void setPlayerVolume(float volume) {
- // TODO: implement this
- }
-
- @Override
- public float getPlayerVolume() {
- // TODO: implement this
- return -1;
- }
-}
diff --git a/media/version-compat-tests/current/service/src/androidTest/java/androidx/media/test/service/TestHelperService.java b/media/version-compat-tests/current/service/src/androidTest/java/androidx/media/test/service/TestHelperService.java
deleted file mode 100644
index 8df40b9..0000000
--- a/media/version-compat-tests/current/service/src/androidTest/java/androidx/media/test/service/TestHelperService.java
+++ /dev/null
@@ -1,76 +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.media.test.service;
-
-import static androidx.media.test.lib.TestHelperUtil.ACTION_TEST_HELPER;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.support.mediacompat.testlib.ITestHelperForServiceApp;
-
-import androidx.media.MediaSession2;
-
-/**
- * A Service that creates {@link MediaSession2} and calls its methods according to the client app's
- * requests.
- */
-public class TestHelperService extends Service {
-
- MediaSession2 mSession2;
- ServiceBinder mBinder;
-
- @Override
- public void onCreate() {
- super.onCreate();
- mBinder = new ServiceBinder();
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- if (ACTION_TEST_HELPER.equals(intent.getAction())) {
- return mBinder;
- }
- return null;
- }
-
- private class ServiceBinder extends ITestHelperForServiceApp.Stub {
- @Override
- public Bundle getSessionToken2(String testName) throws RemoteException {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
-
- // TODO: Create the right session according to testName, and return its token here.
- mSession2 = new MediaSession2.Builder(TestHelperService.this)
- .setPlayer(new MockPlayer(0))
- .build();
- return mSession2.getToken().toBundle();
- }
-
- @Override
- public void callMediaSession2Method(int method, Bundle args) throws RemoteException {
- // TODO: Call appropriate method (mSession2.~~~)
- }
-
- // TODO: call(MediaPlayerBase/Agent)Method may be also needed.
- // If so, do not create mPlayer/mAgent, but get them from mSession.getPlayer()/getAgent().
- }
-}
diff --git a/media/version-compat-tests/lib/src/main/aidl/android/support/mediacompat/testlib/ITestHelperForServiceApp.aidl b/media/version-compat-tests/lib/src/main/aidl/android/support/mediacompat/testlib/ITestHelperForServiceApp.aidl
deleted file mode 100644
index d12e8ca..0000000
--- a/media/version-compat-tests/lib/src/main/aidl/android/support/mediacompat/testlib/ITestHelperForServiceApp.aidl
+++ /dev/null
@@ -1,25 +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 android.support.mediacompat.testlib;
-
-import android.os.Bundle;
-
-interface ITestHelperForServiceApp {
-
- Bundle getSessionToken2(String testName);
- void callMediaSession2Method(int method, in Bundle args);
-}
diff --git a/media/version-compat-tests/lib/src/main/java/androidx/media/test/lib/TestHelperUtil.java b/media/version-compat-tests/lib/src/main/java/androidx/media/test/lib/TestHelperUtil.java
deleted file mode 100644
index 9cc68b5..0000000
--- a/media/version-compat-tests/lib/src/main/java/androidx/media/test/lib/TestHelperUtil.java
+++ /dev/null
@@ -1,34 +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.media.test.lib;
-
-import android.content.ComponentName;
-import android.support.mediacompat.testlib.util.IntentUtil;
-
-/**
- * Methods and constants used for calling methods between client and service apps by using
- * TestHelper/TestHelperService.
- */
-public class TestHelperUtil {
- public static final ComponentName SERVICE_TEST_HELPER_COMPONENT_NAME = new ComponentName(
- IntentUtil.SERVICE_PACKAGE_NAME, "androidx.media.test.service.TestHelperService");
-
- public static final String ACTION_TEST_HELPER = "androidx.media.action.test.TEST_HELPER";
-
- private TestHelperUtil() {
- }
-}
diff --git a/mediarouter/src/main/res/values-af/strings.xml b/mediarouter/src/main/res/values-af/strings.xml
index f2f054d..1968699 100644
--- a/mediarouter/src/main/res/values-af/strings.xml
+++ b/mediarouter/src/main/res/values-af/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">"Stelsel"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Toestelle"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Uitsaai-knoppie"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Uitsaai-knoppie. Ontkoppel"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Uitsaai-knoppie. Koppel tans"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Uitsaai-knoppie. Gekoppel"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Saai uit na"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Soek tans toestelle"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Ontkoppel"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Hou op uitsaai"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Maak toe"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Speel"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Onderbreek"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Stop"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Vou uit"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Vou in"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albumkunswerk"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Volumeglyer"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Geen media is gekies nie"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Geen inligting is beskikbaar nie"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Saai tans skerm uit"</string>
+ <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
index 06ec198..5e4eb42 100644
--- a/mediarouter/src/main/res/values-am/strings.xml
+++ b/mediarouter/src/main/res/values-am/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">"ሥርዓት"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"መሣሪያዎች"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"የCast አዝራር"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast አዝራር። ግንኙነት ተቋርጧል"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"የCast አዝራር። በመገናኘት ላይ"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"የCast አዝራር። ተገናኝቷል"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Cast አድርግ ወደ"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"መሣሪያዎችን በማግኘት ላይ"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ግንኙነት አቋርጥ"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Cast ማድረግ አቁም"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"ዝጋ"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"አጫውት"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"ባለበት አቁም"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"አቁም"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"ዘርጋ"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"ሰብስብ"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"የአልበም ስነ-ጥበብ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"ተንሸራታች የድምፅ መቆጣጠሪያ"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"ምንም ማህደረ መረጃ አልተመረጠም"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"ምንም መረጃ አይገኝም"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"ማያ ገጽን Cast በማድረግ ላይ"</string>
+ <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
index 6ff046b..12a6df3 100644
--- a/mediarouter/src/main/res/values-ar/strings.xml
+++ b/mediarouter/src/main/res/values-ar/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">"النظام"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"الأجهزة"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"زر الإرسال"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"زر الإرسال. تم قطع الاتصال"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"زر الإرسال. جارٍ الاتصال"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"زر الإرسال. تم الاتصال"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"إرسال إلى"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"جارٍ البحث عن أجهزة"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"قطع اتصال"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"إيقاف الإرسال"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"إغلاق"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"تشغيل"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"إيقاف مؤقت"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"إيقاف"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"توسيع"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"تصغير"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"صورة الألبوم"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"شريط تمرير مستوى الصوت"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"لم يتم اختيار أي وسائط"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"لا تتوفر أي معلومات"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"جارٍ إرسال الشاشة"</string>
+ <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-as/strings.xml b/mediarouter/src/main/res/values-as/strings.xml
deleted file mode 100644
index 792c255..0000000
--- a/mediarouter/src/main/res/values-as/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?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="3117964881088969586">"ছিষ্টেম"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"ডিভাইচসমূহ"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"কাষ্ট বুটাম"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"কাষ্ট বুটাম। সংযোগ বিচ্ছিন্ন কৰা হ’ল"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"কাষ্ট বুটাম। সংযোগ কৰি থকা হৈছে"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"কাষ্ট বুটাম। সংযোগ কৰা হ’ল"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"ইয়াত কাষ্ট কৰক"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"ডিভাইচ বিচাৰি থকা হৈছে"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"বিচ্ছিন্ন কৰক"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"কাষ্ট কৰা বন্ধ কৰক"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"বন্ধ কৰক"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"প্লে কৰক"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"পজ কৰক"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"ৰখাওক"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"বিস্তাৰ কৰক"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"সংকুচিত কৰক"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"এলবাম আৰ্ট"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"ধ্বনি শ্লাইডাৰ"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"কোনো মিডিয়া বাছনি কৰা হোৱা নাই"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"কোনো তথ্য নাই"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"স্ক্ৰীণ কাষ্ট কৰি থকা হৈছে"</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
index 91ee101..805709b 100644
--- a/mediarouter/src/main/res/values-b+sr+Latn/strings.xml
+++ b/mediarouter/src/main/res/values-b+sr+Latn/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">"Uređaji"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Dugme Prebaci"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Dugme Prebaci. Veza je prekinuta"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Dugme Prebaci. Povezuje se"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Dugme Prebaci. Povezan je"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Prebacite na"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Traže se uređaji"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Prekini vezu"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Zaustavi prebacivanje"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Zatvori"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Pusti"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pauziraj"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Zaustavi"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Proširi"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Skupi"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Omot albuma"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Klizač za jačinu zvuka"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nema izabranih medija"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nema dostupnih informacija"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Prebacuje se ekran"</string>
+ <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
index 208b225..b0ae4d5 100644
--- a/mediarouter/src/main/res/values-be/strings.xml
+++ b/mediarouter/src/main/res/values-be/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">"Сістэма"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Прылады"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Кнопка трансляцыі"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Кнопка трансляцыі. Прылада адлучана"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Кнопка трансляцыі. Прылада злучаецца"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Кнопка трансляцыі. Прылада злучана"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Трансліраваць на прыладу"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Пошук прылад"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Адлучыць"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Спыніць трансляцыю"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Закрыць"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Прайграць"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Прыпыніць"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Спыніць"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Разгарнуць"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Згарнуць"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Вокладка альбома"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Рэгулятар гучнасці"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Мультымедыя не выбрана"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Інфармацыя адсутнічае"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Трансліруецца змесціва экрана"</string>
+ <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
index 03048a1..7491533 100644
--- a/mediarouter/src/main/res/values-bg/strings.xml
+++ b/mediarouter/src/main/res/values-bg/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">"Система"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Устройства"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Бутон за предаване"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Бутон за предаване. Връзката е прекратена"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Бутон за предаване. Установява се връзка"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Бутон за предаване. Установена е връзка"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Предаване към"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Търсят се устройства"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Прекратяване на връзката"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Спиране на предаването"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Затваряне"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Възпроизвеждане"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Поставяне на пауза"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Спиране"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Разгъване"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Свиване"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Обложка на албума"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Плъзгач за силата на звука"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Няма избрана мултимедия"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Няма налична информация"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Екранът се предава"</string>
+ <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
index 15f0f52..b3ed757 100644
--- a/mediarouter/src/main/res/values-bn/strings.xml
+++ b/mediarouter/src/main/res/values-bn/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">"সিস্টেম"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"ডিভাইস"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"কাস্ট করার বোতাম"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"কাস্ট করার বোতাম। কানেক্ট করা নেই"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"কাস্ট করার বোতাম। কানেক্ট করা হচ্ছে"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"কাস্ট করার বোতাম। কানেক্ট হয়েছে"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"এখানে কাস্ট করুন:"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"ডিভাইস খোঁজা হচ্ছে"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"কানেকশন বিচ্ছিন্ন করুন"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"কাস্ট করা বন্ধ করুন"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"বন্ধ করুন"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"চালান"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"পজ করুন"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"থামান"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"বড় করে দেখুন"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"আড়াল করুন"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"অ্যালবাম আর্ট"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"ভলিউম স্লাইডার"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"কোনও মিডিয়া বেছে নেননি"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"কোনও তথ্য নেই"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"স্ক্রিন কাস্ট করা হচ্ছে"</string>
+ <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
index 11ba502..553efdf 100644
--- a/mediarouter/src/main/res/values-bs/strings.xml
+++ b/mediarouter/src/main/res/values-bs/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">"Uređaji"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Dugme za emitiranje"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Dugme za emitiranje. Veza je prekinuta"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Dugme za emitiranje. Povezivanje"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Dugme za emitiranje. Povezano"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Emitiranje na"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Traženje uređaja"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Prekini vezu"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Zaustavi emitiranje"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Zatvori"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Pokreni"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pauziraj"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Zaustavi"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Proširi"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Suzi"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Omot albuma"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Klizač za jačinu zvuka"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nije odabran nijedan medij"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nema dostupnih informacija"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Emitiranje ekrana"</string>
+ <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
index d5ea5b6..e6a2f71 100644
--- a/mediarouter/src/main/res/values-ca/strings.xml
+++ b/mediarouter/src/main/res/values-ca/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Dispositius"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Botó d\'emetre"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Botó d\'emetre. Desconnectat."</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Botó d\'emetre. S\'està connectant."</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Botó d\'emetre. Connectat."</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Emet contingut a"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"S\'estan cercant dispositius"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Desconnecta"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Atura l\'emissió"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Tanca"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Reprodueix"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Posa en pausa"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Atura"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Desplega"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Replega"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Imatge de l\'àlbum"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Control lliscant de volum"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"No hi ha contingut multimèdia seleccionat"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"No hi ha informació disponible"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"S\'està emetent la pantalla"</string>
+ <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
index d8e6c6b7..a914d34 100644
--- a/mediarouter/src/main/res/values-cs/strings.xml
+++ b/mediarouter/src/main/res/values-cs/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">"Systém"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Zařízení"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Tlačítko odesílání"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Tlačítko odesílání. Odpojeno"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Tlačítko odesílání. Připojování"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Tlačítko odesílání. Připojeno"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Odeslat do zařízení"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Hledání zařízení"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Odpojit"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Zastavit odesílání"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Zavřít"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Přehrát"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pozastavit"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Zastavit"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Rozbalit"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Sbalit"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Obal alba"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Posuvník hlasitosti"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Není vybrán žádný mediální obsah"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nejsou k dispozici žádné informace"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Odesílání obsahu obrazovky"</string>
+ <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
index 5a95576..5736cb5 100644
--- a/mediarouter/src/main/res/values-da/strings.xml
+++ b/mediarouter/src/main/res/values-da/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">"Enheder"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Cast-knap"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast-knap. Forbindelsen er afbrudt"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast-knap. Opretter forbindelse"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast-knap. Der er oprettet forbindelse"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Cast til"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Finder enheder"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Afbryd forbindelse"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Stop med at caste"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Luk"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Afspil"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Sæt på pause"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Stop"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Udvid"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Skjul"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albumgrafik"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Lydstyrkeskyder"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Ingen medier er markeret"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Der er ingen tilgængelige oplysninger"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Skærmen castes"</string>
+ <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
index e2927da..bfab0be 100644
--- a/mediarouter/src/main/res/values-de/strings.xml
+++ b/mediarouter/src/main/res/values-de/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">"Geräte"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Cast-Symbol"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast-Symbol. Nicht verbunden."</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast-Symbol. Verbindung wird hergestellt."</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast-Symbol. Verbunden."</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Streamen auf"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Geräte werden gesucht"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Trennen"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Streaming beenden"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Schließen"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Wiedergabe"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pause"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Stopp"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Maximieren"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Minimieren"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albumcover"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Schieberegler für die Lautstärke"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Keine Medien ausgewählt"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Keine Informationen verfügbar"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Bildschirm wird übertragen"</string>
+ <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
index d689f25..6290c3d 100644
--- a/mediarouter/src/main/res/values-el/strings.xml
+++ b/mediarouter/src/main/res/values-el/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">"Σύστημα"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Συσκευές"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Κουμπί μετάδοσης"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Κουμπί μετάδοσης. Αποσυνδέθηκε"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Κουμπί μετάδοσης. Σύνδεση"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Κουμπί μετάδοσης. Συνδέθηκε"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Μετάδοση σε"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Εύρεση συσκευών"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Αποσύνδεση"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Διακοπή μετάδοσης"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Κλείσιμο"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Αναπαραγωγή"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Παύση"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Διακοπή"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Ανάπτυξη"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Σύμπτυξη"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Εξώφυλλο άλμπουμ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Ρυθμιστικό έντασης ήχου"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Δεν επιλέχθηκαν μέσα"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Δεν υπάρχουν διαθέσιμες πληροφορίες"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Μετάδοση οθόνης"</string>
+ <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
index cec1175..51a2955 100644
--- a/mediarouter/src/main/res/values-es-rUS/strings.xml
+++ b/mediarouter/src/main/res/values-es-rUS/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Dispositivos"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Botón para transmitir"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Botón para transmitir (desconectado)"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Botón para transmitir (conectando)"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Botón para transmitir (conectado)"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Transmitir a"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Buscando dispositivos"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Desconectar"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Detener transmisión"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Cerrar"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Reproducir"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pausa"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Detener"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Expandir"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Contraer"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Imagen del álbum"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Control deslizante del volumen"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"No se seleccionó ningún contenido multimedia"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Sin información disponible"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Transmitiendo pantalla"</string>
+ <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
index 34de0dc..e07a751 100644
--- a/mediarouter/src/main/res/values-es/strings.xml
+++ b/mediarouter/src/main/res/values-es/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Dispositivos"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Botón de enviar"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Botón de enviar. Desconectado"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Botón de enviar. Conectando"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Botón de enviar. Conectado"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Enviar a"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Buscando dispositivos"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Desconectar"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Detener envío"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Cerrar"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Reproducir"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pausar"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Detener"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Mostrar"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Ocultar"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Carátula del álbum"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Control deslizante de volumen"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"No se ha seleccionado contenido multimedia"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"No hay información disponible"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Enviando pantalla"</string>
+ <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
index 386462a..4ff3f62 100644
--- a/mediarouter/src/main/res/values-et/strings.xml
+++ b/mediarouter/src/main/res/values-et/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">"Süsteem"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Seadmed"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Ülekandenupp"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Ülekandenupp. Ühendus on katkestatud"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Ülekandenupp. Ühendamine"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Ülekandenupp. Ühendatud"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Ülekandmine seadmesse"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Seadmete otsimine"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Katkesta ühendus"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Katkesta ülekandmine"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Sule"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Esita"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Peata"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Katkesta"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Laienda"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Ahenda"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albumi kujundus"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Helitugevuse liugur"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Meediat pole valitud"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Teave pole saadaval"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Ekraanikuva ülekandmine"</string>
+ <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
index d8749f3..18aeed3 100644
--- a/mediarouter/src/main/res/values-eu/strings.xml
+++ b/mediarouter/src/main/res/values-eu/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Gailuak"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"\"Igorri\" botoia"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"\"Igorri\" botoia. Deskonektatuta."</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"\"Igorri\" botoia. Konektatzen."</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"\"Igorri\" botoia. Konektatuta."</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Igorri hona"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Gailuak bilatzen"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Deskonektatu"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Utzi igortzeari"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Itxi"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Erreproduzitu"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pausatu"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Gelditu"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Zabaldu"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Tolestu"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albumaren azala"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Bolumenaren graduatzailea"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Ez da hautatu multimedia-edukirik"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Ez dago informaziorik"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Pantaila igortzen"</string>
+ <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
index 4c9928e..eb0ea6c 100644
--- a/mediarouter/src/main/res/values-fa/strings.xml
+++ b/mediarouter/src/main/res/values-fa/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">"سیستم"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"دستگاهها"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"دکمه فرستادن"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"دکمه فرستادن. اتصال قطع شد"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"دکمه فرستادن. درحال اتصال"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"دکمه فرستادن. متصل"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"ارسال محتوا به"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"درحال پیدا کردن دستگاهها"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"قطع اتصال"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"توقف ارسال محتوا"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"بستن"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"پخش"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"مکث"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"توقف"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"بزرگ کردن"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"کوچک کردن"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"عکس روی جلد آلبوم"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"لغزنده میزان صدا"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"رسانهای انتخاب نشده است"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"اطلاعاتی دردسترس نیست"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"صفحه ارسال محتوا"</string>
+ <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
index 6c51525..a365147 100644
--- a/mediarouter/src/main/res/values-fi/strings.xml
+++ b/mediarouter/src/main/res/values-fi/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">"Järjestelmä"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Laitteet"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Cast-painike"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast-painike. Yhteys katkaistu"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast-painike. Yhdistetään"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast-painike. Yhdistetty"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Suoratoiston kohde"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Etsitään laitteita"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Katkaise yhteys"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Lopeta suoratoisto"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Sulje"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Toista"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Keskeytä"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Pysäytä"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Laajenna"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Tiivistä"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albumin kansikuva"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Äänenvoimakkuuden liukusäädin"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Ei valittua mediaa"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Ei tietoja saatavilla"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Suoratoistetaan näyttöä"</string>
+ <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
index e5cb25e..8df9031 100644
--- a/mediarouter/src/main/res/values-fr-rCA/strings.xml
+++ b/mediarouter/src/main/res/values-fr-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">"Système"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Appareils"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Bouton Diffuser"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Bouton Diffuser. Déconnecté"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Bouton Diffuser. Connexion en cours…"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Bouton Diffuser. Connecté"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Diffuser vers"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Recherche d\'appareils en cours…"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Déconnecter"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Arrêter la diffusion"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Fermer"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Lire"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pause"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Arrêter"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Développer"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Réduire"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Image de l\'album"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Curseur de réglage du volume"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Aucun média sélectionné"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Aucune donnée trouvée"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Diffusion de l\'écran en cours…"</string>
+ <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
index 8518e0b..cfce49b 100644
--- a/mediarouter/src/main/res/values-fr/strings.xml
+++ b/mediarouter/src/main/res/values-fr/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">"Système"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Appareils"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Icône Cast"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Icône Cast. Déconnecté"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Icône Cast. Connexion…"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Icône Cast. Connecté"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Caster sur"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Recherche d\'appareils…"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Déconnecter"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Arrêter la diffusion"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Fermer"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Lecture"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pause"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Arrêt"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Développer"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Réduire"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Image de l\'album"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Curseur de volume"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Aucun contenu multimédia sélectionné"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Aucune information disponible"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Diffusion de l\'écran…"</string>
+ <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
index df0480f..2eb5e04 100644
--- a/mediarouter/src/main/res/values-gl/strings.xml
+++ b/mediarouter/src/main/res/values-gl/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Dispositivos"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Botón de emitir"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Botón de emitir. Desconectado"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Botón de emitir. Conectando"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Botón de emitir. Conectado"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Emitir en"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Buscando dispositivos"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Desconectar"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Deter emisión"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Pechar"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Reproducir"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pór en pausa"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Deter"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Despregar"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Contraer"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Portada do álbum"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Control desprazable do volume"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Non se seleccionou ningún recurso multimedia"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Non hai información dispoñible"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Emitindo pantalla"</string>
+ <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
index e83daf2..8459bcd 100644
--- a/mediarouter/src/main/res/values-gu/strings.xml
+++ b/mediarouter/src/main/res/values-gu/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">"સિસ્ટમ"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"ઉપકરણો"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"કાસ્ટ બટન"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"કાસ્ટ બટન. ડિસ્કનેક્ટેડ"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"કાસ્ટ બટન. કનેક્ટ કરી રહ્યાં છીએ"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"કાસ્ટ બટન. કનેક્ટેડ"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"આના પર કાસ્ટ કરો"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"ઉપકરણો શોધી રહ્યાં છીએ"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ડિસ્કનેક્ટ કરો"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"કાસ્ટ કરવાનું રોકો"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"બંધ કરો"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"ચલાવો"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"થોભાવો"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"રોકો"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"વિસ્તાર કરો"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"સંકુચિત કરો"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"આલ્બમ આર્ટ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"વૉલ્યુમ સ્લાઇડર"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"કોઈ મીડિયા પસંદ કરેલ નથી"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"કોઈ માહિતી ઉપલબ્ધ નથી"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"સ્ક્રીનને કાસ્ટ કરી રહ્યાં છીએ"</string>
+ <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
index 5026adc..891d765 100644
--- a/mediarouter/src/main/res/values-hi/strings.xml
+++ b/mediarouter/src/main/res/values-hi/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">"सिस्टम"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"डिवाइस"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"कास्ट बटन"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"कास्ट बटन. डिसकनेक्ट हो गया"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"कास्ट बटन. कनेक्ट हो रहा है"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"कास्ट बटन. कनेक्ट हो गया"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"इस पर कास्ट करें"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"डिवाइस ढूंढे जा रहे हैं"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"डिसकनेक्ट करें"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"कास्ट करना रोकें"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"बंद करें"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"चलाएं"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"रोकें"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"बंद करें"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"बड़ा करके देखें"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"छोटा करें"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"एल्बम आर्ट"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"आवाज़ बढ़ाने या घटाने वाला स्लाइडर"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"कोई मीडिया नहीं चुना गया"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"कोई जानकारी मौजूद नहीं है"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"स्क्रीन कास्ट की जा रही है"</string>
+ <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
index 425cf36..e17a0e75 100644
--- a/mediarouter/src/main/res/values-hr/strings.xml
+++ b/mediarouter/src/main/res/values-hr/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">"Sustav"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Uređaji"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Gumb za emitiranje"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Gumb za emitiranje. Veza prekinuta"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Gumb za emitiranje. Povezivanje"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Gumb za emitiranje. Povezan"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Emitiranje na"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Traženje uređaja"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Prekini vezu"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Zaustavi emitiranje"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Zatvori"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Reproduciraj"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pauziraj"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Zaustavi"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Proširi"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Sažmi"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Naslovnica albuma"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Klizač za glasnoću"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nije odabran nijedan medij"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Informacije nisu dostupne"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Emitiranje zaslona"</string>
+ <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
index 7d47861..a9f80f4 100644
--- a/mediarouter/src/main/res/values-hu/strings.xml
+++ b/mediarouter/src/main/res/values-hu/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">"Rendszer"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Eszközök"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Átküldés gomb"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Átküldés gomb. Kapcsolat bontva"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Átküldés gomb. Csatlakozás"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Átküldés gomb. Csatlakoztatva"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Átküldés ide:"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Eszközök keresése"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Leválasztás"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Átküldés leállítása"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Bezárás"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Lejátszás"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Szünet"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Leállítás"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Kibontás"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Összecsukás"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Lemezborító"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Hangerőszabályzó"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nincs kiválasztott médiatartalom"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nincs információ"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Képernyőtartalom átküldése…"</string>
+ <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
index 77cba70..e48fac5 100644
--- a/mediarouter/src/main/res/values-hy/strings.xml
+++ b/mediarouter/src/main/res/values-hy/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">"Համակարգ"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Սարքեր"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Հեռարձակման կոճակ"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Հեռարձակման կոճակ: Սարքն անջատած է:"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Հեռարձակման կոճակ: Սարքը միանում է:"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Հեռարձակման կոճակ: Սարքը միացված է:"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Ընտրեք սարք"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Սարքերի որոնում"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Անջատել"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Դադարեցնել հեռարձակումը"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Փակել"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Նվագարկել"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Դադարեցնել"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Կանգնեցնել"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Ծավալել"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Ծալել"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Ալբոմի շապիկ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Ձայնի ուժգնության կարգավորիչ"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Մեդիա ֆայլ չի ընտրվել"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Տեղեկություններ չկան"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Էկրանի հեռարձակում"</string>
+ <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
index 777f85b..5a19254 100644
--- a/mediarouter/src/main/res/values-in/strings.xml
+++ b/mediarouter/src/main/res/values-in/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">"Perangkat"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Tombol Cast"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Tombol Cast. Terputus"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Tombol Cast. Menghubungkan"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Tombol Cast. Terhubung"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Cast ke"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Mencari perangkat"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Putuskan hubungan"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Hentikan cast"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Tutup"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Putar"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Jeda"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Berhenti"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Luaskan"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Ciutkan"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Sampul album"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Penggeser volume"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Tidak ada media yang dipilih"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Tidak ada info yang tersedia"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Melakukan cast layar"</string>
+ <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
index 66334e4..bc3c36d 100644
--- a/mediarouter/src/main/res/values-is/strings.xml
+++ b/mediarouter/src/main/res/values-is/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">"Kerfi"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Tæki"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Útsendingarhnappur"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Útsendingarhnappur. Aftengt"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Útsendingarhnappur. Tengist"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Útsendingarhnappur. Tengt"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Senda út í"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Leitað að tækjum"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Aftengja"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Stöðva útsendingu"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Loka"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Spila"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Gera hlé"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Stöðva"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Stækka"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Draga saman"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Plötuumslag"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Hljóðstyrkssleði"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Ekkert efni valið"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Engar upplýsingar í boði"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Skjár sendur út"</string>
+ <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
index 845ce6f..3bbfecd 100644
--- a/mediarouter/src/main/res/values-it/strings.xml
+++ b/mediarouter/src/main/res/values-it/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Dispositivi"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Pulsante Trasmetti"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Pulsante Trasmetti. Disconnesso"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Pulsante Trasmetti. Connessione in corso"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Pulsante Trasmetti. Connesso"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Trasmetti a"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Ricerca di dispositivi"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Disconnetti"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Interrompi trasmissione"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Chiudi"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Riproduci"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Metti in pausa"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Interrompi"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Espandi"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Comprimi"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Copertina dell\'album"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Dispositivo di scorrimento del volume"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nessun contenuto multimediale selezionato"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nessuna informazione disponibile"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Trasmissione dello schermo attiva"</string>
+ <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
index 30e60d5..72ebc9c 100644
--- a/mediarouter/src/main/res/values-iw/strings.xml
+++ b/mediarouter/src/main/res/values-iw/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">"מערכת"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"מכשירים"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"לחצן הפעלת Cast"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"לחצן הפעלת Cast. מנותק"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"לחצן הפעלת Cast. מתחבר"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"לחצן הפעלת Cast. מחובר"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"העברה אל"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"מתבצע חיפוש מכשירים"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ניתוק"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"עצירת העברה"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"סגירה"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"הפעלה"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"השהיה"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"הפסקה"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"הרחבה"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"כיווץ"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"עטיפת אלבום"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"מחוון עוצמה"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"לא נבחרה מדיה"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"אין מידע זמין"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"העברת מסך מתבצעת"</string>
+ <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
index 74bf75c..b33ffb90 100644
--- a/mediarouter/src/main/res/values-ja/strings.xml
+++ b/mediarouter/src/main/res/values-ja/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">"システム"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"端末"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"キャスト アイコン"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"キャスト アイコン。接続解除済み"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"キャスト アイコン。接続中"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"キャスト アイコン。接続済み"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"キャスト先"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"端末を検出しています"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"接続を解除"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"キャストを停止"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"閉じる"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"再生"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"一時停止"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"停止"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"展開"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"折りたたむ"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"アルバムアート"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"音量スライダー"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"メディアが選択されていません"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"情報がありません"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"画面をキャストしています"</string>
+ <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
index 7ee094e..446a9e0 100644
--- a/mediarouter/src/main/res/values-ka/strings.xml
+++ b/mediarouter/src/main/res/values-ka/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">"სისტემა"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"მოწყობილობები"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"ტრანსლირების ღილაკი"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"ტრანსლირების ღილაკი. გათიშული"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"ტრანსლირების ღილაკი. მიმდინარეობს დაკავშირება"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"ტრანსლირების ღილაკი. დაკავშირებული"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"ტრანსლირება"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"მიმდინარეობს მოწყობილობების მოძიება"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"გათიშვა"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"ტრანსლირების შეწყვეტა"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"დახურვა"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"დაკვრა"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"პაუზა"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"შეწყვეტა"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"გაშლა"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"ჩაკეცვა"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ალბომის გარეკანი"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"ხმის სლაიდერი"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"მედია არჩეული არ არის"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"ინფორმაცია არ არის ხელმისაწვდომი"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"მიმდინარეობს ეკრანის ტრანსლირება"</string>
+ <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
index d107272..d512ff9 100644
--- a/mediarouter/src/main/res/values-kk/strings.xml
+++ b/mediarouter/src/main/res/values-kk/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">"Жүйе"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Құрылғылар"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Трансляциялау түймесі"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Трансляциялау түймесі. Ажыратылды"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Трансляциялау түймесі. Қосылуда"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Трансляциялау түймесі. Қосылды"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Келесіге трансляциялау:"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Құрылғылар ізделуде"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Ажырату"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Трансляцияны тоқтату"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Жабу"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Ойнату"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Кідірту"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Тоқтату"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Жаю"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Жию"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Альбомның мұқабасы"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Дыбыс деңгейінің жүгірткісі"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Ешқандай медиафайл таңдалмаған"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Ешқандай ақпарат жоқ"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Экран трансляциялануда"</string>
+ <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
index eb8a3467..9303a1b 100644
--- a/mediarouter/src/main/res/values-km/strings.xml
+++ b/mediarouter/src/main/res/values-km/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">"ប្រព័ន្ធ"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"ឧបករណ៍"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"ប៊ូតុងបញ្ជូន"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"ប៊ូតុងបញ្ជូន។ បានផ្តាច់"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"ប៊ូតុងបញ្ជូន។ កំពុងភ្ជាប់"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"ប៊ូតុងបញ្ជូន។ បានភ្ជាប់ហើយ"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"បញ្ជូនទៅ"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"កំពុងស្វែងរកឧបករណ៍"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ផ្ដាច់"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"ឈប់ភ្ជាប់"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"បិទ"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"លេង"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"ផ្អាក"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"ឈប់"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"ពង្រីក"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"បង្រួម"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"រូបភាពសិល្បៈក្របអាល់ប៊ុម"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"របារកម្រិតសំឡេង"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"មិនបានជ្រើសរើសមេឌៀទេ"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"មិនមានព័ត៌មានទេ"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"កំពុងបញ្ជូនអេក្រង់"</string>
+ <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
index fd8b1fd..f495017 100644
--- a/mediarouter/src/main/res/values-kn/strings.xml
+++ b/mediarouter/src/main/res/values-kn/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">"ಸಿಸ್ಟಂ"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"ಸಾಧನಗಳು"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"ಬಿತ್ತರಿಸು ಬಟನ್"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"ಬಿತ್ತರಿಸು ಬಟನ್. ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"ಬಿತ್ತರಿಸು ಬಟನ್. ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"ಬಿತ್ತರಿಸು ಬಟನ್. ಸಂಪರ್ಕಿತಗೊಂಡಿದೆ"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"ಇದಕ್ಕೆ ಬಿತ್ತರಿಸಿ"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"ಸಾಧನಗಳನ್ನು ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿ"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"ಮುಚ್ಚಿ"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"ಪ್ಲೇ"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"ವಿರಾಮ"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"ನಿಲ್ಲಿಸಿ"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"ಹಿಗ್ಗಿಸಿ"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"ಕುಗ್ಗಿಸಿ"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ಆಲ್ಬಮ್ ಕಲೆ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"ವಾಲ್ಯೂಮ್ ಸ್ಲೈಡರ್"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"ಯಾವುದೇ ಮಾಧ್ಯಮವನ್ನು ಆಯ್ಕೆ ಮಾಡಿಲ್ಲ"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"ಯಾವುದೇ ಮಾಹಿತಿ ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"ಪರದೆಯನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
+ <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
index f2e926f..178fab0 100644
--- a/mediarouter/src/main/res/values-ko/strings.xml
+++ b/mediarouter/src/main/res/values-ko/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">"시스템"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"기기"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"전송 버튼"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"전송 버튼. 연결 해제됨"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"전송 버튼. 연결 중"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"전송 버튼. 연결됨"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"전송 대상"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"기기를 찾는 중"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"연결 해제"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"전송 중지"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"닫기"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"재생"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"일시중지"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"중지"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"펼치기"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"접기"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"앨범아트"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"볼륨 슬라이더"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"선택된 미디어 없음"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"사용할 수 있는 정보 없음"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"화면 전송 중"</string>
+ <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
index 2e4fcd8..100e5a5 100644
--- a/mediarouter/src/main/res/values-ky/strings.xml
+++ b/mediarouter/src/main/res/values-ky/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">"Тутум"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Түзмөктөр"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Тышкы экранга чыгаруу баскычы"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Тышкы экранга чыгаруу баскычы. Түзмөк ажырап турат."</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Тышкы экранга чыгаруу баскычы. Түзмөк туташууда"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Тышкы экранга чыгаруу баскычы. Түзмөк туташып турат"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Түзмөккө чыгаруу"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Түзмөктөр изделүүдө"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Ажыратуу"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Тышкы экранга чыгарууну токтотуу"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Жабуу"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Ойнотуу"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Тындыруу"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Токтотуу"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Жайып көрсөтүү"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Жыйыштыруу"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Альбом мукабасы"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Үн башкаруучу сыдырма"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Эч нерсе тандалган жок"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Эч маалымат жок"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Тышкы экранга чыгарылууда"</string>
+ <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
index 0b52b24..79bd210 100644
--- a/mediarouter/src/main/res/values-lo/strings.xml
+++ b/mediarouter/src/main/res/values-lo/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">"ລະບົບ"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"ອຸປະກອນ"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"ປຸ່ມສົ່ງສັນຍານ"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"ປຸ່ມສົ່ງສັນຍານ. ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"ປຸ່ມສົ່ງສັນຍານ. ກຳລັງເຊື່ອມຕໍ່"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"ປຸ່ມສົ່ງສັນຍານ. ເຊື່ອມຕໍ່ແລ້ວ"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"ສົ່ງສັນຍານໄປທີ່"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"ກຳລັງຊອກຫາອຸປະກອນ"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ຕັດການເຊື່ອມຕໍ່"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"ຢຸດການສົ່ງສັນຍານ"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"ປິດ"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"ຫຼິ້ນ"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"ຢຸດຊົ່ວຄາວ"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"ຢຸດ"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"ຂະຫຍາຍ"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"ຫຍໍ້ລົງ"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ໜ້າປົກອະລະບໍ້າ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"ຕົວປັບລະດັບສຽງ"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"ບໍ່ໄດ້ເລືອກສື່ໃດ"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"ບໍ່ມີຂໍ້ມູນ"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"ກຳລັງສົ່ງສັນຍານພາບ"</string>
+ <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
index 1108c32..6f1ce9f 100644
--- a/mediarouter/src/main/res/values-lt/strings.xml
+++ b/mediarouter/src/main/res/values-lt/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Įrenginiai"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Perdavimo mygtukas"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Perdavimo mygtukas. Atsijungta"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Perdavimo mygtukas. Prisijungiama"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Perdavimo mygtukas. Prisijungta"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Perduoti į"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Randami įrenginiai"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Atjungti"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Sustabdyti perdavimą"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Uždaryti"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Leisti"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pristabdyti"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Sustabdyti"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Išskleisti"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Sutraukti"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albumo viršelis"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Garsumo šliaužiklis"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nepasirinkta jokios medijos"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Informacija nepasiekiama"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Perduodamas ekranas"</string>
+ <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
index 950b3dc..56432f8 100644
--- a/mediarouter/src/main/res/values-lv/strings.xml
+++ b/mediarouter/src/main/res/values-lv/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">"Sistēma"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Ierīces"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Apraides poga"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Apraides poga. Savienojums pārtraukts."</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Apraides poga. Notiek savienojuma izveide."</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Apraides poga. Savienojums izveidots."</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Apraides veikšana uz ierīci"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Notiek ierīču meklēšana"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Atvienot"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Pārtraukt apraidi"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Aizvērt"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Atskaņot"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pauzēt"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Apturēt"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Izvērst"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Sakļaut"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albuma noformējums"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Skaļuma slīdnis"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nav atlasīts multivides saturs"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nav informācijas"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Notiek ekrāna apraide"</string>
+ <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
index 5739525..e4572c5 100644
--- a/mediarouter/src/main/res/values-mk/strings.xml
+++ b/mediarouter/src/main/res/values-mk/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">"Систем"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Уреди"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Копче за Cast"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Копче за Cast. Исклучено"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Копче за Cast. Се поврзува"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Копче за Cast. Поврзано"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Емитување на"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Се бараат уреди"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Исклучи"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Сопри со емитување"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Затвори"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Пушти"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Пауза"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Запри"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Прошири"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Собери"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Омот на албум"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Лизгач за јачина на звук"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Не се избрани аудиовизуелни датотеки"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Нема достапни информации"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Се емитува екран"</string>
+ <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
index 7d48372..d7c987b 100644
--- a/mediarouter/src/main/res/values-ml/strings.xml
+++ b/mediarouter/src/main/res/values-ml/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">"സിസ്റ്റം"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"ഉപകരണങ്ങൾ"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"കാസ്റ്റ് ബട്ടൺ"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"കാസ്റ്റ് ബട്ടൺ. വിച്ഛേദിച്ചു"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"കാസ്റ്റ് ബട്ടൺ. കണക്റ്റ് ചെയ്യുന്നു"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"കാസ്റ്റ് ബട്ടൺ. കണക്റ്റ് ചെയ്തു"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"ഇതിലേക്ക് കാസ്റ്റ് ചെയ്യുക"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"ഉപകരണങ്ങൾ കണ്ടെത്തുന്നു"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"വിച്ഛേദിക്കുക"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"കാസ്റ്റ് ചെയ്യുന്നത് നിർത്തുക"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"അടയ്ക്കുക"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"പ്ലേ ചെയ്യുക"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"തൽക്കാലം നിർത്തുക"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"നിര്ത്തുക"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"വികസിപ്പിക്കുക"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"ചുരുക്കുക"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ആൽബം ആർട്ട്"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"വോളിയം സ്ലൈഡർ"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"മീഡിയയൊന്നും തിരഞ്ഞെടുത്തിട്ടില്ല"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"വിവരങ്ങളൊന്നും ലഭ്യമല്ല"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"സ്ക്രീൻ കാസ്റ്റ് ചെയ്യുന്നു"</string>
+ <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
index 84d128f..9f03518 100644
--- a/mediarouter/src/main/res/values-mn/strings.xml
+++ b/mediarouter/src/main/res/values-mn/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">"Систем"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Төхөөрөмжүүд"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Дамжуулах товчлуур"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Дамжуулах товчлуур. Салсан"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Дамжуулах товчлуур. Холбогдож байна"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Дамжуулах товчлуур. Холбогдсон"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Дараахад дамжуулах"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Төхөөрөмжүүдийг хайж байна"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Салгах"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Дамжуулахыг зогсоох"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Хаах"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Тоглуулах"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Түр зогсоох"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Зогсоох"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Дэлгэх"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Буулгах"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Цомгийн зураг"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Дууны түвшин тохируулагч"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Ямар ч медиа сонгоогүй байна"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Мэдээлэл алга"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Дэлгэцийг дамжуулж байна"</string>
+ <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
index d3a0736..f3ccbb9 100644
--- a/mediarouter/src/main/res/values-mr/strings.xml
+++ b/mediarouter/src/main/res/values-mr/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">"सिस्टम"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"डिव्हाइस"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"कास्ट बटण"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"कास्ट बटण. डिस्कनेक्ट केले आहे"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"कास्ट बटण. कनेक्ट करत आहे"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"कास्ट बटण. कनेक्ट केले आहे"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"यावर कास्ट करा"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"डिव्हाइस शोधत आहे"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"डिस्कनेक्ट करा"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"कास्ट करणे थांबवा"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"बंद"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"खेळा"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"थांबवा"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"थांबा"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"विस्तार करा"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"कोलॅप्स"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"अल्बम कला"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"व्हॉल्यूम स्लायडर"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"मीडिया निवडला नाही"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"कोणतीही माहिती उपलब्ध नाही"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"स्क्रीन कास्ट करत आहे"</string>
+ <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
index f7c0840..5096704 100644
--- a/mediarouter/src/main/res/values-ms/strings.xml
+++ b/mediarouter/src/main/res/values-ms/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">"Peranti"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Butang hantar"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Butang hantar. Sambungan diputuskan"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Butang hantar. Menyambung"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Butang hantar. Disambungkan"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Hantar ke"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Mencari peranti"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Putuskan sambungan"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Berhenti menghantar"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Tutup"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Main"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Jeda"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Berhenti"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Kembangkan"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Runtuhkan"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Seni album"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Peluncur kelantangan"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Tiada media yang dipilih"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Maklumat tidak tersedia"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Menghantar skrin"</string>
+ <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
index c6698f1..5e843a0 100644
--- a/mediarouter/src/main/res/values-my/strings.xml
+++ b/mediarouter/src/main/res/values-my/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">"စနစ်"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"စက်များ"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"ကာစ်ခလုတ်"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"ကာစ်ခလုတ်။ ချိတ်ဆက်မထားပါ"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"ကာစ်ခလုတ်။ ချိတ်ဆက်နေသည်"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"ကာစ်ခလုတ်။ ချိတ်ဆက်ထားသည်"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"ဤစက်သို့ ကာစ်လုပ်ရန်"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"စက်များကို ရှာနေသည်"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ချိတ်ဆက်မှု ဖြုတ်ရန်"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"ကာစ်လုပ်ခြင်းကို ရပ်ရန်"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"ပိတ်ရန်"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"ကစားရန်"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"ခဏရပ်ရန်"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"ရပ်ရန်"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"ချဲ့ရန်"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"လျှော့ပြရန်"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"အယ်လ်ဘမ်ပုံ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"အသံအတိုးအကျယ်ချိန်သည့် ရွှေ့တုံး"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"မီဒီယာ ရွေးမထားပါ"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"အချက်အလက် မရရှိနိုင်ပါ"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"ကာစ်တ်လုပ်သည့် မျက်နှာပြင်"</string>
+ <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
index a4a04f5..487b9d5 100644
--- a/mediarouter/src/main/res/values-nb/strings.xml
+++ b/mediarouter/src/main/res/values-nb/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">"Enheter"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Cast-ikonet"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast-ikonet. Frakoblet"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast-ikonet. Kobler til"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast-ikonet. Tilkoblet"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Cast til"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Finner enheter"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Koble fra"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Stopp castingen"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Lukk"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Spill av"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Sett på pause"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Stopp"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Vis"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Skjul"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albumgrafikk"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Glidebryter for volum"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Ingen medier er valgt"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Ingen informasjon er tilgjengelig"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Caster skjermen"</string>
+ <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
index b844aa3..8a13ac7 100644
--- a/mediarouter/src/main/res/values-ne/strings.xml
+++ b/mediarouter/src/main/res/values-ne/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">"प्रणाली"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"यन्त्रहरू"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Cast बटन"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast बटन। जडान विच्छेद गरियो"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast बटन। जडान गरिँदै छ"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast बटन। जडान गरियो"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"यसमा Cast गर्नुहोस्"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"यन्त्रहरू पत्ता लगाइँदै छ"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"विच्छेद गर्नुहोस्"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"casting रोक्नुहोस्"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"बन्द गर्नुहोस्"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"खेल्नुहोस्"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"पज गर्नुहोस्"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"रोक्नुहोस्"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"विस्तृत गर्नुहोस्"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"संक्षिप्त गर्नुहोस्"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"एल्बम आर्ट"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"भोल्युमको स्लाइडर"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"कुनै पनि मिडिया चयन गरिएन"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"कुनै पनि जानकारी उपलब्ध छैन"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"स्क्रिन Cast गरिँदै छ"</string>
+ <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
index c1279aa..eb19187 100644
--- a/mediarouter/src/main/res/values-nl/strings.xml
+++ b/mediarouter/src/main/res/values-nl/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">"Systeem"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Apparaten"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Cast-icoon"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast-icoon. Verbinding verbroken"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast-icoon. Verbinding maken"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast-icoon. Verbonden"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Casten naar"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Apparaten zoeken"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Verbinding verbreken"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Casten stoppen"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Sluiten"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Afspelen"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pauzeren"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Stoppen"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Uitvouwen"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Samenvouwen"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albumhoes"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Volumeschuifregelaar"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Geen media geselecteerd"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Geen informatie beschikbaar"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Scherm casten"</string>
+ <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-or/strings.xml b/mediarouter/src/main/res/values-or/strings.xml
deleted file mode 100644
index 05a309b..0000000
--- a/mediarouter/src/main/res/values-or/strings.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?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="3117964881088969586">"ସିଷ୍ଟମ୍"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"ଡିଭାଇସ୍"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"କାଷ୍ଟ ବଟନ୍"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"କାଷ୍ଟ ବଟନ୍। ଡିସ୍କନେକ୍ଟ ହୋଇଗଲା"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"କାଷ୍ଟ ବଟନ୍। କନେକ୍ଟ କରାଯାଉଛି"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"କାଷ୍ଟ ବଟନ୍। କନେକ୍ଟ ହୋଇଛି"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"ଏଥିରେ କାଷ୍ଟ କରନ୍ତୁ"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"ଡିଭାଇସ୍ ଖୋଜାଯାଉଛି"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ଡିସ୍କନେକ୍ଟ କରନ୍ତୁ"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"ବନ୍ଦ କରନ୍ତୁ"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"ଚଲାନ୍ତୁ"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"ପଜ୍ କରନ୍ତୁ"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"ରୋକନ୍ତୁ"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"ବିସ୍ତାର କରନ୍ତୁ"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"ସଂକୁଚିତ କରନ୍ତୁ"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ଆଲବମ୍ ଆର୍ଟ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"ଭଲ୍ୟୁମ୍ ସ୍ଲାଇଡର୍"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"କୌଣସି ମିଡିଆ ଚୟନ କରାଯାଇନାହିଁ"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"କୌଣସି ସୂଚନା ଉପଲବ୍ଧ ନାହିଁ"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"ସ୍କ୍ରୀନ୍ କାଷ୍ଟ କରାଯାଉଛି"</string>
-</resources>
diff --git a/mediarouter/src/main/res/values-pa/strings.xml b/mediarouter/src/main/res/values-pa/strings.xml
index 45eb814..5092ae0 100644
--- a/mediarouter/src/main/res/values-pa/strings.xml
+++ b/mediarouter/src/main/res/values-pa/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">"ਸਿਸਟਮ"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"ਡੀਵਾਈਸਾਂ"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"\'ਕਾਸਟ ਕਰੋ\' ਬਟਨ"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"\'ਕਾਸਟ ਕਰੋ\' ਬਟਨ। ਡਿਸਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"\'ਕਾਸਟ ਕਰੋ\' ਬਟਨ। ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"\'ਕਾਸਟ ਕਰੋ\' ਬਟਨ। ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"ਏਥੇ ਕਾਸਟ ਕਰੋ"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"ਡੀਵਾਈਸ ਲੱਭੇ ਜਾ ਰਹੇ ਹਨ"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"ਬੰਦ ਕਰੋ"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"ਚਲਾਓ"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"ਰੋਕੋ"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"ਬੰਦ ਕਰੋ"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"ਵਿਸਤਾਰ ਕਰੋ"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"ਸਮੇਟੋ"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ਐਲਬਮ ਕਲਾ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"ਵੌਲਿਊਮ ਸਲਾਈਡਰ"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ ਚੁਣਿਆ ਗਿਆ"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"ਕੋਈ ਜਾਣਕਾਰੀ ਉਪਲਬਧ ਨਹੀਂ"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"ਸਕ੍ਰੀਨ \'ਤੇ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <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
index b0bf098..6f52faf 100644
--- a/mediarouter/src/main/res/values-pl/strings.xml
+++ b/mediarouter/src/main/res/values-pl/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">"Urządzenia"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Przycisk Cast"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Przycisk Cast – rozłączono"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Przycisk Cast – łączę"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Przycisk Cast – połączono"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Przesyłaj na"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Szukam urządzeń"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Odłącz"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Zatrzymaj przesyłanie"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Zamknij"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Odtwórz"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Wstrzymaj"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Zatrzymaj"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Rozwiń"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Zwiń"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Okładka albumu"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Suwak głośności"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nie wybrano multimediów"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Brak informacji"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Przesyłam ekran"</string>
+ <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
index e527f35..213424a 100644
--- a/mediarouter/src/main/res/values-pt-rBR/strings.xml
+++ b/mediarouter/src/main/res/values-pt-rBR/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Dispositivos"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Botão \"Transmitir\""</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Botão \"Transmitir\". Desconectado"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Botão \"Transmitir\". Conectando"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Botão \"Transmitir\". Conectado"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Transmitir para"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Localizando dispositivos"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Desconectar"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Parar transmissão"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Fechar"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Reproduzir"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pausar"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Parar"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Expandir"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Recolher"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Arte do álbum"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Controle deslizante de volume"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nenhuma mídia selecionada"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nenhuma informação disponível"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Transmitindo tela"</string>
+ <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
index 1a2d2ba..4780144 100644
--- a/mediarouter/src/main/res/values-pt-rPT/strings.xml
+++ b/mediarouter/src/main/res/values-pt-rPT/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Dispositivos"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Botão Transmitir"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Botão Transmitir. Desligado."</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Botão Transmitir. A ligar..."</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Botão Transmitir. Ligado."</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Transmitir para"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"A localizar dispositivos..."</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Desligar"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Parar transmissão"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Fechar"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Reproduzir"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Colocar em pausa"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Parar"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Expandir"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Reduzir"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Imagem do álbum"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Controlo de deslize do volume"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nenhum conteúdo multimédia selecionado."</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nenhuma informação disponível."</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"A transmitir o ecrã..."</string>
+ <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
index e527f35..213424a 100644
--- a/mediarouter/src/main/res/values-pt/strings.xml
+++ b/mediarouter/src/main/res/values-pt/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">"Sistema"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Dispositivos"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Botão \"Transmitir\""</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Botão \"Transmitir\". Desconectado"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Botão \"Transmitir\". Conectando"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Botão \"Transmitir\". Conectado"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Transmitir para"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Localizando dispositivos"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Desconectar"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Parar transmissão"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Fechar"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Reproduzir"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pausar"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Parar"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Expandir"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Recolher"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Arte do álbum"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Controle deslizante de volume"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nenhuma mídia selecionada"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nenhuma informação disponível"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Transmitindo tela"</string>
+ <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
index c3292b4..82660fc 100644
--- a/mediarouter/src/main/res/values-ro/strings.xml
+++ b/mediarouter/src/main/res/values-ro/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">"Dispozitive"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Butonul de proiecție"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Butonul de proiecție. Deconectat"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Butonul de proiecție. Se conectează"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Butonul de proiecție. Conectat"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Proiectați pe"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Se caută dispozitive"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Deconectați"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Nu mai proiectați"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Închideți"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Redați"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Întrerupeți"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Opriți"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Extindeți"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Restrângeți"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Grafica albumului"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Glisor pentru volum"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Niciun conținut media selectat"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nu sunt disponibile informații"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Se proiectează ecranul"</string>
+ <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
index de0fe64..b3e5e16 100644
--- a/mediarouter/src/main/res/values-ru/strings.xml
+++ b/mediarouter/src/main/res/values-ru/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">"Система"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Устройства"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Кнопка трансляции"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Кнопка трансляции. Устройство отключено."</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Кнопка трансляции. Устройство подключается."</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Кнопка трансляции. Устройство подключено."</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Транслировать на устройство"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Поиск устройств…"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Отключить"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Остановить трансляцию"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Закрыть"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Воспроизвести"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Приостановить"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Остановить"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Показать"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Скрыть"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Обложка"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Регулятор громкости"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Медиафайл не выбран"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Данных нет"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Трансляция экрана…"</string>
+ <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
index 95bd78c..044f1a37 100644
--- a/mediarouter/src/main/res/values-si/strings.xml
+++ b/mediarouter/src/main/res/values-si/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">"පද්ධතිය"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"උපාංග"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"විකාශ බොත්තම"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"විකාශ බොත්තම. විසන්ධි කරන ලදී"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"විකාශ බොත්තම සම්බන්ධ කරමින්"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"විකාශ බොත්තම සම්බන්ධ කරන ලදී"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"විකාශය"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"උපාංග සෙවීම"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"විසන්ධි කරන්න"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"විකාශය නවතන්න"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"වසන්න"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"ධාවනය කරන්න"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"විරාමය"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"නවත්වන්න"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"දිග හරින්න"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"හකුළන්න"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ඇල්බම කලාව"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"හඬ පරිමා ස්ලයිඩරය"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"මාධ්ය තෝරා නැත"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"ලබා ගත හැකි තොරතුරු නොමැත"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"විකාශ තිරය"</string>
+ <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
index 765ff2c..bb81d011 100644
--- a/mediarouter/src/main/res/values-sk/strings.xml
+++ b/mediarouter/src/main/res/values-sk/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">"Systém"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Zariadenia"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Tlačidlo prenosu"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Tlačidlo prenosu. Odpojené"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Tlačidlo prenosu. Pripája sa"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Tlačidlo prenosu. Pripojené"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Prenos do zariadenia"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Hľadajú sa zariadenia"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Odpojiť"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Zastaviť prenos"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Zavrieť"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Prehrať"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pozastaviť"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Zastaviť"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Rozbaliť"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Zbaliť"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Obrázok albumu"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Posúvač hlasitosti"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nie sú vybraté žiadne médiá"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nie sú k dispozícii žiadne informácie"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Prenáša sa obrazovka"</string>
+ <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
index fe83391..2b0eeb8 100644
--- a/mediarouter/src/main/res/values-sl/strings.xml
+++ b/mediarouter/src/main/res/values-sl/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">"Naprave"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Gumb za predvajanje"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Gumb za predvajanje. Povezava je prekinjena."</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Gumb za predvajanje. Vzpostavljanje povezave."</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Gumb za predvajanje. Povezava je vzpostavljena."</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Predvajanje v napravi:"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Iskanje naprav"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Prekini povezavo"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Ustavi predvajanje"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Zapri"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Predvajaj"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Začasno ustavi"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Ustavi"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Razširi"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Strni"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Naslovnica albuma"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Drsnik za glasnost"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Predstavnost ni izbrana"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Ni podatkov"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Predvajanje vsebine zaslona"</string>
+ <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
index aec71e7..f172212 100644
--- a/mediarouter/src/main/res/values-sq/strings.xml
+++ b/mediarouter/src/main/res/values-sq/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">"Sistemi"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Pajisjet"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Butoni i transmetimit"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Butoni i transmetimit. Je i shkëputur"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Butoni i transmetimit. Po lidhet"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Butoni i transmetimit. Je i lidhur"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Transmeto te"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Po kërkon pajisje"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Shkëput"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Ndalo transmetimin"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Mbyll"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Luaj"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pauzë"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Ndalo"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Zgjero"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Palos"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Kopertina e albumit"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Rrëshqitësi i volumit"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Nuk është zgjedhur asnjë media"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Nuk jepet asnjë informacion"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Po transmeton ekranin"</string>
+ <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
index 31abee0..e5d35776 100644
--- a/mediarouter/src/main/res/values-sr/strings.xml
+++ b/mediarouter/src/main/res/values-sr/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">"Систем"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Уређаји"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Дугме Пребаци"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Дугме Пребаци. Веза је прекинута"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Дугме Пребаци. Повезује се"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Дугме Пребаци. Повезан је"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Пребаците на"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Траже се уређаји"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Прекини везу"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Заустави пребацивање"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Затвори"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Пусти"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Паузирај"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Заустави"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Прошири"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Скупи"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Омот албума"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Клизач за јачину звука"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Нема изабраних медија"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Нема доступних информација"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Пребацује се екран"</string>
+ <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
index 4b04e77..3ed8212 100644
--- a/mediarouter/src/main/res/values-sv/strings.xml
+++ b/mediarouter/src/main/res/values-sv/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">"Enheter"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Cast-knappen"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast-knappen. Frånkopplad"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast-knappen. Ansluter"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast-knappen. Ansluten"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Casta till"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Letar efter enheter"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Koppla från"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Sluta casta"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Stäng"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Spela upp"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Pausa"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Stopp"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Utöka"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Dölj"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Skivomslag"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Volymreglage"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Ingen media har valts"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Det finns ingen information"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Skärmen castas"</string>
+ <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
index 03228c3..2a7af85 100644
--- a/mediarouter/src/main/res/values-sw/strings.xml
+++ b/mediarouter/src/main/res/values-sw/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">"Mfumo"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Vifaa"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Kitufe cha kutuma"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Kitufe cha kutuma. Kimeondolewa"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Kitufe cha kutuma. Kinaunganishwa"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Kitufe cha kutuma. Kimeunganishwa"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Tuma kwenye"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Inatafuta vifaa"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Ondoa"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Acha kutuma"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Funga"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Cheza"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Sitisha"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Acha kucheza"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Panua"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Kunja"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Sanaa ya albamu"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Kidhibiti cha sauti"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Hakuna maudhui yaliyochaguliwa"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Hakuna maelezo yaliyopatikana"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Inatuma skrini"</string>
+ <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
index 0b00c84..6b4f896 100644
--- a/mediarouter/src/main/res/values-ta/strings.xml
+++ b/mediarouter/src/main/res/values-ta/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">"சிஸ்டம்"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"சாதனங்கள்"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"அலைபரப்பும் பட்டன்"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"அலைபரப்பும் பட்டன். துண்டிக்கப்பட்டது"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"அலைபரப்பும் பட்டன். இணைக்கிறது"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"அலைபரப்பும் பட்டன். இணைக்கப்பட்டது"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"இதற்கு அலைபரப்பு:"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"சாதனங்களைத் தேடுகிறது"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"தொடர்பைத் துண்டி"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"அலைபரப்புவதை நிறுத்து"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"மூடுவதற்கான பட்டன்"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"இயக்குவதற்கான பட்டன்"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"இடைநிறுத்துவதற்கான பட்டன்"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"நிறுத்துவதற்கான பட்டன்"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"விரிப்பதற்கான பட்டன்"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"சுருக்குவதற்கான பட்டன்"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ஆல்பம் ஆர்ட்"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"ஒலியளவு ஸ்லைடர்"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"மீடியா எதுவும் தேர்ந்தெடுக்கப்படவில்லை"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"தகவல் எதுவுமில்லை"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"திரையை அலைபரப்புகிறது"</string>
+ <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
index a8fe99a6..0d4168f 100644
--- a/mediarouter/src/main/res/values-te/strings.xml
+++ b/mediarouter/src/main/res/values-te/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">"సిస్టమ్"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"పరికరాలు"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Cast బటన్"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Cast బటన్. డిస్కనెక్ట్ చేయబడింది"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Cast బటన్. కనెక్ట్ చేస్తోంది"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Cast బటన్. కనెక్ట్ చేయబడింది"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"దీనికి ప్రసారం చేయండి"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"పరికరాలను కనుగొంటోంది"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"డిస్కనెక్ట్ చేయి"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"ప్రసారాన్ని ఆపివేయి"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"మూసివేయి"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"ఆడండి"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"పాజ్ చేయి"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"ఆపు"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"విస్తరించు"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"కుదించు"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ఆల్బమ్ ఆర్ట్"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"వాల్యూమ్ స్లయిడర్"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"మీడియా ఏదీ ఎంచుకోలేదు"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"సమాచారం అందుబాటులో లేదు"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"స్క్రీన్ను ప్రసారం చేస్తోంది"</string>
+ <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
index 4a388ed..b360779 100644
--- a/mediarouter/src/main/res/values-th/strings.xml
+++ b/mediarouter/src/main/res/values-th/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">"ระบบ"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"อุปกรณ์"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"ปุ่ม \"แคสต์\""</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"ปุ่ม \"แคสต์\" ยกเลิกการเชื่อมต่อแล้ว"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"ปุ่ม \"แคสต์\" กำลังเชื่อมต่อ"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"ปุ่ม \"แคสต์\" เชื่อมต่อแล้ว"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"แคสต์ไปยัง"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"กำลังค้นหาอุปกรณ์"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"ยกเลิกการเชื่อมต่อ"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"หยุดแคสต์"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"ปิด"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"เปิด"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"หยุดชั่วคราว"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"หยุด"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"ขยาย"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"ยุบ"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"ปกอัลบั้ม"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"แถบเลื่อนปรับระดับเสียง"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"ไม่ได้เลือกสื่อไว้"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"ไม่มีข้อมูล"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"กำลังแคสต์หน้าจอ"</string>
+ <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
index 0e450f3..4d21125 100644
--- a/mediarouter/src/main/res/values-tl/strings.xml
+++ b/mediarouter/src/main/res/values-tl/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">"Mga Device"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Button na I-cast"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Button na I-cast. Nadiskonekta"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Button na I-cast. Kumokonekta"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Button na I-cast. Nakakonekta"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"I-cast sa"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Naghahanap ng mga device"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Idiskonekta"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Ihinto ang pag-cast"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Isara"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"I-play"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"I-pause"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Ihinto"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"I-expand"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"I-collapse"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Album art"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Slider ng volume"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Walang napiling media"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Walang available na impormasyon"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Ikina-cast ang screen"</string>
+ <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
index 5c8882f..e44f443 100644
--- a/mediarouter/src/main/res/values-tr/strings.xml
+++ b/mediarouter/src/main/res/values-tr/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ınla düğmesi"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Yayınla düğmesi. Bağlantı kesildi"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Yayınla düğmesi. Bağlanıyor"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Yayınla düğmesi. Bağlandı"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Yayınlanacak yer:"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Cihazlar bulunuyor"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Bağlantıyı kes"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Yayını durdur"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Kapat"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Oynat"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Duraklat"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Durdur"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Genişlet"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Daralt"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Albüm kapağı"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Ses düzeyi kaydırma çubuğu"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Medya seçilmedi"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Bilgi yok"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Ekran yayınlanıyor"</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ı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
index c90ece6..28e09bd 100644
--- a/mediarouter/src/main/res/values-uk/strings.xml
+++ b/mediarouter/src/main/res/values-uk/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">"Система"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Пристрої"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Кнопка трансляції"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Кнопка трансляції. Від’єднано"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Кнопка трансляції. Під’єднання"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Кнопка трансляції. Під’єднано"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Транслювати на пристрій"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Пошук пристроїв"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Від’єднати"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Припинити трансляцію"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Закрити"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Відтворити"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Призупинити"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Зупинити"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Розгорнути"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Згорнути"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Обкладинка альбому"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Повзунок гучності"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Не вибрано медіа-вміст"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Немає даних"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Трансляція екрана"</string>
+ <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
index 4ae82e6..8c09830 100644
--- a/mediarouter/src/main/res/values-ur/strings.xml
+++ b/mediarouter/src/main/res/values-ur/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">"سسٹم"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"آلات"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"کاسٹ کرنے کا بٹن"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"کاسٹ کرنے کا بٹن۔ غیر منسلک ہے"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"کاسٹ کرنے کا بٹن۔ منسلک ہو رہا ہے"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"کاسٹ کرنے کا بٹن۔ منسلک ہے"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"اس میں کاسٹ کریں"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"آلات تلاش کیے جا رہے ہیں"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"غیر منسلک کریں"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"کاسٹ کرنا بند کریں"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"بند کریں"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"چلائیں"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"موقوف کریں"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"روکیں"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"پھیلائیں"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"سکیڑیں"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"البم آرٹ"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"والیوم سلائیڈر"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"کوئی میڈیا منتخب نہیں ہے"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"کوئی معلومات دستیاب نہیں ہے"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"اسکرین کاسٹ ہو رہی ہے"</string>
+ <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 bd7394b..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">"Kichraytirish"</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">"Hech narsa tanlanmagan"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Hech narsa topilmadi"</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
index 82204b4..d0f7311 100644
--- a/mediarouter/src/main/res/values-vi/strings.xml
+++ b/mediarouter/src/main/res/values-vi/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">"Hệ thống"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Thiết bị"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Nút truyền"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Nút truyền. Đã ngắt kết nối"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Nút truyền. Đang kết nối"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Nút truyền. Đã kết nối"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Truyền tới"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Đang tìm thiết bị"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Ngắt kết nối"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Dừng truyền"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Đóng"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Phát"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Tạm dừng"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Dừng"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Mở rộng"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Thu gọn"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Ảnh bìa album"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Thanh trượt âm lượng"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Chưa chọn phương tiện nào"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Không có thông tin nào"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Đang truyền màn hình"</string>
+ <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
index 92fe319..140c817 100644
--- a/mediarouter/src/main/res/values-zh-rCN/strings.xml
+++ b/mediarouter/src/main/res/values-zh-rCN/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">"系统"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"设备"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"投射按钮"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"投射按钮。已断开连接"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"投射按钮。正在连接"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"投射按钮。已连接"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"投射到"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"正在查找设备"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"断开连接"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"停止投射"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"关闭"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"播放"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"暂停"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"停止"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"展开"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"收起"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"专辑封面"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"音量滑块"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"未选择任何媒体内容"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"没有任何相关信息"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"正在投射屏幕"</string>
+ <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
index 2de9f04..9318093 100644
--- a/mediarouter/src/main/res/values-zh-rHK/strings.xml
+++ b/mediarouter/src/main/res/values-zh-rHK/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">"系統"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"裝置"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"投放按鈕"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"投放按鈕。解除咗連線"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"投放按鈕。連緊線"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"投放按鈕。連咗線"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"投放至"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"正在尋找裝置"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"解除連接"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"停止投放"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"閂"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"播"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"暫停"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"停"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"展開"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"收合"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"專輯封面"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"音量滑桿"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"未選取任何媒體"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"沒有資料可以提供"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"正在投放畫面"</string>
+ <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
index 08b92c6..bd2f9ad 100644
--- a/mediarouter/src/main/res/values-zh-rTW/strings.xml
+++ b/mediarouter/src/main/res/values-zh-rTW/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">"系統"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"裝置"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"投放按鈕"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"投放按鈕;已中斷連線"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"投放按鈕;連線中"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"投放按鈕;已連線"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"投放到"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"正在尋找裝置"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"中斷連線"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"停止投放"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"關閉"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"播放"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"暫停"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"停止"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"展開"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"收合"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"專輯封面"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"音量滑桿"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"未選取任何媒體"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"沒有可用的資訊"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"正在投放畫面"</string>
+ <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
index cf767c0..e91293f 100644
--- a/mediarouter/src/main/res/values-zu/strings.xml
+++ b/mediarouter/src/main/res/values-zu/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">"Isistimu"</string>
- <string name="mr_user_route_category_name" msgid="8236416097133080726">"Amadivayisi"</string>
- <string name="mr_button_content_description" msgid="1685185767093348095">"Inkinobho yokusakaza"</string>
- <string name="mr_cast_button_disconnected" msgid="5501231066847739632">"Inkinobho yokusakaza. Kunqanyuliwe"</string>
- <string name="mr_cast_button_connecting" msgid="8959304318293841992">"Inkinobho yokusakaza. Kuyaxhunywa"</string>
- <string name="mr_cast_button_connected" msgid="1350095112462806159">"Inkinobho yokusakaza. Kuxhunyiwe"</string>
- <string name="mr_chooser_title" msgid="7548226170787476564">"Sakaza ku-"</string>
- <string name="mr_chooser_searching" msgid="5504553798429329689">"Ithola amadivayisi"</string>
- <string name="mr_controller_disconnect" msgid="1370654436555555647">"Nqamula"</string>
- <string name="mr_controller_stop_casting" msgid="7617024847862349259">"Misa ukusakaza"</string>
- <string name="mr_controller_close_description" msgid="5468775621814500662">"Vala"</string>
- <string name="mr_controller_play" msgid="4443315438268112801">"Dlala"</string>
- <string name="mr_controller_pause" msgid="4701315813294065305">"Phumula"</string>
- <string name="mr_controller_stop" msgid="5106056093749454009">"Misa"</string>
- <string name="mr_controller_expand_group" msgid="2422682304043876468">"Nweba"</string>
- <string name="mr_controller_collapse_group" msgid="5518911192681928413">"Goqa"</string>
- <string name="mr_controller_album_art" msgid="5813284753012893250">"Ubuciko be-albhamu"</string>
- <string name="mr_controller_volume_slider" msgid="691656961160498512">"Isilayida sevolumu"</string>
- <string name="mr_controller_no_media_selected" msgid="4342878516155861006">"Ayikho imidiya ekhethiwe"</string>
- <string name="mr_controller_no_info_available" msgid="7299368841849988218">"Alukho ulwazi olutholakalayo"</string>
- <string name="mr_controller_casting_screen" msgid="5286734709674025661">"Isikrini sokusakaza"</string>
+ <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/src/main/java/androidx/paging/AsyncPagedListDiffer.java b/paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.java
index 0033665..f30163d 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<>(diffCallback).build();
+ mConfig = new AsyncDifferConfig.Builder<T>(diffCallback).build();
}
@SuppressWarnings("WeakerAccess")
@@ -227,7 +227,6 @@
*
* @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/preference/res/values-af/strings.xml b/preference/res/values-af/strings.xml
index 0f325ec..17c2037 100644
--- a/preference/res/values-af/strings.xml
+++ b/preference/res/values-af/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">"AAN"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"AF"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Gevorderd"</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">"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
index c7de5d8..052425c 100644
--- a/preference/res/values-am/strings.xml
+++ b/preference/res/values-am/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">"በርቷል"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ጠፍቷል"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"የላቀ"</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">"በርቷል"</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
index 90b2266..1e5515d 100644
--- a/preference/res/values-ar/strings.xml
+++ b/preference/res/values-ar/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">"تفعيل"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"إيقاف"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"إعدادات متقدمة"</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">"تفعيل"</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-as/strings.xml b/preference/res/values-as/strings.xml
deleted file mode 100644
index 739db0d..0000000
--- a/preference/res/values-as/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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">"অন কৰক"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"অফ অৱস্থাত আছে"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"উন্নত"</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>
-</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
index 6ab31a0..61c784ae 100644
--- a/preference/res/values-b+sr+Latn/strings.xml
+++ b/preference/res/values-b+sr+Latn/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">"UKLJUČENO"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ISKLJUČENO"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Napredno"</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">"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
index 0e2bd91..8ebdeaf 100644
--- a/preference/res/values-be/strings.xml
+++ b/preference/res/values-be/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">"УКЛ."</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ВЫКЛ."</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Пашыраныя налады"</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">"УКЛ."</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
index 0323468..e2e9544 100644
--- a/preference/res/values-bg/strings.xml
+++ b/preference/res/values-bg/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">"ВКЛ."</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ИЗКЛ."</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Разширени"</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">"ВКЛ."</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
index 92cd74f..a17e22a 100644
--- a/preference/res/values-bn/strings.xml
+++ b/preference/res/values-bn/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">"চালু"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"বন্ধ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"উন্নত"</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">"চালু"</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
index 6ab31a0..61c784ae 100644
--- a/preference/res/values-bs/strings.xml
+++ b/preference/res/values-bs/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">"UKLJUČENO"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ISKLJUČENO"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Napredno"</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">"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
index 10f3d94..56e5c66 100644
--- a/preference/res/values-ca/strings.xml
+++ b/preference/res/values-ca/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">"ACTIVAT"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DESACTIVAT"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Opcions avançades"</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">"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
index 11a67f8..5865c0b 100644
--- a/preference/res/values-cs/strings.xml
+++ b/preference/res/values-cs/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">"ZAP"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"VYP"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Rozšířená nastavení"</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">"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
index 67cb27c..da2532f 100644
--- a/preference/res/values-da/strings.xml
+++ b/preference/res/values-da/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">"TIL"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"FRA"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Avanceret"</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">"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
index 759818d..5b0be51 100644
--- a/preference/res/values-de/strings.xml
+++ b/preference/res/values-de/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">"EIN"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"AUS"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Erweitert"</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">"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
index 645d0bf..59ba395 100644
--- a/preference/res/values-el/strings.xml
+++ b/preference/res/values-el/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">"ΕΝΕΡΓΗ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ΑΝΕΝΕΡΓΗ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Σύνθετες"</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">"ΕΝΕΡΓΟΠΟΙΗΣΗ"</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
index e7639c1..3911ab9 100644
--- a/preference/res/values-es-rUS/strings.xml
+++ b/preference/res/values-es-rUS/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">"ACTIVADA"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DESACTIVADA"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Opciones avanzadas"</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">"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
index f40f3ea..3911ab9 100644
--- a/preference/res/values-es/strings.xml
+++ b/preference/res/values-es/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">"ACTIVADO"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DESACTIVADA"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Avanzada"</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">"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
index a315280..9fa4f4f 100644
--- a/preference/res/values-et/strings.xml
+++ b/preference/res/values-et/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">"SEES"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"VÄLJAS"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Täpsem"</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">"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
index 1a71b90..6718992 100644
--- a/preference/res/values-eu/strings.xml
+++ b/preference/res/values-eu/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">"AKTIBATUTA"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DESAKTIBATUTA"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Hobespen aurreratuak"</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">"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
index b4191aa..86e9f30 100644
--- a/preference/res/values-fa/strings.xml
+++ b/preference/res/values-fa/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">"روشن"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"خاموش"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"پیشرفته"</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">"روشن"</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
index cd82547..cec0857 100644
--- a/preference/res/values-fi/strings.xml
+++ b/preference/res/values-fi/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">"KÄYTÖSSÄ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"POIS KÄYTÖSTÄ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Lisäasetukset"</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">"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
index 07af614..db4c2b5 100644
--- a/preference/res/values-fr-rCA/strings.xml
+++ b/preference/res/values-fr-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">"ACTIVÉ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DÉSACTIVÉ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Avancé"</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">"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
index e74b2a4..b5cca98 100644
--- a/preference/res/values-fr/strings.xml
+++ b/preference/res/values-fr/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">"ACTIVÉ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DÉSACTIVÉ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Préférences avancées"</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">"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
index 8091d9c..3911ab9 100644
--- a/preference/res/values-gl/strings.xml
+++ b/preference/res/values-gl/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">"ACTIVADO"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DESACTIVADO"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Configuración avanzada"</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">"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
index a5c0287..468fd2c 100644
--- a/preference/res/values-gu/strings.xml
+++ b/preference/res/values-gu/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">"ચાલુ કરો"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"બંધ કરો"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"વિગતવાર"</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">"ચાલુ"</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
index 3ac8ecc..dcfb766 100644
--- a/preference/res/values-hi/strings.xml
+++ b/preference/res/values-hi/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">"चालू"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"बंद"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"बेहतर सेटिंग"</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">"चालू"</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
index 6ab31a0..61c784ae 100644
--- a/preference/res/values-hr/strings.xml
+++ b/preference/res/values-hr/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">"UKLJUČENO"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ISKLJUČENO"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Napredno"</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">"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
index 0b65185..85f80aa 100644
--- a/preference/res/values-hu/strings.xml
+++ b/preference/res/values-hu/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">"BE"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"KI"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Speciális"</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">"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
index c9d47a8..06f9d22 100644
--- a/preference/res/values-hy/strings.xml
+++ b/preference/res/values-hy/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">"ՄԻԱՑՎԱԾ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ԱՆՋԱՏԱԾ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Լրացուցիչ"</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">"ՄԻԱՑՎԱԾ"</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
index d56dcd3..e17c251 100644
--- a/preference/res/values-in/strings.xml
+++ b/preference/res/values-in/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">"AKTIF"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"NONAKTIF"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Lanjutan"</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">"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
index 6af367f..361d1c3 100644
--- a/preference/res/values-is/strings.xml
+++ b/preference/res/values-is/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">"KVEIKT"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"SLÖKKT"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Ítarlegt"</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">"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
index 4fb3179..2514600 100644
--- a/preference/res/values-it/strings.xml
+++ b/preference/res/values-it/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">"Avanzate"</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">"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
index 8afe71e..6ca15e5 100644
--- a/preference/res/values-iw/strings.xml
+++ b/preference/res/values-iw/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">"מופעל"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"כבוי"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"מתקדם"</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">"מופעל"</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
index 30ebd124..2d599d3 100644
--- a/preference/res/values-ja/strings.xml
+++ b/preference/res/values-ja/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">"詳細設定"</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">"詳細設定"</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
index 731ddd4..21b8246 100644
--- a/preference/res/values-ka/strings.xml
+++ b/preference/res/values-ka/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">"ჩართული"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"გამორთული"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"დამატებით"</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">"ჩართული"</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
index 2a5880c..ebbba78 100644
--- a/preference/res/values-kk/strings.xml
+++ b/preference/res/values-kk/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">"ҚОСУЛЫ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ӨШІРУЛІ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Қосымша"</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">"ҚОСУЛЫ"</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
index 4945df6..d7cb942 100644
--- a/preference/res/values-km/strings.xml
+++ b/preference/res/values-km/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">"បើក"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"បិទ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"កម្រិតខ្ពស់"</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">"បើក"</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
index a5a6200..9ce1917 100644
--- a/preference/res/values-kn/strings.xml
+++ b/preference/res/values-kn/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">"ಆನ್"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ಆಫ್"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"ಸುಧಾರಿತ"</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">"ಆನ್"</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
index 78d6449..ab1f380 100644
--- a/preference/res/values-ko/strings.xml
+++ b/preference/res/values-ko/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">"사용"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"사용 안함"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"고급"</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">"사용"</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
index 621effa..257c6d5 100644
--- a/preference/res/values-ky/strings.xml
+++ b/preference/res/values-ky/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">"КҮЙҮК"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ӨЧҮК"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Өркүндөтүлгөн"</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">"КҮЙҮК"</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
index 9a740a8..f4c1e2d 100644
--- a/preference/res/values-lo/strings.xml
+++ b/preference/res/values-lo/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">"ເປີດ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ປິດ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"ຂັ້ນສູງ"</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">"ເປີດ"</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
index ddfd0dc..ef1bfd6 100644
--- a/preference/res/values-lt/strings.xml
+++ b/preference/res/values-lt/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">"ĮJUNGTA"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"IŠJUNGTA"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Išplėstinė"</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">"Į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
index 07c4dea..e4890b1 100644
--- a/preference/res/values-lv/strings.xml
+++ b/preference/res/values-lv/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">"IESLĒGTS"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"IZSLĒGTS"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Papildu iestatījumi"</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">"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
index fd4d5a1..f276876 100644
--- a/preference/res/values-mk/strings.xml
+++ b/preference/res/values-mk/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">"ВКЛУЧЕНО"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ИСКЛУЧЕНО"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Напредни"</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">"ВКЛУЧЕНО"</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
index 46d5e49..83d1125 100644
--- a/preference/res/values-ml/strings.xml
+++ b/preference/res/values-ml/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">"ഓൺ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ഓഫ്"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"വിപുലമായത്"</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">"ഓൺ"</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
index bf54850..2d20950 100644
--- a/preference/res/values-mn/strings.xml
+++ b/preference/res/values-mn/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">"ИДЭВХТЭЙ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ИДЭВХГҮЙ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Дэлгэрэнгүй"</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">"АСААЛТТАЙ"</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
index 2cd0eec..1e492dd 100644
--- a/preference/res/values-mr/strings.xml
+++ b/preference/res/values-mr/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">"चालू"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"बंद"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"प्रगत"</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">"चालू"</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
index b753aac..1601d8a 100644
--- a/preference/res/values-ms/strings.xml
+++ b/preference/res/values-ms/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">"HIDUP"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"MATI"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Terperinci"</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">"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
index e1a96ec..77237bc 100644
--- a/preference/res/values-my/strings.xml
+++ b/preference/res/values-my/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">"ဖွင့်ရန်"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ပိတ်ရန်"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"အဆင့်မြင့်"</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">"ဖွင့်ရန်"</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
index 07e7b3a..d5c814b 100644
--- a/preference/res/values-nb/strings.xml
+++ b/preference/res/values-nb/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">"PÅ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"AV"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Avansert"</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">"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
index 28cdfe9..1da1f25 100644
--- a/preference/res/values-ne/strings.xml
+++ b/preference/res/values-ne/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">"सक्रिय"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"निष्क्रिय पार्नुहोस्"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"उन्नत"</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">"सक्रिय छ"</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
index 5269cf0..dc84ab8 100644
--- a/preference/res/values-nl/strings.xml
+++ b/preference/res/values-nl/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">"AAN"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"UIT"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Geavanceerd"</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">"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-or/strings.xml b/preference/res/values-or/strings.xml
deleted file mode 100644
index 40ec596..0000000
--- a/preference/res/values-or/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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">"ଅନ୍ ଅଛି"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ଅଫ୍ ଅଛି"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"ଅଧିକ ଉନ୍ନତ"</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>
-</resources>
diff --git a/preference/res/values-pa/strings.xml b/preference/res/values-pa/strings.xml
index 9d1a2f9..29471c3 100644
--- a/preference/res/values-pa/strings.xml
+++ b/preference/res/values-pa/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">"ਚਾਲੂ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ਬੰਦ"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"ਉੱਨਤ"</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">"ਚਾਲੂ"</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
index d5d3bc1..ef7bbf8 100644
--- a/preference/res/values-pl/strings.xml
+++ b/preference/res/values-pl/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">"WŁ."</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"WYŁ."</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Zaawansowane"</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">"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
index a77b7d4..433e8e3 100644
--- a/preference/res/values-pt-rBR/strings.xml
+++ b/preference/res/values-pt-rBR/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">"ATIVADO"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DESATIVADO"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Avançado"</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">"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
index 2c02859..4f296f6 100644
--- a/preference/res/values-pt-rPT/strings.xml
+++ b/preference/res/values-pt-rPT/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">"ATIVADO"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DESATIVADO"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Avançadas"</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">"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
index a77b7d4..433e8e3 100644
--- a/preference/res/values-pt/strings.xml
+++ b/preference/res/values-pt/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">"ATIVADO"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DESATIVADO"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Avançado"</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">"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
index 296bef2..1353a6f 100644
--- a/preference/res/values-ro/strings.xml
+++ b/preference/res/values-ro/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">"ACTIVAT"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"DEZACTIVAT"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Avansat"</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">"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
index 854a395..8449700 100644
--- a/preference/res/values-ru/strings.xml
+++ b/preference/res/values-ru/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">"ВКЛ."</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ВЫКЛ."</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Дополнительно"</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">"ВКЛ."</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
index 11f85fe..27bf118 100644
--- a/preference/res/values-si/strings.xml
+++ b/preference/res/values-si/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">"ක්රියාත්මකයි"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ක්රියාවිරහිතයි"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"උසස්"</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">"ක්රියාත්මකයි"</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
index 5d56e98..a087a8b 100644
--- a/preference/res/values-sk/strings.xml
+++ b/preference/res/values-sk/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">"ZAP."</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"VYP."</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Rozšírené"</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">"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
index c21b129..887c1b1 100644
--- a/preference/res/values-sl/strings.xml
+++ b/preference/res/values-sl/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">"VKLOPLJENO"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"IZKLOPLJENO"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Dodatno"</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">"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
index 7ba659c..f2f5b77 100644
--- a/preference/res/values-sq/strings.xml
+++ b/preference/res/values-sq/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">"AKTIV"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"JOAKTIV"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Të përparuara"</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">"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
index 3128648..322ace5 100644
--- a/preference/res/values-sr/strings.xml
+++ b/preference/res/values-sr/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">"УКЉУЧЕНО"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ИСКЉУЧЕНО"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Напредно"</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">"УКЉУЧЕНО"</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
index 9257e88..c689ea1 100644
--- a/preference/res/values-sv/strings.xml
+++ b/preference/res/values-sv/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">"PÅ"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"AV"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Avancerat"</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">"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
index f3e72d5..9010663 100644
--- a/preference/res/values-sw/strings.xml
+++ b/preference/res/values-sw/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">"IMEWASHWA"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"IMEZIMWA"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Mipangilio ya Kina"</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">"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
index d13e3ec..9fc536d 100644
--- a/preference/res/values-ta/strings.xml
+++ b/preference/res/values-ta/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">"ஆன்"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ஆஃப்"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"மேம்பட்டவை"</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">"ஆன் செய்"</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
index 30d0c45..7277c76 100644
--- a/preference/res/values-te/strings.xml
+++ b/preference/res/values-te/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">"ఆన్ చేయండి"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ఆఫ్ చేయండి"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"అధునాతన"</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">"ఆన్"</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
index 18e3ba4..90a5433 100644
--- a/preference/res/values-th/strings.xml
+++ b/preference/res/values-th/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">"เปิด"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ปิด"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"ขั้นสูง"</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">"เปิด"</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
index 1d9a85d..5b6885b 100644
--- a/preference/res/values-tl/strings.xml
+++ b/preference/res/values-tl/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">"NAKA-ON"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"NAKA-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">"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
index 8363a5b..fa66179 100644
--- a/preference/res/values-tr/strings.xml
+++ b/preference/res/values-tr/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">"AÇIK"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"KAPALI"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Gelişmiş"</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">"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
index b8c60e0..47280c3 100644
--- a/preference/res/values-uk/strings.xml
+++ b/preference/res/values-uk/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">"УВІМКНЕНО"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"ВИМКНЕНО"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Додатково"</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">"УВІМКНЕНО"</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
index 0e6560f..c304b12 100644
--- a/preference/res/values-ur/strings.xml
+++ b/preference/res/values-ur/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">"آن"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"آف ہے"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"جدید ترین"</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">"آن"</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 15f1021..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">"YOQILMAGAN"</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
index 3cdbad3..d8ea12b 100644
--- a/preference/res/values-vi/strings.xml
+++ b/preference/res/values-vi/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">"BẬT"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"TẮT"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Nâng cao"</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">"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
index 368e7a3..3f91ed6 100644
--- a/preference/res/values-zh-rCN/strings.xml
+++ b/preference/res/values-zh-rCN/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">"开启"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"关闭"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"高级"</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">"开启"</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
index ac8a0ed..fe64c50af 100644
--- a/preference/res/values-zh-rHK/strings.xml
+++ b/preference/res/values-zh-rHK/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">"開啟"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"關閉"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"進階"</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">"開啟"</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
index ac8a0ed..fe64c50af 100644
--- a/preference/res/values-zh-rTW/strings.xml
+++ b/preference/res/values-zh-rTW/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">"開啟"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"關閉"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"進階"</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">"開啟"</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
index 85b99bb..dab4cba 100644
--- a/preference/res/values-zu/strings.xml
+++ b/preference/res/values-zu/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">"VULA"</string>
- <string name="v7_preference_off" msgid="5138405918326871307">"VALA"</string>
- <string name="expand_button_title" msgid="1234962710353108940">"Okuthuthukisiwe"</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">"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/preference/src/main/java/androidx/preference/PreferenceCategory.java b/preference/src/main/java/androidx/preference/PreferenceCategory.java
index d00d959..3585bd9 100644
--- a/preference/src/main/java/androidx/preference/PreferenceCategory.java
+++ b/preference/src/main/java/androidx/preference/PreferenceCategory.java
@@ -20,7 +20,6 @@
import android.util.AttributeSet;
import androidx.core.content.res.TypedArrayUtils;
-import androidx.core.os.BuildCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat;
@@ -67,30 +66,21 @@
}
@Override
- public void onBindViewHolder(PreferenceViewHolder holder) {
- super.onBindViewHolder(holder);
- if (BuildCompat.isAtLeastP()) {
- holder.itemView.setAccessibilityHeading(true);
- }
- }
-
- @Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(info);
- if (!BuildCompat.isAtLeastP()) {
- CollectionItemInfoCompat existingItemInfo = info.getCollectionItemInfo();
- if (existingItemInfo == null) {
- return;
- }
- final CollectionItemInfoCompat newItemInfo = CollectionItemInfoCompat.obtain(
- existingItemInfo.getRowIndex(),
- existingItemInfo.getRowSpan(),
- existingItemInfo.getColumnIndex(),
- existingItemInfo.getColumnSpan(),
- true /* heading */,
- existingItemInfo.isSelected());
- info.setCollectionItemInfo(newItemInfo);
+ CollectionItemInfoCompat existingItemInfo = info.getCollectionItemInfo();
+ if (existingItemInfo == null) {
+ return;
}
+
+ final CollectionItemInfoCompat newItemInfo = CollectionItemInfoCompat.obtain(
+ existingItemInfo.getRowIndex(),
+ existingItemInfo.getRowSpan(),
+ existingItemInfo.getColumnIndex(),
+ existingItemInfo.getColumnSpan(),
+ true /* heading */,
+ existingItemInfo.isSelected());
+ info.setCollectionItemInfo(newItemInfo);
}
}
diff --git a/samples/SupportCarDemos/src/main/AndroidManifest.xml b/samples/SupportCarDemos/src/main/AndroidManifest.xml
index ceb6aa7..8bba75f 100644
--- a/samples/SupportCarDemos/src/main/AndroidManifest.xml
+++ b/samples/SupportCarDemos/src/main/AndroidManifest.xml
@@ -140,17 +140,6 @@
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value=".SupportCarDemoActivity" />
</activity>
-
- <activity android:name=".AppBarActivity"
- android:label="App Bar"
- android:parentActivityName=".SupportCarDemoActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.SAMPLE_CODE" />
- </intent-filter>
- <meta-data android:name="android.support.PARENT_ACTIVITY"
- android:value=".SupportCarDemoActivity" />
- </activity>
</application>
</manifest>
diff --git a/samples/SupportCarDemos/src/main/java/com/example/androidx/car/AlphaJumpActivity.java b/samples/SupportCarDemos/src/main/java/com/example/androidx/car/AlphaJumpActivity.java
index fcbe2a3..6801a6a 100644
--- a/samples/SupportCarDemos/src/main/java/com/example/androidx/car/AlphaJumpActivity.java
+++ b/samples/SupportCarDemos/src/main/java/com/example/androidx/car/AlphaJumpActivity.java
@@ -24,14 +24,14 @@
import android.view.ViewGroup;
import android.widget.TextView;
+import java.util.Arrays;
+import java.util.Collection;
+
import androidx.car.widget.AlphaJumpBucketer;
import androidx.car.widget.IAlphaJumpAdapter;
import androidx.car.widget.PagedListView;
import androidx.recyclerview.widget.RecyclerView;
-import java.util.Arrays;
-import java.util.Collection;
-
/**
* An activity with a long list of cheeses, initially in a random order but you can use alpha jump
* to quickly jump to your favourite cheese.
diff --git a/samples/SupportCarDemos/src/main/java/com/example/androidx/car/AppBarActivity.java b/samples/SupportCarDemos/src/main/java/com/example/androidx/car/AppBarActivity.java
deleted file mode 100644
index 3919c5a..0000000
--- a/samples/SupportCarDemos/src/main/java/com/example/androidx/car/AppBarActivity.java
+++ /dev/null
@@ -1,86 +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 com.example.androidx.car;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.view.Menu;
-
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
-import androidx.car.widget.ListItem;
-import androidx.car.widget.ListItemAdapter;
-import androidx.car.widget.ListItemProvider;
-import androidx.car.widget.PagedListView;
-import androidx.car.widget.TextListItem;
-
-/**
- * Demo activity for creating {@code App Bar} with {@link Toolbar}.
- */
-public class AppBarActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_app_bar);
- Toolbar toolbar = findViewById(R.id.car_toolbar);
- setSupportActionBar(toolbar);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setTitle("Title");
- getSupportActionBar().setSubtitle("Subtitle");
-
- setUpList();
- }
-
- private void setUpList() {
- PagedListView list = findViewById(R.id.list);
- list.setAdapter(new ListItemAdapter(this, new SampleProvider(this, 50)));
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.demo_menu, menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- private static class SampleProvider extends ListItemProvider {
-
- private int mCount;
- private Context mContext;
-
- SampleProvider(Context context, int count) {
- mContext = context;
- mCount = count;
- }
-
- @Override
- public ListItem get(int position) {
- if (position < 0 || position >= mCount) {
- throw new IndexOutOfBoundsException();
- }
- TextListItem item = new TextListItem(mContext);
- item.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
- item.setTitle("title");
- return item;
- }
-
- @Override
- public int size() {
- return mCount;
- }
- }
-}
diff --git a/samples/SupportCarDemos/src/main/res/layout/activity_app_bar.xml b/samples/SupportCarDemos/src/main/res/layout/activity_app_bar.xml
deleted file mode 100644
index 74dcbc3..0000000
--- a/samples/SupportCarDemos/src/main/res/layout/activity_app_bar.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <androidx.appcompat.widget.Toolbar
- android:id="@+id/car_toolbar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/car_card" />
-
- <androidx.car.widget.PagedListView
- android:id="@+id/list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:gutter="both" />
-</LinearLayout>
diff --git a/samples/SupportCarDemos/src/main/res/layout/list_dialog_activity.xml b/samples/SupportCarDemos/src/main/res/layout/list_dialog_activity.xml
index 1b67ddcb..790e25e 100644
--- a/samples/SupportCarDemos/src/main/res/layout/list_dialog_activity.xml
+++ b/samples/SupportCarDemos/src/main/res/layout/list_dialog_activity.xml
@@ -34,53 +34,53 @@
android:checked="true"
android:text="@string/list_dialog_checkbox_title" />
- <com.google.android.material.textfield.TextInputLayout
+ <android.support.design.widget.TextInputLayout
android:id="@+id/num_of_sections"
android:layout_width="match_parent"
android:layout_height="@dimen/car_single_line_list_item_height"
android:hint="@string/list_dialog_num_of_sections_hint"
app:hintTextAppearance="@style/TextAppearance.Car.Hint">
- <com.google.android.material.textfield.TextInputEditText
+ <android.support.design.widget.TextInputEditText
android:id="@+id/num_of_sections_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Car.Body2"/>
- </com.google.android.material.textfield.TextInputLayout>
+ </android.support.design.widget.TextInputLayout>
- <com.google.android.material.textfield.TextInputLayout
+ <android.support.design.widget.TextInputLayout
android:id="@+id/num_of_items"
android:layout_width="match_parent"
android:layout_height="@dimen/car_single_line_list_item_height"
android:hint="@string/list_dialog_num_of_items_hint"
app:hintTextAppearance="@style/TextAppearance.Car.Hint">
- <com.google.android.material.textfield.TextInputEditText
+ <android.support.design.widget.TextInputEditText
android:id="@+id/num_of_items_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Car.Body2"/>
- </com.google.android.material.textfield.TextInputLayout>
+ </android.support.design.widget.TextInputLayout>
- <com.google.android.material.textfield.TextInputLayout
+ <android.support.design.widget.TextInputLayout
android:id="@+id/initial_position"
android:layout_width="match_parent"
android:layout_height="@dimen/car_single_line_list_item_height"
android:hint="@string/list_dialog_initial_position_hint"
app:hintTextAppearance="@style/TextAppearance.Car.Hint">
- <com.google.android.material.textfield.TextInputEditText
+ <android.support.design.widget.TextInputEditText
android:id="@+id/initial_position_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Car.Body2"/>
- </com.google.android.material.textfield.TextInputLayout>
+ </android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/create_dialog"
diff --git a/samples/SupportCarDemos/src/main/res/menu/demo_menu.xml b/samples/SupportCarDemos/src/main/res/menu/demo_menu.xml
deleted file mode 100644
index a1b256b..0000000
--- a/samples/SupportCarDemos/src/main/res/menu/demo_menu.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<menu xmlns:tools="http://schemas.android.com/tools"
- xmlns:android="http://schemas.android.com/apk/res/android"
- tools:ignore="AppCompatResource"
- xmlns:app="http://schemas.android.com/apk/res-auto">
-
- <item
- android:id="@+id/action_icon"
- android:icon="@drawable/pressed_icon"
- android:title="Action1 with icon"
- app:showAsAction="always|withText"/>
-
- <item
- android:id="@+id/action_overflow"
- android:title="Action2"
- app:showAsAction="always|withText"/>
-
- <item
- android:id="@+id/action_overflow2"
- android:title="Action3"
- app:showAsAction="never" />
-</menu>
\ No newline at end of file
diff --git a/samples/SupportContentDemos/build.gradle b/samples/SupportContentDemos/build.gradle
index 8d8a06c..d7b61e8 100644
--- a/samples/SupportContentDemos/build.gradle
+++ b/samples/SupportContentDemos/build.gradle
@@ -1,4 +1,3 @@
-
/*
* Copyright (C) 2017 The Android Open Source Project
*
@@ -15,19 +14,16 @@
* limitations under the License.
*/
-import static androidx.build.dependencies.DependenciesKt.SUPPORT_DESIGN
-
plugins {
id("SupportAndroidTestAppPlugin")
}
dependencies {
- implementation(SUPPORT_DESIGN, libs.exclude_for_material)
+ implementation("com.android.support:design:28.0.0-SNAPSHOT", { transitive = false })
implementation(project(":transition"))
implementation(project(":recyclerview"))
implementation(project(":appcompat"))
implementation(project(":contentpager"))
- implementation(project(":cardview"))
}
android {
diff --git a/samples/SupportContentDemos/src/main/java/com/example/android/support/content/demos/ContentPagerDemoActivity.java b/samples/SupportContentDemos/src/main/java/com/example/android/support/content/demos/ContentPagerDemoActivity.java
index 119f3a1..8a661fc 100644
--- a/samples/SupportContentDemos/src/main/java/com/example/android/support/content/demos/ContentPagerDemoActivity.java
+++ b/samples/SupportContentDemos/src/main/java/com/example/android/support/content/demos/ContentPagerDemoActivity.java
@@ -19,6 +19,8 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.Snackbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
@@ -34,10 +36,6 @@
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-import com.google.android.material.snackbar.BaseTransientBottomBar;
-import com.google.android.material.snackbar.Snackbar;
-
import java.util.Locale;
/**
@@ -143,7 +141,7 @@
private void msg(String msg) {
Snackbar.make(
mRecycler,
- msg, BaseTransientBottomBar.LENGTH_LONG)
+ msg, Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
diff --git a/samples/SupportDesignDemos/build.gradle b/samples/SupportDesignDemos/build.gradle
index 2bf34000..8721e2b 100644
--- a/samples/SupportDesignDemos/build.gradle
+++ b/samples/SupportDesignDemos/build.gradle
@@ -1,11 +1,18 @@
-import static androidx.build.dependencies.DependenciesKt.SUPPORT_DESIGN
-
plugins {
id("SupportAndroidTestAppPlugin")
}
dependencies {
- implementation(SUPPORT_DESIGN, libs.exclude_for_material)
+ api "com.android.temp.support:design:28.0.0-alpha1", {
+ exclude group: 'androidx.annotation'
+ exclude group: 'androidx.core'
+ exclude group: 'androidx.legacy'
+ exclude group: 'androidx.fragment'
+ exclude group: 'androidx.transition'
+ exclude group: 'androidx.appcompat'
+ exclude group: 'androidx.recyclerview'
+ exclude group: 'androidx.cardview'
+ }
implementation(project(":transition"))
implementation(project(":recyclerview"))
implementation(project(":appcompat"))
@@ -14,6 +21,8 @@
android {
defaultConfig {
+ minSdkVersion 14
vectorDrawables.useSupportLibrary = true
}
}
+
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/AppBarLayoutUsageBase.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/AppBarLayoutUsageBase.java
index bcf244a..9607991 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/AppBarLayoutUsageBase.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/AppBarLayoutUsageBase.java
@@ -18,6 +18,9 @@
import android.os.Bundle;
import android.os.Handler;
+import android.support.design.widget.AppBarLayout;
+import android.support.design.widget.CollapsingToolbarLayout;
+import android.support.design.widget.TabLayout;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
@@ -32,9 +35,6 @@
import com.example.android.support.design.Cheeses;
import com.example.android.support.design.R;
import com.example.android.support.design.Shakespeare;
-import com.google.android.material.appbar.AppBarLayout;
-import com.google.android.material.appbar.CollapsingToolbarLayout;
-import com.google.android.material.tabs.TabLayout;
import java.util.Random;
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomNavigationViewUsage.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomNavigationViewUsage.java
index 412f1f4..e4ae51f 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomNavigationViewUsage.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomNavigationViewUsage.java
@@ -18,6 +18,7 @@
import android.content.res.ColorStateList;
import android.os.Bundle;
+import android.support.design.widget.BottomNavigationView;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
@@ -27,7 +28,6 @@
import androidx.appcompat.app.AppCompatActivity;
import com.example.android.support.design.R;
-import com.google.android.material.bottomnavigation.BottomNavigationView;
/**
* This demonstrates idiomatic usage of the bottom navigation widget.
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetDynamicContent.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetDynamicContent.java
index 077bb1f..d96db57 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetDynamicContent.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetDynamicContent.java
@@ -17,6 +17,7 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.BottomSheetBehavior;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -30,7 +31,6 @@
import com.example.android.support.design.Cheeses;
import com.example.android.support.design.R;
-import com.google.android.material.bottomsheet.BottomSheetBehavior;
import java.util.ArrayList;
import java.util.Random;
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetHideable.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetHideable.java
index 2988c14..1888c1b 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetHideable.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetHideable.java
@@ -17,6 +17,7 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.BottomSheetBehavior;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
@@ -25,7 +26,6 @@
import androidx.annotation.Nullable;
import com.example.android.support.design.R;
-import com.google.android.material.bottomsheet.BottomSheetBehavior;
/**
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModal.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModal.java
index 69ab271..262f390 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModal.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModal.java
@@ -16,7 +16,7 @@
package com.example.android.support.design.widget;
-import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+import android.support.design.widget.BottomSheetDialogFragment;
/**
* This demonstrates basic usage of {@link BottomSheetDialogFragment}.
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModalBase.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModalBase.java
index e3c31ae..7cef4a8 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModalBase.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModalBase.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.os.Bundle;
+import android.support.design.widget.BottomSheetDialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -29,7 +30,6 @@
import com.example.android.support.design.Cheeses;
import com.example.android.support.design.R;
-import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
abstract class BottomSheetModalBase extends AppCompatActivity {
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModalSkipCollapsed.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModalSkipCollapsed.java
index 729154a..509dd7c 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModalSkipCollapsed.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetModalSkipCollapsed.java
@@ -16,7 +16,7 @@
package com.example.android.support.design.widget;
-import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+import android.support.design.widget.BottomSheetDialogFragment;
/**
* This demonstrates basic usage of {@link BottomSheetDialogFragment}.
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetPersistent.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetPersistent.java
index 2da32ab..5e02e60 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetPersistent.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetPersistent.java
@@ -16,8 +16,9 @@
package com.example.android.support.design.widget;
+import android.support.design.widget.BottomSheetBehavior;
+
import com.example.android.support.design.R;
-import com.google.android.material.bottomsheet.BottomSheetBehavior;
/**
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetUsageBase.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetUsageBase.java
index 4d873cf..62c76be 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetUsageBase.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetUsageBase.java
@@ -17,6 +17,7 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.BottomSheetBehavior;
import android.text.TextUtils;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -26,7 +27,6 @@
import com.example.android.support.design.R;
import com.example.android.support.design.Shakespeare;
-import com.google.android.material.bottomsheet.BottomSheetBehavior;
/**
* This demonstrates basic usage of {@link BottomSheetBehavior}.
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetWithFab.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetWithFab.java
index c197b93..b3a2855 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetWithFab.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetWithFab.java
@@ -18,6 +18,7 @@
import android.os.Bundle;
+import android.support.design.widget.BottomSheetBehavior;
import android.view.View;
import android.widget.Button;
@@ -25,7 +26,6 @@
import androidx.annotation.Nullable;
import com.example.android.support.design.R;
-import com.google.android.material.bottomsheet.BottomSheetBehavior;
/**
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetWithFragment.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetWithFragment.java
index c7fb168..b095c37 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetWithFragment.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/BottomSheetWithFragment.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.os.Bundle;
+import android.support.design.widget.BottomSheetBehavior;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -30,7 +31,6 @@
import androidx.recyclerview.widget.RecyclerView;
import com.example.android.support.design.R;
-import com.google.android.material.bottomsheet.BottomSheetBehavior;
/**
* This demonstrates basic usage of {@link BottomSheetBehavior} with Fragment.
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/CustomSnackbar.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/CustomSnackbar.java
index af62e4f8..bcc6303 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/CustomSnackbar.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/CustomSnackbar.java
@@ -15,13 +15,13 @@
*/
package com.example.android.support.design.widget;
+import android.support.design.widget.BaseTransientBottomBar;
import android.view.View;
import android.widget.TextView;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.example.android.support.design.R;
-import com.google.android.material.snackbar.BaseTransientBottomBar;
/**
* Sample code for a custom snackbar that shows two separate text views and two images
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/CustomSnackbarUsage.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/CustomSnackbarUsage.java
index 1b0057c..bd0168e 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/CustomSnackbarUsage.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/CustomSnackbarUsage.java
@@ -17,6 +17,7 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.BaseTransientBottomBar;
import android.view.LayoutInflater;
import android.view.View;
@@ -24,7 +25,6 @@
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.example.android.support.design.R;
-import com.google.android.material.snackbar.BaseTransientBottomBar;
/**
* This demonstrates custom usage of the snackbar
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewUsage.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewUsage.java
index c90d44f..7ed367a 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewUsage.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewUsage.java
@@ -17,6 +17,7 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.NavigationView;
import android.util.TypedValue;
import android.view.MenuItem;
import android.view.View;
@@ -26,7 +27,6 @@
import androidx.drawerlayout.widget.DrawerLayout;
import com.example.android.support.design.R;
-import com.google.android.material.navigation.NavigationView;
/**
* This demonstrates basic usage of NavigationView
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewUsageBase.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewUsageBase.java
index 86848bb..5d452a9 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewUsageBase.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewUsageBase.java
@@ -17,6 +17,7 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.NavigationView;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
@@ -25,7 +26,6 @@
import androidx.appcompat.app.AppCompatActivity;
import com.example.android.support.design.R;
-import com.google.android.material.navigation.NavigationView;
public abstract class NavigationViewUsageBase extends AppCompatActivity {
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewWithoutDrawer.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewWithoutDrawer.java
index 2a443398..81e9419 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewWithoutDrawer.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/NavigationViewWithoutDrawer.java
@@ -16,10 +16,10 @@
package com.example.android.support.design.widget;
+import android.support.design.widget.NavigationView;
import android.view.MenuItem;
import com.example.android.support.design.R;
-import com.google.android.material.navigation.NavigationView;
/**
* This demonstrates basic usage of NavigationView
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/SnackbarUsage.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/SnackbarUsage.java
index 35d910d2..c0475ab 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/SnackbarUsage.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/SnackbarUsage.java
@@ -17,6 +17,7 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.Snackbar;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
@@ -24,7 +25,6 @@
import androidx.appcompat.app.AppCompatActivity;
import com.example.android.support.design.R;
-import com.google.android.material.snackbar.Snackbar;
/**
* This demonstrates idiomatic usage of the snackbar
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutCustomItemsUsage.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutCustomItemsUsage.java
index 23f6eb9..299ea75 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutCustomItemsUsage.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutCustomItemsUsage.java
@@ -17,12 +17,12 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.TabLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.example.android.support.design.R;
-import com.google.android.material.tabs.TabLayout;
/**
* This demonstrates usage of TabLayout with custom items
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutPreselectedUsage.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutPreselectedUsage.java
index ed90273..f0b04cd 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutPreselectedUsage.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutPreselectedUsage.java
@@ -17,6 +17,7 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.TabLayout;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -32,7 +33,6 @@
import com.example.android.support.design.Cheeses;
import com.example.android.support.design.R;
-import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutUsage.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutUsage.java
index 7f77086..3eb2c4f 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutUsage.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TabLayoutUsage.java
@@ -17,6 +17,7 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.TabLayout;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -32,7 +33,6 @@
import com.example.android.support.design.Cheeses;
import com.example.android.support.design.R;
-import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
import java.util.Random;
diff --git a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TextInputLayoutUsage.java b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TextInputLayoutUsage.java
index fd054c9..92a7a66 100644
--- a/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TextInputLayoutUsage.java
+++ b/samples/SupportDesignDemos/src/main/java/com/example/android/support/design/widget/TextInputLayoutUsage.java
@@ -17,12 +17,12 @@
package com.example.android.support.design.widget;
import android.os.Bundle;
+import android.support.design.widget.TextInputLayout;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import com.example.android.support.design.R;
-import com.google.android.material.textfield.TextInputLayout;
/**
* This demonstrates idiomatic usage of {@code TextInputLayout}
diff --git a/samples/SupportDesignDemos/src/main/res/layout/custom_snackbar_with_fab.xml b/samples/SupportDesignDemos/src/main/res/layout/custom_snackbar_with_fab.xml
index ad55e8a..9c51d39 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/custom_snackbar_with_fab.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/custom_snackbar_with_fab.xml
@@ -34,7 +34,7 @@
</LinearLayout>
- <com.google.android.material.floatingactionbutton.FloatingActionButton
+ <android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="bottom|end"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin.xml
index d6d9033..b3f1638 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin.xml
@@ -22,13 +22,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="192dp"
android:layout_width="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- <com.google.android.material.appbar.CollapsingToolbarLayout
+ <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -40,9 +40,9 @@
android:layout_width="match_parent"
app:layout_collapseMode="pin"/>
- </com.google.android.material.appbar.CollapsingToolbarLayout>
+ </android.support.design.widget.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_recyclerview"/>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin_nested.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin_nested.xml
index d96dacf..09e83cf 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin_nested.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin_nested.xml
@@ -22,12 +22,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="192dp"
android:layout_width="match_parent">
- <com.google.android.material.appbar.CollapsingToolbarLayout
+ <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -50,9 +50,9 @@
</FrameLayout>
- </com.google.android.material.appbar.CollapsingToolbarLayout>
+ </android.support.design.widget.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_recyclerview"/>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin_with_fab.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin_with_fab.xml
index c90ed6b..2660cb5 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin_with_fab.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_pin_with_fab.xml
@@ -22,13 +22,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="192dp"
android:layout_width="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- <com.google.android.material.appbar.CollapsingToolbarLayout
+ <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -40,13 +40,13 @@
android:layout_width="match_parent"
app:layout_collapseMode="pin"/>
- </com.google.android.material.appbar.CollapsingToolbarLayout>
+ </android.support.design.widget.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_scrollview"/>
- <com.google.android.material.floatingactionbutton.FloatingActionButton
+ <android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_anchor="@id/app_bar"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_scroll.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_scroll.xml
index 602bc25..9aa38af 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_scroll.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_scroll.xml
@@ -22,13 +22,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="192dp"
android:layout_width="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- <com.google.android.material.appbar.CollapsingToolbarLayout
+ <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -40,9 +40,9 @@
android:layout_width="match_parent"
app:layout_collapseMode="pin"/>
- </com.google.android.material.appbar.CollapsingToolbarLayout>
+ </android.support.design.widget.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_scrollview"/>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_scroll_with_swiperefresh.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_scroll_with_swiperefresh.xml
index 5910227..36c4020e 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_scroll_with_swiperefresh.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_scroll_with_swiperefresh.xml
@@ -22,13 +22,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="192dp"
android:layout_width="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- <com.google.android.material.appbar.CollapsingToolbarLayout
+ <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -40,9 +40,9 @@
android:layout_width="match_parent"
app:layout_collapseMode="pin"/>
- </com.google.android.material.appbar.CollapsingToolbarLayout>
+ </android.support.design.widget.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_recyclerview_swiperefresh"/>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_with_image.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_with_image.xml
index a671f91..fb801974 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_with_image.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_with_image.xml
@@ -22,13 +22,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="192dp"
android:layout_width="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- <com.google.android.material.appbar.CollapsingToolbarLayout
+ <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -49,9 +49,9 @@
android:layout_width="match_parent"
app:layout_collapseMode="pin"/>
- </com.google.android.material.appbar.CollapsingToolbarLayout>
+ </android.support.design.widget.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_scrollview"/>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_with_image_insets.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_with_image_insets.xml
index 6d6ad13..a38bdf4 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_with_image_insets.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_collapse_with_image_insets.xml
@@ -23,14 +23,14 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
- <com.google.android.material.appbar.CollapsingToolbarLayout
+ <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_app_bar"
android:layout_width="match_parent"
android:layout_height="256dp"
@@ -52,9 +52,9 @@
android:layout_width="match_parent"
app:layout_collapseMode="pin"/>
- </com.google.android.material.appbar.CollapsingToolbarLayout>
+ </android.support.design.widget.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_scrollview"/>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_parallax_overlap.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_parallax_overlap.xml
index 73c8391..86700aa 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_parallax_overlap.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_parallax_overlap.xml
@@ -22,13 +22,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="192dp"
android:layout_width="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- <com.google.android.material.appbar.CollapsingToolbarLayout
+ <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -49,9 +49,9 @@
android:layout_width="match_parent"
app:layout_collapseMode="pin"/>
- </com.google.android.material.appbar.CollapsingToolbarLayout>
+ </android.support.design.widget.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_scrollview_with_image" />
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_pinned.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_pinned.xml
index 0a5d9eb..e4682dd 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_pinned.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_pinned.xml
@@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
@@ -34,13 +34,13 @@
android:layout_width="match_parent"
app:layout_scrollFlags="scroll|enterAlways"/>
- <com.google.android.material.tabs.TabLayout
+ <android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"/>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_recyclerview"/>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_pinned_with_swiperefres.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_pinned_with_swiperefres.xml
index ae14514..b66ba33 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_pinned_with_swiperefres.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_pinned_with_swiperefres.xml
@@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
@@ -34,13 +34,13 @@
android:layout_width="match_parent"
app:layout_scrollFlags="scroll|enterAlways"/>
- <com.google.android.material.tabs.TabLayout
+ <android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"/>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_recyclerview_swiperefresh" />
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_scroll.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_scroll.xml
index 6b1856c..186d8d6 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_scroll.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_scroll.xml
@@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
@@ -34,14 +34,14 @@
android:layout_width="match_parent"
app:layout_scrollFlags="scroll|enterAlways"/>
- <com.google.android.material.tabs.TabLayout
+ <android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways"
app:tabMode="scrollable"/>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_scrollview"/>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_scroll_snap.xml b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_scroll_snap.xml
index 0bdb1a5..2154762 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_scroll_snap.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_appbar_toolbar_scroll_tabs_scroll_snap.xml
@@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.appbar.AppBarLayout
+ <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
@@ -34,14 +34,14 @@
android:layout_width="match_parent"
app:layout_scrollFlags="scroll|enterAlways|snap"/>
- <com.google.android.material.tabs.TabLayout
+ <android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:tabMode="scrollable"/>
- </com.google.android.material.appbar.AppBarLayout>
+ </android.support.design.widget.AppBarLayout>
<include layout="@layout/include_appbar_scrollview"/>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_bottom_navigation_view.xml b/samples/SupportDesignDemos/src/main/res/layout/design_bottom_navigation_view.xml
index a416573..b2a4d59 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_bottom_navigation_view.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_bottom_navigation_view.xml
@@ -66,7 +66,7 @@
android:layout_below="@+id/button_select_next"/>
</RelativeLayout>
</ScrollView>
- <com.google.android.material.bottomnavigation.BottomNavigationView
+ <android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="56dp"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_bottom_sheet_with_fab.xml b/samples/SupportDesignDemos/src/main/res/layout/design_bottom_sheet_with_fab.xml
index c0f2787..4776455 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_bottom_sheet_with_fab.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_bottom_sheet_with_fab.xml
@@ -61,7 +61,7 @@
</LinearLayout>
- <com.google.android.material.floatingactionbutton.FloatingActionButton
+ <android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_add"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_bottom_sheet_with_fragment.xml b/samples/SupportDesignDemos/src/main/res/layout/design_bottom_sheet_with_fragment.xml
index 5956de78..508e9e4 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_bottom_sheet_with_fragment.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_bottom_sheet_with_fragment.xml
@@ -43,7 +43,7 @@
<fragment
android:id="@+id/bottom_sheet"
- class="com.example.com.google.android.material.bottomsheet.BottomSheetWithFragment$BottomSheetFragment"
+ class="com.example.android.support.design.widget.BottomSheetWithFragment$BottomSheetFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/bottom_sheet_behavior"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_fab.xml b/samples/SupportDesignDemos/src/main/res/layout/design_fab.xml
index d9cd75a..c49ee07 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_fab.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_fab.xml
@@ -44,7 +44,7 @@
android:text="@string/fab_size_normal"
android:layout_margin="16dp"/>
- <com.google.android.material.floatingactionbutton.FloatingActionButton
+ <android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="16dp"
@@ -58,7 +58,7 @@
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:text="@string/fab_size_mini" />
- <com.google.android.material.floatingactionbutton.FloatingActionButton
+ <android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="16dp"
@@ -73,7 +73,7 @@
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:text="@string/fab_size_custom" />
- <com.google.android.material.floatingactionbutton.FloatingActionButton
+ <android.support.design.widget.FloatingActionButton
android:id="@+id/custom_fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_navigation.xml b/samples/SupportDesignDemos/src/main/res/layout/design_navigation.xml
index 37a9329..2a3c605 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_navigation.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_navigation.xml
@@ -47,7 +47,7 @@
</LinearLayout>
- <com.google.android.material.navigation.NavigationView
+ <android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_navigation_without_drawer.xml b/samples/SupportDesignDemos/src/main/res/layout/design_navigation_without_drawer.xml
index 7c4d044..548d339 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_navigation_without_drawer.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_navigation_without_drawer.xml
@@ -21,7 +21,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.navigation.NavigationView
+ <android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="0dp"
android:layout_height="match_parent"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_snackbar_with_fab.xml b/samples/SupportDesignDemos/src/main/res/layout/design_snackbar_with_fab.xml
index aaadca5..45ae83e 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_snackbar_with_fab.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_snackbar_with_fab.xml
@@ -58,7 +58,7 @@
</LinearLayout>
- <com.google.android.material.floatingactionbutton.FloatingActionButton
+ <android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="bottom|end"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_tabs_custom.xml b/samples/SupportDesignDemos/src/main/res/layout/design_tabs_custom.xml
index f8a3b18..72a0782 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_tabs_custom.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_tabs_custom.xml
@@ -31,7 +31,7 @@
app:contentInsetStart="72dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
- <com.google.android.material.tabs.TabLayout
+ <android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_height="wrap_content"
android:layout_width="match_parent"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_tabs_item.xml b/samples/SupportDesignDemos/src/main/res/layout/design_tabs_item.xml
index 6773b85..bcde5dc 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_tabs_item.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_tabs_item.xml
@@ -31,19 +31,19 @@
app:contentInsetStart="72dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
- <com.google.android.material.tabs.TabLayout
+ <android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- <com.google.android.material.tabs.TabItem
+ <android.support.design.widget.TabItem
android:text="@string/tab_text"/>
- <com.google.android.material.tabs.TabItem
+ <android.support.design.widget.TabItem
android:icon="@drawable/ic_android"/>
- </com.google.android.material.tabs.TabLayout>
+ </android.support.design.widget.TabLayout>
</LinearLayout>
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_tabs_viewpager.xml b/samples/SupportDesignDemos/src/main/res/layout/design_tabs_viewpager.xml
index 269dd2cd..c501136 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_tabs_viewpager.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_tabs_viewpager.xml
@@ -31,7 +31,7 @@
app:contentInsetStart="72dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
- <com.google.android.material.tabs.TabLayout
+ <android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_height="wrap_content"
android:layout_width="match_parent"
diff --git a/samples/SupportDesignDemos/src/main/res/layout/design_text_input.xml b/samples/SupportDesignDemos/src/main/res/layout/design_text_input.xml
index 2958f0d..fc9ff00 100644
--- a/samples/SupportDesignDemos/src/main/res/layout/design_text_input.xml
+++ b/samples/SupportDesignDemos/src/main/res/layout/design_text_input.xml
@@ -25,19 +25,19 @@
android:orientation="vertical"
android:padding="16dp">
- <com.google.android.material.textfield.TextInputLayout
+ <android.support.design.widget.TextInputLayout
android:id="@+id/input_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
- <com.google.android.material.textfield.TextInputEditText
+ <android.support.design.widget.TextInputEditText
android:id="@+id/edit_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/form_username" />
- </com.google.android.material.textfield.TextInputLayout>
+ </android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
@@ -64,22 +64,22 @@
</LinearLayout>
- <com.google.android.material.textfield.TextInputLayout
+ <android.support.design.widget.TextInputLayout
android:id="@+id/input_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:errorEnabled="true">
- <com.google.android.material.textfield.TextInputEditText
+ <android.support.design.widget.TextInputEditText
android:id="@+id/edit_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/form_email" />
- </com.google.android.material.textfield.TextInputLayout>
+ </android.support.design.widget.TextInputLayout>
- <com.google.android.material.textfield.TextInputLayout
+ <android.support.design.widget.TextInputLayout
android:id="@+id/input_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -93,9 +93,9 @@
android:layout_height="wrap_content"
android:hint="@string/form_description" />
- </com.google.android.material.textfield.TextInputLayout>
+ </android.support.design.widget.TextInputLayout>
- <com.google.android.material.textfield.TextInputLayout
+ <android.support.design.widget.TextInputLayout
android:id="@+id/input_auto_complete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -109,9 +109,9 @@
android:layout_height="wrap_content"
android:hint="@string/form_auto_complete" />
- </com.google.android.material.textfield.TextInputLayout>
+ </android.support.design.widget.TextInputLayout>
- <com.google.android.material.textfield.TextInputLayout
+ <android.support.design.widget.TextInputLayout
android:id="@+id/input_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -125,7 +125,7 @@
android:hint="@string/form_password"
android:inputType="textPassword" />
- </com.google.android.material.textfield.TextInputLayout>
+ </android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
diff --git a/samples/SupportMediaDemos/build.gradle b/samples/SupportMediaDemos/build.gradle
index fecf2a5..bf23177 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 b686fcd..267eafd 100644
--- a/samples/SupportMediaDemos/src/main/AndroidManifest.xml
+++ b/samples/SupportMediaDemos/src/main/AndroidManifest.xml
@@ -15,17 +15,14 @@
-->
<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 -->
<activity android:name="VideoSelector"
- android:theme="@style/Theme.AppCompat"
- android:configChanges="orientation|screenSize">
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:configChanges="orientation|screenSize"
+ >
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
@@ -34,8 +31,8 @@
<!-- Video playback activity -->
<activity android:name="VideoViewTest"
- android:theme="@style/Theme.AppCompat"
- android:configChanges="orientation|screenSize">
+ android:configChanges="orientation|screenSize"
+ >
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
</intent-filter>
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 2289769..d640303 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,7 +29,6 @@
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;
@@ -37,7 +36,6 @@
import android.view.WindowManager;
import android.widget.Toast;
-import androidx.fragment.app.FragmentActivity;
import androidx.media.widget.MediaControlView2;
import androidx.media.widget.VideoView2;
@@ -45,7 +43,7 @@
* Test application for VideoView2/MediaControlView2
*/
@SuppressLint("NewApi")
-public class VideoViewTest extends FragmentActivity {
+public class VideoViewTest extends Activity {
public static final String LOOPING_EXTRA_NAME =
"com.example.androidx.media.VideoViewTest.IsLooping";
public static final String USE_TEXTURE_VIEW_EXTRA_NAME =
@@ -73,7 +71,6 @@
setContentView(R.layout.video_activity);
mVideoView = findViewById(R.id.video_view);
- mVideoView.setActivity(this);
String errorString = null;
Intent intent = getIntent();
@@ -85,11 +82,12 @@
if (mUseTextureView) {
mVideoView.setViewType(VideoView2.VIEW_TYPE_TEXTUREVIEW);
}
+
+ mVideoView.setFullScreenRequestListener(new FullScreenRequestListener());
mVideoView.setVideoUri(contentUri);
mMediaControlView = new MediaControlView2(this);
mVideoView.setMediaControlView2(mMediaControlView, 2000);
- mMediaControlView.setOnFullScreenListener(new FullScreenListener());
}
if (errorString != null) {
showErrorDialog(errorString);
@@ -181,10 +179,9 @@
}
};
- private class FullScreenListener
- implements MediaControlView2.OnFullScreenListener {
+ private class FullScreenRequestListener implements VideoView2.OnFullScreenRequestListener {
@Override
- public void onFullScreen(View view, boolean fullScreen) {
+ public void onFullScreenRequest(View view, boolean fullScreen) {
// TODO: Remove bottom controls after adding back button functionality.
if (mPrevHeight == 0 && mPrevWidth == 0) {
ViewGroup.LayoutParams params = mVideoView.getLayoutParams();
@@ -226,7 +223,6 @@
public static class MyVideoView extends VideoView2 {
private float mDX;
private float mDY;
- private Activity mActivity;
public MyVideoView(Context context) {
super(context);
@@ -259,18 +255,6 @@
}
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/build.gradle b/samples/SupportSliceDemos/build.gradle
index bd68a95..8675869 100644
--- a/samples/SupportSliceDemos/build.gradle
+++ b/samples/SupportSliceDemos/build.gradle
@@ -24,6 +24,7 @@
implementation(project(":slice-view"))
implementation(project(":slice-builders"))
implementation(project(":slice-core"))
+ implementation("com.android.support:design:28.0.0-SNAPSHOT", { transitive = false })
implementation(project(":transition"))
implementation(project(":recyclerview"))
implementation(project(":appcompat"))
diff --git a/samples/SupportSliceDemos/src/main/AndroidManifest.xml b/samples/SupportSliceDemos/src/main/AndroidManifest.xml
index 4d43211..355a77a 100644
--- a/samples/SupportSliceDemos/src/main/AndroidManifest.xml
+++ b/samples/SupportSliceDemos/src/main/AndroidManifest.xml
@@ -48,7 +48,6 @@
<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/SampleSliceProvider.java b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
index afa5415..0beb745 100644
--- a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
+++ b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
@@ -65,27 +65,9 @@
public static final String ACTION_TOAST_RANGE_VALUE =
"com.example.androidx.slice.action.TOAST_RANGE_VALUE";
- public static final String[] URI_PATHS = {
- "message",
- "wifi",
- "note",
- "ride",
- "toggle",
- "toggle2",
- "toggletester",
- "contact",
- "contact2",
- "gallery",
- "gallery2",
- "weather",
- "reservation",
- "loadlist",
- "loadgrid",
- "inputrange",
- "range",
- "subscription",
- "singleitems",
- };
+ public static final String[] URI_PATHS = {"message", "wifi", "note", "ride", "toggle",
+ "toggle2", "contact", "gallery", "weather", "reservation", "loadlist", "loadgrid",
+ "inputrange", "range", "contact2", "subscription"};
/**
* @return Uri with the provided path
@@ -134,16 +116,12 @@
return createCustomToggleSlice(sliceUri);
case "/toggle2":
return createTwoCustomToggleSlices(sliceUri);
- case "/toggletester":
- return createdToggleTesterSlice(sliceUri);
case "/contact":
return createContact(sliceUri);
case "/contact2":
return createContact2(sliceUri);
case "/gallery":
- return createGallery(sliceUri, true /* showHeader */);
- case "/gallery2":
- return createGallery(sliceUri, false /* showHeader */);
+ return createGallery(sliceUri);
case "/weather":
return createWeather(sliceUri);
case "/reservation":
@@ -158,8 +136,6 @@
return createDownloadProgressRange(sliceUri);
case "/subscription":
return createCatSlice(sliceUri, false /* customSeeMore */);
- case "/singleitems":
- return createSingleSlice(sliceUri);
}
throw new IllegalArgumentException("Unknown uri " + sliceUri);
}
@@ -205,41 +181,58 @@
.build();
}
- private Slice createGallery(Uri sliceUri, boolean showHeader) {
+ private Slice createGallery(Uri sliceUri) {
SliceAction primaryAction = new SliceAction(
getBroadcastIntent(ACTION_TOAST, "open photo album"),
IconCompat.createWithResource(getContext(), R.drawable.slices_1),
LARGE_IMAGE,
"Open photo album");
- ListBuilder lb = new ListBuilder(getContext(), sliceUri, INFINITY)
- .setAccentColor(0xff4285F4);
- if (showHeader) {
- lb.addRow(b -> b
- .setTitle("Family trip to Hawaii")
- .setSubtitle("Sep 30, 2017 - Oct 2, 2017")
- .setPrimaryAction(primaryAction))
- .addAction(new SliceAction(
- getBroadcastIntent(ACTION_TOAST, "cast photo album"),
- IconCompat.createWithResource(getContext(), R.drawable.ic_cast),
- "Cast photo album"))
- .addAction(new SliceAction(
- getBroadcastIntent(ACTION_TOAST, "share photo album"),
- IconCompat.createWithResource(getContext(), R.drawable.ic_share),
- "Share photo album"));
- }
- int[] galleryResId = new int[] {R.drawable.slices_1, R.drawable.slices_2,
- R.drawable.slices_3, R.drawable.slices_4};
- int imageCount = 7;
- GridRowBuilder grb = new GridRowBuilder(lb);
- for (int i = 0; i < imageCount; i++) {
- IconCompat ic = IconCompat.createWithResource(getContext(),
- galleryResId[i % galleryResId.length]);
- grb.addCell(cb -> cb.addImage(ic, LARGE_IMAGE));
- }
- grb.setPrimaryAction(primaryAction)
- .setSeeMoreAction(getBroadcastIntent(ACTION_TOAST, "see your gallery"))
- .setContentDescription("Images from your trip to Hawaii");
- return lb.addGridRow(grb).build();
+ return new ListBuilder(getContext(), sliceUri, INFINITY)
+ .setColor(0xff4285F4)
+ .addRow(b -> b
+ .setTitle("Family trip to Hawaii")
+ .setSubtitle("Sep 30, 2017 - Oct 2, 2017")
+ .setPrimaryAction(primaryAction))
+ .addAction(new SliceAction(
+ getBroadcastIntent(ACTION_TOAST, "cast photo album"),
+ IconCompat.createWithResource(getContext(), R.drawable.ic_cast),
+ "Cast photo album"))
+ .addAction(new SliceAction(
+ getBroadcastIntent(ACTION_TOAST, "share photo album"),
+ IconCompat.createWithResource(getContext(), R.drawable.ic_share),
+ "Share photo album"))
+ .addGridRow(b -> b
+ .addCell(cb -> cb
+ .addImage(IconCompat.createWithResource(getContext(),
+ R.drawable.slices_1),
+ LARGE_IMAGE))
+ .addCell(cb -> cb
+ .addImage(IconCompat.createWithResource(getContext(),
+ R.drawable.slices_2),
+ LARGE_IMAGE))
+ .addCell(cb -> cb
+ .addImage(IconCompat.createWithResource(getContext(),
+ R.drawable.slices_3),
+ LARGE_IMAGE))
+ .addCell(cb -> cb
+ .addImage(IconCompat.createWithResource(getContext(),
+ R.drawable.slices_4),
+ LARGE_IMAGE))
+ .addCell(cb -> cb
+ .addImage(IconCompat.createWithResource(getContext(),
+ R.drawable.slices_2),
+ LARGE_IMAGE))
+ .addCell(cb -> cb
+ .addImage(IconCompat.createWithResource(getContext(),
+ R.drawable.slices_3),
+ LARGE_IMAGE))
+ .addCell(cb -> cb
+ .addImage(IconCompat.createWithResource(getContext(),
+ R.drawable.slices_4),
+ LARGE_IMAGE))
+ .setSeeMoreAction(getBroadcastIntent(ACTION_TOAST, "see your gallery"))
+ .setContentDescription("Images from your trip to Hawaii"))
+ .build();
}
private Slice createCatSlice(Uri sliceUri, boolean customSeeMore) {
@@ -287,7 +280,7 @@
ListBuilder b = new ListBuilder(getContext(), sliceUri, INFINITY);
ListBuilder.RowBuilder rb = new ListBuilder.RowBuilder(b);
GridRowBuilder gb = new GridRowBuilder(b);
- return b.setAccentColor(0xff3949ab)
+ return b.setColor(0xff3949ab)
.addRow(rb
.setTitle("Mady Pitza")
.setSubtitle("Frequently contacted contact")
@@ -329,7 +322,7 @@
R.drawable.mady), SMALL_IMAGE, "Mady");
return new ListBuilder(getContext(), sliceUri, INFINITY)
- .setAccentColor(0xff3949ab)
+ .setColor(0xff3949ab)
.setHeader(b -> b
.setTitle("Mady Pitza")
.setSummary("Called " + lastCalledString)
@@ -384,7 +377,7 @@
private Slice createNoteSlice(Uri sliceUri) {
// TODO: Remote input.
return new ListBuilder(getContext(), sliceUri, INFINITY)
- .setAccentColor(0xfff4b400)
+ .setColor(0xfff4b400)
.addRow(b -> b.setTitle("Create new note"))
.addAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, "create note"),
IconCompat.createWithResource(getContext(), R.drawable.ic_create),
@@ -400,7 +393,7 @@
private Slice createReservationSlice(Uri sliceUri) {
return new ListBuilder(getContext(), sliceUri, INFINITY)
- .setAccentColor(0xffFF5252)
+ .setColor(0xffFF5252)
.setHeader(b -> b
.setTitle("Upcoming trip to Seattle")
.setSubtitle("Feb 1 - 19 | 2 guests"))
@@ -438,8 +431,8 @@
SliceAction primaryAction = new SliceAction(getBroadcastIntent(ACTION_TOAST, "get ride"),
IconCompat.createWithResource(getContext(), R.drawable.ic_car), "Get Ride");
- return new ListBuilder(getContext(), sliceUri, TimeUnit.SECONDS.toMillis(10))
- .setAccentColor(0xff0F9D58)
+ return new ListBuilder(getContext(), sliceUri, -TimeUnit.MINUTES.toMillis(2))
+ .setColor(0xff0F9D58)
.setHeader(b -> b
.setTitle("Get ride")
.setSubtitle(headerSubtitle)
@@ -462,7 +455,7 @@
private Slice createCustomToggleSlice(Uri sliceUri) {
return new ListBuilder(getContext(), sliceUri, INFINITY)
- .setAccentColor(0xffff4081)
+ .setColor(0xffff4081)
.addRow(b -> b
.setTitle("Custom toggle")
.setSubtitle("It can support two states")
@@ -475,7 +468,7 @@
private Slice createTwoCustomToggleSlices(Uri sliceUri) {
return new ListBuilder(getContext(), sliceUri, INFINITY)
- .setAccentColor(0xffff4081)
+ .setColor(0xffff4081)
.addRow(b -> b
.setTitle("2 toggles")
.setSubtitle("each supports two states")
@@ -521,7 +514,7 @@
String sliceCDString = wifiEnabled ? "Wifi connected to " + state
: "Wifi disconnected, 10 networks available";
ListBuilder lb = new ListBuilder(getContext(), sliceUri, INFINITY)
- .setAccentColor(0xff4285f4)
+ .setColor(0xff4285f4)
.setHeader(b -> b
.setTitle("Wi-fi")
.setSubtitle(state)
@@ -577,7 +570,7 @@
new SliceAction(getBroadcastIntent(ACTION_TOAST, "open star rating"),
icon, "Rate");
return new ListBuilder(getContext(), sliceUri, INFINITY)
- .setAccentColor(0xffff4081)
+ .setColor(0xffff4081)
.addInputRange(c -> c
.setTitle("Star rating")
.setSubtitle("Rate from 5 to 10 because it's weird")
@@ -597,7 +590,7 @@
new SliceAction(
getBroadcastIntent(ACTION_TOAST, "open download"), icon, "Download");
return new ListBuilder(getContext(), sliceUri, INFINITY)
- .setAccentColor(0xffff4081)
+ .setColor(0xffff4081)
.addRange(c -> c
.setTitle("Download progress")
.setSubtitle("Download is happening")
@@ -607,116 +600,6 @@
.build();
}
- private Slice createdToggleTesterSlice(Uri uri) {
- IconCompat star = IconCompat.createWithResource(getContext(), R.drawable.toggle_star);
- IconCompat icon = IconCompat.createWithResource(getContext(), R.drawable.ic_star_on);
-
- SliceAction primaryAction = new SliceAction(
- getBroadcastIntent(ACTION_TOAST, "primary action"), icon, "Primary action");
- SliceAction toggleAction = new SliceAction(
- getBroadcastIntent(ACTION_TOAST, "star note"), star, "Star note", false);
- SliceAction toggleAction2 = new SliceAction(
- getBroadcastIntent(ACTION_TOAST, "star note 2"), star, "Star note 2", true);
- SliceAction toggleAction3 = new SliceAction(
- getBroadcastIntent(ACTION_TOAST, "star note 3"), star, "Star note 3", false);
-
- ListBuilder lb = new ListBuilder(getContext(), uri, INFINITY);
-
- // Primary action toggle
- ListBuilder.RowBuilder primaryToggle = new ListBuilder.RowBuilder(lb);
- primaryToggle.setTitle("Primary action is a toggle")
- .setPrimaryAction(toggleAction);
-
- // End toggle + normal primary action
- ListBuilder.RowBuilder endToggle = new ListBuilder.RowBuilder(lb);
- endToggle.setTitle("Only end toggles")
- .setSubtitle("Normal primary action")
- .setPrimaryAction(primaryAction)
- .addEndItem(toggleAction)
- .addEndItem(toggleAction2);
-
- // Start toggle + normal primary
- ListBuilder.RowBuilder startToggle = new ListBuilder.RowBuilder(lb);
- startToggle.setTitle("One start toggle")
- .setTitleItem(toggleAction)
- .setSubtitle("Normal primary action")
- .setPrimaryAction(primaryAction);
-
- // Start + end toggles + normal primary action
- ListBuilder.RowBuilder someToggles = new ListBuilder.RowBuilder(lb);
- someToggles.setTitleItem(toggleAction)
- .setPrimaryAction(primaryAction)
- .setTitle("Start & end toggles")
- .setSubtitle("Normal primary action")
- .addEndItem(toggleAction2)
- .addEndItem(toggleAction3);
-
- // Start toggle ONLY
- ListBuilder.RowBuilder startToggleOnly = new ListBuilder.RowBuilder(lb);
- startToggleOnly.setTitle("Start action is a toggle")
- .setSubtitle("No other actions")
- .setTitleItem(toggleAction);
-
- // End toggle ONLY
- ListBuilder.RowBuilder endToggleOnly = new ListBuilder.RowBuilder(lb);
- endToggleOnly.setTitle("End action is a toggle")
- .setSubtitle("No other actions")
- .addEndItem(toggleAction);
-
- // All toggles: end item should be ignored / replaced with primary action
- ListBuilder.RowBuilder muchToggles = new ListBuilder.RowBuilder(lb);
- muchToggles.setTitleItem(toggleAction)
- .setTitle("All toggles")
- .setSubtitle("Even the primary action")
- .setPrimaryAction(toggleAction2)
- .addEndItem(toggleAction3);
-
- lb.addRow(primaryToggle);
- lb.addRow(endToggleOnly);
- lb.addRow(endToggle);
- lb.addRow(startToggleOnly);
- lb.addRow(startToggle);
- lb.addRow(someToggles);
- lb.addRow(muchToggles);
- return lb.build();
- }
-
- private Slice createSingleSlice(Uri uri) {
- IconCompat ic2 = IconCompat.createWithResource(getContext(), R.drawable.ic_create);
- IconCompat image = IconCompat.createWithResource(getContext(), R.drawable.cat_3);
- IconCompat toggle = IconCompat.createWithResource(getContext(), R.drawable.toggle_star);
- SliceAction toggleAction = new SliceAction(
- getBroadcastIntent(ACTION_TOAST, "toggle action"), toggle, "toggle", false);
- SliceAction simpleAction = new SliceAction(
- getBroadcastIntent(ACTION_TOAST, "icon action"), ic2, "icon");
- ListBuilder lb = new ListBuilder(getContext(), uri, INFINITY);
- return lb.addRow(new ListBuilder.RowBuilder(lb)
- .setTitle("Single title"))
- .addRow(new ListBuilder.RowBuilder(lb)
- .setSubtitle("Single subtitle"))
- //Time stamps
- .addRow(new ListBuilder.RowBuilder(lb)
- .setTitleItem(System.currentTimeMillis()))
- .addRow(new ListBuilder.RowBuilder(lb)
- .addEndItem(System.currentTimeMillis()))
- // Toggle actions
- .addRow(new ListBuilder.RowBuilder(lb)
- .setTitleItem(toggleAction))
- .addRow(new ListBuilder.RowBuilder(lb)
- .addEndItem(toggleAction))
- // Icon actions
- .addRow(new ListBuilder.RowBuilder(lb)
- .setTitleItem(simpleAction))
- .addRow(new ListBuilder.RowBuilder(lb)
- .addEndItem(simpleAction))
- // Images
- .addRow(new ListBuilder.RowBuilder(lb)
- .setTitleItem(image, SMALL_IMAGE))
- .addRow(new ListBuilder.RowBuilder(lb)
- .addEndItem(image, SMALL_IMAGE))
- .build();
- }
-
private Handler mHandler = new Handler();
private SparseArray<String> mListSummaries = new SparseArray<>();
private long mListLastUpdate;
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 7b9d3d6..4facfb3 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,14 +16,13 @@
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;
@@ -49,7 +48,6 @@
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;
@@ -68,7 +66,7 @@
private static final String SLICE_METADATA_KEY = "android.metadata.SLICE_URI";
private static final boolean TEST_INTENT = false;
- private static final boolean TEST_THEMES = true;
+ private static final boolean TEST_THEMES = false;
private static final boolean SCROLLING_ENABLED = true;
private ArrayList<Uri> mSliceUris = new ArrayList<Uri>();
@@ -132,6 +130,7 @@
mSearchView.setQuery(savedInstanceState.getString("SELECTED_QUERY"), true);
}
+ grantPackage(getPackageName());
// TODO: Listen for changes.
updateAvailableSlices();
if (TEST_INTENT) {
@@ -147,6 +146,7 @@
mTypeMenu.add("Shortcut");
mTypeMenu.add("Small");
mTypeMenu.add("Large");
+ menu.add("Auth");
super.onCreateOptionsMenu(menu);
return true;
}
@@ -154,6 +154,9 @@
@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;
@@ -180,6 +183,21 @@
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()
@@ -221,17 +239,7 @@
mContainer.addView(v);
mSliceLiveData = SliceLiveData.fromUri(this, uri);
v.setMode(mSelectedMode);
- 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));
+ mSliceLiveData.observe(this, v);
} else {
Log.w(TAG, "Invalid uri, skipping slice: " + uri);
}
diff --git a/samples/SupportSliceDemos/src/main/res/values/styles.xml b/samples/SupportSliceDemos/src/main/res/values/styles.xml
index fcc4b1f..d276a41 100644
--- a/samples/SupportSliceDemos/src/main/res/values/styles.xml
+++ b/samples/SupportSliceDemos/src/main/res/values/styles.xml
@@ -34,7 +34,21 @@
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
<style name="CustomSliceView" parent="Widget.SliceView">
- <item name="gridTopPadding">4dp</item>
- <item name="gridBottomPadding">4dp</item>
+ <item name="tintColor">@color/tintColor</item>
+
+ <item name="titleColor">@color/textColor</item>
+ <item name="subtitleColor">@color/textColor</item>
+
+ <item name="headerTitleSize">@dimen/textSize</item>
+ <item name="headerSubtitleSize">@dimen/textSize</item>
+ <item name="titleSize">@dimen/textSize</item>
+ <item name="subtitleSize">@dimen/textSize</item>
+ <item name="gridTitleSize">@dimen/textSize</item>
+ <item name="gridSubtitleSize">@dimen/smallTextSize</item>
+
+ <item name="android:paddingLeft">8dp</item>
+ <item name="android:paddingTop">8dp</item>
+ <item name="android:paddingRight">8dp</item>
+ <item name="android:paddingBottom">8dp</item>
</style>
</resources>
diff --git a/slices/builders/api/current.txt b/slices/builders/api/current.txt
index f191aed..1041eb9 100644
--- a/slices/builders/api/current.txt
+++ b/slices/builders/api/current.txt
@@ -77,8 +77,7 @@
method public deprecated androidx.slice.builders.ListBuilder addSeeMoreAction(android.app.PendingIntent);
method public deprecated androidx.slice.builders.ListBuilder addSeeMoreRow(androidx.slice.builders.ListBuilder.RowBuilder);
method public deprecated androidx.slice.builders.ListBuilder addSeeMoreRow(androidx.core.util.Consumer<androidx.slice.builders.ListBuilder.RowBuilder>);
- method public androidx.slice.builders.ListBuilder setAccentColor(int);
- method public deprecated androidx.slice.builders.ListBuilder setColor(int);
+ method public androidx.slice.builders.ListBuilder setColor(int);
method public androidx.slice.builders.ListBuilder setHeader(androidx.slice.builders.ListBuilder.HeaderBuilder);
method public androidx.slice.builders.ListBuilder setHeader(androidx.core.util.Consumer<androidx.slice.builders.ListBuilder.HeaderBuilder>);
method public androidx.slice.builders.ListBuilder setKeywords(java.util.List<java.lang.String>);
diff --git a/slices/builders/build.gradle b/slices/builders/build.gradle
index 91c7599..ec85148 100644
--- a/slices/builders/build.gradle
+++ b/slices/builders/build.gradle
@@ -37,5 +37,4 @@
description = "A set of builders to create templates using SliceProvider APIs"
minSdkVersion = 19
failOnUncheckedWarnings = false
- failOnDeprecationWarnings = false
}
diff --git a/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java b/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
index 76b9e08..1c81ebd 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
@@ -82,10 +82,9 @@
* <ul>
* <li>{@link androidx.slice.widget.SliceView#MODE_SHORTCUT} - The primary {@link SliceAction}
* of the slice is used your primary action should contain an image and title representative
- * of your slice. If providing a tintable icon, use {@link #setAccentColor(int)} to specify the
- * color. If a header has been specified for the list, the primary action associated with it
- * will be used, otherwise it will be the primary action associated with the first row of the
- * list.
+ * of your slice. If providing a tintable icon, use {@link #setColor(int)} to specify the color.
+ * If a header has been specified for the list, the primary action associated with it will be
+ * used, otherwise it will be the primary action associated with the first row of the list.
* </li>
* <li>{@link androidx.slice.widget.SliceView#MODE_SMALL} - Only a single row of content is
* displayed in small format. If a header has been specified it will be displayed. If no header
@@ -311,15 +310,6 @@
}
/**
- * @deprecated TO BE REMOVED; use {@link #setAccentColor(int)} instead.
- */
- @Deprecated
- @NonNull
- public ListBuilder setColor(@ColorInt int color) {
- return setAccentColor(color);
- }
-
- /**
* Sets the color to use on tintable items within the list builder.
* Things that might be tinted are:
* <ul>
@@ -332,7 +322,7 @@
* </ul>
*/
@NonNull
- public ListBuilder setAccentColor(@ColorInt int color) {
+ public ListBuilder setColor(@ColorInt int color) {
mImpl.setColor(color);
return this;
}
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/GridRowBuilderListV1Impl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/GridRowBuilderListV1Impl.java
index 16471ed..714b570 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/GridRowBuilderListV1Impl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/GridRowBuilderListV1Impl.java
@@ -18,9 +18,11 @@
import static android.app.slice.Slice.HINT_HORIZONTAL;
import static android.app.slice.Slice.HINT_LARGE;
+import static android.app.slice.Slice.HINT_LIST_ITEM;
import static android.app.slice.Slice.HINT_NO_TINT;
import static android.app.slice.Slice.HINT_PARTIAL;
import static android.app.slice.Slice.HINT_SEE_MORE;
+import static android.app.slice.Slice.HINT_SHORTCUT;
import static android.app.slice.Slice.HINT_TITLE;
import static android.app.slice.Slice.SUBTYPE_CONTENT_DESCRIPTION;
@@ -57,12 +59,23 @@
/**
*/
@Override
- public void apply(Slice.Builder builder) {
- builder.addHints(HINT_HORIZONTAL);
+ @NonNull
+ public Slice build() {
+ Slice.Builder sb = new Slice.Builder(getBuilder())
+ .addHints(HINT_HORIZONTAL, HINT_LIST_ITEM);
+ sb.addSubSlice(getBuilder().addHints(HINT_HORIZONTAL, HINT_LIST_ITEM).build());
if (mPrimaryAction != null) {
- Slice.Builder actionBuilder = new Slice.Builder(getBuilder()).addHints(HINT_TITLE);
- builder.addSubSlice(mPrimaryAction.buildSlice(actionBuilder));
+ Slice.Builder actionBuilder = new Slice.Builder(getBuilder())
+ .addHints(HINT_SHORTCUT, HINT_TITLE);
+ sb.addSubSlice(mPrimaryAction.buildSlice(actionBuilder));
}
+ return sb.build();
+ }
+
+ /**
+ */
+ @Override
+ public void apply(Slice.Builder builder) {
}
/**
@@ -83,7 +96,7 @@
*/
@Override
public void addCell(TemplateBuilderImpl builder) {
- builder.apply(getBuilder());
+ getBuilder().addSubSlice(builder.getBuilder().addHints(HINT_LIST_ITEM).build());
}
@@ -92,7 +105,7 @@
@Override
public void setSeeMoreCell(@NonNull TemplateBuilderImpl builder) {
builder.getBuilder().addHints(HINT_SEE_MORE);
- builder.apply(getBuilder());
+ getBuilder().addSubSlice(builder.build());
}
/**
@@ -171,8 +184,8 @@
@Override
public void addTitleText(@Nullable CharSequence text, boolean isLoading) {
@Slice.SliceHint String[] hints = isLoading
- ? new String[] {HINT_PARTIAL, HINT_TITLE}
- : new String[] {HINT_TITLE};
+ ? new String[] {HINT_PARTIAL, HINT_LARGE}
+ : new String[] {HINT_LARGE};
getBuilder().addText(text, null, hints);
}
@@ -223,12 +236,20 @@
@RestrictTo(LIBRARY)
@Override
public void apply(Slice.Builder b) {
- getBuilder().addHints(HINT_HORIZONTAL);
+ }
+
+ /**
+ */
+ @Override
+ @NonNull
+ public Slice build() {
if (mContentIntent != null) {
- b.addAction(mContentIntent, getBuilder().build(), null);
- } else {
- b.addSubSlice(getBuilder().build());
+ return new Slice.Builder(getBuilder())
+ .addHints(HINT_HORIZONTAL)
+ .addAction(mContentIntent, getBuilder().build(), null)
+ .build();
}
+ return getBuilder().addHints(HINT_HORIZONTAL).build();
}
}
}
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderV1Impl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderV1Impl.java
index 8b16abe..c771b62 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderV1Impl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderV1Impl.java
@@ -76,7 +76,7 @@
*/
@Override
public void apply(Slice.Builder builder) {
- builder.addLong(System.currentTimeMillis(), SUBTYPE_MILLIS, HINT_LAST_UPDATED);
+ builder.addTimestamp(System.currentTimeMillis(), SUBTYPE_MILLIS, HINT_LAST_UPDATED);
if (mSliceHeader != null) {
builder.addSubSlice(mSliceHeader);
}
@@ -95,7 +95,6 @@
@NonNull
@Override
public void addRow(@NonNull TemplateBuilderImpl builder) {
- builder.getBuilder().addHints(HINT_LIST_ITEM);
getBuilder().addSubSlice(builder.build());
}
@@ -104,7 +103,6 @@
@NonNull
@Override
public void addGridRow(@NonNull TemplateBuilderImpl builder) {
- builder.getBuilder().addHints(HINT_LIST_ITEM);
getBuilder().addSubSlice(builder.build());
}
@@ -560,6 +558,7 @@
getBuilder()).addHints(HINT_TITLE, HINT_SHORTCUT);
b.addSubSlice(mPrimaryAction.buildSlice(sb), null);
}
+ b.addHints(HINT_LIST_ITEM);
}
}
diff --git a/slices/core/api/current.txt b/slices/core/api/current.txt
index c6077bf..09a69fd 100644
--- a/slices/core/api/current.txt
+++ b/slices/core/api/current.txt
@@ -26,7 +26,6 @@
}
public abstract class SliceProvider extends android.content.ContentProvider implements androidx.core.app.CoreComponentFactory.CompatWrapped {
- ctor public SliceProvider(java.lang.String...);
ctor public SliceProvider();
method public final int bulkInsert(android.net.Uri, android.content.ContentValues[]);
method public final android.net.Uri canonicalize(android.net.Uri);
diff --git a/slices/core/src/androidTest/java/androidx/slice/SliceTest.java b/slices/core/src/androidTest/java/androidx/slice/SliceTest.java
index e092c97..041c8fe 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_LONG, item.getFormat());
+ assertEquals(FORMAT_TIMESTAMP, item.getFormat());
assertEquals(43, item.getTimestamp());
}
diff --git a/slices/core/src/androidTest/java/androidx/slice/compat/CompatPermissionManagerTest.java b/slices/core/src/androidTest/java/androidx/slice/compat/CompatPermissionManagerTest.java
deleted file mode 100644
index 552df8c..0000000
--- a/slices/core/src/androidTest/java/androidx/slice/compat/CompatPermissionManagerTest.java
+++ /dev/null
@@ -1,94 +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.slice.compat;
-
-import static androidx.core.content.PermissionChecker.PERMISSION_DENIED;
-import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.PackageManager;
-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.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class CompatPermissionManagerTest {
-
- private final Context mContext = InstrumentationRegistry.getContext();
-
- @Test
- public void testAutoGrant() {
- final Uri uri = new Uri.Builder()
- .scheme(ContentResolver.SCHEME_CONTENT)
- .authority("my.authority")
- .path("my_path")
- .build();
- final String testPermission = "android.permission.SOME_PERMISSION";
-
- final int grantedPid = Process.myPid();
- final int grantedUid = Process.myUid();
-
- final int nonGrantedPid = grantedPid + 1;
- final int nonGrantedUid = grantedUid + 1;
-
- Context permContext = new ContextWrapper(mContext) {
- @Override
- public int checkPermission(String permission, int pid, int uid) {
- if (testPermission.equals(permission)) {
- if (grantedUid == uid) {
- return PackageManager.PERMISSION_GRANTED;
- } else if (nonGrantedUid == uid) {
- return PackageManager.PERMISSION_DENIED;
- }
- }
- return super.checkPermission(permission, pid, uid);
- }
-
- @Override
- public PackageManager getPackageManager() {
- PackageManager pm = spy(super.getPackageManager());
- when(pm.getPackagesForUid(grantedUid)).thenReturn(new String[] { "grant_pkg"});
- when(pm.getPackagesForUid(nonGrantedUid)).thenReturn(new String[] { "other_pkg"});
- return pm;
- }
- };
- CompatPermissionManager manager = spy(new CompatPermissionManager(permContext, "nothing", 0,
- new String[] {testPermission}));
-
- assertEquals(PERMISSION_DENIED, manager.checkSlicePermission(uri,
- nonGrantedPid, nonGrantedUid));
-
- assertEquals(PERMISSION_GRANTED, manager.checkSlicePermission(uri, grantedPid, grantedUid));
- verify(manager).grantSlicePermission(eq(uri), eq("grant_pkg"));
-
- }
-
-}
diff --git a/slices/core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java b/slices/core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java
deleted file mode 100644
index cc4ba49..0000000
--- a/slices/core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java
+++ /dev/null
@@ -1,134 +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.slice.compat;
-
-import static androidx.core.content.PermissionChecker.PERMISSION_DENIED;
-import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;
-import static androidx.slice.compat.SliceProviderCompat.EXTRA_BIND_URI;
-import static androidx.slice.compat.SliceProviderCompat.EXTRA_SLICE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import androidx.slice.Slice;
-import androidx.slice.SliceProvider;
-import androidx.slice.SliceSpec;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Collections;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SliceProviderCompatTest {
-
- private final Context mContext = InstrumentationRegistry.getContext();
-
- @Test
- public void testBindWithPermission() {
- Uri uri = new Uri.Builder()
- .scheme(ContentResolver.SCHEME_CONTENT)
- .authority("my.authority")
- .path("my_path")
- .build();
- Slice s = new Slice.Builder(uri)
- .addText("", null)
- .build();
-
- SliceProvider provider = spy(new SliceProviderImpl());
- CompatPermissionManager permissions = mock(CompatPermissionManager.class);
- when(permissions.checkSlicePermission(any(Uri.class), anyInt(), anyInt()))
- .thenReturn(PERMISSION_GRANTED);
-
- when(provider.onBindSlice(eq(uri))).thenReturn(s);
- SliceProviderCompat compat = new SliceProviderCompat(provider, permissions,
- mContext) {
- @Override
- public String getCallingPackage() {
- return mContext.getPackageName();
- }
- };
-
- Bundle b = new Bundle();
- b.putParcelable(EXTRA_BIND_URI, uri);
- SliceProviderCompat.addSpecs(b, Collections.<SliceSpec>emptySet());
-
- Bundle result = compat.call(SliceProviderCompat.METHOD_SLICE, null, b);
- assertEquals(s.toString(), new Slice(result.getBundle(EXTRA_SLICE)).toString());
- }
-
- @Test
- public void testBindWithoutPermission() {
- Uri uri = new Uri.Builder()
- .scheme(ContentResolver.SCHEME_CONTENT)
- .authority("my.authority")
- .path("my_path")
- .build();
- Slice s = new Slice.Builder(uri)
- .addText("", null)
- .build();
-
- SliceProvider provider = spy(new SliceProviderImpl());
- CompatPermissionManager permissions = mock(CompatPermissionManager.class);
- when(permissions.checkSlicePermission(any(Uri.class), anyInt(), anyInt()))
- .thenReturn(PERMISSION_DENIED);
-
- when(provider.onBindSlice(eq(uri))).thenReturn(s);
- SliceProviderCompat compat = new SliceProviderCompat(provider, permissions,
- mContext) {
- @Override
- public String getCallingPackage() {
- return mContext.getPackageName();
- }
- };
-
- Bundle b = new Bundle();
- b.putParcelable(EXTRA_BIND_URI, uri);
- SliceProviderCompat.addSpecs(b, Collections.<SliceSpec>emptySet());
-
- Bundle result = compat.call(SliceProviderCompat.METHOD_SLICE, null, b);
- assertNotEquals(s.toString(), new Slice(result.getBundle(EXTRA_SLICE)).toString());
- }
-
- public static class SliceProviderImpl extends SliceProvider {
-
- @Override
- public boolean onCreateSliceProvider() {
- return true;
- }
-
- @Override
- public Slice onBindSlice(Uri sliceUri) {
- return null;
- }
- }
-}
diff --git a/slices/core/src/main/java/androidx/slice/Slice.java b/slices/core/src/main/java/androidx/slice/Slice.java
index aa077cb..d18ef23 100644
--- a/slices/core/src/main/java/androidx/slice/Slice.java
+++ b/slices/core/src/main/java/androidx/slice/Slice.java
@@ -35,6 +35,7 @@
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;
@@ -387,7 +388,7 @@
}
/**
- * Add a long to the slice being constructed
+ * Add a timestamp to the slice being constructed
* @param subType Optional template-specific type information
* @see {@link SliceItem#getSubType()}
*/
@@ -398,16 +399,6 @@
}
/**
- * 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()}
@@ -416,7 +407,7 @@
@Deprecated
public Slice.Builder addTimestamp(long time, @Nullable String subType,
@SliceHint String... hints) {
- mItems.add(new SliceItem(time, FORMAT_LONG, subType, hints));
+ mItems.add(new SliceItem(time, FORMAT_TIMESTAMP, subType, hints));
return this;
}
@@ -464,37 +455,20 @@
public String toString(String indent) {
StringBuilder sb = new StringBuilder();
sb.append(indent);
- sb.append("slice ");
- addHints(sb, mHints);
- sb.append("{\n");
- String nextIndent = indent + " ";
+ sb.append("slice: ");
+ sb.append("\n");
+ indent += " ";
for (int i = 0; i < mItems.length; i++) {
SliceItem item = mItems[i];
- sb.append(item.toString(nextIndent));
+ sb.append(item.toString(indent));
+ if (!FORMAT_SLICE.equals(item.getFormat())) {
+ sb.append("\n");
+ }
}
- 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
@@ -519,6 +493,6 @@
private static Slice callBindSlice(Context context, Uri uri,
Set<SliceSpec> supportedSpecs) {
return SliceConvert.wrap(context.getSystemService(SliceManager.class)
- .bindSlice(uri, unwrap(supportedSpecs)));
+ .bindSlice(uri, new ArrayList<>(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 fea5b4ca..73ff368 100644
--- a/slices/core/src/main/java/androidx/slice/SliceConvert.java
+++ b/slices/core/src/main/java/androidx/slice/SliceConvert.java
@@ -19,16 +19,17 @@
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;
/**
@@ -42,8 +43,9 @@
*/
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(), unwrap(slice.getSpec()));
+ slice.getUri());
builder.addHints(slice.getHints());
+ builder.setSpec(unwrap(slice.getSpec()));
for (androidx.slice.SliceItem item : slice.getItems()) {
switch (item.getFormat()) {
case FORMAT_SLICE:
@@ -65,8 +67,8 @@
case FORMAT_INT:
builder.addInt(item.getInt(), item.getSubType(), item.getHints());
break;
- case FORMAT_LONG:
- builder.addLong(item.getLong(), item.getSubType(), item.getHints());
+ case FORMAT_TIMESTAMP:
+ builder.addTimestamp(item.getTimestamp(), item.getSubType(), item.getHints());
break;
}
}
@@ -117,8 +119,8 @@
case FORMAT_INT:
builder.addInt(item.getInt(), item.getSubType(), item.getHints());
break;
- case FORMAT_LONG:
- builder.addLong(item.getLong(), item.getSubType(), item.getHints());
+ case FORMAT_TIMESTAMP:
+ builder.addTimestamp(item.getTimestamp(), item.getSubType(), item.getHints());
break;
}
}
@@ -135,7 +137,7 @@
*/
@RestrictTo(RestrictTo.Scope.LIBRARY)
public static Set<androidx.slice.SliceSpec> wrap(
- Set<android.app.slice.SliceSpec> supportedSpecs) {
+ List<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 f6ae848..004e51d 100644
--- a/slices/core/src/main/java/androidx/slice/SliceItem.java
+++ b/slices/core/src/main/java/androidx/slice/SliceItem.java
@@ -23,8 +23,7 @@
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 androidx.slice.Slice.addHints;
+import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
import android.app.PendingIntent;
import android.app.RemoteInput;
@@ -58,7 +57,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_LONG}</li>
+ * <li>{@link android.app.slice.SliceItem#FORMAT_TIMESTAMP}</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
@@ -77,7 +76,7 @@
*/
@RestrictTo(Scope.LIBRARY)
@StringDef({FORMAT_SLICE, FORMAT_TEXT, FORMAT_IMAGE, FORMAT_ACTION, FORMAT_INT,
- FORMAT_LONG, FORMAT_REMOTE_INPUT, FORMAT_LONG})
+ FORMAT_TIMESTAMP, FORMAT_REMOTE_INPUT, FORMAT_LONG})
public @interface SliceType {
}
@@ -163,7 +162,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_LONG}</li>
+ * <li>{@link android.app.slice.SliceItem#FORMAT_TIMESTAMP}</li>
* <li>{@link android.app.slice.SliceItem#FORMAT_REMOTE_INPUT}</li>
* @see #getSubType() ()
*/
@@ -346,7 +345,7 @@
case FORMAT_INT:
dest.putInt(OBJ, (Integer) mObj);
break;
- case FORMAT_LONG:
+ case FORMAT_TIMESTAMP:
dest.putLong(OBJ, (Long) mObj);
break;
}
@@ -368,7 +367,7 @@
new Slice(in.getBundle(OBJ_2)));
case FORMAT_INT:
return in.getInt(OBJ);
- case FORMAT_LONG:
+ case FORMAT_TIMESTAMP:
return in.getLong(OBJ);
}
throw new RuntimeException("Unsupported type " + type);
@@ -390,8 +389,8 @@
return "Action";
case FORMAT_INT:
return "Int";
- case FORMAT_LONG:
- return "Long";
+ case FORMAT_TIMESTAMP:
+ return "Timestamp";
case FORMAT_REMOTE_INPUT:
return "RemoteInput";
}
@@ -413,35 +412,36 @@
@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(indent).append(getAction()).append(",\n");
+ sb.append(getAction());
+ sb.append("\n");
sb.append(getSlice().toString(indent));
break;
case FORMAT_TEXT:
- sb.append(indent).append('"').append(getText()).append('"');
+ sb.append(getText());
break;
case FORMAT_IMAGE:
- sb.append(indent).append(getIcon());
+ sb.append(getIcon());
break;
case FORMAT_INT:
- sb.append(indent).append(getInt());
+ sb.append(getInt());
break;
- case FORMAT_LONG:
- sb.append(indent).append(getLong());
+ case FORMAT_TIMESTAMP:
+ sb.append(getTimestamp());
break;
default:
- sb.append(indent).append(SliceItem.typeToString(getFormat()));
+ sb.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 9c604eb..7ec9232 100644
--- a/slices/core/src/main/java/androidx/slice/SliceProvider.java
+++ b/slices/core/src/main/java/androidx/slice/SliceProvider.java
@@ -20,9 +20,20 @@
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.PERMS_PREFIX;
+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;
@@ -37,23 +48,26 @@
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;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
-import androidx.annotation.VisibleForTesting;
import androidx.core.app.CoreComponentFactory;
import androidx.core.os.BuildCompat;
-import androidx.slice.compat.CompatPermissionManager;
-import androidx.slice.compat.SliceProviderCompat;
+import androidx.slice.compat.CompatPinnedList;
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;
@@ -104,31 +118,14 @@
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 String[] mAutoGrantPermissions;
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+ private CompatPinnedList mPinnedList;
- private SliceProviderCompat mCompat;
-
-
- /**
- * A version of constructing a SliceProvider that allows autogranting slice permissions
- * to apps that hold specific platform permissions.
- * <p>
- * When an app tries to bind a slice from this provider that it does not have access to,
- * This provider will check if the caller holds permissions to any of the autoGrantPermissions
- * specified, if they do they will be granted persisted uri access to all slices of this
- * provider.
- *
- * @param autoGrantPermissions List of permissions that holders are auto-granted access
- * to slices.
- */
- public SliceProvider(@NonNull String... autoGrantPermissions) {
- mAutoGrantPermissions = autoGrantPermissions;
- }
-
- public SliceProvider() {
- mAutoGrantPermissions = new String[0];
- }
+ private String mCallback;
/**
* Implement this to initialize your slice provider on startup.
@@ -150,33 +147,18 @@
@Override
public Object getWrapper() {
if (BuildCompat.isAtLeastP()) {
- return new SliceProviderWrapperContainer.SliceProviderWrapper(this,
- mAutoGrantPermissions);
+ return new SliceProviderWrapperContainer.SliceProviderWrapper(this);
}
return null;
}
@Override
public final boolean onCreate() {
- if (!BuildCompat.isAtLeastP()) {
- mCompat = new SliceProviderCompat(this,
- onCreatePermissionManager(mAutoGrantPermissions), getContext());
- }
+ mPinnedList = new CompatPinnedList(getContext(),
+ DATA_PREFIX + getClass().getName());
return onCreateSliceProvider();
}
- /**
- * @hide
- * @param autoGrantPermissions
- */
- @VisibleForTesting
- @RestrictTo(RestrictTo.Scope.LIBRARY)
- protected CompatPermissionManager onCreatePermissionManager(
- String[] autoGrantPermissions) {
- return new CompatPermissionManager(getContext(), PERMS_PREFIX + getClass().getName(),
- Process.myUid(), autoGrantPermissions);
- }
-
@Override
public final String getType(Uri uri) {
if (DEBUG) Log.d(TAG, "getFormat " + uri);
@@ -185,7 +167,115 @@
@Override
public Bundle call(String method, String arg, Bundle extras) {
- return mCompat != null ? mCompat.call(method, arg, extras) : null;
+ 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);
}
/**
@@ -247,6 +337,35 @@
}
}
+ 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
deleted file mode 100644
index 8321a05..0000000
--- a/slices/core/src/main/java/androidx/slice/compat/CompatPermissionManager.java
+++ /dev/null
@@ -1,220 +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.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.annotation.RestrictTo;
-import androidx.collection.ArraySet;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * @hide
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
-public class CompatPermissionManager {
-
- private static final String TAG = "CompatPermissionManager";
- public static final String ALL_SUFFIX = "_all";
-
- private final Context mContext;
- private final String mPrefsName;
- private final int mMyUid;
- private final String[] mAutoGrantPermissions;
-
- public CompatPermissionManager(Context context, String prefsName, int myUid,
- String[] autoGrantPermissions) {
- mContext = context;
- mPrefsName = prefsName;
- mMyUid = myUid;
- mAutoGrantPermissions = autoGrantPermissions;
- }
-
- private SharedPreferences getPrefs() {
- return mContext.getSharedPreferences(mPrefsName, Context.MODE_PRIVATE);
- }
-
- public int checkSlicePermission(Uri uri, int pid, int uid) {
- if (uid == mMyUid) {
- return PERMISSION_GRANTED;
- }
- String[] pkgs = mContext.getPackageManager().getPackagesForUid(uid);
- for (String pkg : pkgs) {
- if (checkSlicePermission(uri, pkg) == PERMISSION_GRANTED) {
- return PERMISSION_GRANTED;
- }
- }
- for (String autoGrantPermission : mAutoGrantPermissions) {
- if (mContext.checkPermission(autoGrantPermission, pid, uid) == PERMISSION_GRANTED) {
- for (String pkg : pkgs) {
- grantSlicePermission(uri, pkg);
- }
- 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 da602f5..56b8122 100644
--- a/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java
+++ b/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java
@@ -28,8 +28,6 @@
import androidx.core.util.ObjectsCompat;
import androidx.slice.SliceSpec;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Set;
/**
@@ -72,22 +70,6 @@
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>());
}
@@ -103,8 +85,8 @@
if (TextUtils.isEmpty(specNamesStr) || TextUtils.isEmpty(specRevsStr)) {
return new ArraySet<>();
}
- String[] specNames = specNamesStr.split(",", -1);
- String[] specRevs = specRevsStr.split(",", -1);
+ String[] specNames = specNamesStr.split(",");
+ String[] specRevs = specRevsStr.split(",");
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 5fa33ae..f3270f8 100644
--- a/slices/core/src/main/java/androidx/slice/compat/SlicePermissionActivity.java
+++ b/slices/core/src/main/java/androidx/slice/compat/SlicePermissionActivity.java
@@ -20,20 +20,16 @@
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnDismissListener;
-import android.content.pm.ApplicationInfo;
+import android.content.Intent;
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;
/**
@@ -44,8 +40,6 @@
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;
@@ -62,12 +56,8 @@
try {
PackageManager pm = getPackageManager();
- CharSequence app1 = BidiFormatter.getInstance().unicodeWrap(
- loadSafeLabel(pm, pm.getApplicationInfo(mCallingPkg, 0))
- .toString());
- CharSequence app2 = BidiFormatter.getInstance().unicodeWrap(
- loadSafeLabel(pm, pm.getApplicationInfo(mProviderPkg, 0))
- .toString());
+ CharSequence app1 = pm.getApplicationInfo(mCallingPkg, 0).loadLabel(pm);
+ CharSequence app2 = pm.getApplicationInfo(mProviderPkg, 0).loadLabel(pm);
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle(getString(R.string.abc_slice_permission_title, app1, app2))
.setView(R.layout.abc_slice_permission_request)
@@ -85,50 +75,14 @@
}
}
- // 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) {
- SliceProviderCompat.grantSlicePermission(this, getPackageName(), mCallingPkg,
- mUri.buildUpon().path("").build());
+ 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);
}
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 22e832e..61bc65e 100644
--- a/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
+++ b/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
@@ -15,30 +15,19 @@
*/
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 static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;
-
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;
@@ -47,8 +36,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;
@@ -61,13 +50,9 @@
*/
@RestrictTo(Scope.LIBRARY)
public class SliceProviderCompat {
- public static final String PERMS_PREFIX = "slice_perms_";
private static final String TAG = "SliceProviderCompat";
- private static final String DATA_PREFIX = "slice_data_";
- private static final String ALL_FILES = DATA_PREFIX + "all_slice_files";
- private static final long SLICE_BIND_ANR = 2000;
-
+ public static final String EXTRA_BIND_URI = "slice_uri";
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";
@@ -75,11 +60,7 @@
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";
@@ -87,213 +68,22 @@
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 final Context mContext;
-
- private String mCallback;
- private final SliceProvider mProvider;
- private CompatPinnedList mPinnedList;
- private CompatPermissionManager mPermissionManager;
-
- public SliceProviderCompat(SliceProvider provider, CompatPermissionManager permissionManager,
- Context context) {
- mProvider = provider;
- mContext = context;
- String prefsFile = DATA_PREFIX + getClass().getName();
- SharedPreferences allFiles = mContext.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(mContext, prefsFile);
- mPermissionManager = permissionManager;
- }
-
- private Context getContext() {
- return mContext;
- }
-
- public 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 != null ? s.toBundle() : null);
- 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 != null ? s.toBundle() : null);
- } 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 (mPermissionManager.checkSlicePermission(sliceUri, Binder.getCallingPid(),
- Binder.getCallingUid()) != PERMISSION_GRANTED) {
- 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}.
*/
public static Slice bindSlice(Context context, Uri uri,
Set<SliceSpec> supportedSpecs) {
- ProviderHolder holder = acquireClient(context.getContentResolver(), uri);
- if (holder.mProvider == null) {
+ ContentProviderClient provider = context.getContentResolver()
+ .acquireContentProviderClient(uri);
+ if (provider == null) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
try {
Bundle extras = new Bundle();
extras.putParcelable(EXTRA_BIND_URI, uri);
addSpecs(extras, supportedSpecs);
- final Bundle res = holder.mProvider.call(METHOD_SLICE, null, extras);
+ final Bundle res = provider.call(METHOD_SLICE, null, extras);
if (res == null) {
return null;
}
@@ -303,9 +93,15 @@
}
return new Slice((Bundle) bundle);
} catch (RemoteException e) {
- Log.e(TAG, "Unable to bind slice", e);
+ // Arbitrary and not worth documenting, as Activity
+ // Manager will kill this process shortly anyway.
return null;
} finally {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ provider.close();
+ } else {
+ provider.release();
+ }
}
}
@@ -341,10 +137,6 @@
*/
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
@@ -353,37 +145,23 @@
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(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;
+ context.getPackageManager().queryIntentContentProviders(intent, 0);
+ if (providers == null) {
+ throw new IllegalArgumentException("Unable to resolve intent " + intent);
}
String authority = providers.get(0).providerInfo.authority;
Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority).build();
- ProviderHolder holder = acquireClient(resolver, uri);
- if (holder.mProvider == null) {
+ ContentProviderClient provider = resolver.acquireContentProviderClient(uri);
+ if (provider == null) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
try {
Bundle extras = new Bundle();
extras.putParcelable(EXTRA_INTENT, intent);
addSpecs(extras, supportedSpecs);
- final Bundle res = holder.mProvider.call(METHOD_MAP_INTENT, null, extras);
+ final Bundle res = provider.call(METHOD_MAP_INTENT, null, extras);
if (res == null) {
return null;
}
@@ -393,8 +171,11 @@
}
return new Slice((Bundle) bundle);
} catch (RemoteException e) {
- Log.e(TAG, "Unable to bind slice", e);
+ // Arbitrary and not worth documenting, as Activity
+ // Manager will kill this process shortly anyway.
return null;
+ } finally {
+ provider.close();
}
}
@@ -403,8 +184,9 @@
*/
public static void pinSlice(Context context, Uri uri,
Set<SliceSpec> supportedSpecs) {
- ProviderHolder holder = acquireClient(context.getContentResolver(), uri);
- if (holder.mProvider == null) {
+ ContentProviderClient provider = context.getContentResolver()
+ .acquireContentProviderClient(uri);
+ if (provider == null) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
try {
@@ -412,9 +194,12 @@
extras.putParcelable(EXTRA_BIND_URI, uri);
extras.putString(EXTRA_PKG, context.getPackageName());
addSpecs(extras, supportedSpecs);
- holder.mProvider.call(METHOD_PIN, null, extras);
+ provider.call(METHOD_PIN, null, extras);
} catch (RemoteException e) {
- Log.e(TAG, "Unable to pin slice", e);
+ // Arbitrary and not worth documenting, as Activity
+ // Manager will kill this process shortly anyway.
+ } finally {
+ provider.close();
}
}
@@ -423,8 +208,9 @@
*/
public static void unpinSlice(Context context, Uri uri,
Set<SliceSpec> supportedSpecs) {
- ProviderHolder holder = acquireClient(context.getContentResolver(), uri);
- if (holder.mProvider == null) {
+ ContentProviderClient provider = context.getContentResolver()
+ .acquireContentProviderClient(uri);
+ if (provider == null) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
try {
@@ -432,9 +218,12 @@
extras.putParcelable(EXTRA_BIND_URI, uri);
extras.putString(EXTRA_PKG, context.getPackageName());
addSpecs(extras, supportedSpecs);
- holder.mProvider.call(METHOD_UNPIN, null, extras);
+ provider.call(METHOD_UNPIN, null, extras);
} catch (RemoteException e) {
- Log.e(TAG, "Unable to unpin slice", e);
+ // Arbitrary and not worth documenting, as Activity
+ // Manager will kill this process shortly anyway.
+ } finally {
+ provider.close();
}
}
@@ -442,21 +231,26 @@
* Compat version of {@link android.app.slice.SliceManager#getPinnedSpecs(Uri)}.
*/
public static Set<SliceSpec> getPinnedSpecs(Context context, Uri uri) {
- ProviderHolder holder = acquireClient(context.getContentResolver(), uri);
- if (holder.mProvider == null) {
+ ContentProviderClient provider = context.getContentResolver()
+ .acquireContentProviderClient(uri);
+ if (provider == null) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
try {
Bundle extras = new Bundle();
extras.putParcelable(EXTRA_BIND_URI, uri);
- final Bundle res = holder.mProvider.call(METHOD_GET_PINNED_SPECS, null, extras);
- if (res != null) {
- return getSpecs(res);
+ final Bundle res = provider.call(METHOD_GET_PINNED_SPECS, null, extras);
+ if (res == null) {
+ return null;
}
+ return getSpecs(res);
} catch (RemoteException e) {
- Log.e(TAG, "Unable to get pinned specs", e);
+ // Arbitrary and not worth documenting, as Activity
+ // Manager will kill this process shortly anyway.
+ return null;
+ } finally {
+ provider.close();
}
- return null;
}
/**
@@ -464,8 +258,7 @@
*/
public static Uri mapIntentToUri(Context context, Intent intent) {
Preconditions.checkNotNull(intent, "intent");
- Preconditions.checkArgument(intent.getComponent() != null || intent.getPackage() != null
- || intent.getData() != null,
+ Preconditions.checkArgument(intent.getComponent() != null || intent.getPackage() != null,
String.format("Slice intent must be explicit %s", intent));
ContentResolver resolver = context.getContentResolver();
@@ -475,41 +268,39 @@
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(queryIntent, 0);
+ context.getPackageManager().queryIntentContentProviders(intent, 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)) {
+ && resolve.activityInfo.metaData.containsKey(SliceHints.SLICE_METADATA_KEY)) {
return Uri.parse(
- resolve.activityInfo.metaData.getString(SLICE_METADATA_KEY));
+ resolve.activityInfo.metaData.getString(SliceHints.SLICE_METADATA_KEY));
}
return null;
}
String authority = providers.get(0).providerInfo.authority;
Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority).build();
- try (ProviderHolder holder = acquireClient(resolver, uri)) {
- if (holder.mProvider == null) {
+ try (ContentProviderClient provider = resolver.acquireContentProviderClient(uri)) {
+ if (provider == null) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
Bundle extras = new Bundle();
extras.putParcelable(EXTRA_INTENT, intent);
- final Bundle res = holder.mProvider.call(METHOD_MAP_ONLY_INTENT, null, extras);
- if (res != null) {
- return res.getParcelable(EXTRA_SLICE);
+ final Bundle res = provider.call(METHOD_MAP_ONLY_INTENT, null, extras);
+ if (res == null) {
+ return null;
}
+ return res.getParcelable(EXTRA_SLICE);
} catch (RemoteException e) {
- Log.e(TAG, "Unable to map slice", e);
+ // Arbitrary and not worth documenting, as Activity
+ // Manager will kill this process shortly anyway.
+ return null;
}
- return null;
}
/**
@@ -517,114 +308,17 @@
*/
public static @NonNull Collection<Uri> getSliceDescendants(Context context, @NonNull Uri uri) {
ContentResolver resolver = context.getContentResolver();
- try (ProviderHolder holder = acquireClient(resolver, uri)) {
+ try (ContentProviderClient provider = resolver.acquireContentProviderClient(uri)) {
Bundle extras = new Bundle();
extras.putParcelable(EXTRA_BIND_URI, uri);
- final Bundle res = holder.mProvider.call(METHOD_GET_DESCENDANTS, null, extras);
- if (res != null) {
- return res.getParcelableArrayList(EXTRA_SLICE_DESCENDANTS);
- }
+ final Bundle res = provider.call(METHOD_GET_DESCENDANTS, null, extras);
+ return res.getParcelableArrayList(EXTRA_SLICE_DESCENDANTS);
} catch (RemoteException e) {
Log.e(TAG, "Unable to get slice descendants", e);
}
return Collections.emptyList();
}
- /**
- * 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 (ProviderHolder holder = acquireClient(resolver, 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 = holder.mProvider.call(METHOD_CHECK_PERMISSION, null, extras);
- if (res != null) {
- 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 (ProviderHolder holder = acquireClient(resolver, uri)) {
- Bundle extras = new Bundle();
- extras.putParcelable(EXTRA_BIND_URI, uri);
- extras.putString(EXTRA_PROVIDER_PKG, packageName);
- extras.putString(EXTRA_PKG, toPackage);
-
- holder.mProvider.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 (ProviderHolder holder = acquireClient(resolver, uri)) {
- Bundle extras = new Bundle();
- extras.putParcelable(EXTRA_BIND_URI, uri);
- extras.putString(EXTRA_PROVIDER_PKG, packageName);
- extras.putString(EXTRA_PKG, toPackage);
-
- holder.mProvider.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;
- }
-
- private static ProviderHolder acquireClient(ContentResolver resolver, Uri uri) {
- ContentProviderClient provider = resolver.acquireContentProviderClient(uri);
- if (provider == null) {
- throw new IllegalArgumentException("No provider found for " + uri);
- }
- return new ProviderHolder(provider);
- }
-
- private static class ProviderHolder implements AutoCloseable {
- private final ContentProviderClient mProvider;
-
- ProviderHolder(ContentProviderClient provider) {
- this.mProvider = provider;
- }
-
- @Override
- public void close() {
- if (mProvider == null) return;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- mProvider.close();
- } else {
- mProvider.release();
- }
- }
+ private SliceProviderCompat() {
}
}
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 c04c2fd..8641530 100644
--- a/slices/core/src/main/java/androidx/slice/compat/SliceProviderWrapperContainer.java
+++ b/slices/core/src/main/java/androidx/slice/compat/SliceProviderWrapperContainer.java
@@ -29,10 +29,11 @@
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
+import androidx.collection.ArraySet;
import androidx.slice.SliceConvert;
import java.util.Collection;
-import java.util.Set;
+import java.util.List;
/**
* @hide
@@ -47,9 +48,7 @@
private androidx.slice.SliceProvider mSliceProvider;
- public SliceProviderWrapper(androidx.slice.SliceProvider provider,
- String[] autoGrantPermissions) {
- super(autoGrantPermissions);
+ public SliceProviderWrapper(androidx.slice.SliceProvider provider) {
mSliceProvider = provider;
}
@@ -65,8 +64,8 @@
}
@Override
- public Slice onBindSlice(Uri sliceUri, Set<SliceSpec> supportedVersions) {
- androidx.slice.SliceProvider.setSpecs(wrap(supportedVersions));
+ public Slice onBindSlice(Uri sliceUri, List<SliceSpec> supportedVersions) {
+ androidx.slice.SliceProvider.setSpecs(new ArraySet<>(wrap(supportedVersions)));
try {
return SliceConvert.unwrap(mSliceProvider.onBindSlice(sliceUri));
} finally {
diff --git a/slices/core/src/main/res/values-as/strings.xml b/slices/core/src/main/res/values-as/strings.xml
deleted file mode 100644
index 95722b9..0000000
--- a/slices/core/src/main/res/values-as/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-~ Copyright 2018 The Android Open Source Project
-~
-~ Licensed under the Apache License, Version 2.0 (the "License");
-~ you may not use this file except in compliance with the License.
-~ You may obtain a copy of the License at
-~
-~ http://www.apache.org/licenses/LICENSE-2.0
-~
-~ Unless required by applicable law or agreed to in writing, software
-~ distributed under the License is distributed on an "AS IS" BASIS,
-~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-~ See the License for the specific language governing permissions and
-~ limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="abc_slices_permission_request" msgid="3604847235923472451">"<xliff:g id="APP_0">%1$s</xliff:g>এ <xliff:g id="APP_2">%2$s</xliff:g>ৰ অংশ দেখুওৱাব খুজিছে"</string>
- <string name="abc_slice_permission_title" msgid="4175332421259324948">"<xliff:g id="APP_0">%1$s</xliff:g>ক <xliff:g id="APP_2">%2$s</xliff:g>ৰ অংশ দেখুওৱাবলৈ অনুমতি দিবনে?"</string>
- <string name="abc_slice_permission_text_1" msgid="4525743640399572811">"- ই <xliff:g id="APP">%1$s</xliff:g>ৰ তথ্য পঢ়িব পাৰে"</string>
- <string name="abc_slice_permission_text_2" msgid="7323565634860251794">"- ই <xliff:g id="APP">%1$s</xliff:g>ৰ ভিতৰত কাৰ্য কৰিব পাৰে"</string>
- <string name="abc_slice_permission_checkbox" msgid="5696872682700058611">"<xliff:g id="APP">%1$s</xliff:g>ক যিকোনো এপৰ অংশ দেখুওৱাবলৈ অনুমতি দিয়ক"</string>
- <string name="abc_slice_permission_allow" msgid="5024599872061409708">"অনুমতি দিয়ক"</string>
- <string name="abc_slice_permission_deny" msgid="3819478292430407705">"অস্বীকাৰ কৰক"</string>
-</resources>
diff --git a/slices/core/src/main/res/values-be/strings.xml b/slices/core/src/main/res/values-be/strings.xml
index 5fadc3f..c9fc9a8 100644
--- a/slices/core/src/main/res/values-be/strings.xml
+++ b/slices/core/src/main/res/values-be/strings.xml
@@ -17,11 +17,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="abc_slices_permission_request" msgid="3604847235923472451">"Праграма <xliff:g id="APP_0">%1$s</xliff:g> запытвае дазвол на паказ фрагментаў праграмы <xliff:g id="APP_2">%2$s</xliff:g>"</string>
- <string name="abc_slice_permission_title" msgid="4175332421259324948">"Дазволіць праграме <xliff:g id="APP_0">%1$s</xliff:g> паказваць фрагменты праграмы <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
+ <string name="abc_slices_permission_request" msgid="3604847235923472451">"Праграма <xliff:g id="APP_0">%1$s</xliff:g> запытвае дазвол на паказ зрэзаў праграмы <xliff:g id="APP_2">%2$s</xliff:g>"</string>
+ <string name="abc_slice_permission_title" msgid="4175332421259324948">"Дазволіць праграме <xliff:g id="APP_0">%1$s</xliff:g> паказваць зрэзы праграмы <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
<string name="abc_slice_permission_text_1" msgid="4525743640399572811">"- Можа счытваць інфармацыю з праграмы <xliff:g id="APP">%1$s</xliff:g>"</string>
<string name="abc_slice_permission_text_2" msgid="7323565634860251794">"- Можа выконваць дзеянні ў праграме <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="abc_slice_permission_checkbox" msgid="5696872682700058611">"Дазволіць праграме <xliff:g id="APP">%1$s</xliff:g> паказваць фрагменты іншых праграм"</string>
+ <string name="abc_slice_permission_checkbox" msgid="5696872682700058611">"Дазволіць праграме <xliff:g id="APP">%1$s</xliff:g> паказваць зрэзы іншых праграм"</string>
<string name="abc_slice_permission_allow" msgid="5024599872061409708">"Дазволіць"</string>
<string name="abc_slice_permission_deny" msgid="3819478292430407705">"Адмовіць"</string>
</resources>
diff --git a/slices/core/src/main/res/values-ja/strings.xml b/slices/core/src/main/res/values-ja/strings.xml
index 315326f..a04df0b 100644
--- a/slices/core/src/main/res/values-ja/strings.xml
+++ b/slices/core/src/main/res/values-ja/strings.xml
@@ -19,7 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slices_permission_request" msgid="3604847235923472451">"<xliff:g id="APP_0">%1$s</xliff:g> が <xliff:g id="APP_2">%2$s</xliff:g> のスライスの表示をリクエストしています"</string>
<string name="abc_slice_permission_title" msgid="4175332421259324948">"<xliff:g id="APP_2">%2$s</xliff:g> のスライスの表示を <xliff:g id="APP_0">%1$s</xliff:g> に許可しますか?"</string>
- <string name="abc_slice_permission_text_1" msgid="4525743640399572811">"- <xliff:g id="APP">%1$s</xliff:g> からの情報を読み取ることができます"</string>
+ <string name="abc_slice_permission_text_1" msgid="4525743640399572811">"- <xliff:g id="APP">%1$s</xliff:g> からの情報を読み取ることがあります"</string>
<string name="abc_slice_permission_text_2" msgid="7323565634860251794">"- <xliff:g id="APP">%1$s</xliff:g> 内部で操作することがあります"</string>
<string name="abc_slice_permission_checkbox" msgid="5696872682700058611">"すべてのアプリのスライスを表示することを <xliff:g id="APP">%1$s</xliff:g> に許可する"</string>
<string name="abc_slice_permission_allow" msgid="5024599872061409708">"許可"</string>
diff --git a/slices/core/src/main/res/values-or/strings.xml b/slices/core/src/main/res/values-or/strings.xml
deleted file mode 100644
index f6b9443..0000000
--- a/slices/core/src/main/res/values-or/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-~ Copyright 2018 The Android Open Source Project
-~
-~ Licensed under the Apache License, Version 2.0 (the "License");
-~ you may not use this file except in compliance with the License.
-~ You may obtain a copy of the License at
-~
-~ http://www.apache.org/licenses/LICENSE-2.0
-~
-~ Unless required by applicable law or agreed to in writing, software
-~ distributed under the License is distributed on an "AS IS" BASIS,
-~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-~ See the License for the specific language governing permissions and
-~ limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="abc_slices_permission_request" msgid="3604847235923472451">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> ସ୍ଲାଇସ୍କୁ ଦେଖାଇବା ପାଇଁ ଚାହେଁ"</string>
- <string name="abc_slice_permission_title" msgid="4175332421259324948">"<xliff:g id="APP_2">%2$s</xliff:g> ସ୍ଲାଇସ୍କୁ ଦେଖାଇବା ପାଇଁ <xliff:g id="APP_0">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
- <string name="abc_slice_permission_text_1" msgid="4525743640399572811">"- ଏହା <xliff:g id="APP">%1$s</xliff:g>ରୁ ସୂଚନାକୁ ପଢ଼ିପାରିବ"</string>
- <string name="abc_slice_permission_text_2" msgid="7323565634860251794">"- ଏହା <xliff:g id="APP">%1$s</xliff:g> ଭିତରେ କାମ କରିପାରିବ"</string>
- <string name="abc_slice_permission_checkbox" msgid="5696872682700058611">"ଯେକୌଣସି ଆପ୍ରେ ସ୍ଲାଇସ୍କୁ ଦେଖାଇବା ପାଇଁ <xliff:g id="APP">%1$s</xliff:g>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
- <string name="abc_slice_permission_allow" msgid="5024599872061409708">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
- <string name="abc_slice_permission_deny" msgid="3819478292430407705">"ଅସ୍ଵୀକାର କରନ୍ତୁ"</string>
-</resources>
diff --git a/slices/view/api/current.txt b/slices/view/api/current.txt
index 7be0368..5a37826 100644
--- a/slices/view/api/current.txt
+++ b/slices/view/api/current.txt
@@ -5,8 +5,6 @@
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);
@@ -26,7 +24,6 @@
method public static androidx.slice.SliceMetadata from(android.content.Context, androidx.slice.Slice);
method public long getExpiry();
method public int getHeaderType();
- method public android.app.PendingIntent getInputRangeAction();
method public long getLastUpdatedTime();
method public int getLoadingState();
method public androidx.slice.core.SliceAction getPrimaryAction();
@@ -120,13 +117,12 @@
method public java.util.List<androidx.slice.SliceItem> getSliceActions();
method public void onChanged(androidx.slice.Slice);
method public void onClick(android.view.View);
- method public void setAccentColor(int);
method public void setMode(int);
method public void setOnSliceActionListener(androidx.slice.widget.SliceView.OnSliceActionListener);
method public void setScrollable(boolean);
method public void setSlice(androidx.slice.Slice);
method public void setSliceActions(java.util.List<androidx.slice.SliceItem>);
- method public deprecated void setTint(int);
+ method public void setTint(int);
field public static final int MODE_LARGE = 2; // 0x2
field public static final int MODE_SHORTCUT = 3; // 0x3
field public static final int MODE_SMALL = 1; // 0x1
diff --git a/slices/view/src/androidTest/AndroidManifest.xml b/slices/view/src/androidTest/AndroidManifest.xml
index 7c90f90..78f3ad8 100644
--- a/slices/view/src/androidTest/AndroidManifest.xml
+++ b/slices/view/src/androidTest/AndroidManifest.xml
@@ -27,7 +27,6 @@
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 e0e8f51..5564f72 100644
--- a/slices/view/src/androidTest/java/androidx/slice/SliceManagerTest.java
+++ b/slices/view/src/androidTest/java/androidx/slice/SliceManagerTest.java
@@ -16,10 +16,7 @@
package androidx.slice;
-import static androidx.slice.compat.SliceProviderCompat.PERMS_PREFIX;
-
import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -39,8 +36,8 @@
import androidx.annotation.NonNull;
import androidx.core.os.BuildCompat;
-import androidx.slice.compat.CompatPermissionManager;
import androidx.slice.render.SliceRenderActivity;
+import androidx.slice.widget.SliceLiveData;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +45,6 @@
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
import java.util.concurrent.Executor;
@RunWith(AndroidJUnit4.class)
@@ -93,28 +89,6 @@
}
@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;
@@ -150,8 +124,7 @@
mManager.pinSlice(uri);
verify(mSliceProvider).onSlicePinned(eq(uri));
- // Disabled while we update APIs.
- //assertEquals(SliceLiveData.SUPPORTED_SPECS, mManager.getPinnedSpecs(uri));
+ assertEquals(SliceLiveData.SUPPORTED_SPECS, mManager.getPinnedSpecs(uri));
}
@Test
@@ -172,8 +145,8 @@
when(mSliceProvider.onMapIntentToUri(eq(intent))).thenReturn(expected);
Uri uri = mManager.mapIntentToUri(intent);
- verify(mSliceProvider).onMapIntentToUri(eq(intent));
assertEquals(expected, uri);
+ verify(mSliceProvider).onMapIntentToUri(eq(intent));
}
@Test
@@ -239,12 +212,6 @@
}
}
- protected CompatPermissionManager onCreatePermissionManager(
- String[] autoGrantPermissions) {
- return new CompatPermissionManager(getContext(), PERMS_PREFIX + getClass().getName(),
- -1 /* Different uid to run permissions */, autoGrantPermissions);
- }
-
@Override
public Collection<Uri> onGetSliceDescendants(Uri uri) {
if (sSliceProviderReceiver != null) {
diff --git a/slices/view/src/androidTest/java/androidx/slice/SliceMetadataTest.java b/slices/view/src/androidTest/java/androidx/slice/SliceMetadataTest.java
index 78c8cf6..650114e 100644
--- a/slices/view/src/androidTest/java/androidx/slice/SliceMetadataTest.java
+++ b/slices/view/src/androidTest/java/androidx/slice/SliceMetadataTest.java
@@ -16,6 +16,7 @@
package androidx.slice;
+import static android.app.slice.Slice.HINT_PARTIAL;
import static android.app.slice.Slice.HINT_TITLE;
import static androidx.slice.SliceMetadata.LOADED_ALL;
@@ -23,7 +24,6 @@
import static androidx.slice.SliceMetadata.LOADED_PARTIAL;
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
import static androidx.slice.core.SliceHints.HINT_KEYWORDS;
-import static androidx.slice.core.SliceHints.INFINITY;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
@@ -36,6 +36,7 @@
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.drawable.Icon;
import android.net.Uri;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
@@ -91,7 +92,7 @@
PendingIntent pi = getIntent("");
Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
new Canvas(b).drawColor(0xffff0000);
- IconCompat icon = IconCompat.createWithBitmap(b);
+ IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
SliceAction action1 = new SliceAction(pi, icon, "action1");
SliceAction action2 = new SliceAction(pi, icon, "action2");
@@ -122,7 +123,7 @@
PendingIntent pi = getIntent("");
Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
new Canvas(b).drawColor(0xffff0000);
- IconCompat icon = IconCompat.createWithBitmap(b);
+ IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
SliceAction primaryAction = new SliceAction(pi, icon, "action");
@@ -145,7 +146,7 @@
PendingIntent pi = getIntent("");
Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
new Canvas(b).drawColor(0xffff0000);
- IconCompat icon = IconCompat.createWithBitmap(b);
+ IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
SliceAction primaryAction = new SliceAction(pi, icon, "action");
SliceAction endAction = new SliceAction(pi, "toogle action", false);
@@ -168,7 +169,7 @@
PendingIntent pi = getIntent("");
Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
new Canvas(b).drawColor(0xffff0000);
- IconCompat icon = IconCompat.createWithBitmap(b);
+ IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
SliceAction primaryAction = new SliceAction(pi, icon, "action");
SliceAction sliceAction = new SliceAction(pi, "another action", true);
@@ -191,7 +192,7 @@
PendingIntent pi = getIntent("");
Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
new Canvas(b).drawColor(0xffff0000);
- IconCompat icon = IconCompat.createWithBitmap(b);
+ IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
SliceAction endAction1 = new SliceAction(pi, icon, "action");
SliceAction endAction2 = new SliceAction(pi, "toogle action", false);
@@ -262,7 +263,7 @@
.setTitle("another title")
.setValue(5)
.setMax(10)
- .setInputAction(pi));
+ .setAction(pi));
Slice sliderSlice = lb.build();
SliceMetadata sliderInfo = SliceMetadata.from(mContext, sliderSlice);
@@ -304,22 +305,22 @@
Uri uri = Uri.parse("content://pkg/slice");
Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
new Canvas(b).drawColor(0xffff0000);
- IconCompat icon = IconCompat.createWithBitmap(b);
+ Icon icon = Icon.createWithBitmap(b);
ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
GridRowBuilder grb = new GridRowBuilder(lb);
grb.addCell(new GridRowBuilder.CellBuilder(grb)
.addText("some text")
.addText("more text")
- .addImage(icon, ICON_IMAGE));
+ .addImage(IconCompat.createFromIcon(icon), ICON_IMAGE));
grb.addCell(new GridRowBuilder.CellBuilder(grb)
.addText("some text")
.addText("more text")
- .addImage(icon, ICON_IMAGE));
+ .addImage(IconCompat.createFromIcon(icon), ICON_IMAGE));
grb.addCell(new GridRowBuilder.CellBuilder(grb)
.addText("some text")
.addText("more text")
- .addImage(icon, ICON_IMAGE));
+ .addImage(IconCompat.createFromIcon(icon), ICON_IMAGE));
lb.addGridRow(grb);
Slice gridSlice = lb.build();
@@ -406,7 +407,7 @@
PendingIntent pi = getIntent("");
Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
new Canvas(b).drawColor(0xffff0000);
- IconCompat icon = IconCompat.createWithBitmap(b);
+ IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
SliceAction toggleAction = new SliceAction(pi, icon, "toggle", false /* isChecked */);
SliceAction toggleAction2 = new SliceAction(pi, icon, "toggle2", true /* isChecked */);
@@ -467,31 +468,6 @@
}
@Test
- public void testGetInputRangeAction() {
- Uri uri = Uri.parse("content://pkg/slice");
- PendingIntent expectedIntent = getIntent("rangeintent");
-
- Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
- new Canvas(b).drawColor(0xffff0000);
- IconCompat icon = IconCompat.createWithBitmap(b);
- SliceAction primaryAction = new SliceAction(getIntent(""), icon, "action");
-
- ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
- lb.addInputRange(new ListBuilder.InputRangeBuilder(lb)
- .setTitle("another title")
- .setValue(7)
- .setMin(5)
- .setMax(10)
- .setPrimaryAction(primaryAction)
- .setInputAction(expectedIntent));
- Slice sliderSlice = lb.build();
-
- SliceMetadata sliderInfo = SliceMetadata.from(mContext, sliderSlice);
- assertEquals(expectedIntent, sliderInfo.getInputRangeAction());
- assertEquivalent(primaryAction, sliderInfo.getPrimaryAction());
- }
-
- @Test
public void testGetRangeForProgress() {
Uri uri = Uri.parse("content://pkg/slice");
@@ -551,23 +527,17 @@
@Test
public void testGetLoadingState() {
Uri uri = Uri.parse("content://pkg/slice");
- Slice s1 = new ListBuilder(mContext, uri, INFINITY).build();
+ Slice s1 = new Slice.Builder(uri).build();
SliceMetadata SliceMetadata1 = SliceMetadata.from(mContext, s1);
int actualState1 = SliceMetadata1.getLoadingState();
assertEquals(LOADED_NONE, actualState1);
- ListBuilder lb = new ListBuilder(mContext, uri, INFINITY);
- Slice s2 = lb.addRow(new ListBuilder.RowBuilder(lb)
- .setTitle(null, true /* isLoading */))
- .build();
+ Slice s2 = new Slice.Builder(uri).addText(null, null, HINT_PARTIAL).build();
SliceMetadata SliceMetadata2 = SliceMetadata.from(mContext, s2);
int actualState2 = SliceMetadata2.getLoadingState();
assertEquals(LOADED_PARTIAL, actualState2);
- ListBuilder lb2 = new ListBuilder(mContext, uri, INFINITY);
- Slice s3 = lb2.addRow(new ListBuilder.RowBuilder(lb2)
- .setTitle("Title", false /* isLoading */))
- .build();
+ Slice s3 = new Slice.Builder(uri).addText("Text", null).build();
SliceMetadata SliceMetadata3 = SliceMetadata.from(mContext, s3);
int actualState3 = SliceMetadata3.getLoadingState();
assertEquals(LOADED_ALL, actualState3);
@@ -580,9 +550,9 @@
long ttl = TimeUnit.DAYS.toMillis(1);
Slice ttlSlice = new Slice.Builder(uri)
.addText("Some text", null)
- .addLong(timestamp, null)
- .addLong(timestamp, null, SliceHints.HINT_LAST_UPDATED)
- .addLong(ttl, null, SliceHints.HINT_TTL)
+ .addTimestamp(timestamp, null)
+ .addTimestamp(timestamp, null, SliceHints.HINT_LAST_UPDATED)
+ .addTimestamp(ttl, null, SliceHints.HINT_TTL)
.build();
SliceMetadata si1 = SliceMetadata.from(mContext, ttlSlice);
@@ -591,7 +561,7 @@
Slice noTtlSlice = new Slice.Builder(uri)
.addText("Some text", null)
- .addLong(timestamp, null).build();
+ .addTimestamp(timestamp, null).build();
SliceMetadata si2 = SliceMetadata.from(mContext, noTtlSlice);
long retrievedTtl2 = si2.getExpiry();
assertEquals(0, retrievedTtl2);
@@ -604,9 +574,9 @@
long ttl = TimeUnit.DAYS.toMillis(1);
Slice ttlSlice = new Slice.Builder(uri)
.addText("Some text", null)
- .addLong(timestamp - 20, null)
- .addLong(timestamp, null, SliceHints.HINT_LAST_UPDATED)
- .addLong(ttl, null, SliceHints.HINT_TTL)
+ .addTimestamp(timestamp - 20, null)
+ .addTimestamp(timestamp, null, SliceHints.HINT_LAST_UPDATED)
+ .addTimestamp(ttl, null, SliceHints.HINT_TTL)
.build();
SliceMetadata si1 = SliceMetadata.from(mContext, ttlSlice);
@@ -615,7 +585,7 @@
Slice noTtlSlice = new Slice.Builder(uri)
.addText("Some text", null)
- .addLong(timestamp, null).build();
+ .addTimestamp(timestamp, null).build();
SliceMetadata si2 = SliceMetadata.from(mContext, noTtlSlice);
long retrievedLastUpdated2 = si2.getLastUpdatedTime();
diff --git a/slices/view/src/androidTest/java/androidx/slice/SlicePermissionTest.java b/slices/view/src/androidTest/java/androidx/slice/SlicePermissionTest.java
deleted file mode 100644
index ffb65e0..0000000
--- a/slices/view/src/androidTest/java/androidx/slice/SlicePermissionTest.java
+++ /dev/null
@@ -1,185 +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.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/androidTest/java/androidx/slice/render/RenderTest.java b/slices/view/src/androidTest/java/androidx/slice/render/RenderTest.java
index 4c3b6fc..deb1f90 100644
--- a/slices/view/src/androidTest/java/androidx/slice/render/RenderTest.java
+++ b/slices/view/src/androidTest/java/androidx/slice/render/RenderTest.java
@@ -16,15 +16,12 @@
package androidx.slice.render;
-import static android.os.Build.VERSION.SDK_INT;
-
import static androidx.slice.render.SliceRenderer.SCREENSHOT_DIR;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.os.Build;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -32,11 +29,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -47,7 +39,7 @@
private final Context mContext = InstrumentationRegistry.getContext();
@Test
- public void testRender() throws Exception {
+ public void testRender() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
@@ -61,53 +53,8 @@
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
latch.await(30000, TimeUnit.MILLISECONDS);
- String path = new File(mContext.getFilesDir(), SCREENSHOT_DIR).getAbsolutePath();
- if (SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
- "mv " + path + " " + "/sdcard/");
- } else {
- deleteDir(new File("/sdcard/" + SCREENSHOT_DIR));
- copyDirectory(new File(path), new File("/sdcard/" + SCREENSHOT_DIR));
- }
- }
-
-
- public static void copyDirectory(File sourceLocation, File targetLocation) throws Exception {
- if (sourceLocation.isDirectory()) {
- if (!targetLocation.exists()) {
- targetLocation.mkdirs();
- }
-
- String[] children = sourceLocation.list();
- for (int i = 0; i < children.length; i++) {
- copyDirectory(new File(sourceLocation, children[i]), new File(
- targetLocation, children[i]));
- }
- } else {
- copyFile(sourceLocation, targetLocation);
- }
- }
-
- public static void copyFile(File sourceLocation, File targetLocation) throws Exception {
- InputStream in = new FileInputStream(sourceLocation);
- OutputStream out = new FileOutputStream(targetLocation);
-
- byte[] buf = new byte[1024];
- int len;
- while ((len = in.read(buf)) > 0) {
- out.write(buf, 0, len);
- }
- in.close();
- out.close();
- }
-
- static void deleteDir(File file) {
- File[] contents = file.listFiles();
- if (contents != null) {
- for (File f : contents) {
- deleteDir(f);
- }
- }
- file.delete();
+ String path = mContext.getDataDir().toString() + "/" + SCREENSHOT_DIR;
+ InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
+ "mv " + path + " " + "/sdcard/");
}
}
diff --git a/slices/view/src/androidTest/java/androidx/slice/render/SliceCreator.java b/slices/view/src/androidTest/java/androidx/slice/render/SliceCreator.java
index 5f08f3f..2312b36 100644
--- a/slices/view/src/androidTest/java/androidx/slice/render/SliceCreator.java
+++ b/slices/view/src/androidTest/java/androidx/slice/render/SliceCreator.java
@@ -57,27 +57,9 @@
"com.example.androidx.slice.action.TOAST";
public static final String EXTRA_TOAST_MESSAGE = "com.example.androidx.extra.TOAST_MESSAGE";
- public static final String[] URI_PATHS = {
- "message",
- "wifi",
- "wifi2",
- "note",
- "ride",
- "ride-ttl",
- "toggle",
- "toggle2",
- "contact",
- "gallery",
- "subscription",
- "subscription2",
- "weather",
- "reservation",
- "inputrange",
- "inputrange2",
- "range",
- "permission",
- "empty",
- };
+ public static final String[] URI_PATHS = {"message", "wifi", "wifi2", "note", "ride",
+ "ride-ttl", "toggle", "toggle2", "contact", "gallery", "subscription", "subscription2",
+ "weather", "reservation", "inputrange", "range", "permission"};
private final Context mContext;
@@ -133,14 +115,10 @@
return createReservationSlice(sliceUri);
case "/inputrange":
return createStarRatingInputRange(sliceUri);
- case "/inputrange2":
- return createBasicInputRange(sliceUri);
case "/range":
return createDownloadProgressRange(sliceUri);
case "/permission":
return createPermissionSlice(sliceUri);
- case "/empty":
- return new ListBuilder(getContext(), sliceUri, INFINITY).build();
}
throw new IllegalArgumentException("Unknown uri " + sliceUri);
}
@@ -258,7 +236,7 @@
"See contact info"), IconCompat.createWithResource(getContext(),
R.drawable.mady), SMALL_IMAGE, "Mady");
GridRowBuilder gb = new GridRowBuilder(b);
- return b.setAccentColor(0xff3949ab)
+ return b.setColor(0xff3949ab)
.addRow(rb
.setTitle("Mady Pitza")
.setSubtitle("Frequently contacted contact")
@@ -314,7 +292,7 @@
private Slice createNoteSlice(Uri sliceUri) {
// TODO: Remote input.
ListBuilder lb = new ListBuilder(getContext(), sliceUri, INFINITY);
- return lb.setAccentColor(0xfff4b400)
+ return lb.setColor(0xfff4b400)
.addRow(new ListBuilder.RowBuilder(lb)
.setTitle("Create new note")
.setSubtitle("with this note taking app")
@@ -344,11 +322,11 @@
? -TimeUnit.MINUTES.toMillis(2) // negative for testing
: INFINITY;
ListBuilder lb = new ListBuilder(getContext(), sliceUri, ttl);
- return lb.setAccentColor(0xff0F9D58)
+ return lb.setColor(0xff0F9D58)
.setHeader(new ListBuilder.HeaderBuilder(lb)
.setTitle("Get ride")
.setSubtitle(headerSubtitle)
- .setSummary("Ride to work in 12 min | Ride home in 1 hour 45 min")
+ .setSummarySubtitle("Ride to work in 12 min | Ride home in 1 hour 45 min")
.setPrimaryAction(primaryAction))
.addRow(new ListBuilder.RowBuilder(lb)
.setTitle("Work")
@@ -367,7 +345,7 @@
private Slice createCustomToggleSlice(Uri sliceUri) {
ListBuilder b = new ListBuilder(getContext(), sliceUri, -TimeUnit.HOURS.toMillis(1));
- return b.setAccentColor(0xffff4081)
+ return b.setColor(0xffff4081)
.addRow(new ListBuilder.RowBuilder(b)
.setTitle("Custom toggle")
.addEndItem(
@@ -380,7 +358,7 @@
private Slice createTwoCustomToggleSlices(Uri sliceUri) {
ListBuilder lb = new ListBuilder(getContext(), sliceUri, INFINITY);
- return lb.setAccentColor(0xffff4081)
+ return lb.setColor(0xffff4081)
.addRow(new ListBuilder.RowBuilder(lb)
.setTitle("2 toggles")
.setSubtitle("each supports two states")
@@ -420,7 +398,7 @@
ListBuilder lb = new ListBuilder(getContext(), sliceUri, INFINITY);
SliceAction primaryAction = new SliceAction(getIntent(Settings.ACTION_WIFI_SETTINGS),
IconCompat.createWithResource(getContext(), R.drawable.ic_wifi), "Wi-fi Settings");
- lb.setAccentColor(0xff4285f4);
+ lb.setColor(0xff4285f4);
lb.addRow(new ListBuilder.RowBuilder(lb)
.setTitle("Wi-fi")
.setTitleItem(IconCompat.createWithResource(getContext(), R.drawable.ic_wifi),
@@ -481,7 +459,7 @@
.addCell(new GridRowBuilder.CellBuilder(gb2)
.addTitleText("Check Out")
.addText("11:00 AM, Feb 19"));
- return lb.setAccentColor(0xffFF5252)
+ return lb.setColor(0xffFF5252)
.setHeader(new ListBuilder.HeaderBuilder(lb)
.setTitle("Upcoming trip to Seattle")
.setSubtitle("Feb 1 - 19 | 2 guests"))
@@ -497,30 +475,13 @@
.build();
}
- private Slice createBasicInputRange(Uri sliceUri) {
- IconCompat icon = IconCompat.createWithResource(getContext(), R.drawable.ic_star_on);
- SliceAction primaryAction =
- new SliceAction(getBroadcastIntent(ACTION_TOAST, "open star rating"),
- icon, "Rate");
- ListBuilder lb = new ListBuilder(getContext(), sliceUri, INFINITY);
- return lb.setAccentColor(0xff4285f4)
- .addInputRange(new ListBuilder.InputRangeBuilder(lb)
- .setTitle("Alarm volume")
- .setSubtitle("Adjust your volume")
- .setInputAction(getBroadcastIntent(ACTION_TOAST, "volume changed"))
- .setValue(80)
- .setPrimaryAction(primaryAction)
- .setContentDescription("Slider for alarm volume"))
- .build();
- }
-
private Slice createStarRatingInputRange(Uri sliceUri) {
IconCompat icon = IconCompat.createWithResource(getContext(), R.drawable.ic_star_on);
SliceAction primaryAction =
new SliceAction(getBroadcastIntent(ACTION_TOAST, "open star rating"), icon,
"Rate");
ListBuilder lb = new ListBuilder(getContext(), sliceUri, INFINITY);
- return lb.setAccentColor(0xffff4081)
+ return lb.setColor(0xffff4081)
.addInputRange(new ListBuilder.InputRangeBuilder(lb)
.setTitle("Star rating")
.setSubtitle("Pick a rating from 0 to 5")
@@ -541,7 +502,7 @@
getBroadcastIntent(ACTION_TOAST, "open download"), icon,
"Download");
ListBuilder lb = new ListBuilder(getContext(), sliceUri, INFINITY);
- return lb.setAccentColor(0xffff4081)
+ return lb.setColor(0xffff4081)
.addRange(new ListBuilder.RangeBuilder(lb)
.setTitle("Download progress")
.setSubtitle("Download is happening")
diff --git a/slices/view/src/androidTest/java/androidx/slice/render/SliceRenderer.java b/slices/view/src/androidTest/java/androidx/slice/render/SliceRenderer.java
index ec5e55a..0734edf 100644
--- a/slices/view/src/androidTest/java/androidx/slice/render/SliceRenderer.java
+++ b/slices/view/src/androidTest/java/androidx/slice/render/SliceRenderer.java
@@ -116,7 +116,7 @@
private File getScreenshotDirectory() {
if (sScreenshotDirectory == null) {
- File storage = mContext.getFilesDir();
+ File storage = mContext.getDataDir();
sScreenshotDirectory = new File(storage, SCREENSHOT_DIR);
if (!sScreenshotDirectory.exists()) {
if (!sScreenshotDirectory.mkdirs()) {
@@ -188,12 +188,12 @@
.setActionMode(SliceUtils.SerializeOptions.MODE_CONVERT));
byte[] bytes = outputStream.toByteArray();
- Log.d(TAG, "Serialized: " + new String(bytes));
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
return SliceUtils.parseSlice(mContext, inputStream, "UTF-8",
new SliceUtils.SliceActionListener() {
@Override
- public void onSliceAction(Uri actionUri) { }
+ public void onSliceAction(Uri actionUri) {
+ }
});
} catch (Exception e) {
throw new RuntimeException(e);
diff --git a/slices/view/src/main/java/androidx/slice/SliceManager.java b/slices/view/src/main/java/androidx/slice/SliceManager.java
index 83febcc..63c56e8 100644
--- a/slices/view/src/main/java/androidx/slice/SliceManager.java
+++ b/slices/view/src/main/java/androidx/slice/SliceManager.java
@@ -28,7 +28,6 @@
import androidx.core.os.BuildCompat;
import java.util.Collection;
-import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
@@ -126,8 +125,10 @@
* <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);
/**
@@ -140,8 +141,9 @@
public abstract @Nullable Slice bindSlice(@NonNull Uri uri);
/**
- * 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.
+ * 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}.
*
* @param intent The intent associated with a slice.
* @return The Slice provided by the app or null if none is given.
@@ -152,23 +154,12 @@
public abstract @Nullable Slice bindSlice(@NonNull Intent intent);
/**
- * 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>
+ * 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}.
+ *
* @param intent The intent associated with a slice.
- * @return The Slice Uri provided by the app or null if none exists.
+ * @return The Slice Uri provided by the app or null if none is given.
* @see Slice
* @see SliceProvider#onMapIntentToUri(Intent)
* @see Intent
@@ -232,12 +223,6 @@
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 5192dad..fb9fccd 100644
--- a/slices/view/src/main/java/androidx/slice/SliceManagerBase.java
+++ b/slices/view/src/main/java/androidx/slice/SliceManagerBase.java
@@ -19,9 +19,11 @@
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;
@@ -29,6 +31,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
+import androidx.core.content.PermissionChecker;
import java.util.concurrent.Executor;
@@ -68,6 +71,31 @@
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 0018c13..1badbb4 100644
--- a/slices/view/src/main/java/androidx/slice/SliceManagerCompat.java
+++ b/slices/view/src/main/java/androidx/slice/SliceManagerCompat.java
@@ -29,7 +29,6 @@
import androidx.slice.widget.SliceLiveData;
import java.util.Collection;
-import java.util.List;
import java.util.Set;
@@ -77,30 +76,7 @@
}
@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 ec49fe2..e0c0342 100644
--- a/slices/view/src/main/java/androidx/slice/SliceManagerWrapper.java
+++ b/slices/view/src/main/java/androidx/slice/SliceManagerWrapper.java
@@ -28,10 +28,9 @@
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;
@@ -43,7 +42,7 @@
class SliceManagerWrapper extends SliceManagerBase {
private final android.app.slice.SliceManager mManager;
- private final Set<SliceSpec> mSpecs;
+ private final List<SliceSpec> mSpecs;
SliceManagerWrapper(Context context) {
this(context, context.getSystemService(android.app.slice.SliceManager.class));
@@ -52,7 +51,7 @@
SliceManagerWrapper(Context context, android.app.slice.SliceManager manager) {
super(context);
mManager = manager;
- mSpecs = unwrap(SUPPORTED_SPECS);
+ mSpecs = new ArrayList<>(unwrap(SUPPORTED_SPECS));
}
@Override
@@ -67,9 +66,7 @@
@Override
public @NonNull Set<androidx.slice.SliceSpec> getPinnedSpecs(@NonNull Uri uri) {
- // Disabled while we update APIs.
- //return SliceConvert.wrap(mManager.getPinnedSpecs(uri));
- return Collections.EMPTY_SET;
+ return SliceConvert.wrap(mManager.getPinnedSpecs(uri));
}
@Nullable
@@ -89,30 +86,9 @@
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 d7c9097..8a4ee03 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;
@@ -35,7 +35,6 @@
import static androidx.slice.widget.EventInfo.ROW_TYPE_PROGRESS;
import static androidx.slice.widget.EventInfo.ROW_TYPE_SLIDER;
-import android.app.PendingIntent;
import android.content.Context;
import android.text.TextUtils;
@@ -119,17 +118,17 @@
private SliceMetadata(@NonNull Context context, @NonNull Slice slice) {
mSlice = slice;
mContext = context;
- SliceItem ttlItem = SliceQuery.find(slice, FORMAT_LONG, HINT_TTL, null);
+ SliceItem ttlItem = SliceQuery.find(slice, FORMAT_TIMESTAMP, HINT_TTL, null);
if (ttlItem != null) {
mExpiry = ttlItem.getTimestamp();
}
- SliceItem updatedItem = SliceQuery.find(slice, FORMAT_LONG, HINT_LAST_UPDATED, null);
+ SliceItem updatedItem = SliceQuery.find(slice, FORMAT_TIMESTAMP, HINT_LAST_UPDATED, null);
if (updatedItem != null) {
mLastUpdated = updatedItem.getTimestamp();
}
mSliceActions = getSliceActions(mSlice);
- mListContent = new ListContent(context, slice, null, 0, 0);
+ mListContent = new ListContent(context, slice);
mHeaderItem = mListContent.getHeaderItem();
mTemplateType = mListContent.getHeaderTemplateType();
@@ -198,23 +197,6 @@
}
/**
- * Gets the input range action associated for this slice, if it exists.
- *
- * @return the {@link android.app.PendingIntent} for the input range.
- */
- @Nullable
- public PendingIntent getInputRangeAction() {
- if (mTemplateType == ROW_TYPE_SLIDER) {
- RowContent rc = new RowContent(mContext, mHeaderItem, true /* isHeader */);
- SliceItem range = rc.getRange();
- if (range != null) {
- return range.getAction();
- }
- }
- return null;
- }
-
- /**
* Gets the range information associated with a progress bar or input range associated with this
* slice, if it exists.
*
@@ -288,7 +270,7 @@
public int getLoadingState() {
// Check loading state
boolean hasHintPartial = SliceQuery.find(mSlice, null, HINT_PARTIAL, null) != null;
- if (!mListContent.isValid()) {
+ if (mSlice.getItems().size() == 0) {
// Empty slice
return LOADED_NONE;
} else if (hasHintPartial) {
diff --git a/slices/view/src/main/java/androidx/slice/SliceXml.java b/slices/view/src/main/java/androidx/slice/SliceXml.java
index 43b4c9b..673bfca 100644
--- a/slices/view/src/main/java/androidx/slice/SliceXml.java
+++ b/slices/view/src/main/java/androidx/slice/SliceXml.java
@@ -30,7 +30,6 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
-import android.os.Build;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
@@ -182,10 +181,6 @@
break;
case android.app.slice.SliceItem.FORMAT_TEXT:
v = parser.getText();
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
- // 19-21 don't allow special characters in XML, so we base64 encode it.
- v = new String(Base64.decode(v, Base64.NO_WRAP));
- }
b.addText(Html.fromHtml(v), subtype, hints);
break;
case android.app.slice.SliceItem.FORMAT_LONG:
@@ -305,19 +300,9 @@
break;
case android.app.slice.SliceItem.FORMAT_TEXT:
if (item.getText() instanceof Spanned) {
- String text = Html.toHtml((Spanned) item.getText());
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
- // 19-21 don't allow special characters in XML, so we base64 encode it.
- text = Base64.encodeToString(text.getBytes(), Base64.NO_WRAP);
- }
- serializer.text(text);
+ serializer.text(Html.toHtml((Spanned) item.getText()));
} else {
- String text = String.valueOf(item.getText());
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
- // 19-21 don't allow special characters in XML, so we base64 encode it.
- text = Base64.encodeToString(text.getBytes(), Base64.NO_WRAP);
- }
- serializer.text(text);
+ serializer.text(String.valueOf(item.getText()));
}
break;
case android.app.slice.SliceItem.FORMAT_LONG:
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 c194fef..69d5c44 100644
--- a/slices/view/src/main/java/androidx/slice/widget/GridContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/GridContent.java
@@ -17,6 +17,7 @@
package androidx.slice.widget;
import static android.app.slice.Slice.HINT_ACTIONS;
+import static android.app.slice.Slice.HINT_LIST_ITEM;
import static android.app.slice.Slice.HINT_SEE_MORE;
import static android.app.slice.Slice.HINT_SHORTCUT;
import static android.app.slice.Slice.HINT_TITLE;
@@ -25,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;
@@ -101,11 +102,7 @@
new String[] {HINT_ACTIONS} /* nonHints */);
mAllImages = true;
if (FORMAT_SLICE.equals(gridItem.getFormat())) {
- List<SliceItem> items = gridItem.getSlice().getItems();
- if (items.size() == 1 && FORMAT_SLICE.equals(items.get(0).getFormat())) {
- // TODO: this can be removed at release
- items = items.get(0).getSlice().getItems();
- }
+ List<SliceItem> items = gridItem.getSlice().getItems().get(0).getSlice().getItems();
items = filterAndProcessItems(items);
// Check if it it's only one item that is a slice
if (items.size() == 1 && items.get(0).getFormat().equals(FORMAT_SLICE)) {
@@ -200,14 +197,11 @@
List<SliceItem> filteredItems = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {
SliceItem item = items.get(i);
- // TODO: This see more can be removed at release
- boolean containsSeeMore = SliceQuery.find(item, null, HINT_SEE_MORE, null) != null;
- boolean isNonCellContent = containsSeeMore
- || item.hasAnyHints(HINT_SHORTCUT, HINT_SEE_MORE, HINT_KEYWORDS, HINT_TTL,
- HINT_LAST_UPDATED);
+ boolean isNonCellContent = item.hasAnyHints(HINT_SHORTCUT, HINT_SEE_MORE,
+ HINT_KEYWORDS, HINT_TTL, HINT_LAST_UPDATED);
if (SUBTYPE_CONTENT_DESCRIPTION.equals(item.getSubType())) {
mContentDescr = item;
- } else if (!isNonCellContent) {
+ } else if (item.hasHint(HINT_LIST_ITEM) && !isNonCellContent) {
filteredItems.add(item);
}
}
@@ -230,8 +224,6 @@
/**
* @return the height to display a grid row at when it is used as a small template.
- * Does not include padding that might be added by slice view attributes,
- * see {@link ListContent#getListHeight(Context, List)}.
*/
public int getSmallHeight() {
return getHeight(true /* isSmall */);
@@ -239,8 +231,6 @@
/**
* @return the height the content in this template requires to be displayed.
- * Does not include padding that might be added by slice view attributes,
- * see {@link ListContent#getListHeight(Context, List)}.
*/
public int getActualHeight() {
return getHeight(false /* isSmall */);
@@ -305,7 +295,7 @@
if (SUBTYPE_CONTENT_DESCRIPTION.equals(item.getSubType())) {
mContentDescr = item;
} else if (mTextCount < 2 && (FORMAT_TEXT.equals(itemFormat)
- || FORMAT_LONG.equals(itemFormat))) {
+ || FORMAT_TIMESTAMP.equals(itemFormat))) {
mTextCount++;
mCellItems.add(item);
} else if (imageCount < 1 && FORMAT_IMAGE.equals(item.getFormat())) {
@@ -350,7 +340,7 @@
|| cellItem.hasAnyHints(HINT_KEYWORDS, HINT_TTL, HINT_LAST_UPDATED);
return !isNonCellContent
&& (FORMAT_TEXT.equals(format)
- || FORMAT_LONG.equals(format)
+ || FORMAT_TIMESTAMP.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 78df091..4b8078c 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;
@@ -48,6 +48,7 @@
import androidx.annotation.ColorInt;
import androidx.annotation.RestrictTo;
+import androidx.slice.Slice;
import androidx.slice.SliceItem;
import androidx.slice.core.SliceQuery;
import androidx.slice.view.R;
@@ -78,12 +79,9 @@
private static final int MAX_CELL_IMAGES = 1;
private int mRowIndex;
- private int mRowCount;
-
private int mSmallImageSize;
private int mIconSize;
private int mGutter;
- private int mTextPadding;
private GridContent mGridContent;
private LinearLayout mViewContainer;
@@ -102,43 +100,17 @@
mIconSize = res.getDimensionPixelSize(R.dimen.abc_slice_icon_size);
mSmallImageSize = res.getDimensionPixelSize(R.dimen.abc_slice_small_image_size);
mGutter = res.getDimensionPixelSize(R.dimen.abc_slice_grid_gutter);
- mTextPadding = res.getDimensionPixelSize(R.dimen.abc_slice_grid_text_padding);
}
@Override
public int getSmallHeight() {
// GridRow is small if its the first element in a list without a header presented in small
- if (mGridContent == null) {
- return 0;
- }
- return mGridContent.getSmallHeight() + getExtraTopPadding() + getExtraBottomPadding();
+ return mGridContent != null ? mGridContent.getSmallHeight() : 0;
}
@Override
public int getActualHeight() {
- if (mGridContent == null) {
- return 0;
- }
- return mGridContent.getActualHeight() + getExtraTopPadding() + getExtraBottomPadding();
- }
-
- private int getExtraTopPadding() {
- if (mGridContent != null && mGridContent.isAllImages()) {
- // Might need to add padding if in first or last position
- if (mRowIndex == 0) {
- return mGridTopPadding;
- }
- }
- return 0;
- }
-
- private int getExtraBottomPadding() {
- if (mGridContent != null && mGridContent.isAllImages()) {
- if (mRowIndex == mRowCount - 1 || getMode() == MODE_SMALL) {
- return mGridBottomPadding;
- }
- }
- return 0;
+ return mGridContent != null ? mGridContent.getActualHeight() : 0;
}
@Override
@@ -160,19 +132,22 @@
}
}
+ @Override
+ public void setSlice(Slice slice) {
+ // Nothing to do
+ }
+
/**
* This is called when GridView is being used as a component in a larger template.
*/
@Override
- public void setSliceItem(SliceItem slice, boolean isHeader, int rowIndex,
- int rowCount, SliceView.OnSliceActionListener observer) {
+ public void setSliceItem(SliceItem slice, boolean isHeader, int index,
+ SliceView.OnSliceActionListener observer) {
resetView();
setSliceActionListener(observer);
- mRowIndex = rowIndex;
- mRowCount = rowCount;
+ mRowIndex = index;
mGridContent = new GridContent(getContext(), slice);
populateViews(mGridContent);
- mViewContainer.setPadding(0, getExtraTopPadding(), 0, getExtraBottomPadding());
}
private void populateViews(GridContent gc) {
@@ -229,11 +204,6 @@
seeMoreView = (LinearLayout) inflater.inflate(
R.layout.abc_slice_grid_see_more, mViewContainer, false);
extraText = seeMoreView.findViewById(R.id.text_see_more_count);
-
- // Update text appearance
- TextView moreText = seeMoreView.findViewById(R.id.text_see_more);
- moreText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mGridTitleSize);
- moreText.setTextColor(mTitleColor);
}
mViewContainer.addView(seeMoreView, new LinearLayout.LayoutParams(0, MATCH_PARENT, 1));
extraText.setText(getResources().getString(R.string.abc_slice_more_content, numExtra));
@@ -279,29 +249,25 @@
Iterator<SliceItem> iterator = textItems.iterator();
while (textItems.size() > 1) {
SliceItem item = iterator.next();
- if (!item.hasAnyHints(HINT_TITLE, HINT_LARGE)) {
+ if (!item.hasHint(HINT_TITLE)) {
iterator.remove();
}
}
}
- SliceItem prevItem = null;
for (int i = 0; i < cellItems.size(); i++) {
SliceItem item = cellItems.get(i);
final String itemFormat = item.getFormat();
- int padding = determinePadding(prevItem);
if (textCount < maxCellText && (FORMAT_TEXT.equals(itemFormat)
- || FORMAT_LONG.equals(itemFormat))) {
+ || FORMAT_TIMESTAMP.equals(itemFormat))) {
if (textItems != null && !textItems.contains(item)) {
continue;
}
- if (addItem(item, mTintColor, cellContainer, padding)) {
- prevItem = item;
+ if (addItem(item, mTintColor, cellContainer, singleItem)) {
textCount++;
added = true;
}
} else if (imageCount < MAX_CELL_IMAGES && FORMAT_IMAGE.equals(item.getFormat())) {
- if (addItem(item, mTintColor, cellContainer, 0)) {
- prevItem = item;
+ if (addItem(item, mTintColor, cellContainer, singleItem)) {
imageCount++;
added = true;
}
@@ -334,28 +300,22 @@
/**
* Adds simple items to a container. Simple items include icons, text, and timestamps.
- *
- * @param item item to add to the container.
- * @param container the container to add to.
- * @param padding the padding to apply to the item.
- *
* @return Whether an item was added.
*/
- private boolean addItem(SliceItem item, int color, ViewGroup container, int padding) {
+ 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_LONG.equals(format)) {
+ if (FORMAT_TEXT.equals(format) || FORMAT_TIMESTAMP.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 ? mGridTitleSize : mGridSubtitleSize);
+ tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, title ? mTitleSize : mSubtitleSize);
tv.setTextColor(title ? mTitleColor : mSubtitleColor);
- CharSequence text = FORMAT_LONG.equals(format)
+ CharSequence text = FORMAT_TIMESTAMP.equals(format)
? SliceViewUtil.getRelativeTimeString(item.getTimestamp())
: item.getText();
tv.setText(text);
container.addView(tv);
- tv.setPadding(0, padding, 0, 0);
addedView = tv;
} else if (FORMAT_IMAGE.equals(format)) {
ImageView iv = new ImageView(getContext());
@@ -379,19 +339,6 @@
return addedView != null;
}
- private int determinePadding(SliceItem prevItem) {
- if (prevItem == null) {
- // No need for top padding
- return 0;
- } else if (FORMAT_IMAGE.equals(prevItem.getFormat())) {
- return mTextPadding;
- } else if (FORMAT_TEXT.equals(prevItem.getFormat())
- || FORMAT_LONG.equals(prevItem.getFormat())) {
- return mVerticalGridTextPadding;
- }
- return 0;
- }
-
private void makeClickable(View layout, boolean isClickable) {
layout.setOnClickListener(isClickable ? this : null);
layout.setBackground(isClickable
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 81059d4..9e077ab 100644
--- a/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java
+++ b/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java
@@ -17,7 +17,6 @@
package androidx.slice.widget;
import static android.app.slice.Slice.HINT_HORIZONTAL;
-import static android.app.slice.Slice.HINT_SUMMARY;
import static android.app.slice.Slice.SUBTYPE_MESSAGE;
import static android.app.slice.Slice.SUBTYPE_SOURCE;
import static android.app.slice.SliceItem.FORMAT_INT;
@@ -104,14 +103,14 @@
/**
* Set the {@link SliceItem}'s to be displayed in the adapter and the accent color.
*/
- public void setSliceItems(List<SliceItem> slices, int color, int mode) {
+ public void setSliceItems(List<SliceItem> slices, int color) {
if (slices == null) {
mSlices.clear();
} else {
mIdGen.resetUsage();
mSlices = new ArrayList<>(slices.size());
for (SliceItem s : slices) {
- mSlices.add(new SliceWrapper(s, mIdGen, mode));
+ mSlices.add(new SliceWrapper(s, mIdGen));
}
}
mColor = color;
@@ -192,6 +191,8 @@
null);
break;
}
+ int mode = mParent != null ? mParent.getMode() : MODE_LARGE;
+ ((SliceChildView) v).setMode(mode);
return v;
}
@@ -200,10 +201,10 @@
private final int mType;
private final long mId;
- public SliceWrapper(SliceItem item, IdGenerator idGen, int mode) {
+ public SliceWrapper(SliceItem item, IdGenerator idGen) {
mItem = item;
mType = getFormat(item);
- mId = idGen.getId(item, mode);
+ mId = idGen.getId(item);
}
public static int getFormat(SliceItem item) {
@@ -247,16 +248,14 @@
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, getItemCount(), mSliceObserver);
- mSliceChildView.setSliceActions(isHeader ? mSliceActions : null);
- mSliceChildView.setLastUpdated(isHeader ? mLastUpdated : -1);
- mSliceChildView.setShowLastUpdated(isHeader && mShowLastUpdated);
- if (mSliceChildView instanceof RowView) {
+ mSliceChildView.setSliceItem(item, isHeader, position, mSliceObserver);
+ if (isHeader && mSliceChildView instanceof RowView) {
((RowView) mSliceChildView).setSingleItem(getItemCount() == 1);
+ mSliceChildView.setSliceActions(mSliceActions);
+ mSliceChildView.setLastUpdated(mLastUpdated);
+ mSliceChildView.setShowLastUpdated(mShowLastUpdated);
}
int[] info = new int[2];
info[0] = ListContent.getRowType(mContext, item, isHeader, mSliceActions);
@@ -286,12 +285,8 @@
private final ArrayMap<String, Long> mCurrentIds = new ArrayMap<>();
private final ArrayMap<String, Integer> mUsedIds = new ArrayMap<>();
- public long getId(SliceItem item, int mode) {
+ public long getId(SliceItem item) {
String str = genString(item);
- SliceItem summary = SliceQuery.find(item, null, HINT_SUMMARY, null);
- if (summary != null) {
- str += mode; // mode matters
- }
if (!mCurrentIds.containsKey(str)) {
mCurrentIds.put(str, mNextLong++);
}
diff --git a/slices/view/src/main/java/androidx/slice/widget/LargeTemplateView.java b/slices/view/src/main/java/androidx/slice/widget/LargeTemplateView.java
index 0cba347..6632097 100644
--- a/slices/view/src/main/java/androidx/slice/widget/LargeTemplateView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/LargeTemplateView.java
@@ -16,7 +16,7 @@
package androidx.slice.widget;
-import static androidx.slice.widget.SliceView.MODE_SMALL;
+import static android.app.slice.Slice.HINT_HORIZONTAL;
import android.content.Context;
import android.os.Build;
@@ -28,6 +28,7 @@
import androidx.annotation.RestrictTo;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+import androidx.slice.Slice;
import androidx.slice.SliceItem;
import java.util.ArrayList;
@@ -44,6 +45,7 @@
private final View mForeground;
private final LargeSliceAdapter mAdapter;
private final RecyclerView mRecyclerView;
+ private Slice mSlice;
private boolean mIsScrollable;
private ListContent mListContent;
private List<SliceItem> mDisplayedItems = new ArrayList<>();
@@ -129,8 +131,13 @@
return 0;
}
SliceItem headerItem = mListContent.getHeaderItem();
- return mListContent.getHeight(getContext(), headerItem, true /* isHeader */,
- 0 /* rowIndex */, 1 /* rowCount */, MODE_SMALL);
+ if (headerItem.hasHint(HINT_HORIZONTAL)) {
+ GridContent gc = new GridContent(getContext(), headerItem);
+ return gc.getSmallHeight();
+ } else {
+ RowContent rc = new RowContent(getContext(), headerItem, mListContent.hasHeader());
+ return rc.getSmallHeight();
+ }
}
@Override
@@ -153,8 +160,8 @@
}
@Override
- public void setSliceContent(ListContent sliceContent) {
- mListContent = sliceContent;
+ public void setSlice(Slice slice) {
+ mSlice = slice;
populate();
}
@@ -177,10 +184,11 @@
}
private void populate() {
- if (mListContent == null) {
+ if (mSlice == null) {
resetView();
return;
}
+ mListContent = new ListContent(getContext(), mSlice);
updateDisplayedItems(getMeasuredHeight());
}
@@ -208,21 +216,21 @@
} else {
mDisplayedItems = mListContent.getRowItems();
}
- mDisplayedItemsHeight = mListContent.getListHeight(getContext(), mDisplayedItems);
- int mode = getMode();
- if (mode == SliceView.MODE_LARGE) {
- mAdapter.setSliceItems(mDisplayedItems, mTintColor, mode);
- } else if (mode == MODE_SMALL) {
+ mDisplayedItemsHeight = ListContent.getListHeight(getContext(), mDisplayedItems);
+ if (getMode() == SliceView.MODE_LARGE) {
+ mAdapter.setSliceItems(mDisplayedItems, mTintColor);
+ } else if (getMode() == SliceView.MODE_SMALL) {
mAdapter.setSliceItems(
- Collections.singletonList(mDisplayedItems.get(0)), mTintColor, mode);
+ Collections.singletonList(mDisplayedItems.get(0)), mTintColor);
}
}
@Override
public void resetView() {
+ mSlice = null;
mDisplayedItemsHeight = 0;
mDisplayedItems.clear();
- mAdapter.setSliceItems(null, -1, getMode());
+ mAdapter.setSliceItems(null, -1);
mListContent = null;
}
}
diff --git a/slices/view/src/main/java/androidx/slice/widget/ListContent.java b/slices/view/src/main/java/androidx/slice/widget/ListContent.java
index 8f3cdf2..1dca6cb 100644
--- a/slices/view/src/main/java/androidx/slice/widget/ListContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/ListContent.java
@@ -30,12 +30,8 @@
import static androidx.slice.core.SliceHints.HINT_KEYWORDS;
import static androidx.slice.core.SliceHints.HINT_LAST_UPDATED;
import static androidx.slice.core.SliceHints.HINT_TTL;
-import static androidx.slice.widget.SliceView.MODE_LARGE;
-import static androidx.slice.widget.SliceView.MODE_SMALL;
import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -46,7 +42,6 @@
import androidx.slice.core.SliceAction;
import androidx.slice.core.SliceActionImpl;
import androidx.slice.core.SliceQuery;
-import androidx.slice.view.R;
import java.util.ArrayList;
import java.util.List;
@@ -58,7 +53,6 @@
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class ListContent {
- private Slice mSlice;
private SliceItem mHeaderItem;
private SliceItem mColorItem;
private SliceItem mSeeMoreItem;
@@ -66,54 +60,8 @@
private List<SliceItem> mSliceActions;
private Context mContext;
- private int mHeaderTitleSize;
- private int mHeaderSubtitleSize;
- private int mVerticalHeaderTextPadding;
- private int mTitleSize;
- private int mSubtitleSize;
- private int mVerticalTextPadding;
- private int mGridTitleSize;
- private int mGridSubtitleSize;
- private int mVerticalGridTextPadding;
- private int mGridTopPadding;
- private int mGridBottomPadding;
-
- public ListContent(Context context, Slice slice, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- mSlice = slice;
+ public ListContent(Context context, Slice slice) {
mContext = context;
-
- // TODO: duplicated code from SliceChildView; could do something better
- // Some of this information will impact the size calculations for slice content.
- TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SliceView,
- defStyleAttr, defStyleRes);
- try {
- mHeaderTitleSize = (int) a.getDimension(
- R.styleable.SliceView_headerTitleSize, 0);
- mHeaderSubtitleSize = (int) a.getDimension(
- R.styleable.SliceView_headerSubtitleSize, 0);
- mVerticalHeaderTextPadding = (int) a.getDimension(
- R.styleable.SliceView_headerTextVerticalPadding, 0);
-
- mTitleSize = (int) a.getDimension(R.styleable.SliceView_titleSize, 0);
- mSubtitleSize = (int) a.getDimension(
- R.styleable.SliceView_subtitleSize, 0);
- mVerticalTextPadding = (int) a.getDimension(
- R.styleable.SliceView_textVerticalPadding, 0);
-
- mGridTitleSize = (int) a.getDimension(R.styleable.SliceView_gridTitleSize, 0);
- mGridSubtitleSize = (int) a.getDimension(
- R.styleable.SliceView_gridSubtitleSize, 0);
- int defaultVerticalGridPadding = context.getResources().getDimensionPixelSize(
- R.dimen.abc_slice_grid_text_inner_padding);
- mVerticalGridTextPadding = (int) a.getDimension(
- R.styleable.SliceView_gridTextVerticalPadding, defaultVerticalGridPadding);
- mGridTopPadding = (int) a.getDimension(R.styleable.SliceView_gridTopPadding, 0);
- mGridBottomPadding = (int) a.getDimension(R.styleable.SliceView_gridTopPadding, 0);
- } finally {
- a.recycle();
- }
-
populate(slice);
}
@@ -159,7 +107,7 @@
*
* @return the total height of all the rows contained in the provided list.
*/
- public int getListHeight(Context context, List<SliceItem> listItems) {
+ public static int getListHeight(Context context, List<SliceItem> listItems) {
if (listItems == null) {
return 0;
}
@@ -171,12 +119,10 @@
hasRealHeader = !maybeHeader.hasAnyHints(HINT_LIST_ITEM, HINT_HORIZONTAL);
}
if (listItems.size() == 1 && !maybeHeader.hasHint(HINT_HORIZONTAL)) {
- return getHeight(context, maybeHeader, true /* isHeader */, 0, 1, MODE_LARGE);
+ return getHeight(context, maybeHeader, true);
}
- int rowCount = listItems.size();
for (int i = 0; i < listItems.size(); i++) {
- height += getHeight(context, listItems.get(i), i == 0 && hasRealHeader /* isHeader */,
- i, rowCount, MODE_LARGE);
+ height += getHeight(context, listItems.get(i), i == 0 && hasRealHeader /* isHeader */);
}
return height;
}
@@ -203,10 +149,8 @@
RowContent rc = new RowContent(mContext, mSeeMoreItem, false /* isHeader */);
visibleHeight += rc.getActualHeight();
}
- int rowCount = mRowItems.size();
- for (int i = 0; i < rowCount; i++) {
- int itemHeight = getHeight(mContext, mRowItems.get(i), i == 0 /* isHeader */,
- i, rowCount, MODE_LARGE);
+ for (int i = 0; i < mRowItems.size(); i++) {
+ int itemHeight = getHeight(mContext, mRowItems.get(i), i == 0 /* isHeader */);
if ((height == -1 && i > idealItemCount)
|| (height > 0 && visibleHeight + itemHeight > height)) {
break;
@@ -226,20 +170,13 @@
return visibleItems;
}
- /**
- * Determines the height of the provided {@link SliceItem}.
- */
- public int getHeight(Context context, SliceItem item, boolean isHeader, int index,
- int count, int mode) {
+ private static int getHeight(Context context, SliceItem item, boolean isHeader) {
if (item.hasHint(HINT_HORIZONTAL)) {
GridContent gc = new GridContent(context, item);
- int topPadding = gc.isAllImages() && index == 0 ? mGridTopPadding : 0;
- int bottomPadding = gc.isAllImages() && index == count - 1 ? mGridBottomPadding : 0;
- int height = mode == MODE_SMALL ? gc.getSmallHeight() : gc.getActualHeight();
- return height + topPadding + bottomPadding;
+ return gc.getActualHeight();
} else {
RowContent rc = new RowContent(context, item, isHeader);
- return mode == MODE_SMALL ? rc.getSmallHeight() : rc.getActualHeight();
+ return rc.getActualHeight();
}
}
@@ -251,11 +188,6 @@
}
@Nullable
- public Slice getSlice() {
- return mSlice;
- }
-
- @Nullable
public SliceItem getColorItem() {
return mColorItem;
}
@@ -359,7 +291,7 @@
private static SliceItem findHeaderItem(@NonNull Slice slice) {
// See if header is specified
String[] nonHints = new String[] {HINT_LIST_ITEM, HINT_SHORTCUT, HINT_ACTIONS,
- HINT_KEYWORDS, HINT_TTL, HINT_LAST_UPDATED, HINT_HORIZONTAL};
+ HINT_KEYWORDS, HINT_TTL, HINT_LAST_UPDATED};
SliceItem header = SliceQuery.find(slice, FORMAT_SLICE, null, nonHints);
if (header != null && isValidHeader(header)) {
return header;
@@ -370,7 +302,7 @@
@Nullable
private static SliceItem getSeeMoreItem(@NonNull Slice slice) {
SliceItem item = SliceQuery.find(slice, null, HINT_SEE_MORE, null);
- if (item != null) {
+ if (item != null && item.hasHint(HINT_SEE_MORE)) {
if (FORMAT_SLICE.equals(item.getFormat())) {
List<SliceItem> items = item.getSlice().getItems();
if (items.size() == 1 && FORMAT_ACTION.equals(items.get(0).getFormat())) {
diff --git a/slices/view/src/main/java/androidx/slice/widget/MessageView.java b/slices/view/src/main/java/androidx/slice/widget/MessageView.java
index c597ed4..6035d0a 100644
--- a/slices/view/src/main/java/androidx/slice/widget/MessageView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/MessageView.java
@@ -30,6 +30,7 @@
import android.widget.TextView;
import androidx.annotation.RestrictTo;
+import androidx.slice.Slice;
import androidx.slice.SliceItem;
import androidx.slice.core.SliceQuery;
@@ -56,6 +57,11 @@
}
@Override
+ public void setSlice(Slice slice) {
+ // Do nothing it's always a list item
+ }
+
+ @Override
public void resetView() {
// TODO
}
@@ -69,7 +75,7 @@
@Override
public void setSliceItem(SliceItem slice, boolean isHeader, int index,
- int rowCount, SliceView.OnSliceActionListener observer) {
+ SliceView.OnSliceActionListener observer) {
setSliceActionListener(observer);
mRowIndex = index;
SliceItem source = SliceQuery.findSubtype(slice, FORMAT_IMAGE, SUBTYPE_SOURCE);
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 5ef06e9..bc3826f 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowContent.java
@@ -16,7 +16,7 @@
package androidx.slice.widget;
-import static android.app.slice.Slice.HINT_HORIZONTAL;
+import static android.app.slice.Slice.HINT_ACTIONS;
import static android.app.slice.Slice.HINT_PARTIAL;
import static android.app.slice.Slice.HINT_SEE_MORE;
import static android.app.slice.Slice.HINT_SHORTCUT;
@@ -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;
@@ -95,7 +95,15 @@
Log.w(TAG, "Provided SliceItem is invalid for RowContent");
return false;
}
- determineStartAndPrimaryAction(rowSlice);
+ // Find primary action first (otherwise filtered out of valid row items)
+ String[] hints = new String[] {HINT_SHORTCUT, HINT_TITLE};
+ mPrimaryAction = SliceQuery.find(rowSlice, FORMAT_SLICE, hints,
+ new String[] { HINT_ACTIONS, HINT_KEYWORDS} /* nonHints */);
+
+ if (mPrimaryAction == null && FORMAT_ACTION.equals(rowSlice.getFormat())
+ && rowSlice.getSlice().getItems().size() == 1) {
+ mPrimaryAction = rowSlice;
+ }
mContentDescr = SliceQuery.findSubtype(rowSlice, FORMAT_TEXT, SUBTYPE_CONTENT_DESCRIPTION);
@@ -104,7 +112,7 @@
// If we've only got one item that's a slice / action use those items instead
if (rowItems.size() == 1 && (FORMAT_ACTION.equals(rowItems.get(0).getFormat())
|| FORMAT_SLICE.equals(rowItems.get(0).getFormat()))
- && !rowItems.get(0).hasAnyHints(HINT_SHORTCUT, HINT_TITLE)) {
+ && !rowItems.get(0).hasHint(HINT_SHORTCUT)) {
if (isValidRow(rowItems.get(0))) {
rowSlice = rowItems.get(0);
rowItems = filterInvalidItems(rowSlice);
@@ -114,12 +122,14 @@
mRange = rowSlice;
}
if (rowItems.size() > 0) {
- // Remove the things we already know about
- if (mStartItem != null) {
- rowItems.remove(mStartItem);
- }
- if (mPrimaryAction != null) {
- rowItems.remove(mPrimaryAction);
+ // Start item
+ SliceItem firstItem = rowItems.get(0);
+ if (FORMAT_SLICE.equals(firstItem.getFormat())) {
+ SliceItem unwrappedItem = firstItem.getSlice().getItems().get(0);
+ if (isStartType(unwrappedItem)) {
+ mStartItem = unwrappedItem;
+ rowItems.remove(0);
+ }
}
// Text + end items
@@ -147,11 +157,11 @@
}
// Special rules for end items: only one timestamp
boolean hasTimestamp = mStartItem != null
- && FORMAT_LONG.equals(mStartItem.getFormat());
+ && FORMAT_TIMESTAMP.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_LONG.equals(item.getFormat())) {
+ if (FORMAT_TIMESTAMP.equals(item.getFormat())) {
if (!hasTimestamp) {
hasTimestamp = true;
mEndItems.add(item);
@@ -176,37 +186,6 @@
}
/**
- * Sets the {@link #getPrimaryAction()} and {@link #getStartItem()} for this row.
- */
- private void determineStartAndPrimaryAction(@NonNull SliceItem rowSlice) {
- List<SliceItem> possibleStartItems = SliceQuery.findAll(rowSlice, null, HINT_TITLE, null);
- if (possibleStartItems.size() > 0) {
- // The start item will be at position 0 if it exists
- String format = possibleStartItems.get(0).getFormat();
- if ((FORMAT_ACTION.equals(format)
- && SliceQuery.find(possibleStartItems.get(0), FORMAT_IMAGE) != null)
- || FORMAT_SLICE.equals(format)
- || FORMAT_LONG.equals(format)
- || FORMAT_IMAGE.equals(format)) {
- mStartItem = possibleStartItems.get(0);
- }
- }
-
- String[] hints = new String[] {HINT_SHORTCUT, HINT_TITLE};
- List<SliceItem> possiblePrimaries = SliceQuery.findAll(rowSlice, FORMAT_SLICE, hints, null);
- if (possiblePrimaries.isEmpty() && FORMAT_ACTION.equals(rowSlice.getFormat())
- && rowSlice.getSlice().getItems().size() == 1) {
- mPrimaryAction = rowSlice;
- } else if (mStartItem != null && possiblePrimaries.size() > 1
- && possiblePrimaries.get(0) == mStartItem) {
- // Next item is the primary action
- mPrimaryAction = possiblePrimaries.get(1);
- } else if (possiblePrimaries.size() > 0) {
- mPrimaryAction = possiblePrimaries.get(0);
- }
- }
-
- /**
* @return the {@link SliceItem} used to populate this row.
*/
@NonNull
@@ -223,22 +202,6 @@
}
/**
- * @return the {@link SliceItem} for the icon to use for the input range thumb drawable.
- */
- @Nullable
- public SliceItem getInputRangeThumb() {
- if (mRange != null) {
- List<SliceItem> items = mRange.getSlice().getItems();
- for (int i = 0; i < items.size(); i++) {
- if (FORMAT_IMAGE.equals(items.get(i).getFormat())) {
- return items.get(i);
- }
- }
- }
- return null;
- }
-
- /**
* @return the {@link SliceItem} used for the main intent for this row; can be null.
*/
@Nullable
@@ -358,7 +321,6 @@
*/
public boolean isValid() {
return mStartItem != null
- || mPrimaryAction != null
|| mTitleItem != null
|| mSubtitleItem != null
|| mEndItems.size() > 0
@@ -376,17 +338,17 @@
// Must be slice or action
if (FORMAT_SLICE.equals(rowSlice.getFormat())
|| FORMAT_ACTION.equals(rowSlice.getFormat())) {
- List<SliceItem> rowItems = rowSlice.getSlice().getItems();
- // Special case: default see more just has an action but no other items
- if (rowSlice.hasHint(HINT_SEE_MORE) && rowItems.isEmpty()) {
- return true;
- }
// Must have at least one legitimate child
+ List<SliceItem> rowItems = rowSlice.getSlice().getItems();
for (int i = 0; i < rowItems.size(); i++) {
if (isValidRowContent(rowSlice, rowItems.get(i))) {
return true;
}
}
+ // Special case: default see more just has an action but no other items
+ if (rowSlice.hasHint(HINT_SEE_MORE) && rowItems.isEmpty()) {
+ return true;
+ }
}
return false;
}
@@ -406,20 +368,39 @@
}
/**
- * @return whether this item is valid content to visibly appear in a row.
+ * @return whether this item is valid content to display in a row.
*/
private static boolean isValidRowContent(SliceItem slice, SliceItem item) {
- if (item.hasAnyHints(HINT_KEYWORDS, HINT_TTL, HINT_LAST_UPDATED, HINT_HORIZONTAL)
- || SUBTYPE_CONTENT_DESCRIPTION.equals(item.getSubType())) {
+ if (item.hasAnyHints(HINT_KEYWORDS, HINT_TTL, HINT_LAST_UPDATED)) {
return false;
}
+ if (FORMAT_SLICE.equals(item.getFormat()) && !item.hasHint(HINT_SHORTCUT)) {
+ // Unpack contents of slice
+ item = item.getSlice().getItems().get(0);
+ }
final String itemFormat = item.getFormat();
- return FORMAT_IMAGE.equals(itemFormat)
- || FORMAT_TEXT.equals(itemFormat)
- || FORMAT_LONG.equals(itemFormat)
- || FORMAT_ACTION.equals(itemFormat)
+ return (FORMAT_TEXT.equals(itemFormat)
+ && !SUBTYPE_CONTENT_DESCRIPTION.equals(item.getSubType()))
+ || FORMAT_IMAGE.equals(itemFormat)
+ || FORMAT_TIMESTAMP.equals(itemFormat)
|| FORMAT_REMOTE_INPUT.equals(itemFormat)
- || FORMAT_SLICE.equals(itemFormat)
+ || (FORMAT_SLICE.equals(itemFormat) && item.hasHint(HINT_TITLE)
+ && !item.hasHint(HINT_SHORTCUT))
+ || (FORMAT_SLICE.equals(itemFormat) && item.hasHint(HINT_SHORTCUT)
+ && !item.hasHint(HINT_TITLE))
+ || FORMAT_ACTION.equals(itemFormat)
|| (FORMAT_INT.equals(itemFormat) && SUBTYPE_RANGE.equals(slice.getSubType()));
}
+
+ /**
+ * @return Whether this item is appropriate to be considered a "start" item, i.e. go in the
+ * front slot of a row.
+ */
+ private static boolean isStartType(SliceItem item) {
+ final String type = item.getFormat();
+ return (FORMAT_ACTION.equals(type) && (SliceQuery.find(item, FORMAT_IMAGE) != null))
+ || FORMAT_IMAGE.equals(type)
+ || (FORMAT_TIMESTAMP.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 d9cf7d7..2479d70 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowView.java
@@ -21,12 +21,13 @@
import static android.app.slice.Slice.HINT_PARTIAL;
import static android.app.slice.Slice.HINT_SHORTCUT;
import static android.app.slice.Slice.SUBTYPE_MAX;
+import static android.app.slice.Slice.SUBTYPE_TOGGLE;
import static android.app.slice.Slice.SUBTYPE_VALUE;
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;
@@ -45,7 +46,6 @@
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.StyleSpan;
-import android.util.ArrayMap;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
@@ -62,11 +62,13 @@
import androidx.annotation.RestrictTo;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.graphics.drawable.IconCompat;
+import androidx.slice.Slice;
import androidx.slice.SliceItem;
import androidx.slice.core.SliceActionImpl;
import androidx.slice.core.SliceQuery;
import androidx.slice.view.R;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -90,7 +92,7 @@
private TextView mSecondaryText;
private TextView mLastUpdatedText;
private View mDivider;
- private ArrayMap<SliceActionImpl, SliceActionView> mToggles = new ArrayMap<>();
+ private ArrayList<SliceActionView> mToggles = new ArrayList<>();
private LinearLayout mEndContainer;
private ProgressBar mRangeBar;
private View mSeeMoreView;
@@ -215,12 +217,17 @@
}
}
+ @Override
+ public void setSlice(Slice slice) {
+ // Nothing to do
+ }
+
/**
* This is called when RowView is being used as a component in a large template.
*/
@Override
public void setSliceItem(SliceItem slice, boolean isHeader, int index,
- int rowCount, SliceView.OnSliceActionListener observer) {
+ SliceView.OnSliceActionListener observer) {
setSliceActionListener(observer);
mRowIndex = index;
mIsHeader = ListContent.isValidHeader(slice);
@@ -239,9 +246,9 @@
if (contentDescr != null) {
mContent.setContentDescription(contentDescr);
}
+ boolean showStart = false;
final SliceItem startItem = mRowContent.getStartItem();
- boolean showStart = startItem != null && mRowIndex > 0;
- if (showStart) {
+ if (startItem != null) {
showStart = addItem(startItem, mTintColor, true /* isStart */);
}
mStartContainer.setVisibility(showStart ? View.VISIBLE : View.GONE);
@@ -262,12 +269,11 @@
addSubtitle(subtitleItem);
SliceItem primaryAction = mRowContent.getPrimaryAction();
- if (primaryAction != null && primaryAction != startItem) {
+ if (primaryAction != null) {
mRowAction = new SliceActionImpl(primaryAction);
if (mRowAction.isToggle()) {
// If primary action is a toggle, add it and we're done
addAction(mRowAction, mTintColor, mEndContainer, false /* isStart */);
- // TODO: if start item is tappable, touch feedback should exclude it
setViewClickable(mRootView, true);
return;
}
@@ -284,10 +290,16 @@
// If we're here we can can show end items; check for top level actions first
List<SliceItem> endItems = mRowContent.getEndItems();
- if (mHeaderActions != null && mHeaderActions.size() > 0) {
+ if (mIsHeader && mHeaderActions != null && mHeaderActions.size() > 0) {
// Use these if we have them instead
endItems = mHeaderActions;
}
+ boolean hasRowAction = mRowAction != null;
+ if (endItems.isEmpty()) {
+ if (hasRowAction) setViewClickable(mRootView, true);
+ return;
+ }
+
// If we're here we might be able to show end items
int itemCount = 0;
boolean firstItemIsADefaultToggle = false;
@@ -296,7 +308,7 @@
final SliceItem endItem = endItems.get(i);
if (itemCount < MAX_END_ITEMS) {
if (addItem(endItem, mTintColor, false /* isStart */)) {
- if (SliceQuery.find(endItem, FORMAT_ACTION) != null) {
+ if (FORMAT_ACTION.equals(endItem.getFormat())) {
hasEndItemAction = true;
}
itemCount++;
@@ -309,21 +321,19 @@
}
// If there is a row action and the first end item is a default toggle, show the divider.
- mDivider.setVisibility(mRowAction != null && firstItemIsADefaultToggle
+ mDivider.setVisibility(hasRowAction && firstItemIsADefaultToggle
? View.VISIBLE : View.GONE);
- boolean hasStartAction = startItem != null
- && SliceQuery.find(startItem, FORMAT_ACTION) != null;
-
- if (mRowAction != null) {
- // If there are outside actions make only the content bit clickable
- // TODO: if start item is an image touch feedback should include it
- setViewClickable((hasEndItemAction || hasStartAction) ? mContent : mRootView, true);
- } else if (hasEndItemAction != hasStartAction && (itemCount == 1 || hasStartAction)) {
- // Single action; make whole row clickable for it
- if (!mToggles.isEmpty()) {
- mRowAction = mToggles.keySet().iterator().next();
+ if (hasRowAction) {
+ if (itemCount > 0 && hasEndItemAction) {
+ setViewClickable(mContent, true);
} else {
- mRowAction = new SliceActionImpl(hasEndItemAction ? endItems.get(0) : startItem);
+ setViewClickable(mRootView, true);
+ }
+ } else if (mRowContent.endItemsContainAction() && itemCount == 1) {
+ // If the only end item is an action, make the whole row clickable.
+ SliceItem unwrappedActionItem = endItems.get(0).getSlice().getItems().get(0);
+ if (!SUBTYPE_TOGGLE.equals(unwrappedActionItem.getSubType())) {
+ mRowAction = new SliceActionImpl(endItems.get(0));
}
setViewClickable(mRootView, true);
}
@@ -331,7 +341,7 @@
private void addSubtitle(final SliceItem subtitleItem) {
CharSequence subtitleTimeString = null;
- if (mShowLastUpdated && mLastUpdated != -1) {
+ if (mShowLastUpdated) {
subtitleTimeString = getResources().getString(R.string.abc_slice_updated,
SliceViewUtil.getRelativeTimeString(mLastUpdated));
}
@@ -344,8 +354,6 @@
? mHeaderSubtitleSize
: mSubtitleSize);
mSecondaryText.setTextColor(mSubtitleColor);
- int verticalPadding = mIsHeader ? mVerticalHeaderTextPadding : mVerticalTextPadding;
- mSecondaryText.setPadding(0, verticalPadding, 0, 0);
}
if (subtitleTimeString != null) {
if (!TextUtils.isEmpty(subtitle)) {
@@ -390,7 +398,7 @@
addView(progressBar);
mRangeBar = progressBar;
if (isSeekBar) {
- SliceItem thumb = mRowContent.getInputRangeThumb();
+ SliceItem thumb = SliceQuery.find(range, FORMAT_IMAGE);
SeekBar seekBar = (SeekBar) mRangeBar;
if (thumb != null) {
seekBar.setThumb(thumb.getIcon().loadDrawable(getContext()));
@@ -437,8 +445,9 @@
info.setPosition(EventInfo.POSITION_START, 0, 1);
}
sav.setAction(actionContent, info, mObserver, color);
+
if (isToggle) {
- mToggles.put(actionContent, sav);
+ mToggles.add(sav);
}
}
@@ -451,8 +460,7 @@
int imageMode = 0;
SliceItem timeStamp = null;
ViewGroup container = isStart ? mStartContainer : mEndContainer;
- if (FORMAT_SLICE.equals(sliceItem.getFormat())
- || FORMAT_ACTION.equals(sliceItem.getFormat())) {
+ if (FORMAT_SLICE.equals(sliceItem.getFormat())) {
if (sliceItem.hasHint(HINT_SHORTCUT)) {
addAction(new SliceActionImpl(sliceItem), color, container, isStart);
return true;
@@ -464,7 +472,7 @@
if (FORMAT_IMAGE.equals(sliceItem.getFormat())) {
icon = sliceItem.getIcon();
imageMode = sliceItem.hasHint(HINT_NO_TINT) ? SMALL_IMAGE : ICON_IMAGE;
- } else if (FORMAT_LONG.equals(sliceItem.getFormat())) {
+ } else if (FORMAT_TIMESTAMP.equals(sliceItem.getFormat())) {
timeStamp = sliceItem;
}
View addedView = null;
@@ -521,25 +529,21 @@
@Override
public void onClick(View view) {
- if (mRowAction != null && mRowAction.getActionItem() != null) {
- // Check if it's a row click for a toggle, in this case need to update the UI
- if (mRowAction.isToggle() && !(view instanceof SliceActionView)) {
- SliceActionView sav = mToggles.get(mRowAction);
- if (sav != null) {
- sav.toggle();
+ if (mRowAction != null && mRowAction.getActionItem() != null && !mRowAction.isToggle()) {
+ // Check for a row action
+ try {
+ mRowAction.getActionItem().fireAction(null, null);
+ if (mObserver != null) {
+ EventInfo info = new EventInfo(getMode(), EventInfo.ACTION_TYPE_CONTENT,
+ EventInfo.ROW_TYPE_LIST, mRowIndex);
+ mObserver.onSliceAction(info, mRowAction.getSliceItem());
}
- } else {
- try {
- mRowAction.getActionItem().fireAction(null, null);
- if (mObserver != null) {
- EventInfo info = new EventInfo(getMode(), EventInfo.ACTION_TYPE_CONTENT,
- EventInfo.ROW_TYPE_LIST, mRowIndex);
- mObserver.onSliceAction(info, mRowAction.getSliceItem());
- }
- } catch (CanceledException e) {
- Log.e(TAG, "PendingIntent for slice cannot be sent", e);
- }
+ } catch (CanceledException e) {
+ Log.e(TAG, "PendingIntent for slice cannot be sent", e);
}
+ } else if (mToggles.size() == 1) {
+ // If there is only one toggle and no row action, just toggle it.
+ mToggles.get(0).toggle();
}
}
@@ -553,18 +557,16 @@
@Override
public void resetView() {
- mRootView.setVisibility(VISIBLE);
+ mRootView.setVisibility(View.VISIBLE);
setViewClickable(mRootView, false);
setViewClickable(mContent, false);
mStartContainer.removeAllViews();
mEndContainer.removeAllViews();
mPrimaryText.setText(null);
mSecondaryText.setText(null);
- mLastUpdatedText.setText(null);
- mLastUpdatedText.setVisibility(GONE);
mToggles.clear();
mRowAction = null;
- mDivider.setVisibility(GONE);
+ mDivider.setVisibility(View.GONE);
if (mRangeBar != null) {
removeView(mRangeBar);
}
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 2f97c64..37ef17b 100644
--- a/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java
@@ -26,6 +26,7 @@
import static android.app.slice.SliceItem.FORMAT_SLICE;
import static android.app.slice.SliceItem.FORMAT_TEXT;
+import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.Context;
@@ -42,7 +43,6 @@
import android.widget.ImageView;
import androidx.annotation.RestrictTo;
-import androidx.core.graphics.drawable.DrawableCompat;
import androidx.slice.Slice;
import androidx.slice.SliceItem;
import androidx.slice.core.SliceQuery;
@@ -56,7 +56,7 @@
private static final String TAG = "ShortcutView";
- private ListContent mListContent;
+ private Slice mSlice;
private Uri mUri;
private SliceItem mActionItem;
private SliceItem mLabel;
@@ -72,23 +72,21 @@
mLargeIconSize = res.getDimensionPixelSize(R.dimen.abc_slice_shortcut_size);
}
+ @SuppressLint("NewApi") // mIcon can only be non-null on API 23+
@Override
- public void setSliceContent(ListContent sliceContent) {
+ public void setSlice(Slice slice) {
resetView();
- mListContent = sliceContent;
- if (mListContent == null) {
- return;
- }
- determineShortcutItems(getContext());
- SliceItem colorItem = mListContent.getColorItem();
+ mSlice = slice;
+ determineShortcutItems(getContext(), slice);
+ SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
if (colorItem == null) {
- colorItem = SliceQuery.findSubtype(sliceContent.getSlice(), FORMAT_INT, SUBTYPE_COLOR);
+ colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
}
final int color = colorItem != null
? colorItem.getInt()
: SliceViewUtil.getColorAccent(getContext());
- Drawable circle = DrawableCompat.wrap(new ShapeDrawable(new OvalShape()));
- DrawableCompat.setTint(circle, color);
+ ShapeDrawable circle = new ShapeDrawable(new OvalShape());
+ circle.setTint(color);
ImageView iv = new ImageView(getContext());
if (mIcon != null && !mIcon.hasHint(HINT_NO_TINT)) {
// Only set the background if we're tintable
@@ -100,7 +98,7 @@
final int iconSize = isImage ? mLargeIconSize : mSmallIconSize;
SliceViewUtil.createCircledIcon(getContext(), iconSize, mIcon.getIcon(),
isImage, this /* parent */);
- mUri = sliceContent.getSlice().getUri();
+ mUri = slice.getUri();
setClickable(true);
} else {
setClickable(false);
@@ -114,9 +112,6 @@
@Override
public boolean performClick() {
- if (mListContent == null) {
- return false;
- }
if (!callOnClick()) {
try {
if (mActionItem != null) {
@@ -132,8 +127,8 @@
EventInfo.ROW_TYPE_SHORTCUT, 0 /* rowIndex */);
SliceItem interactedItem = mActionItem != null
? mActionItem
- : new SliceItem(mListContent.getSlice(), FORMAT_SLICE,
- null /* subtype */, mListContent.getSlice().getHints());
+ : new SliceItem(mSlice, FORMAT_SLICE, null /* subtype */,
+ mSlice.getHints());
mObserver.onSliceAction(ei, interactedItem);
}
} catch (CanceledException e) {
@@ -146,12 +141,9 @@
/**
* Looks at the slice and determines which items are best to use to compose the shortcut.
*/
- private void determineShortcutItems(Context context) {
- if (mListContent == null) {
- return;
- }
- SliceItem primaryAction = mListContent.getPrimaryAction();
- Slice slice = mListContent.getSlice();
+ private void determineShortcutItems(Context context, Slice slice) {
+ ListContent lc = new ListContent(context, slice);
+ SliceItem primaryAction = lc.getPrimaryAction();
if (primaryAction != null) {
// Preferred case: slice has a primary action
@@ -203,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_ACTION,
+ new Slice.Builder(slice.getUri()).build(), FORMAT_SLICE,
null /* subtype */, null);
}
}
@@ -212,7 +204,7 @@
@Override
public void resetView() {
- mListContent = null;
+ mSlice = null;
mUri = null;
mActionItem = null;
mLabel = null;
diff --git a/slices/view/src/main/java/androidx/slice/widget/SliceChildView.java b/slices/view/src/main/java/androidx/slice/widget/SliceChildView.java
index fcd71bb..2400e738c 100644
--- a/slices/view/src/main/java/androidx/slice/widget/SliceChildView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/SliceChildView.java
@@ -19,11 +19,13 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
+import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
+import androidx.slice.Slice;
import androidx.slice.SliceItem;
import androidx.slice.view.R;
@@ -43,15 +45,10 @@
protected int mSubtitleColor;
protected int mHeaderTitleSize;
protected int mHeaderSubtitleSize;
- protected int mVerticalHeaderTextPadding;
protected int mTitleSize;
protected int mSubtitleSize;
- protected int mVerticalTextPadding;
protected int mGridTitleSize;
protected int mGridSubtitleSize;
- protected int mVerticalGridTextPadding;
- protected int mGridTopPadding;
- protected int mGridBottomPadding;
protected boolean mShowLastUpdated;
protected long mLastUpdated = -1;
@@ -63,46 +60,6 @@
this(context);
}
- /**
- * Called when the view should be reset.
- */
- public abstract void resetView();
-
- /**
- * Sets the content to display in this slice.
- */
- public void setSliceContent(ListContent content) {
- // Do nothing
- }
-
- /**
- * Called when the slice being displayed in this view is an element of a larger list.
- */
- public void setSliceItem(SliceItem slice, boolean isHeader, int rowIndex,
- int rowCount, SliceView.OnSliceActionListener observer) {
- // Do nothing
- }
-
- /**
- * Sets the slice actions for this view.
- */
- public void setSliceActions(List<SliceItem> actions) {
- // Do nothing
- }
-
- /**
- * @return the height of the view when displayed in {@link SliceView#MODE_SMALL}.
- */
- public int getSmallHeight() {
- return 0;
- }
-
- /**
- * @return the height of the view when displayed in {@link SliceView#MODE_LARGE}.
- */
- public int getActualHeight() {
- return 0;
- }
/**
* Set the mode of the slice being presented.
@@ -120,6 +77,37 @@
}
/**
+ * @return the height of this view when displayed in {@link SliceView#MODE_SMALL}.
+ */
+ public int getSmallHeight() {
+ return 0;
+ }
+
+ /**
+ * @return the height of this view if it displayed all of its contents.
+ */
+ public int getActualHeight() {
+ return 0;
+ }
+
+ /**
+ * @param slice the slice to show in this view.
+ */
+ public abstract void setSlice(Slice slice);
+
+ /**
+ * Called when the view should be reset.
+ */
+ public abstract void resetView();
+
+ /**
+ * @return the view.
+ */
+ public View getView() {
+ return this;
+ }
+
+ /**
* Sets a custom color to use for tinting elements like icons for this view.
*/
public void setTint(@ColorInt int tintColor) {
@@ -158,31 +146,33 @@
mTintColor = themeColor != -1 ? themeColor : mTintColor;
mTitleColor = a.getColor(R.styleable.SliceView_titleColor, 0);
mSubtitleColor = a.getColor(R.styleable.SliceView_subtitleColor, 0);
-
mHeaderTitleSize = (int) a.getDimension(
R.styleable.SliceView_headerTitleSize, 0);
mHeaderSubtitleSize = (int) a.getDimension(
R.styleable.SliceView_headerSubtitleSize, 0);
- mVerticalHeaderTextPadding = (int) a.getDimension(
- R.styleable.SliceView_headerTextVerticalPadding, 0);
-
mTitleSize = (int) a.getDimension(R.styleable.SliceView_titleSize, 0);
mSubtitleSize = (int) a.getDimension(
R.styleable.SliceView_subtitleSize, 0);
- mVerticalTextPadding = (int) a.getDimension(
- R.styleable.SliceView_textVerticalPadding, 0);
-
mGridTitleSize = (int) a.getDimension(R.styleable.SliceView_gridTitleSize, 0);
mGridSubtitleSize = (int) a.getDimension(
R.styleable.SliceView_gridSubtitleSize, 0);
- int defaultVerticalGridPadding = getContext().getResources().getDimensionPixelSize(
- R.dimen.abc_slice_grid_text_inner_padding);
- mVerticalGridTextPadding = (int) a.getDimension(
- R.styleable.SliceView_gridTextVerticalPadding, defaultVerticalGridPadding);
- mGridTopPadding = (int) a.getDimension(R.styleable.SliceView_gridTopPadding, 0);
- mGridBottomPadding = (int) a.getDimension(R.styleable.SliceView_gridTopPadding, 0);
} finally {
a.recycle();
}
}
+
+ /**
+ * Called when the slice being displayed in this view is an element of a larger list.
+ */
+ public void setSliceItem(SliceItem slice, boolean isHeader, int rowIndex,
+ SliceView.OnSliceActionListener observer) {
+ // Do nothing
+ }
+
+ /**
+ * Sets the slice actions for this view.
+ */
+ public void setSliceActions(List<SliceItem> actions) {
+ // Do nothing
+ }
}
diff --git a/slices/view/src/main/java/androidx/slice/widget/SliceView.java b/slices/view/src/main/java/androidx/slice/widget/SliceView.java
index 7ba9eeb51..855bded 100644
--- a/slices/view/src/main/java/androidx/slice/widget/SliceView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/SliceView.java
@@ -32,7 +32,6 @@
import android.view.ViewConfiguration;
import android.view.ViewGroup;
-import androidx.annotation.ColorInt;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -313,7 +312,7 @@
private int getHeightForMode() {
int mode = getMode();
if (mode == MODE_SHORTCUT) {
- return mListContent != null && mListContent.isValid() ? mShortcutSize : 0;
+ return mShortcutSize;
}
return mode == MODE_LARGE
? mCurrentView.getActualHeight()
@@ -376,7 +375,7 @@
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
- View v = mCurrentView;
+ View v = mCurrentView.getView();
final int left = getPaddingLeft();
final int top = getPaddingTop();
v.layout(left, top, left + v.getMeasuredWidth(), top + v.getMeasuredHeight());
@@ -485,23 +484,15 @@
}
/**
- * @deprecated TO BE REMOVED; use {@link #setAccentColor(int)} instead.
- */
- @Deprecated
- public void setTint(int tintColor) {
- setAccentColor(tintColor);
- }
-
- /**
* Contents of a slice such as icons, text, and controls (e.g. toggle) can be tinted. Normally
* a color for tinting will be provided by the slice. Using this method will override
- * the slice-provided color information and instead tint elements with the color set here.
+ * this color information and instead tint elements with the provided color.
*
- * @param accentColor the color to use for tinting contents of this view.
+ * @param tintColor the color to use for tinting contents of this view.
*/
- public void setAccentColor(@ColorInt int accentColor) {
- mThemeTintColor = accentColor;
- mCurrentView.setTint(accentColor);
+ public void setTint(int tintColor) {
+ mThemeTintColor = tintColor;
+ mCurrentView.setTint(tintColor);
}
/**
@@ -549,14 +540,11 @@
private void reinflate() {
if (mCurrentSlice == null) {
mCurrentView.resetView();
- updateActions();
return;
}
- mListContent = new ListContent(getContext(), mCurrentSlice, mAttrs, mDefStyleAttr,
- mDefStyleRes);
+ mListContent = new ListContent(getContext(), mCurrentSlice);
if (!mListContent.isValid()) {
mCurrentView.resetView();
- updateActions();
return;
}
@@ -591,7 +579,7 @@
mCurrentView.setShowLastUpdated(mShowLastUpdated && expired);
// Set the slice
- mCurrentView.setSliceContent(mListContent);
+ mCurrentView.setSlice(mCurrentSlice);
updateActions();
}
diff --git a/slices/view/src/main/res-public/values/public_attrs.xml b/slices/view/src/main/res-public/values/public_attrs.xml
index a535a6d..ad909ea 100644
--- a/slices/view/src/main/res-public/values/public_attrs.xml
+++ b/slices/view/src/main/res-public/values/public_attrs.xml
@@ -22,14 +22,9 @@
<public type="attr" name="tintColor" />
<public type="attr" name="headerTitleSize" />
<public type="attr" name="headerSubtitleSize" />
- <public type="attr" name="headerTextVerticalPadding" />
<public type="attr" name="titleSize" />
<public type="attr" name="subtitleSize" />
- <public type="attr" name="textVerticalPadding" />
<public type="attr" name="gridTitleSize" />
<public type="attr" name="gridSubtitleSize" />
- <public type="attr" name="gridTextVerticalPadding" />
- <public type="attr" name="gridTopPadding" />
- <public type="attr" name="gridBottomPadding" />
<public type="attr" name="sliceViewStyle" />
-</resources>
+</resources>
\ No newline at end of file
diff --git a/slices/view/src/main/res/layout/abc_slice_grid_see_more.xml b/slices/view/src/main/res/layout/abc_slice_grid_see_more.xml
index 0a2e74622..17c1c0f 100644
--- a/slices/view/src/main/res/layout/abc_slice_grid_see_more.xml
+++ b/slices/view/src/main/res/layout/abc_slice_grid_see_more.xml
@@ -33,6 +33,5 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
- android:paddingTop="@dimen/abc_slice_grid_text_padding"
android:text="@string/abc_slice_more"/>
</LinearLayout>
\ No newline at end of file
diff --git a/slices/view/src/main/res/layout/abc_slice_secondary_text.xml b/slices/view/src/main/res/layout/abc_slice_secondary_text.xml
index c6ff594..0870465 100644
--- a/slices/view/src/main/res/layout/abc_slice_secondary_text.xml
+++ b/slices/view/src/main/res/layout/abc_slice_secondary_text.xml
@@ -15,11 +15,14 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
+<!-- LinearLayout -->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary"
android:gravity="center"
android:layout_height="wrap_content"
+ android:padding="4dp"
android:layout_width="match_parent"
android:maxLines="1"
- android:singleLine="true"
android:ellipsize="end"/>
diff --git a/slices/view/src/main/res/layout/abc_slice_title.xml b/slices/view/src/main/res/layout/abc_slice_title.xml
index eac5e8c..70a1400 100644
--- a/slices/view/src/main/res/layout/abc_slice_title.xml
+++ b/slices/view/src/main/res/layout/abc_slice_title.xml
@@ -18,9 +18,11 @@
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:attr/textColorPrimary"
android:gravity="center"
android:layout_height="wrap_content"
+ android:padding="4dp"
android:layout_width="match_parent"
android:maxLines="1"
- android:singleLine="true"
android:ellipsize="end"/>
diff --git a/slices/view/src/main/res/values-af/strings.xml b/slices/view/src/main/res/values-af/strings.xml
index cfe8138..ea5ab25 100644
--- a/slices/view/src/main/res/values-af/strings.xml
+++ b/slices/view/src/main/res/values-af/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Meer"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Wys meer"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Opgedateer om <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. gelede</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min. gelede</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> jaar gelede</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> jaar gelede</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> dae gelede</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> dag gelede</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Kon nie koppel nie"</string>
</resources>
diff --git a/slices/view/src/main/res/values-am/strings.xml b/slices/view/src/main/res/values-am/strings.xml
index da542e1..ea5ab25 100644
--- a/slices/view/src/main/res/values-am/strings.xml
+++ b/slices/view/src/main/res/values-am/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"መገናኘት አልተቻለም"</string>
</resources>
diff --git a/slices/view/src/main/res/values-ar/strings.xml b/slices/view/src/main/res/values-ar/strings.xml
index 1e9ca94..21aa8a4c 100644
--- a/slices/view/src/main/res/values-ar/strings.xml
+++ b/slices/view/src/main/res/values-ar/strings.xml
@@ -18,32 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_updated" msgid="8155085405396453848">"وقت التحديث الأخير: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="zero">قبل <xliff:g id="ID_2">%d</xliff:g> دقيقة</item>
- <item quantity="two">قبل دقيقتين (<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>
- <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="zero">قبل <xliff:g id="ID_2">%d</xliff:g> سنة</item>
- <item quantity="two">قبل سنتين (<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>
- <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="zero">قبل <xliff:g id="ID_2">%d</xliff:g> يوم</item>
- <item quantity="two">قبل يومين (<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>
- <item quantity="one">قبل <xliff:g id="ID_1">%d</xliff:g> يوم</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"تعذّر الاتصال."</string>
</resources>
diff --git a/slices/view/src/main/res/values-as/strings.xml b/slices/view/src/main/res/values-as/strings.xml
deleted file mode 100644
index dbc598f..0000000
--- a/slices/view/src/main/res/values-as/strings.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2017 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- 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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"সংযোগ কৰিব পৰা নগ\'ল"</string>
-</resources>
diff --git a/slices/view/src/main/res/values-az/strings.xml b/slices/view/src/main/res/values-az/strings.xml
index 837f08c..ea5ab25 100644
--- a/slices/view/src/main/res/values-az/strings.xml
+++ b/slices/view/src/main/res/values-az/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Digər"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Digərinə baxın"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"<xliff:g id="TIME">%1$s</xliff:g> tarixində yenilənib"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> dəq əvvəl</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> dəq əvvəl</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> il əvvəl</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> il əvvəl</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> gün əvvəl</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> gün əvvəl</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Qoşulmaq mümkün olmadı"</string>
</resources>
diff --git a/slices/view/src/main/res/values-b+sr+Latn/strings.xml b/slices/view/src/main/res/values-b+sr+Latn/strings.xml
index 8deb17c..ffd9b9b 100644
--- a/slices/view/src/main/res/values-b+sr+Latn/strings.xml
+++ b/slices/view/src/main/res/values-b+sr+Latn/strings.xml
@@ -18,23 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"i još <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="abc_slice_more" msgid="1983560225998630901">"Još"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Prikaži više"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Ažurirano <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="one">pre <xliff:g id="ID_2">%d</xliff:g> min</item>
- <item quantity="few">pre <xliff:g id="ID_2">%d</xliff:g> min</item>
- <item quantity="other">pre <xliff:g id="ID_2">%d</xliff:g> min</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="one">pre <xliff:g id="ID_2">%d</xliff:g> god</item>
- <item quantity="few">pre <xliff:g id="ID_2">%d</xliff:g> god</item>
- <item quantity="other">pre <xliff:g id="ID_2">%d</xliff:g> god</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="one">pre <xliff:g id="ID_2">%d</xliff:g> dan</item>
- <item quantity="few">pre <xliff:g id="ID_2">%d</xliff:g> dana</item>
- <item quantity="other">pre <xliff:g id="ID_2">%d</xliff:g> dana</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Povezivanje nije uspelo"</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..df8e965 100644
--- a/slices/view/src/main/res/values-be/strings.xml
+++ b/slices/view/src/main/res/values-be/strings.xml
@@ -18,26 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Не атрымалася падключыцца"</string>
</resources>
diff --git a/slices/view/src/main/res/values-bg/strings.xml b/slices/view/src/main/res/values-bg/strings.xml
index b019a46b..ea5ab25 100644
--- a/slices/view/src/main/res/values-bg/strings.xml
+++ b/slices/view/src/main/res/values-bg/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..8737d8c 100644
--- a/slices/view/src/main/res/values-bn/strings.xml
+++ b/slices/view/src/main/res/values-bn/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"কানেক্ট করা যায়নি"</string>
</resources>
diff --git a/slices/view/src/main/res/values-bs/strings.xml b/slices/view/src/main/res/values-bs/strings.xml
index cb84c18..ea5ab25 100644
--- a/slices/view/src/main/res/values-bs/strings.xml
+++ b/slices/view/src/main/res/values-bs/strings.xml
@@ -18,23 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Više"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Prikaži više"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Ažurirano <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="one">Prije <xliff:g id="ID_2">%d</xliff:g> min.</item>
- <item quantity="few">Prije <xliff:g id="ID_2">%d</xliff:g> min.</item>
- <item quantity="other">Prije <xliff:g id="ID_2">%d</xliff:g> min.</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="one">Prije <xliff:g id="ID_2">%d</xliff:g> god.</item>
- <item quantity="few">Prije <xliff:g id="ID_2">%d</xliff:g> god.</item>
- <item quantity="other">Prije <xliff:g id="ID_2">%d</xliff:g> god.</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="one">Prije <xliff:g id="ID_2">%d</xliff:g> dan</item>
- <item quantity="few">Prije <xliff:g id="ID_2">%d</xliff:g> dana</item>
- <item quantity="other">Prije <xliff:g id="ID_2">%d</xliff:g> dana</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Povezivanje nije uspjelo"</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..8ae6f78c 100644
--- a/slices/view/src/main/res/values-ca/strings.xml
+++ b/slices/view/src/main/res/values-ca/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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> més"</string>
- <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>
- <string name="abc_slice_error" msgid="4188371422904147368">"No s\'ha pogut connectar"</string>
</resources>
diff --git a/slices/view/src/main/res/values-cs/strings.xml b/slices/view/src/main/res/values-cs/strings.xml
index c4c1fce..1d39c0f 100644
--- a/slices/view/src/main/res/values-cs/strings.xml
+++ b/slices/view/src/main/res/values-cs/strings.xml
@@ -18,26 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"a ještě <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="abc_slice_more" msgid="1983560225998630901">"Více"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Zobrazit více"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Aktualizováno <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="few">před <xliff:g id="ID_2">%d</xliff:g> min</item>
- <item quantity="many">před <xliff:g id="ID_2">%d</xliff:g> min</item>
- <item quantity="other">před <xliff:g id="ID_2">%d</xliff:g> min</item>
- <item quantity="one">před <xliff:g id="ID_1">%d</xliff:g> min</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="few">před <xliff:g id="ID_2">%d</xliff:g> lety</item>
- <item quantity="many">před <xliff:g id="ID_2">%d</xliff:g> roku</item>
- <item quantity="other">před <xliff:g id="ID_2">%d</xliff:g> lety</item>
- <item quantity="one">před <xliff:g id="ID_1">%d</xliff:g> rokem</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="few">před <xliff:g id="ID_2">%d</xliff:g> dny</item>
- <item quantity="many">před <xliff:g id="ID_2">%d</xliff:g> dne</item>
- <item quantity="other">před <xliff:g id="ID_2">%d</xliff:g> dny</item>
- <item quantity="one">před <xliff:g id="ID_1">%d</xliff:g> dnem</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Nelze se připojit"</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..40de41d 100644
--- a/slices/view/src/main/res/values-da/strings.xml
+++ b/slices/view/src/main/res/values-da/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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> mere"</string>
- <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>
- <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..9d9bede 100644
--- a/slices/view/src/main/res/values-de/strings.xml
+++ b/slices/view/src/main/res/values-de/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Verbindung nicht möglich"</string>
</resources>
diff --git a/slices/view/src/main/res/values-el/strings.xml b/slices/view/src/main/res/values-el/strings.xml
index 31092af..ea5ab25 100644
--- a/slices/view/src/main/res/values-el/strings.xml
+++ b/slices/view/src/main/res/values-el/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</resources>
diff --git a/slices/view/src/main/res/values-en-rAU/strings.xml b/slices/view/src/main/res/values-en-rAU/strings.xml
index 8fa5b45..ea5ab25 100644
--- a/slices/view/src/main/res/values-en-rAU/strings.xml
+++ b/slices/view/src/main/res/values-en-rAU/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"More"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Show more"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Updated <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 ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min ago</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> yr ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> yr ago</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> days ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> day ago</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Couldn\'t connect"</string>
</resources>
diff --git a/slices/view/src/main/res/values-en-rCA/strings.xml b/slices/view/src/main/res/values-en-rCA/strings.xml
index 8fa5b45..ea5ab25 100644
--- a/slices/view/src/main/res/values-en-rCA/strings.xml
+++ b/slices/view/src/main/res/values-en-rCA/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"More"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Show more"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Updated <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 ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min ago</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> yr ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> yr ago</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> days ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> day ago</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Couldn\'t connect"</string>
</resources>
diff --git a/slices/view/src/main/res/values-en-rGB/strings.xml b/slices/view/src/main/res/values-en-rGB/strings.xml
index 8fa5b45..ea5ab25 100644
--- a/slices/view/src/main/res/values-en-rGB/strings.xml
+++ b/slices/view/src/main/res/values-en-rGB/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"More"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Show more"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Updated <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 ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min ago</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> yr ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> yr ago</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> days ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> day ago</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Couldn\'t connect"</string>
</resources>
diff --git a/slices/view/src/main/res/values-en-rIN/strings.xml b/slices/view/src/main/res/values-en-rIN/strings.xml
index 8fa5b45..ea5ab25 100644
--- a/slices/view/src/main/res/values-en-rIN/strings.xml
+++ b/slices/view/src/main/res/values-en-rIN/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"More"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Show more"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Updated <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 ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min ago</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> yr ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> yr ago</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> days ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> day ago</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Couldn\'t connect"</string>
</resources>
diff --git a/slices/view/src/main/res/values-en-rXC/strings.xml b/slices/view/src/main/res/values-en-rXC/strings.xml
index b24c1e6..b793412 100644
--- a/slices/view/src/main/res/values-en-rXC/strings.xml
+++ b/slices/view/src/main/res/values-en-rXC/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"More"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Show more"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Updated <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 ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> min ago</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> yr ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> yr ago</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> days ago</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> day ago</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Couldn\'t connect"</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..a445505 100644
--- a/slices/view/src/main/res/values-es-rUS/strings.xml
+++ b/slices/view/src/main/res/values-es-rUS/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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> más"</string>
- <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>
- <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..dcdd33e 100644
--- a/slices/view/src/main/res/values-es/strings.xml
+++ b/slices/view/src/main/res/values-es/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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> más"</string>
- <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>
- <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 7e053e92..a1675ff 100644
--- a/slices/view/src/main/res/values-et/strings.xml
+++ b/slices/view/src/main/res/values-et/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"ja veel <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <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>
- <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..1c79d4a 100644
--- a/slices/view/src/main/res/values-eu/strings.xml
+++ b/slices/view/src/main/res/values-eu/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"Beste <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <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>
- <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..2b2abd2 100644
--- a/slices/view/src/main/res/values-fa/strings.xml
+++ b/slices/view/src/main/res/values-fa/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"متصل نشد"</string>
</resources>
diff --git a/slices/view/src/main/res/values-fi/strings.xml b/slices/view/src/main/res/values-fi/strings.xml
index dbbe0cd..ea5ab25 100644
--- a/slices/view/src/main/res/values-fi/strings.xml
+++ b/slices/view/src/main/res/values-fi/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <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..ea5ab25 100644
--- a/slices/view/src/main/res/values-fr-rCA/strings.xml
+++ b/slices/view/src/main/res/values-fr-rCA/strings.xml
@@ -17,21 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Impossible de se connecter"</string>
+ <string name="abc_slice_more_content" msgid="6405516388971241142">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</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..73685ce 100644
--- a/slices/view/src/main/res/values-fr/strings.xml
+++ b/slices/view/src/main/res/values-fr/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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> autres"</string>
- <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>
- <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..573eae9 100644
--- a/slices/view/src/main/res/values-gl/strings.xml
+++ b/slices/view/src/main/res/values-gl/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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> máis"</string>
- <string name="abc_slice_more" msgid="1983560225998630901">"Máis"</string>
- <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>
- </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>
- </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>
- </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..ea5ab25 100644
--- a/slices/view/src/main/res/values-gu/strings.xml
+++ b/slices/view/src/main/res/values-gu/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <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..ea5ab25 100644
--- a/slices/view/src/main/res/values-hi/strings.xml
+++ b/slices/view/src/main/res/values-hi/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"कनेक्ट नहीं हो पाया"</string>
</resources>
diff --git a/slices/view/src/main/res/values-hr/strings.xml b/slices/view/src/main/res/values-hr/strings.xml
index f44b06c..7ecedf6 100644
--- a/slices/view/src/main/res/values-hr/strings.xml
+++ b/slices/view/src/main/res/values-hr/strings.xml
@@ -18,23 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"još <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="abc_slice_more" msgid="1983560225998630901">"Više"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Prikaži više"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Ažurirano <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="one">Prije <xliff:g id="ID_2">%d</xliff:g> min</item>
- <item quantity="few">Prije <xliff:g id="ID_2">%d</xliff:g> min</item>
- <item quantity="other">Prije <xliff:g id="ID_2">%d</xliff:g> min</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="one">Prije <xliff:g id="ID_2">%d</xliff:g> godinu</item>
- <item quantity="few">Prije <xliff:g id="ID_2">%d</xliff:g> godine</item>
- <item quantity="other">Prije <xliff:g id="ID_2">%d</xliff:g> godina</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="one">Prije <xliff:g id="ID_2">%d</xliff:g> dan</item>
- <item quantity="few">Prije <xliff:g id="ID_2">%d</xliff:g> dana</item>
- <item quantity="other">Prije <xliff:g id="ID_2">%d</xliff:g> dana</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Povezivanje nije moguće"</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-hu/strings.xml
+++ b/slices/view/src/main/res/values-hu/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <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..ea5ab25 100644
--- a/slices/view/src/main/res/values-hy/strings.xml
+++ b/slices/view/src/main/res/values-hy/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Չհաջողվեց միանալ"</string>
</resources>
diff --git a/slices/view/src/main/res/values-in/strings.xml b/slices/view/src/main/res/values-in/strings.xml
index 5641ebb..ea5ab25 100644
--- a/slices/view/src/main/res/values-in/strings.xml
+++ b/slices/view/src/main/res/values-in/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Lainnya"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Tampilkan lainnya"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Diupdate <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> menit lalu</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> menit lalu</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> tahun lalu</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> tahun 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 lalu</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> hari lalu</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Tidak dapat terhubung"</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-is/strings.xml
+++ b/slices/view/src/main/res/values-is/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <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..ea5ab25 100644
--- a/slices/view/src/main/res/values-it/strings.xml
+++ b/slices/view/src/main/res/values-it/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <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..ea5ab25 100644
--- a/slices/view/src/main/res/values-iw/strings.xml
+++ b/slices/view/src/main/res/values-iw/strings.xml
@@ -18,26 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <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..ed51803 100644
--- a/slices/view/src/main/res/values-ja/strings.xml
+++ b/slices/view/src/main/res/values-ja/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-ka/strings.xml
+++ b/slices/view/src/main/res/values-ka/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-kk/strings.xml
+++ b/slices/view/src/main/res/values-kk/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</resources>
diff --git a/slices/view/src/main/res/values-km/strings.xml b/slices/view/src/main/res/values-km/strings.xml
index 1e78acb..ea5ab25 100644
--- a/slices/view/src/main/res/values-km/strings.xml
+++ b/slices/view/src/main/res/values-km/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</resources>
diff --git a/slices/view/src/main/res/values-kn/strings.xml b/slices/view/src/main/res/values-kn/strings.xml
index ed7dcd6..ea5ab25 100644
--- a/slices/view/src/main/res/values-kn/strings.xml
+++ b/slices/view/src/main/res/values-kn/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <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..2dc0279 100644
--- a/slices/view/src/main/res/values-ko/strings.xml
+++ b/slices/view/src/main/res/values-ko/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-ky/strings.xml
+++ b/slices/view/src/main/res/values-ky/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-lo/strings.xml
+++ b/slices/view/src/main/res/values-lo/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</resources>
diff --git a/slices/view/src/main/res/values-lt/strings.xml b/slices/view/src/main/res/values-lt/strings.xml
index e4094b4..bb6bcb3 100644
--- a/slices/view/src/main/res/values-lt/strings.xml
+++ b/slices/view/src/main/res/values-lt/strings.xml
@@ -18,26 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"Dar <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="abc_slice_more" msgid="1983560225998630901">"Daugiau"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Rodyti daugiau"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Atnaujinta <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="one">Prieš <xliff:g id="ID_2">%d</xliff:g> min.</item>
- <item quantity="few">Prieš <xliff:g id="ID_2">%d</xliff:g> min.</item>
- <item quantity="many">Prieš <xliff:g id="ID_2">%d</xliff:g> min.</item>
- <item quantity="other">Prieš <xliff:g id="ID_2">%d</xliff:g> min.</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="one">Prieš <xliff:g id="ID_2">%d</xliff:g> m.</item>
- <item quantity="few">Prieš <xliff:g id="ID_2">%d</xliff:g> m.</item>
- <item quantity="many">Prieš <xliff:g id="ID_2">%d</xliff:g> m.</item>
- <item quantity="other">Prieš <xliff:g id="ID_2">%d</xliff:g> m.</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="one">Prieš <xliff:g id="ID_2">%d</xliff:g> d.</item>
- <item quantity="few">Prieš <xliff:g id="ID_2">%d</xliff:g> d.</item>
- <item quantity="many">Prieš <xliff:g id="ID_2">%d</xliff:g> d.</item>
- <item quantity="other">Prieš <xliff:g id="ID_2">%d</xliff:g> d.</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Prisijungti nepavyko"</string>
</resources>
diff --git a/slices/view/src/main/res/values-lv/strings.xml b/slices/view/src/main/res/values-lv/strings.xml
index 45be57c..79ccb99 100644
--- a/slices/view/src/main/res/values-lv/strings.xml
+++ b/slices/view/src/main/res/values-lv/strings.xml
@@ -18,23 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"Vēl <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="abc_slice_more" msgid="1983560225998630901">"Vēl"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Rādīt vairāk"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Atjaunināts <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="zero">Pirms <xliff:g id="ID_2">%d</xliff:g> minūtēm</item>
- <item quantity="one">Pirms <xliff:g id="ID_2">%d</xliff:g> minūtes</item>
- <item quantity="other">Pirms <xliff:g id="ID_2">%d</xliff:g> minūtēm</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="zero">Pirms <xliff:g id="ID_2">%d</xliff:g> gadiem</item>
- <item quantity="one">Pirms <xliff:g id="ID_2">%d</xliff:g> gada</item>
- <item quantity="other">Pirms <xliff:g id="ID_2">%d</xliff:g> gadiem</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="zero">Pirms <xliff:g id="ID_2">%d</xliff:g> dienām</item>
- <item quantity="one">Pirms <xliff:g id="ID_2">%d</xliff:g> dienas</item>
- <item quantity="other">Pirms <xliff:g id="ID_2">%d</xliff:g> dienām</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Nevarēja izveidot savienojumu"</string>
</resources>
diff --git a/slices/view/src/main/res/values-mk/strings.xml b/slices/view/src/main/res/values-mk/strings.xml
index ff88cd7..ea5ab25 100644
--- a/slices/view/src/main/res/values-mk/strings.xml
+++ b/slices/view/src/main/res/values-mk/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Не може да се поврзе"</string>
</resources>
diff --git a/slices/view/src/main/res/values-ml/strings.xml b/slices/view/src/main/res/values-ml/strings.xml
index b67ae80..ea5ab25 100644
--- a/slices/view/src/main/res/values-ml/strings.xml
+++ b/slices/view/src/main/res/values-ml/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-mn/strings.xml
+++ b/slices/view/src/main/res/values-mn/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-mr/strings.xml
+++ b/slices/view/src/main/res/values-mr/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <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..ea5ab25 100644
--- a/slices/view/src/main/res/values-ms/strings.xml
+++ b/slices/view/src/main/res/values-ms/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Tidak dapat menyambung"</string>
</resources>
diff --git a/slices/view/src/main/res/values-my/strings.xml b/slices/view/src/main/res/values-my/strings.xml
index 4a3e3d4..ea5ab25 100644
--- a/slices/view/src/main/res/values-my/strings.xml
+++ b/slices/view/src/main/res/values-my/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-nb/strings.xml
+++ b/slices/view/src/main/res/values-nb/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Kunne ikke koble til"</string>
</resources>
diff --git a/slices/view/src/main/res/values-ne/strings.xml b/slices/view/src/main/res/values-ne/strings.xml
index beb8b311..ea5ab25 100644
--- a/slices/view/src/main/res/values-ne/strings.xml
+++ b/slices/view/src/main/res/values-ne/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-nl/strings.xml
+++ b/slices/view/src/main/res/values-nl/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <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
deleted file mode 100644
index 6bf6019..0000000
--- a/slices/view/src/main/res/values-or/strings.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2017 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- 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_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>
-</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-pa/strings.xml
+++ b/slices/view/src/main/res/values-pa/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <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..9d9bede 100644
--- a/slices/view/src/main/res/values-pl/strings.xml
+++ b/slices/view/src/main/res/values-pl/strings.xml
@@ -18,26 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Nie udało się połączyć"</string>
</resources>
diff --git a/slices/view/src/main/res/values-pt-rBR/strings.xml b/slices/view/src/main/res/values-pt-rBR/strings.xml
index 79cc7b7..629ba48 100644
--- a/slices/view/src/main/res/values-pt-rBR/strings.xml
+++ b/slices/view/src/main/res/values-pt-rBR/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"Mais <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="abc_slice_more" msgid="1983560225998630901">"Mais"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Mostrar mais"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Atualizado às <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 atrás</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> min atrás</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> ano atrás</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> anos atrás</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> dia atrás</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> dias atrás</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Não foi possível conectar"</string>
</resources>
diff --git a/slices/view/src/main/res/values-pt-rPT/strings.xml b/slices/view/src/main/res/values-pt-rPT/strings.xml
index b81ec60..ea5ab25 100644
--- a/slices/view/src/main/res/values-pt-rPT/strings.xml
+++ b/slices/view/src/main/res/values-pt-rPT/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Mais"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Mostrar mais"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Atualizado: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="other">Há <xliff:g id="ID_2">%d</xliff:g> minutos.</item>
- <item quantity="one">Há <xliff:g id="ID_1">%d</xliff:g> minuto.</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other">Há <xliff:g id="ID_2">%d</xliff:g> anos.</item>
- <item quantity="one">Há <xliff:g id="ID_1">%d</xliff:g> ano.</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other">Há <xliff:g id="ID_2">%d</xliff:g> dias.</item>
- <item quantity="one">Há <xliff:g id="ID_1">%d</xliff:g> dia.</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Não foi possível ligar."</string>
</resources>
diff --git a/slices/view/src/main/res/values-pt/strings.xml b/slices/view/src/main/res/values-pt/strings.xml
index 79cc7b7..629ba48 100644
--- a/slices/view/src/main/res/values-pt/strings.xml
+++ b/slices/view/src/main/res/values-pt/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"Mais <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="abc_slice_more" msgid="1983560225998630901">"Mais"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Mostrar mais"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Atualizado às <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 atrás</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> min atrás</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> ano atrás</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> anos atrás</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> dia atrás</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> dias atrás</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Não foi possível conectar"</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-ro/strings.xml
+++ b/slices/view/src/main/res/values-ro/strings.xml
@@ -18,23 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Mai mult"</string>
- <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>
- </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>
- </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>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Nu s-a putut conecta"</string>
</resources>
diff --git a/slices/view/src/main/res/values-ru/strings.xml b/slices/view/src/main/res/values-ru/strings.xml
index 85953aa..9d9bede 100644
--- a/slices/view/src/main/res/values-ru/strings.xml
+++ b/slices/view/src/main/res/values-ru/strings.xml
@@ -18,26 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Ошибка подключения"</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-si/strings.xml
+++ b/slices/view/src/main/res/values-si/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <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..ea5ab25 100644
--- a/slices/view/src/main/res/values-sk/strings.xml
+++ b/slices/view/src/main/res/values-sk/strings.xml
@@ -18,26 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Viac"</string>
- <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>
- </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>
- </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>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Nepodarilo sa pripojiť"</string>
</resources>
diff --git a/slices/view/src/main/res/values-sl/strings.xml b/slices/view/src/main/res/values-sl/strings.xml
index 0389500..59bf101 100644
--- a/slices/view/src/main/res/values-sl/strings.xml
+++ b/slices/view/src/main/res/values-sl/strings.xml
@@ -18,26 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_slice_more_content" msgid="6405516388971241142">"in še <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="abc_slice_more" msgid="1983560225998630901">"Več"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Pokaži več"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Posodobljeno: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="one">pred <xliff:g id="ID_2">%d</xliff:g> minuto</item>
- <item quantity="two">pred <xliff:g id="ID_2">%d</xliff:g> minutama</item>
- <item quantity="few">pred <xliff:g id="ID_2">%d</xliff:g> minutami</item>
- <item quantity="other">pred <xliff:g id="ID_2">%d</xliff:g> minutami</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="one">pred <xliff:g id="ID_2">%d</xliff:g> letom</item>
- <item quantity="two">pred <xliff:g id="ID_2">%d</xliff:g> letoma</item>
- <item quantity="few">pred <xliff:g id="ID_2">%d</xliff:g> leti</item>
- <item quantity="other">pred <xliff:g id="ID_2">%d</xliff:g> leti</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="one">pred <xliff:g id="ID_2">%d</xliff:g> dnem</item>
- <item quantity="two">pred <xliff:g id="ID_2">%d</xliff:g> dnevoma</item>
- <item quantity="few">pred <xliff:g id="ID_2">%d</xliff:g> dnevi</item>
- <item quantity="other">pred <xliff:g id="ID_2">%d</xliff:g> dnevi</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Povezava ni mogoča"</string>
</resources>
diff --git a/slices/view/src/main/res/values-sq/strings.xml b/slices/view/src/main/res/values-sq/strings.xml
index 0359c86..ea5ab25 100644
--- a/slices/view/src/main/res/values-sq/strings.xml
+++ b/slices/view/src/main/res/values-sq/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Më shumë"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Shfaq më shumë"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Përditësuar <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> minuta më parë</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> minutë më parë</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> vite më parë</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> vit më parë</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> ditë më parë</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> ditë më parë</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Nuk mund të lidhej"</string>
</resources>
diff --git a/slices/view/src/main/res/values-sr/strings.xml b/slices/view/src/main/res/values-sr/strings.xml
index 718f3d7..a66220a 100644
--- a/slices/view/src/main/res/values-sr/strings.xml
+++ b/slices/view/src/main/res/values-sr/strings.xml
@@ -18,23 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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="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="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="other">пре <xliff:g id="ID_2">%d</xliff:g> дана</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Повезивање није успело"</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..cbcec4f 100644
--- a/slices/view/src/main/res/values-sv/strings.xml
+++ b/slices/view/src/main/res/values-sv/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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> till"</string>
- <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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Det gick inte att ansluta"</string>
</resources>
diff --git a/slices/view/src/main/res/values-sw/strings.xml b/slices/view/src/main/res/values-sw/strings.xml
index 609c51f..ea5ab25 100644
--- a/slices/view/src/main/res/values-sw/strings.xml
+++ b/slices/view/src/main/res/values-sw/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Mengine"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Onyesha mengine"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Ilisasishwa <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
- <item quantity="other">Dakika <xliff:g id="ID_2">%d</xliff:g> zilizopita</item>
- <item quantity="one">Dakika <xliff:g id="ID_1">%d</xliff:g> iliyopita</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other">Miaka <xliff:g id="ID_2">%d</xliff:g> iliyopita</item>
- <item quantity="one">Mwaka <xliff:g id="ID_1">%d</xliff:g> uliopita</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other">Siku <xliff:g id="ID_2">%d</xliff:g> zilizopita</item>
- <item quantity="one">Siku <xliff:g id="ID_1">%d</xliff:g> iliyopita</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Imeshindwa kuunganisha"</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-ta/strings.xml
+++ b/slices/view/src/main/res/values-ta/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</resources>
diff --git a/slices/view/src/main/res/values-te/strings.xml b/slices/view/src/main/res/values-te/strings.xml
index 82137b8..ea5ab25 100644
--- a/slices/view/src/main/res/values-te/strings.xml
+++ b/slices/view/src/main/res/values-te/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</resources>
diff --git a/slices/view/src/main/res/values-th/strings.xml b/slices/view/src/main/res/values-th/strings.xml
index 3ae19da..ea5ab25 100644
--- a/slices/view/src/main/res/values-th/strings.xml
+++ b/slices/view/src/main/res/values-th/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-tl/strings.xml
+++ b/slices/view/src/main/res/values-tl/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Higit pa"</string>
- <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>
- </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>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> na taon ang nakalipas</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> araw ang nakalipas</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> na araw ang nakalipas</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Hindi makakonekta"</string>
</resources>
diff --git a/slices/view/src/main/res/values-tr/strings.xml b/slices/view/src/main/res/values-tr/strings.xml
index 84da5fb..ea5ab25 100644
--- a/slices/view/src/main/res/values-tr/strings.xml
+++ b/slices/view/src/main/res/values-tr/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Diğer"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Daha fazla göster"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Güncellenme zamanı: <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> dk. önce</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> dk. önce</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> yıl önce</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> yıl önce</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> gün önce</item>
- <item quantity="one"><xliff:g id="ID_1">%d</xliff:g> gün önce</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Bağlanılamadı"</string>
</resources>
diff --git a/slices/view/src/main/res/values-uk/strings.xml b/slices/view/src/main/res/values-uk/strings.xml
index 0706d80..ea5ab25 100644
--- a/slices/view/src/main/res/values-uk/strings.xml
+++ b/slices/view/src/main/res/values-uk/strings.xml
@@ -18,26 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
- <string name="abc_slice_error" msgid="4188371422904147368">"Не вдалося під’єднатися"</string>
</resources>
diff --git a/slices/view/src/main/res/values-ur/strings.xml b/slices/view/src/main/res/values-ur/strings.xml
index 1fff81c4..ce427c0 100644
--- a/slices/view/src/main/res/values-ur/strings.xml
+++ b/slices/view/src/main/res/values-ur/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</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..ea5ab25 100644
--- a/slices/view/src/main/res/values-uz/strings.xml
+++ b/slices/view/src/main/res/values-uz/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <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..ea5ab25 100644
--- a/slices/view/src/main/res/values-vi/strings.xml
+++ b/slices/view/src/main/res/values-vi/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"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>
- <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..ea5ab25 100644
--- a/slices/view/src/main/res/values-zh-rCN/strings.xml
+++ b/slices/view/src/main/res/values-zh-rCN/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</resources>
diff --git a/slices/view/src/main/res/values-zh-rHK/strings.xml b/slices/view/src/main/res/values-zh-rHK/strings.xml
index d1ac276..ea5ab25 100644
--- a/slices/view/src/main/res/values-zh-rHK/strings.xml
+++ b/slices/view/src/main/res/values-zh-rHK/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</resources>
diff --git a/slices/view/src/main/res/values-zh-rTW/strings.xml b/slices/view/src/main/res/values-zh-rTW/strings.xml
index d1ac276..ea5ab25 100644
--- a/slices/view/src/main/res/values-zh-rTW/strings.xml
+++ b/slices/view/src/main/res/values-zh-rTW/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_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>
</resources>
diff --git a/slices/view/src/main/res/values-zu/strings.xml b/slices/view/src/main/res/values-zu/strings.xml
index 966bb1b..ea5ab25 100644
--- a/slices/view/src/main/res/values-zu/strings.xml
+++ b/slices/view/src/main/res/values-zu/strings.xml
@@ -18,20 +18,4 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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">"Okuningi"</string>
- <string name="abc_slice_show_more" msgid="1567717014004692768">"Bonisa okuningi"</string>
- <string name="abc_slice_updated" msgid="8155085405396453848">"Kubuyekezwe ngo-<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> iminithi eledlule</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> iminithi eledlule</item>
- </plurals>
- <plurals name="abc_slice_duration_years" formatted="false" msgid="6212691832333991589">
- <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> unyaka owedlule</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> unyaka owedlule</item>
- </plurals>
- <plurals name="abc_slice_duration_days" formatted="false" msgid="6241698511167107334">
- <item quantity="one"><xliff:g id="ID_2">%d</xliff:g> izinsuku ezedlule</item>
- <item quantity="other"><xliff:g id="ID_2">%d</xliff:g> izinsuku ezedlule</item>
- </plurals>
- <string name="abc_slice_error" msgid="4188371422904147368">"Ayikwazanga ukuxhuma"</string>
</resources>
diff --git a/slices/view/src/main/res/values/attrs.xml b/slices/view/src/main/res/values/attrs.xml
index b73c5a5..f3e621b 100644
--- a/slices/view/src/main/res/values/attrs.xml
+++ b/slices/view/src/main/res/values/attrs.xml
@@ -30,33 +30,17 @@
<attr name="headerTitleSize" format="dimension" />
<!-- Text size to use for subtitle text in the header of the slice. -->
<attr name="headerSubtitleSize" format="dimension"/>
- <!-- Vertical padding to use between header title text and header subtitle text. -->
- <attr name="headerTextVerticalPadding" format="dimension" />
-
<!-- Text size to use for title text in a non-header row of the slice. -->
<attr name="titleSize" format="dimension" />
<!-- Text size to use for subtitle text in a non-header row of the slice. -->
<attr name="subtitleSize" format="dimension" />
- <!-- Vertical padding to use between title text and subtitle text. -->
- <attr name="textVerticalPadding" format="dimension" />
-
<!-- Text size to use for title text in a grid row of the slice. -->
<attr name="gridTitleSize" format="dimension" />
<!-- Text size to use for the subtitle text in a grid row of the slice. -->
<attr name="gridSubtitleSize" format="dimension" />
- <!-- Vertical padding to use between title text and subtitle text in a grid cell. -->
- <attr name="gridTextVerticalPadding" format="dimension" />
- <!-- A grid row with all images goes right to the edge of the view if it's the first or
- last row of a slice. Use this to specify padding to apply to the top of the grid row in
- this situation. -->
- <attr name="gridTopPadding" format="dimension" />
- <!-- A grid row with all images goes right to the edge of the view if it's the first or
- last row of a slice. Use this to specify padding to apply to the bottom of the grid row in
- this situation. -->
- <attr name="gridBottomPadding" format="dimension" />
</declare-styleable>
<!-- To apply a style for all slices shown within an activity or app you
may set this in your app theme pointing to your custom SliceView style.-->
- <attr name="sliceViewStyle" format="reference" />
+ <attr name="sliceViewStyle" format="reference"/>
</resources>
\ No newline at end of file
diff --git a/slices/view/src/main/res/values/dimens.xml b/slices/view/src/main/res/values/dimens.xml
index 2894fcc..f3313bf 100644
--- a/slices/view/src/main/res/values/dimens.xml
+++ b/slices/view/src/main/res/values/dimens.xml
@@ -58,10 +58,6 @@
<dimen name="abc_slice_grid_small_image_text_height">120dp</dimen>
<!-- Gutter between cells in a grid row-->
<dimen name="abc_slice_grid_gutter">4dp</dimen>
- <!-- Space between image and text items in grid row -->
- <dimen name="abc_slice_grid_text_padding">10dp</dimen>
- <!-- Space between text and text items in grid row -->
- <dimen name="abc_slice_grid_text_inner_padding">2dp</dimen>
<!-- Big picture -->
<!-- Min height of row showing a single large image -->
diff --git a/swiperefreshlayout/api/current.txt b/swiperefreshlayout/api/current.txt
index 49e8991..018d30e 100644
--- a/swiperefreshlayout/api/current.txt
+++ b/swiperefreshlayout/api/current.txt
@@ -58,9 +58,7 @@
method public void setProgressViewOffset(boolean, int, int);
method public void setRefreshing(boolean);
method public void setSize(int);
- method public void setSlingshotDistance(int);
field public static final int DEFAULT = 1; // 0x1
- field public static final int DEFAULT_SLINGSHOT_DISTANCE = -1; // 0xffffffff
field public static final int LARGE = 0; // 0x0
field protected int mFrom;
field protected int mOriginalOffsetTop;
diff --git a/swiperefreshlayout/src/main/java/androidx/swiperefreshlayout/widget/SwipeRefreshLayout.java b/swiperefreshlayout/src/main/java/androidx/swiperefreshlayout/widget/SwipeRefreshLayout.java
index 5df8cdd..cd99498 100644
--- a/swiperefreshlayout/src/main/java/androidx/swiperefreshlayout/widget/SwipeRefreshLayout.java
+++ b/swiperefreshlayout/src/main/java/androidx/swiperefreshlayout/widget/SwipeRefreshLayout.java
@@ -36,7 +36,6 @@
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.Px;
import androidx.annotation.VisibleForTesting;
import androidx.core.content.ContextCompat;
import androidx.core.view.NestedScrollingChild;
@@ -74,8 +73,6 @@
// Maps to ProgressBar default style
public static final int DEFAULT = CircularProgressDrawable.DEFAULT;
- public static final int DEFAULT_SLINGSHOT_DISTANCE = -1;
-
@VisibleForTesting
static final int CIRCLE_DIAMETER = 40;
@VisibleForTesting
@@ -152,8 +149,6 @@
int mSpinnerOffsetEnd;
- int mCustomSlingshotDistance;
-
CircularProgressDrawable mProgress;
private Animation mScaleAnimation;
@@ -299,18 +294,6 @@
}
/**
- * Sets a custom slingshot distance.
- *
- * @param slingshotDistance The distance in pixels that the refresh indicator can be pulled
- * beyond its resting position. Use
- * {@link #DEFAULT_SLINGSHOT_DISTANCE} to reset to the default value.
- *
- */
- public void setSlingshotDistance(@Px int slingshotDistance) {
- mCustomSlingshotDistance = slingshotDistance;
- }
-
- /**
* One of DEFAULT, or LARGE.
*/
public void setSize(int size) {
@@ -919,11 +902,8 @@
float dragPercent = Math.min(1f, Math.abs(originalDragPercent));
float adjustedPercent = (float) Math.max(dragPercent - .4, 0) * 5 / 3;
float extraOS = Math.abs(overscrollTop) - mTotalDragDistance;
- float slingshotDist = mCustomSlingshotDistance > 0
- ? mCustomSlingshotDistance
- : (mUsingCustomStart
- ? mSpinnerOffsetEnd - mOriginalOffsetTop
- : mSpinnerOffsetEnd);
+ float slingshotDist = mUsingCustomStart ? mSpinnerOffsetEnd - mOriginalOffsetTop
+ : mSpinnerOffsetEnd;
float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, slingshotDist * 2)
/ slingshotDist);
float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow(
diff --git a/transition/src/main/java/androidx/transition/TransitionManager.java b/transition/src/main/java/androidx/transition/TransitionManager.java
index 579f4b9..517d2e3 100644
--- a/transition/src/main/java/androidx/transition/TransitionManager.java
+++ b/transition/src/main/java/androidx/transition/TransitionManager.java
@@ -193,16 +193,12 @@
static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() {
WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>> runningTransitions =
sRunningTransitions.get();
- if (runningTransitions != null) {
- ArrayMap<ViewGroup, ArrayList<Transition>> transitions = runningTransitions.get();
- if (transitions != null) {
- return transitions;
- }
+ if (runningTransitions == null || runningTransitions.get() == null) {
+ ArrayMap<ViewGroup, ArrayList<Transition>> transitions = new ArrayMap<>();
+ runningTransitions = new WeakReference<>(transitions);
+ sRunningTransitions.set(runningTransitions);
}
- ArrayMap<ViewGroup, ArrayList<Transition>> transitions = new ArrayMap<>();
- runningTransitions = new WeakReference<>(transitions);
- sRunningTransitions.set(runningTransitions);
- return transitions;
+ return runningTransitions.get();
}
private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
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 99383c0..3483d0f 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*", -1);
+ String[] ratings = commaSeparatedRatings.split("\\s*,\\s*");
List<TvContentRating> contentRatings = new ArrayList<>(ratings.length);
for (String rating : ratings) {
try {
diff --git a/v7/appcompat/res/values-af/strings.xml b/v7/appcompat/res/values-af/strings.xml
index b7dd9bc..15ed3b2 100644
--- a/v7/appcompat/res/values-af/strings.xml
+++ b/v7/appcompat/res/values-af/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"AAN"</string>
<string name="abc_capital_off" msgid="121134116657445385">"AF"</string>
<string name="search_menu_title" msgid="146198913615257606">"Soek"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Kieslys+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Simbool+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funksie+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"spasiebalk"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-am/strings.xml b/v7/appcompat/res/values-am/strings.xml
index 485ffad..42bbc06 100644
--- a/v7/appcompat/res/values-am/strings.xml
+++ b/v7/appcompat/res/values-am/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"በርቷል"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ጠፍቷል"</string>
<string name="search_menu_title" msgid="146198913615257606">"ፈልግ"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"ምናሌ+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"ሰርዝ"</string>
</resources>
diff --git a/v7/appcompat/res/values-ar/strings.xml b/v7/appcompat/res/values-ar/strings.xml
index a7683ce..3278162 100644
--- a/v7/appcompat/res/values-ar/strings.xml
+++ b/v7/appcompat/res/values-ar/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"تشغيل"</string>
<string name="abc_capital_off" msgid="121134116657445385">"إيقاف"</string>
<string name="search_menu_title" msgid="146198913615257606">"البحث"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"القائمة+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-as/strings.xml b/v7/appcompat/res/values-as/strings.xml
index a3574d7..1f90618 100644
--- a/v7/appcompat/res/values-as/strings.xml
+++ b/v7/appcompat/res/values-as/strings.xml
@@ -29,19 +29,13 @@
<string name="abc_searchview_description_voice" msgid="893419373245838918">"কণ্ঠধ্বনিৰ যোগেৰে সন্ধান কৰক"</string>
<string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"এটা এপ্ বাছনি কৰক"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"সকলো চাওক"</string>
- <string name="abc_shareactionprovider_share_with_application" msgid="3300176832234831527">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>ৰ জৰিয়তে শ্বেয়াৰ কৰক"</string>
+ <!-- no translation found for abc_shareactionprovider_share_with_application (3300176832234831527) -->
+ <skip />
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ইয়াৰ জৰিয়তে শ্বেয়াৰ কৰক"</string>
- <string name="abc_capital_on" msgid="3405795526292276155">"অন কৰক"</string>
- <string name="abc_capital_off" msgid="121134116657445385">"অফ কৰক"</string>
- <string name="search_menu_title" msgid="146198913615257606">"অনুসন্ধান কৰক"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"মেনু+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"মেটা+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"CTRL+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"শ্বিফ্ট+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"ফাংশ্বন+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"স্পেচ"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"এণ্টাৰ"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"মচক"</string>
+ <!-- no translation found for abc_capital_on (3405795526292276155) -->
+ <skip />
+ <!-- no translation found for abc_capital_off (121134116657445385) -->
+ <skip />
+ <!-- no translation found for search_menu_title (146198913615257606) -->
+ <skip />
</resources>
diff --git a/v7/appcompat/res/values-az/strings.xml b/v7/appcompat/res/values-az/strings.xml
index aae3b94..29e00dd 100644
--- a/v7/appcompat/res/values-az/strings.xml
+++ b/v7/appcompat/res/values-az/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"AKTİV"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DEAKTİV"</string>
<string name="search_menu_title" msgid="146198913615257606">"Axtarış"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menyu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funksiya+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"kosmos"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"daxil olun"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"silin"</string>
</resources>
diff --git a/v7/appcompat/res/values-b+sr+Latn/strings.xml b/v7/appcompat/res/values-b+sr+Latn/strings.xml
index 734525b..c3462f6 100644
--- a/v7/appcompat/res/values-b+sr+Latn/strings.xml
+++ b/v7/appcompat/res/values-b+sr+Latn/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"UKLJUČI"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ISKLJUČI"</string>
<string name="search_menu_title" msgid="146198913615257606">"Pretraži"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"taster za razmak"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-be/strings.xml b/v7/appcompat/res/values-be/strings.xml
index f04076a..99ee19f 100644
--- a/v7/appcompat/res/values-be/strings.xml
+++ b/v7/appcompat/res/values-be/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"УКЛ."</string>
<string name="abc_capital_off" msgid="121134116657445385">"ВЫКЛ."</string>
<string name="search_menu_title" msgid="146198913615257606">"Пошук"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Меню +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Прабел"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-bg/strings.xml b/v7/appcompat/res/values-bg/strings.xml
index 2c607a1..1d37d0d 100644
--- a/v7/appcompat/res/values-bg/strings.xml
+++ b/v7/appcompat/res/values-bg/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ВКЛ."</string>
<string name="abc_capital_off" msgid="121134116657445385">"ИЗКЛ."</string>
<string name="search_menu_title" msgid="146198913615257606">"Търсене"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"клавиша за интервал"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-bn/strings.xml b/v7/appcompat/res/values-bn/strings.xml
index 1c62a2d..2ea7591 100644
--- a/v7/appcompat/res/values-bn/strings.xml
+++ b/v7/appcompat/res/values-bn/strings.xml
@@ -22,11 +22,11 @@
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"আরও বিকল্প"</string>
<string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"সঙ্কুচিত করুন"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"খুঁজুন"</string>
- <string name="abc_search_hint" msgid="7723749260725869598">"সার্চ..."</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"অনুসন্ধান..."</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"ক্যোয়ারী খুঁজুন"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"ক্যোয়ারী সাফ করুন"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ক্যোয়ারী জমা দিন"</string>
- <string name="abc_searchview_description_voice" msgid="893419373245838918">"ভয়েস সার্চ"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"ভয়েস অনুসন্ধান"</string>
<string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"একটি অ্যাপ্লিকেশান বেছে নিন"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"সবগুলো দেখুন"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="3300176832234831527">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> এর সাথে শেয়ার করুন"</string>
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"চালু"</string>
<string name="abc_capital_off" msgid="121134116657445385">"বন্ধ"</string>
<string name="search_menu_title" msgid="146198913615257606">"খুঁজুন"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"মেনু+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"স্পেস"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"মুছুন"</string>
</resources>
diff --git a/v7/appcompat/res/values-bs/strings.xml b/v7/appcompat/res/values-bs/strings.xml
index 00ebc41..07d1411 100644
--- a/v7/appcompat/res/values-bs/strings.xml
+++ b/v7/appcompat/res/values-bs/strings.xml
@@ -20,8 +20,8 @@
<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_searchview_description_search" msgid="8264924765203268293">"Pretraživanje"</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>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Obriši upit"</string>
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"UKLJUČI"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ISKLJUČI"</string>
<string name="search_menu_title" msgid="146198913615257606">"Pretraži"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"razmaknica"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-ca/strings.xml b/v7/appcompat/res/values-ca/strings.xml
index c4f3b4d..03ebec3 100644
--- a/v7/appcompat/res/values-ca/strings.xml
+++ b/v7/appcompat/res/values-ca/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ACTIVAT"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DESACTIVAT"</string>
<string name="search_menu_title" msgid="146198913615257606">"Cerca"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menú+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Maj+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funció+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Espai"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Retorn"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Supr"</string>
</resources>
diff --git a/v7/appcompat/res/values-cs/strings.xml b/v7/appcompat/res/values-cs/strings.xml
index 9111883..05cd4e0 100644
--- a/v7/appcompat/res/values-cs/strings.xml
+++ b/v7/appcompat/res/values-cs/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ZAPNUTO"</string>
<string name="abc_capital_off" msgid="121134116657445385">"VYPNUTO"</string>
<string name="search_menu_title" msgid="146198913615257606">"Hledat"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"mezerník"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-da/strings.xml b/v7/appcompat/res/values-da/strings.xml
index f05e142..813885a 100644
--- a/v7/appcompat/res/values-da/strings.xml
+++ b/v7/appcompat/res/values-da/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"TIL"</string>
<string name="abc_capital_off" msgid="121134116657445385">"FRA"</string>
<string name="search_menu_title" msgid="146198913615257606">"Søg"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"mellemrum"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-de/strings.xml b/v7/appcompat/res/values-de/strings.xml
index fb0dd6a..0b57259 100644
--- a/v7/appcompat/res/values-de/strings.xml
+++ b/v7/appcompat/res/values-de/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"An"</string>
<string name="abc_capital_off" msgid="121134116657445385">"Aus"</string>
<string name="search_menu_title" msgid="146198913615257606">"Suchen"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menütaste +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta-Taste +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Strg +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Umschalttaste +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym-Taste +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funktionstaste +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Leertaste +"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Eingabetaste"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Löschen"</string>
</resources>
diff --git a/v7/appcompat/res/values-el/strings.xml b/v7/appcompat/res/values-el/strings.xml
index b7da605..ec7a666 100644
--- a/v7/appcompat/res/values-el/strings.xml
+++ b/v7/appcompat/res/values-el/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ΕΝΕΡΓΟΠΟΙΗΣΗ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ΑΠΕΝΕΡΓΟΠΟΙΗΣΗ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Αναζήτηση"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"διάστημα"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-en-rAU/strings.xml b/v7/appcompat/res/values-en-rAU/strings.xml
index a315670..a4d048c 100644
--- a/v7/appcompat/res/values-en-rAU/strings.xml
+++ b/v7/appcompat/res/values-en-rAU/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ON"</string>
<string name="abc_capital_off" msgid="121134116657445385">"OFF"</string>
<string name="search_menu_title" msgid="146198913615257606">"Search"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-en-rCA/strings.xml b/v7/appcompat/res/values-en-rCA/strings.xml
index a315670..a4d048c 100644
--- a/v7/appcompat/res/values-en-rCA/strings.xml
+++ b/v7/appcompat/res/values-en-rCA/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ON"</string>
<string name="abc_capital_off" msgid="121134116657445385">"OFF"</string>
<string name="search_menu_title" msgid="146198913615257606">"Search"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-en-rGB/strings.xml b/v7/appcompat/res/values-en-rGB/strings.xml
index a315670..a4d048c 100644
--- a/v7/appcompat/res/values-en-rGB/strings.xml
+++ b/v7/appcompat/res/values-en-rGB/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ON"</string>
<string name="abc_capital_off" msgid="121134116657445385">"OFF"</string>
<string name="search_menu_title" msgid="146198913615257606">"Search"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-en-rIN/strings.xml b/v7/appcompat/res/values-en-rIN/strings.xml
index a315670..a4d048c 100644
--- a/v7/appcompat/res/values-en-rIN/strings.xml
+++ b/v7/appcompat/res/values-en-rIN/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ON"</string>
<string name="abc_capital_off" msgid="121134116657445385">"OFF"</string>
<string name="search_menu_title" msgid="146198913615257606">"Search"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-en-rXC/strings.xml b/v7/appcompat/res/values-en-rXC/strings.xml
index 2e8e581..b1d5f93 100644
--- a/v7/appcompat/res/values-en-rXC/strings.xml
+++ b/v7/appcompat/res/values-en-rXC/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ON"</string>
<string name="abc_capital_off" msgid="121134116657445385">"OFF"</string>
<string name="search_menu_title" msgid="146198913615257606">"Search"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-es-rUS/strings.xml b/v7/appcompat/res/values-es-rUS/strings.xml
index 5d58df0..0cc8a70 100644
--- a/v7/appcompat/res/values-es-rUS/strings.xml
+++ b/v7/appcompat/res/values-es-rUS/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ACTIVADO"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DESACTIVADO"</string>
<string name="search_menu_title" msgid="146198913615257606">"Buscar"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menú+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Mayúscula+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Función+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"espacio"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"intro"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"borrar"</string>
</resources>
diff --git a/v7/appcompat/res/values-es/strings.xml b/v7/appcompat/res/values-es/strings.xml
index 5238229..3e0828b 100644
--- a/v7/appcompat/res/values-es/strings.xml
+++ b/v7/appcompat/res/values-es/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ACTIVADO"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DESACTIVADO"</string>
<string name="search_menu_title" msgid="146198913615257606">"Buscar"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menú +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Mayús +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Función +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Espacio"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Intro"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Eliminar"</string>
</resources>
diff --git a/v7/appcompat/res/values-et/strings.xml b/v7/appcompat/res/values-et/strings.xml
index b944f77..3a3dcbf 100644
--- a/v7/appcompat/res/values-et/strings.xml
+++ b/v7/appcompat/res/values-et/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"SEES"</string>
<string name="abc_capital_off" msgid="121134116657445385">"VÄLJAS"</string>
<string name="search_menu_title" msgid="146198913615257606">"Otsing"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menüü +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Tõstuklahv +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funktsiooniklahv +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"tühik"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"sisestusklahv"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"kustutamisklahv"</string>
</resources>
diff --git a/v7/appcompat/res/values-eu/strings.xml b/v7/appcompat/res/values-eu/strings.xml
index 5a45e61..a651036 100644
--- a/v7/appcompat/res/values-eu/strings.xml
+++ b/v7/appcompat/res/values-eu/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"AKTIBATUTA"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DESAKTIBATUTA"</string>
<string name="search_menu_title" msgid="146198913615257606">"Bilatu"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menua +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ktrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Maius +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funtzioa +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Zuriunea"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Sartu"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Ezabatu"</string>
</resources>
diff --git a/v7/appcompat/res/values-fa/strings.xml b/v7/appcompat/res/values-fa/strings.xml
index 35e6596..9b844b0 100644
--- a/v7/appcompat/res/values-fa/strings.xml
+++ b/v7/appcompat/res/values-fa/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"روشن"</string>
<string name="abc_capital_off" msgid="121134116657445385">"خاموش"</string>
<string name="search_menu_title" msgid="146198913615257606">"جستجو"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"منو+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"کلید فاصله"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-fi/strings.xml b/v7/appcompat/res/values-fi/strings.xml
index 829b6bb..e9bd952 100644
--- a/v7/appcompat/res/values-fi/strings.xml
+++ b/v7/appcompat/res/values-fi/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"KÄYTÖSSÄ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"POIS KÄYTÖSTÄ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Haku"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Valikko+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Vaihto+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"välilyönti"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-fr-rCA/strings.xml b/v7/appcompat/res/values-fr-rCA/strings.xml
index a8ef3ad..a3e763b 100644
--- a/v7/appcompat/res/values-fr-rCA/strings.xml
+++ b/v7/appcompat/res/values-fr-rCA/strings.xml
@@ -22,7 +22,7 @@
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Plus d\'options"</string>
<string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Réduire"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Rechercher"</string>
- <string name="abc_search_hint" msgid="7723749260725869598">"Rechercher…"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Recherche en cours..."</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Requête de recherche"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Effacer la requête"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Envoyer la requête"</string>
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ACTIVÉ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DÉSACTIVÉ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Rechercher"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Méta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Maj+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fonction+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"espace"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"entrée"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"supprimer"</string>
</resources>
diff --git a/v7/appcompat/res/values-fr/strings.xml b/v7/appcompat/res/values-fr/strings.xml
index 5df86b5..1e412ec 100644
--- a/v7/appcompat/res/values-fr/strings.xml
+++ b/v7/appcompat/res/values-fr/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ACTIVÉ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DÉSACTIVÉ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Rechercher"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Méta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Maj+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fonction+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"espace"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"entrée"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"supprimer"</string>
</resources>
diff --git a/v7/appcompat/res/values-gl/strings.xml b/v7/appcompat/res/values-gl/strings.xml
index c500af5..2af80a1 100644
--- a/v7/appcompat/res/values-gl/strings.xml
+++ b/v7/appcompat/res/values-gl/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ACTIVAR"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DESACTIVAR"</string>
<string name="search_menu_title" msgid="146198913615257606">"Buscar"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menú +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Maiús +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sim +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Función +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"espazo"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Intro"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"eliminar"</string>
</resources>
diff --git a/v7/appcompat/res/values-gu/strings.xml b/v7/appcompat/res/values-gu/strings.xml
index 390d59b..7a243ed 100644
--- a/v7/appcompat/res/values-gu/strings.xml
+++ b/v7/appcompat/res/values-gu/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_action_mode_done" msgid="4076576682505996667">"થઈ ગયું"</string>
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"હોમ પર નેવિગેટ કરો"</string>
- <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ઉપર નૅવિગેટ કરો"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ઉપર નેવિગેટ કરો"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"વધુ વિકલ્પો"</string>
<string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"સંકુચિત કરો"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"શોધો"</string>
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ચાલુ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"બંધ"</string>
<string name="search_menu_title" msgid="146198913615257606">"શોધો"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"મેનૂ+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Spacebar"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"ડિલીટ કરો"</string>
</resources>
diff --git a/v7/appcompat/res/values-hi/strings.xml b/v7/appcompat/res/values-hi/strings.xml
index 8a29110..a31ab90 100644
--- a/v7/appcompat/res/values-hi/strings.xml
+++ b/v7/appcompat/res/values-hi/strings.xml
@@ -21,7 +21,7 @@
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"ऊपर जाएं"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"ज़्यादा विकल्प"</string>
<string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"छोटा करें"</string>
- <string name="abc_searchview_description_search" msgid="8264924765203268293">"खोजें"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"सर्च करें"</string>
<string name="abc_search_hint" msgid="7723749260725869598">"खोजा जा रहा है…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"सर्च क्वेरी"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"क्वेरी साफ़ करें"</string>
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"चालू"</string>
<string name="abc_capital_off" msgid="121134116657445385">"बंद"</string>
<string name="search_menu_title" msgid="146198913615257606">"सर्च"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-hr/strings.xml b/v7/appcompat/res/values-hr/strings.xml
index 9253fb9..27a1c2e 100644
--- a/v7/appcompat/res/values-hr/strings.xml
+++ b/v7/appcompat/res/values-hr/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"UKLJUČENO"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ISKLJUČENO"</string>
<string name="search_menu_title" msgid="146198913615257606">"Pretraživanje"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"razmaknica"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-hu/strings.xml b/v7/appcompat/res/values-hu/strings.xml
index 714ef47..d3e413f 100644
--- a/v7/appcompat/res/values-hu/strings.xml
+++ b/v7/appcompat/res/values-hu/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"BE"</string>
<string name="abc_capital_off" msgid="121134116657445385">"KI"</string>
<string name="search_menu_title" msgid="146198913615257606">"Keresés"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Szóköz"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-hy/strings.xml b/v7/appcompat/res/values-hy/strings.xml
index 59c9ee5..1c41ef6 100644
--- a/v7/appcompat/res/values-hy/strings.xml
+++ b/v7/appcompat/res/values-hy/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ՄԻԱՑՎԱԾ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ԱՆՋԱՏՎԱԾ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Որոնել"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"բացատ"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-in/strings.xml b/v7/appcompat/res/values-in/strings.xml
index 1ae3f90..2e9fbb7 100644
--- a/v7/appcompat/res/values-in/strings.xml
+++ b/v7/appcompat/res/values-in/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"AKTIF"</string>
<string name="abc_capital_off" msgid="121134116657445385">"NONAKTIF"</string>
<string name="search_menu_title" msgid="146198913615257606">"Telusuri"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"spasi"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-is/strings.xml b/v7/appcompat/res/values-is/strings.xml
index 3ae59da..3f61d84 100644
--- a/v7/appcompat/res/values-is/strings.xml
+++ b/v7/appcompat/res/values-is/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"KVEIKT"</string>
<string name="abc_capital_off" msgid="121134116657445385">"SLÖKKT"</string>
<string name="search_menu_title" msgid="146198913615257606">"Leita"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Valmynd+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Aðgerðarlykill+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"bilslá"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-it/strings.xml b/v7/appcompat/res/values-it/strings.xml
index 04b64ce..fbd2c58 100644
--- a/v7/appcompat/res/values-it/strings.xml
+++ b/v7/appcompat/res/values-it/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ON"</string>
<string name="abc_capital_off" msgid="121134116657445385">"OFF"</string>
<string name="search_menu_title" msgid="146198913615257606">"Ricerca"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"MENU +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"META +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"CTRL +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"ALT +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"MAIUSC +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"SYM +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"FUNZIONE +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"barra spaziatrice"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"INVIO"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"CANC"</string>
</resources>
diff --git a/v7/appcompat/res/values-iw/strings.xml b/v7/appcompat/res/values-iw/strings.xml
index d0f2211..0a7d0bb 100644
--- a/v7/appcompat/res/values-iw/strings.xml
+++ b/v7/appcompat/res/values-iw/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"פועל"</string>
<string name="abc_capital_off" msgid="121134116657445385">"כבוי"</string>
<string name="search_menu_title" msgid="146198913615257606">"חיפוש"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"תפריט+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"מקש רווח"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-ja/strings.xml b/v7/appcompat/res/values-ja/strings.xml
index db163f3..c4d0e20b 100644
--- a/v7/appcompat/res/values-ja/strings.xml
+++ b/v7/appcompat/res/values-ja/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ON"</string>
<string name="abc_capital_off" msgid="121134116657445385">"OFF"</string>
<string name="search_menu_title" msgid="146198913615257606">"検索"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-ka/strings.xml b/v7/appcompat/res/values-ka/strings.xml
index 6d9c08b..3b077a3 100644
--- a/v7/appcompat/res/values-ka/strings.xml
+++ b/v7/appcompat/res/values-ka/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ჩართულია"</string>
<string name="abc_capital_off" msgid="121134116657445385">"გამორთულია"</string>
<string name="search_menu_title" msgid="146198913615257606">"ძიება"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"შეყვანა"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"წაშლა"</string>
</resources>
diff --git a/v7/appcompat/res/values-kk/strings.xml b/v7/appcompat/res/values-kk/strings.xml
index 9d206bc..c32045b 100644
--- a/v7/appcompat/res/values-kk/strings.xml
+++ b/v7/appcompat/res/values-kk/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ҚОСУЛЫ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ӨШІРУЛІ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Іздеу"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Mәзір+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"бос орын"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-km/strings.xml b/v7/appcompat/res/values-km/strings.xml
index f42da7a..ffe289a 100644
--- a/v7/appcompat/res/values-km/strings.xml
+++ b/v7/appcompat/res/values-km/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"បើក"</string>
<string name="abc_capital_off" msgid="121134116657445385">"បិទ"</string>
<string name="search_menu_title" msgid="146198913615257606">"ស្វែងរក"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-kn/strings.xml b/v7/appcompat/res/values-kn/strings.xml
index ce28303..4218bd6 100644
--- a/v7/appcompat/res/values-kn/strings.xml
+++ b/v7/appcompat/res/values-kn/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ಆನ್"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ಆಫ್"</string>
<string name="search_menu_title" msgid="146198913615257606">"ಹುಡುಕಿ"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-ko/strings.xml b/v7/appcompat/res/values-ko/strings.xml
index db0903f..6c84a2a 100644
--- a/v7/appcompat/res/values-ko/strings.xml
+++ b/v7/appcompat/res/values-ko/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"사용"</string>
<string name="abc_capital_off" msgid="121134116657445385">"사용 안함"</string>
<string name="search_menu_title" msgid="146198913615257606">"검색"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"스페이스바"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"입력"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"삭제"</string>
</resources>
diff --git a/v7/appcompat/res/values-ky/strings.xml b/v7/appcompat/res/values-ky/strings.xml
index 1aba4f0..66202f7 100644
--- a/v7/appcompat/res/values-ky/strings.xml
+++ b/v7/appcompat/res/values-ky/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"КҮЙҮК"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ӨЧҮК"</string>
<string name="search_menu_title" msgid="146198913615257606">"Издөө"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"боштук"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-lo/strings.xml b/v7/appcompat/res/values-lo/strings.xml
index c53a987..1b92df0 100644
--- a/v7/appcompat/res/values-lo/strings.xml
+++ b/v7/appcompat/res/values-lo/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ເປີດ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ປິດ"</string>
<string name="search_menu_title" msgid="146198913615257606">"ຊອກຫາ"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-lt/strings.xml b/v7/appcompat/res/values-lt/strings.xml
index ab9f25c..5793069 100644
--- a/v7/appcompat/res/values-lt/strings.xml
+++ b/v7/appcompat/res/values-lt/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ĮJUNGTI"</string>
<string name="abc_capital_off" msgid="121134116657445385">"IŠJUNGTA"</string>
<string name="search_menu_title" msgid="146198913615257606">"Paieška"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"„Menu“ +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"„Meta“ +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"„Ctrl“ +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"„Alt“ +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"„Shift“ +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"„Sym“ +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"„Function“ +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"tarpo klavišas"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"„Enter“"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"„Delete“"</string>
</resources>
diff --git a/v7/appcompat/res/values-lv/strings.xml b/v7/appcompat/res/values-lv/strings.xml
index 67904a1..67e18d3 100644
--- a/v7/appcompat/res/values-lv/strings.xml
+++ b/v7/appcompat/res/values-lv/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"IESLĒGTS"</string>
<string name="abc_capital_off" msgid="121134116657445385">"IZSLĒGTS"</string>
<string name="search_menu_title" msgid="146198913615257606">"Meklēt"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Poga Izvēlne +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta taustiņš +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Vadīšanas taustiņš +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alternēšanas taustiņš +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Pārslēgšanas taustiņš +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Simbolu taustiņš +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funkcijas taustiņš +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"atstarpes taustiņš"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"ievadīšanas taustiņš"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"dzēšanas taustiņš"</string>
</resources>
diff --git a/v7/appcompat/res/values-mk/strings.xml b/v7/appcompat/res/values-mk/strings.xml
index 408edb1..b12a235 100644
--- a/v7/appcompat/res/values-mk/strings.xml
+++ b/v7/appcompat/res/values-mk/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ВКЛУЧЕНО"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ИСКЛУЧЕНО"</string>
<string name="search_menu_title" msgid="146198913615257606">"Пребарај"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Мени+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"копче Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"копче Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"копче Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"копче Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"копче Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"копче Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"вселена"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"копче enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"избриши"</string>
</resources>
diff --git a/v7/appcompat/res/values-ml/strings.xml b/v7/appcompat/res/values-ml/strings.xml
index e880ebb..9033f8a 100644
--- a/v7/appcompat/res/values-ml/strings.xml
+++ b/v7/appcompat/res/values-ml/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ഓൺ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ഓഫ്"</string>
<string name="search_menu_title" msgid="146198913615257606">"തിരയുക"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"മെനു+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"മെറ്റ+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"ഫംഗ്ഷന്+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"സ്പെയ്സ്"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"ഇല്ലാതാക്കുക"</string>
</resources>
diff --git a/v7/appcompat/res/values-mn/strings.xml b/v7/appcompat/res/values-mn/strings.xml
index 856e9f6..56036ea 100644
--- a/v7/appcompat/res/values-mn/strings.xml
+++ b/v7/appcompat/res/values-mn/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ИДЭВХТЭЙ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ИДЭВХГҮЙ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Хайлт"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Цэс+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Мета+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Функц+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"зай"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"оруулах"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"устгах"</string>
</resources>
diff --git a/v7/appcompat/res/values-mr/strings.xml b/v7/appcompat/res/values-mr/strings.xml
index ed3463c..26ada80 100644
--- a/v7/appcompat/res/values-mr/strings.xml
+++ b/v7/appcompat/res/values-mr/strings.xml
@@ -30,18 +30,8 @@
<string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"एक अॅप निवडा"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"सर्व पहा"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="3300176832234831527">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> सह शेअर करा"</string>
- <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"यांच्यासह शेअर करा"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"यांच्यासह सामायिक करा"</string>
<string name="abc_capital_on" msgid="3405795526292276155">"चालू"</string>
<string name="abc_capital_off" msgid="121134116657445385">"बंद"</string>
<string name="search_menu_title" msgid="146198913615257606">"शोधा"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"मेनू+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"spacebar"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"एंटर करा"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"हटवा"</string>
</resources>
diff --git a/v7/appcompat/res/values-ms/strings.xml b/v7/appcompat/res/values-ms/strings.xml
index 8af4c134..18f84ce 100644
--- a/v7/appcompat/res/values-ms/strings.xml
+++ b/v7/appcompat/res/values-ms/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"HIDUP"</string>
<string name="abc_capital_off" msgid="121134116657445385">"MATI"</string>
<string name="search_menu_title" msgid="146198913615257606">"Cari"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fungsi+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"ruang"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"padam"</string>
</resources>
diff --git a/v7/appcompat/res/values-my/strings.xml b/v7/appcompat/res/values-my/strings.xml
index cfd6625..cbc8791 100644
--- a/v7/appcompat/res/values-my/strings.xml
+++ b/v7/appcompat/res/values-my/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ဖွင့်"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ပိတ်"</string>
<string name="search_menu_title" msgid="146198913615257606">"ရှာဖွေပါ"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-nb/strings.xml b/v7/appcompat/res/values-nb/strings.xml
index f9fd80e..6005234 100644
--- a/v7/appcompat/res/values-nb/strings.xml
+++ b/v7/appcompat/res/values-nb/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"PÅ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"AV"</string>
<string name="search_menu_title" msgid="146198913615257606">"Søk"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Meny+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funksjon+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"mellomrom"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-ne/strings.xml b/v7/appcompat/res/values-ne/strings.xml
index 0a0de14..96b1042 100644
--- a/v7/appcompat/res/values-ne/strings.xml
+++ b/v7/appcompat/res/values-ne/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"सक्रिय गर्नुहोस्"</string>
<string name="abc_capital_off" msgid="121134116657445385">"निष्क्रिय पार्नुहोस्"</string>
<string name="search_menu_title" msgid="146198913615257606">"खोज्नुहोस्"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-nl/strings.xml b/v7/appcompat/res/values-nl/strings.xml
index ffcb3d9..e0d2044 100644
--- a/v7/appcompat/res/values-nl/strings.xml
+++ b/v7/appcompat/res/values-nl/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"AAN"</string>
<string name="abc_capital_off" msgid="121134116657445385">"UIT"</string>
<string name="search_menu_title" msgid="146198913615257606">"Zoeken"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Functie +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"spatie"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"verwijderen"</string>
</resources>
diff --git a/v7/appcompat/res/values-or/strings.xml b/v7/appcompat/res/values-or/strings.xml
index 86e4fb7..4dc6eb4 100644
--- a/v7/appcompat/res/values-or/strings.xml
+++ b/v7/appcompat/res/values-or/strings.xml
@@ -29,19 +29,13 @@
<string name="abc_searchview_description_voice" msgid="893419373245838918">"ଭଏସ୍ ସର୍ଚ୍ଚ"</string>
<string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"ଗୋଟିଏ ଆପ୍ ବାଛନ୍ତୁ"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ସବୁ ଦେଖନ୍ତୁ"</string>
- <string name="abc_shareactionprovider_share_with_application" msgid="3300176832234831527">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ସହ ଶେୟାର୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for abc_shareactionprovider_share_with_application (3300176832234831527) -->
+ <skip />
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ଏହାଙ୍କ ସହ ଶେୟାର୍ କରନ୍ତୁ"</string>
- <string name="abc_capital_on" msgid="3405795526292276155">"ଅନ୍"</string>
- <string name="abc_capital_off" msgid="121134116657445385">"ଅଫ୍"</string>
- <string name="search_menu_title" msgid="146198913615257606">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"ମେନୁ"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"ସ୍ପେସ୍"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"ଏଣ୍ଟର୍"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"ଡିଲିଟ୍"</string>
+ <!-- no translation found for abc_capital_on (3405795526292276155) -->
+ <skip />
+ <!-- no translation found for abc_capital_off (121134116657445385) -->
+ <skip />
+ <!-- no translation found for search_menu_title (146198913615257606) -->
+ <skip />
</resources>
diff --git a/v7/appcompat/res/values-pa/strings.xml b/v7/appcompat/res/values-pa/strings.xml
index fc1fdba..7f28ac8 100644
--- a/v7/appcompat/res/values-pa/strings.xml
+++ b/v7/appcompat/res/values-pa/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ਤੇ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ਬੰਦ"</string>
<string name="search_menu_title" msgid="146198913615257606">"ਖੋਜੋ"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-pl/strings.xml b/v7/appcompat/res/values-pl/strings.xml
index af26367..d706241 100644
--- a/v7/appcompat/res/values-pl/strings.xml
+++ b/v7/appcompat/res/values-pl/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"WŁ."</string>
<string name="abc_capital_off" msgid="121134116657445385">"WYŁ."</string>
<string name="search_menu_title" msgid="146198913615257606">"Szukaj"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funkcyjny+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"spacja"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-pt-rBR/strings.xml b/v7/appcompat/res/values-pt-rBR/strings.xml
index 17d8593..90461ec 100644
--- a/v7/appcompat/res/values-pt-rBR/strings.xml
+++ b/v7/appcompat/res/values-pt-rBR/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ATIVAR"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DESATIVAR"</string>
<string name="search_menu_title" msgid="146198913615257606">"Pesquisar"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"espaço"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-pt-rPT/strings.xml b/v7/appcompat/res/values-pt-rPT/strings.xml
index f8c0fa7..40f6499c 100644
--- a/v7/appcompat/res/values-pt-rPT/strings.xml
+++ b/v7/appcompat/res/values-pt-rPT/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ATIVADO"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DESATIVADO"</string>
<string name="search_menu_title" msgid="146198913615257606">"Pesquisar"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Função +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"espaço"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"eliminar"</string>
</resources>
diff --git a/v7/appcompat/res/values-pt/strings.xml b/v7/appcompat/res/values-pt/strings.xml
index 17d8593..90461ec 100644
--- a/v7/appcompat/res/values-pt/strings.xml
+++ b/v7/appcompat/res/values-pt/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ATIVAR"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DESATIVAR"</string>
<string name="search_menu_title" msgid="146198913615257606">"Pesquisar"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"espaço"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-ro/strings.xml b/v7/appcompat/res/values-ro/strings.xml
index 86495fd..6d04be9 100644
--- a/v7/appcompat/res/values-ro/strings.xml
+++ b/v7/appcompat/res/values-ro/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ACTIVAT"</string>
<string name="abc_capital_off" msgid="121134116657445385">"DEZACTIVAȚI"</string>
<string name="search_menu_title" msgid="146198913615257606">"Căutați"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Meniu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funcție+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"spațiu"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-ru/strings.xml b/v7/appcompat/res/values-ru/strings.xml
index c505bf5..2b28958 100644
--- a/v7/appcompat/res/values-ru/strings.xml
+++ b/v7/appcompat/res/values-ru/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ВКЛ."</string>
<string name="abc_capital_off" msgid="121134116657445385">"ОТКЛ."</string>
<string name="search_menu_title" msgid="146198913615257606">"Поиск"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Меню +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Пробел"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Ввод"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-si/strings.xml b/v7/appcompat/res/values-si/strings.xml
index c154686d..7631288 100644
--- a/v7/appcompat/res/values-si/strings.xml
+++ b/v7/appcompat/res/values-si/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ක්රියාත්මකයි"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ක්රියාවිරහිතයි"</string>
<string name="search_menu_title" msgid="146198913615257606">"සොයන්න"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"මකන්න"</string>
</resources>
diff --git a/v7/appcompat/res/values-sk/strings.xml b/v7/appcompat/res/values-sk/strings.xml
index 67184b0..03faf14 100644
--- a/v7/appcompat/res/values-sk/strings.xml
+++ b/v7/appcompat/res/values-sk/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ZAPNUTÉ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"VYPNUTÉ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Vyhľadávanie"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"medzerník"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"odstrániť"</string>
</resources>
diff --git a/v7/appcompat/res/values-sl/strings.xml b/v7/appcompat/res/values-sl/strings.xml
index e38e5ea..22b8bd4 100644
--- a/v7/appcompat/res/values-sl/strings.xml
+++ b/v7/appcompat/res/values-sl/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"VKLOPLJENO"</string>
<string name="abc_capital_off" msgid="121134116657445385">"IZKLOPLJENO"</string>
<string name="search_menu_title" msgid="146198913615257606">"Iskanje"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Meni +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"preslednica"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-sq/strings.xml b/v7/appcompat/res/values-sq/strings.xml
index 8b958a2..1a1f02e 100644
--- a/v7/appcompat/res/values-sq/strings.xml
+++ b/v7/appcompat/res/values-sq/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"AKTIV"</string>
<string name="abc_capital_off" msgid="121134116657445385">"JOAKTIV"</string>
<string name="search_menu_title" msgid="146198913615257606">"Kërko"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menyja+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funksioni+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"hapësirë"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-sr/strings.xml b/v7/appcompat/res/values-sr/strings.xml
index 4c702bc..5678341 100644
--- a/v7/appcompat/res/values-sr/strings.xml
+++ b/v7/appcompat/res/values-sr/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"УКЉУЧИ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ИСКЉУЧИ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Претражи"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"тастер за размак"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-sv/strings.xml b/v7/appcompat/res/values-sv/strings.xml
index 72b7f88..62d470f 100644
--- a/v7/appcompat/res/values-sv/strings.xml
+++ b/v7/appcompat/res/values-sv/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"PÅ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"AV"</string>
<string name="search_menu_title" msgid="146198913615257606">"Sök"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Meny + "</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta + "</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl + "</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt + "</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Skift + "</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Symbol + "</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Funktion + "</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"blanksteg"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"retur"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-sw/strings.xml b/v7/appcompat/res/values-sw/strings.xml
index 1c623b7..c575ae0 100644
--- a/v7/appcompat/res/values-sw/strings.xml
+++ b/v7/appcompat/res/values-sw/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"IMEWASHWA"</string>
<string name="abc_capital_off" msgid="121134116657445385">"IMEZIMWA"</string>
<string name="search_menu_title" msgid="146198913615257606">"Tafuta"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menyu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"nafasi"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"futa"</string>
</resources>
diff --git a/v7/appcompat/res/values-ta/strings.xml b/v7/appcompat/res/values-ta/strings.xml
index 7aa031a..971a3db 100644
--- a/v7/appcompat/res/values-ta/strings.xml
+++ b/v7/appcompat/res/values-ta/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ஆன்"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ஆஃப்"</string>
<string name="search_menu_title" msgid="146198913615257606">"தேடு"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"மெனு மற்றும்"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"மெட்டா மற்றும்"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"கண்ட்ரோல் மற்றும்"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"ஆல்ட் மற்றும்"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"ஷிஃப்ட் மற்றும்"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"சிம்பல் மற்றும்"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"ஃபங்ஷன் மற்றும்"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"ஸ்பேஸ்"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"எண்டர்"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"டெலிட்"</string>
</resources>
diff --git a/v7/appcompat/res/values-te/strings.xml b/v7/appcompat/res/values-te/strings.xml
index 818f0e39a..f7d7577 100644
--- a/v7/appcompat/res/values-te/strings.xml
+++ b/v7/appcompat/res/values-te/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"ఆన్ చేయి"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ఆఫ్ చేయి"</string>
<string name="search_menu_title" msgid="146198913615257606">"వెతుకు"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"స్పేస్"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-th/strings.xml b/v7/appcompat/res/values-th/strings.xml
index 5ecec86..f8ea1cd 100644
--- a/v7/appcompat/res/values-th/strings.xml
+++ b/v7/appcompat/res/values-th/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"เปิด"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ปิด"</string>
<string name="search_menu_title" msgid="146198913615257606">"ค้นหา"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"เมนู+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-tl/strings.xml b/v7/appcompat/res/values-tl/strings.xml
index 3ef5df6..1ad2689 100644
--- a/v7/appcompat/res/values-tl/strings.xml
+++ b/v7/appcompat/res/values-tl/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"I-ON"</string>
<string name="abc_capital_off" msgid="121134116657445385">"I-OFF"</string>
<string name="search_menu_title" msgid="146198913615257606">"Maghanap"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-tr/strings.xml b/v7/appcompat/res/values-tr/strings.xml
index 153e2c2..fae41d3 100644
--- a/v7/appcompat/res/values-tr/strings.xml
+++ b/v7/appcompat/res/values-tr/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"AÇ"</string>
<string name="abc_capital_off" msgid="121134116657445385">"KAPAT"</string>
<string name="search_menu_title" msgid="146198913615257606">"Ara"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menü+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Üst Karakter+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"İşlev+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"boşluk"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"sil"</string>
</resources>
diff --git a/v7/appcompat/res/values-uk/strings.xml b/v7/appcompat/res/values-uk/strings.xml
index 7aed219..afc74ff 100644
--- a/v7/appcompat/res/values-uk/strings.xml
+++ b/v7/appcompat/res/values-uk/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"УВІМК."</string>
<string name="abc_capital_off" msgid="121134116657445385">"ВИМК."</string>
<string name="search_menu_title" msgid="146198913615257606">"Пошук"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"пробіл"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-ur/strings.xml b/v7/appcompat/res/values-ur/strings.xml
index 997d594..60ec34a 100644
--- a/v7/appcompat/res/values-ur/strings.xml
+++ b/v7/appcompat/res/values-ur/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"آن"</string>
<string name="abc_capital_off" msgid="121134116657445385">"آف"</string>
<string name="search_menu_title" msgid="146198913615257606">"تلاش"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-uz/strings.xml b/v7/appcompat/res/values-uz/strings.xml
index 359b96c..0417cba 100644
--- a/v7/appcompat/res/values-uz/strings.xml
+++ b/v7/appcompat/res/values-uz/strings.xml
@@ -32,16 +32,6 @@
<string name="abc_shareactionprovider_share_with_application" msgid="3300176832234831527">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> orqali ulashish"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Ruxsat berish"</string>
<string name="abc_capital_on" msgid="3405795526292276155">"YONIQ"</string>
- <string name="abc_capital_off" msgid="121134116657445385">"YOQILMAGAN"</string>
+ <string name="abc_capital_off" msgid="121134116657445385">"O‘CHIQ"</string>
<string name="search_menu_title" msgid="146198913615257606">"Qidirish"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menyu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"Probel"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-vi/strings.xml b/v7/appcompat/res/values-vi/strings.xml
index e07efed..4560b4b 100644
--- a/v7/appcompat/res/values-vi/strings.xml
+++ b/v7/appcompat/res/values-vi/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"BẬT"</string>
<string name="abc_capital_off" msgid="121134116657445385">"TẮT"</string>
<string name="search_menu_title" msgid="146198913615257606">"Tìm kiếm"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"phím cách"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"delete"</string>
</resources>
diff --git a/v7/appcompat/res/values-zh-rCN/strings.xml b/v7/appcompat/res/values-zh-rCN/strings.xml
index 6dc1ea2..7b23457 100644
--- a/v7/appcompat/res/values-zh-rCN/strings.xml
+++ b/v7/appcompat/res/values-zh-rCN/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"开启"</string>
<string name="abc_capital_off" msgid="121134116657445385">"关闭"</string>
<string name="search_menu_title" msgid="146198913615257606">"搜索"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"空格键"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter 键"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete 键"</string>
</resources>
diff --git a/v7/appcompat/res/values-zh-rHK/strings.xml b/v7/appcompat/res/values-zh-rHK/strings.xml
index ce753fd..fc32117 100644
--- a/v7/appcompat/res/values-zh-rHK/strings.xml
+++ b/v7/appcompat/res/values-zh-rHK/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"開啟"</string>
<string name="abc_capital_off" msgid="121134116657445385">"關閉"</string>
<string name="search_menu_title" msgid="146198913615257606">"搜尋"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"空白鍵"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter 鍵"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"刪除"</string>
</resources>
diff --git a/v7/appcompat/res/values-zh-rTW/strings.xml b/v7/appcompat/res/values-zh-rTW/strings.xml
index 0f29b8e..35be873 100644
--- a/v7/appcompat/res/values-zh-rTW/strings.xml
+++ b/v7/appcompat/res/values-zh-rTW/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"開啟"</string>
<string name="abc_capital_off" msgid="121134116657445385">"關閉"</string>
<string name="search_menu_title" msgid="146198913615257606">"搜尋"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Menu +"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta +"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl +"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt +"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift +"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym +"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Fn +"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"空格鍵"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"Enter 鍵"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"Delete 鍵"</string>
</resources>
diff --git a/v7/appcompat/res/values-zu/strings.xml b/v7/appcompat/res/values-zu/strings.xml
index e3032f1..e84ba7a 100644
--- a/v7/appcompat/res/values-zu/strings.xml
+++ b/v7/appcompat/res/values-zu/strings.xml
@@ -34,14 +34,4 @@
<string name="abc_capital_on" msgid="3405795526292276155">"VULIWE"</string>
<string name="abc_capital_off" msgid="121134116657445385">"VALIWE"</string>
<string name="search_menu_title" msgid="146198913615257606">"Sesha"</string>
- <string name="abc_prepend_shortcut_label" msgid="1351762916121158029">"Imenyu+"</string>
- <string name="abc_menu_meta_shortcut_label" msgid="7643535737296831317">"Meta+"</string>
- <string name="abc_menu_ctrl_shortcut_label" msgid="1324831542140195728">"Ctrl+"</string>
- <string name="abc_menu_alt_shortcut_label" msgid="1302280443949172191">"Alt+"</string>
- <string name="abc_menu_shift_shortcut_label" msgid="8126296154200614004">"Shift+"</string>
- <string name="abc_menu_sym_shortcut_label" msgid="9002602288060866689">"Sym+"</string>
- <string name="abc_menu_function_shortcut_label" msgid="4792426091847145555">"Function+"</string>
- <string name="abc_menu_space_shortcut_label" msgid="2378550843553983978">"space"</string>
- <string name="abc_menu_enter_shortcut_label" msgid="8341180395196749340">"enter"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="8362206064229013510">"susa"</string>
</resources>
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 c32beab..7991c4e 100644
--- a/v7/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
+++ b/v7/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
@@ -38,7 +38,6 @@
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,6 +128,8 @@
@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,
@@ -509,7 +510,7 @@
* <p>Please note: this only takes effect in Activities created after this call.</p>
*/
public static void setCompatVectorFromResourcesEnabled(boolean enabled) {
- VectorEnabledTintResources.setCompatVectorFromResourcesEnabled(enabled);
+ sCompatVectorFromResourcesEnabled = enabled;
}
/**
@@ -519,6 +520,6 @@
* @see #setCompatVectorFromResourcesEnabled(boolean)
*/
public static boolean isCompatVectorFromResourcesEnabled() {
- return VectorEnabledTintResources.isCompatVectorFromResourcesEnabled();
+ return sCompatVectorFromResourcesEnabled;
}
}
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 af61860f..15fcf88 100644
--- a/v7/appcompat/src/main/java/androidx/appcompat/widget/VectorEnabledTintResources.java
+++ b/v7/appcompat/src/main/java/androidx/appcompat/widget/VectorEnabledTintResources.java
@@ -25,6 +25,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
+import androidx.appcompat.app.AppCompatDelegate;
import java.lang.ref.WeakReference;
@@ -36,10 +37,9 @@
*/
@RestrictTo(LIBRARY_GROUP)
public class VectorEnabledTintResources extends Resources {
- private static boolean sCompatVectorFromResourcesEnabled = false;
public static boolean shouldBeUsed() {
- return isCompatVectorFromResourcesEnabled()
+ return AppCompatDelegate.isCompatVectorFromResourcesEnabled()
&& Build.VERSION.SDK_INT <= MAX_SDK_WHERE_REQUIRED;
}
@@ -74,22 +74,4 @@
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/wear/res/values-as/strings.xml b/wear/res/values-as/strings.xml
deleted file mode 100644
index 2a51efa..0000000
--- a/wear/res/values-as/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="ws_navigation_drawer_content_description" msgid="7216697245762194759">"নেভিগেশ্বন ড্ৰৱাৰ"</string>
- <string name="ws_action_drawer_content_description" msgid="1837365417701148489">"কাৰ্য ড্ৰৱাৰ"</string>
-</resources>
diff --git a/wear/res/values-or/strings.xml b/wear/res/values-or/strings.xml
deleted file mode 100644
index 53e75b3..0000000
--- a/wear/res/values-or/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="ws_navigation_drawer_content_description" msgid="7216697245762194759">"ନେଭିଗେଶନ୍ ପ୍ୟାନେଲ୍"</string>
- <string name="ws_action_drawer_content_description" msgid="1837365417701148489">"କାର୍ଯ୍ୟକାରୀ ପ୍ୟାନେଲ୍"</string>
-</resources>
diff --git a/webkit-codegen/src/test/java/androidx/webkit/internal/codegen/BoundaryInterfaceTest.java b/webkit-codegen/src/test/java/androidx/webkit/internal/codegen/BoundaryInterfaceTest.java
index ba5a9de..00736a7 100644
--- a/webkit-codegen/src/test/java/androidx/webkit/internal/codegen/BoundaryInterfaceTest.java
+++ b/webkit-codegen/src/test/java/androidx/webkit/internal/codegen/BoundaryInterfaceTest.java
@@ -18,9 +18,6 @@
import static org.junit.Assert.assertEquals;
-import androidx.webkit.internal.codegen.representations.ClassRepr;
-import androidx.webkit.internal.codegen.representations.MethodRepr;
-
import com.android.tools.lint.LintCoreProjectEnvironment;
import com.intellij.psi.PsiClass;
@@ -30,13 +27,15 @@
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.util.Arrays;
+import androidx.webkit.internal.codegen.representations.ClassRepr;
+import androidx.webkit.internal.codegen.representations.MethodRepr;
+
@RunWith(JUnit4.class)
public class BoundaryInterfaceTest {
private LintCoreProjectEnvironment mProjectEnv;
@@ -59,12 +58,10 @@
testBoundaryInterfaceGeneration("SingleClassAndMethod");
}
- @Ignore
@Test public void testWebkitReturnTypeGeneratesInvocationHandler() {
testBoundaryInterfaceGeneration("WebKitTypeAsMethodParameter");
}
- @Ignore
@Test public void testWebkitMethodParameterTypeGeneratesInvocationHandler() {
testBoundaryInterfaceGeneration("WebKitTypeAsMethodReturn");
}
diff --git a/webkit/api/current.txt b/webkit/api/current.txt
index e4e9b01..08c6a55 100644
--- a/webkit/api/current.txt
+++ b/webkit/api/current.txt
@@ -1,11 +1,5 @@
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);
@@ -28,34 +22,6 @@
method public abstract void setCacheMode(int);
}
- public class WebMessageCompat {
- ctor public WebMessageCompat(java.lang.String);
- ctor public WebMessageCompat(java.lang.String, androidx.webkit.WebMessagePortCompat[]);
- method public java.lang.String getData();
- method public androidx.webkit.WebMessagePortCompat[] getPorts();
- }
-
- public abstract class WebMessagePortCompat {
- method public abstract void close();
- method public abstract void postMessage(androidx.webkit.WebMessageCompat);
- method public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
- method public abstract void setWebMessageCallback(android.os.Handler, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
- }
-
- public static abstract class WebMessagePortCompat.WebMessageCallbackCompat {
- ctor public WebMessagePortCompat.WebMessageCallbackCompat();
- method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat);
- }
-
- 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);
@@ -67,18 +33,12 @@
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 {
- method public static androidx.webkit.WebMessagePortCompat[] createWebMessageChannel(android.webkit.WebView);
method public static android.content.pm.PackageInfo getCurrentWebViewPackage(android.content.Context);
method public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
method public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
- method public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
method public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String>, android.webkit.ValueCallback<java.lang.Boolean>);
method public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean>);
}
@@ -89,29 +49,7 @@
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_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
- field public static final java.lang.String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
- field public static final java.lang.String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
- 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_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
- field public static final java.lang.String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
- 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 baed9cb..d610dad 100644
--- a/webkit/build.gradle
+++ b/webkit/build.gradle
@@ -40,7 +40,7 @@
}
buildTypes.all {
- consumerProguardFiles new File(webviewBoundaryInterfacesDir, "proguard.flags") , 'proguard-rules.pro'
+ consumerProguardFiles new File(webviewBoundaryInterfacesDir, "proguard.flags")
}
}
diff --git a/webkit/proguard-rules.pro b/webkit/proguard-rules.pro
deleted file mode 100644
index 86756ab..0000000
--- a/webkit/proguard-rules.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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/BoundaryInterfaceTest.java b/webkit/src/androidTest/java/androidx/webkit/BoundaryInterfaceTest.java
deleted file mode 100644
index 3f9857c..0000000
--- a/webkit/src/androidTest/java/androidx/webkit/BoundaryInterfaceTest.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;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import androidx.webkit.internal.WebViewFeatureInternal;
-import androidx.webkit.internal.WebViewGlueCommunicator;
-import androidx.webkit.internal.WebkitToCompatConverter;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests related to the interface between the support library and the Chromium support library glue.
- */
-@RunWith(AndroidJUnit4.class)
-public class BoundaryInterfaceTest {
-
- /**
- * Test ensuring that we can create a {@link androidx.webkit.internal.WebkitToCompatConverter}.
- * This test catches cases where we try to pass post-L android.webkit classes across the
- * boundary - doing so will fail when we (at run-time) create a {@link java.lang.reflect.Proxy}
- * for {@link org.chromium.support_lib_boundary.WebkitToCompatConverterBoundaryInterface} since
- * that proxy will need to look up all the classes referenced from
- * {@link org.chromium.support_lib_boundary.WebkitToCompatConverterBoundaryInterface}.
- */
- @SmallTest
- @Test
- public void testCreateWebkitToCompatConverter() {
- // Use the SERVICE_WORKER_BASIC_USAGE feature as a proxy for knowing whether the current
- // WebView APK is compatible with the support library.
- if (WebViewFeatureInternal.SERVICE_WORKER_BASIC_USAGE.isSupportedByWebView()) {
- WebkitToCompatConverter converter = WebViewGlueCommunicator.getCompatConverter();
- }
- }
-
-}
diff --git a/webkit/src/androidTest/java/androidx/webkit/IncompatibilityTest.java b/webkit/src/androidTest/java/androidx/webkit/IncompatibilityTest.java
deleted file mode 100644
index 09424c6..0000000
--- a/webkit/src/androidTest/java/androidx/webkit/IncompatibilityTest.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;
-
-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/PostMessageTest.java b/webkit/src/androidTest/java/androidx/webkit/PostMessageTest.java
deleted file mode 100644
index 4e74419..0000000
--- a/webkit/src/androidTest/java/androidx/webkit/PostMessageTest.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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.
- */
-
-package androidx.webkit;
-
-import static junit.framework.Assert.assertEquals;
-
-import android.net.Uri;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.runner.AndroidJUnit4;
-import android.webkit.WebView;
-
-import androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat;
-
-import junit.framework.Assert;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CountDownLatch;
-
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class PostMessageTest {
- public static final long TIMEOUT = 6000L;
-
- private WebView mWebView;
- private WebViewOnUiThread mOnUiThread;
-
- private static final String WEBVIEW_MESSAGE = "from_webview";
- private static final String BASE_URI = "http://www.example.com";
-
- @Before
- public void setUp() throws Exception {
- mOnUiThread = new WebViewOnUiThread();
- mOnUiThread.getSettings().setJavaScriptEnabled(true);
- }
-
- @After
- public void tearDown() throws Exception {
- if (mOnUiThread != null) {
- mOnUiThread.cleanUp();
- }
- }
-
- private static final String TITLE_FROM_POST_MESSAGE =
- "<!DOCTYPE html><html><body>"
- + " <script>"
- + " var received = '';"
- + " onmessage = function (e) {"
- + " received += e.data;"
- + " document.title = received; };"
- + " </script>"
- + "</body></html>";
-
- // Acks each received message from the message channel with a seq number.
- private static final String CHANNEL_MESSAGE =
- "<!DOCTYPE html><html><body>"
- + " <script>"
- + " var counter = 0;"
- + " onmessage = function (e) {"
- + " var myPort = e.ports[0];"
- + " myPort.onmessage = function (f) {"
- + " myPort.postMessage(f.data + counter++);"
- + " }"
- + " }"
- + " </script>"
- + "</body></html>";
-
- private void loadPage(String data) {
- mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(BASE_URI, data,
- "text/html", "UTF-8", null);
- }
-
- private void waitForTitle(final String title) {
- new PollingCheck(TIMEOUT) {
- @Override
- protected boolean check() {
- return mOnUiThread.getTitle().equals(title);
- }
- }.run();
- }
-
- // Post a string message to main frame and make sure it is received.
- @Test
- @SdkSuppress(minSdkVersion = 23) // TODO(gsennton) activate this test for pre-M devices when we
- // can pre-install a WebView APK containing support for the WebView Support Library, see
- // b/73454652.
- public void testSimpleMessageToMainFrame() throws Throwable {
- verifyPostMessageToOrigin(Uri.parse(BASE_URI));
- }
-
- // Post a string message to main frame passing a wildcard as target origin
- @Test
- @SdkSuppress(minSdkVersion = 23) // TODO (gsennton) remove this restriction when we can
- // pre-install a WebView APK containing support for the WebView Support Library, see b/73454652.
- public void testWildcardOriginMatchesAnything() throws Throwable {
- verifyPostMessageToOrigin(Uri.parse("*"));
- }
-
- // Post a string message to main frame passing an empty string as target origin
- @Test
- @SdkSuppress(minSdkVersion = 23) // TODO(gsennton) activate this test for pre-M devices when we
- // can pre-install a WebView APK containing support for the WebView Support Library, see
- // b/73454652.
- public void testEmptyStringOriginMatchesAnything() throws Throwable {
- verifyPostMessageToOrigin(Uri.parse(""));
- }
-
- private void verifyPostMessageToOrigin(Uri origin) throws Throwable {
- loadPage(TITLE_FROM_POST_MESSAGE);
- WebMessageCompat message = new WebMessageCompat(WEBVIEW_MESSAGE);
- mOnUiThread.postWebMessageCompat(message, origin);
- waitForTitle(WEBVIEW_MESSAGE);
- }
-
- // Post multiple messages to main frame and make sure they are received in
- // correct order.
- @Test
- @SdkSuppress(minSdkVersion = 23) // TODO(gsennton) activate this test for pre-M devices when we
- // can pre-install a WebView APK containing support for the WebView Support Library, see
- // b/73454652.
- public void testMultipleMessagesToMainFrame() throws Throwable {
- loadPage(TITLE_FROM_POST_MESSAGE);
- for (int i = 0; i < 10; i++) {
- mOnUiThread.postWebMessageCompat(new WebMessageCompat(Integer.toString(i)),
- Uri.parse(BASE_URI));
- }
- waitForTitle("0123456789");
- }
-
- // Create a message channel and make sure it can be used for data transfer to/from js.
- @Test
- @SdkSuppress(minSdkVersion = 23) // TODO(gsennton) activate this test for pre-M devices when we
- // can pre-install a WebView APK containing support for the WebView Support Library, see
- // b/73454652.
- public void testMessageChannel() throws Throwable {
- loadPage(CHANNEL_MESSAGE);
- final WebMessagePortCompat[] channel = mOnUiThread.createWebMessageChannelCompat();
- WebMessageCompat message =
- new WebMessageCompat(WEBVIEW_MESSAGE, new WebMessagePortCompat[]{channel[1]});
- mOnUiThread.postWebMessageCompat(message, Uri.parse(BASE_URI));
- final int messageCount = 3;
- final CountDownLatch latch = new CountDownLatch(messageCount);
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- for (int i = 0; i < messageCount; i++) {
- channel[0].postMessage(new WebMessageCompat(WEBVIEW_MESSAGE + i));
- }
- channel[0].setWebMessageCallback(new WebMessageCallbackCompat() {
- @Override
- public void onMessage(WebMessagePortCompat port, WebMessageCompat message) {
- int i = messageCount - (int) latch.getCount();
- assertEquals(WEBVIEW_MESSAGE + i + i, message.getData());
- latch.countDown();
- }
- });
- }
- });
- // Wait for all the responses to arrive.
- boolean ignore = latch.await(TIMEOUT, java.util.concurrent.TimeUnit.MILLISECONDS);
- }
-
- // Test that a message port that is closed cannot used to send a message
- @Test
- @SdkSuppress(minSdkVersion = 23) // TODO(gsennton) activate this test for pre-M devices when we
- // can pre-install a WebView APK containing support for the WebView Support Library, see
- // b/73454652.
- public void testClose() throws Throwable {
- loadPage(CHANNEL_MESSAGE);
- final WebMessagePortCompat[] channel = mOnUiThread.createWebMessageChannelCompat();
- WebMessageCompat message =
- new WebMessageCompat(WEBVIEW_MESSAGE, new WebMessagePortCompat[]{channel[1]});
- mOnUiThread.postWebMessageCompat(message, Uri.parse(BASE_URI));
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- try {
- channel[0].close();
- channel[0].postMessage(new WebMessageCompat(WEBVIEW_MESSAGE));
- } catch (IllegalStateException ex) {
- // expect to receive an exception
- return;
- }
- Assert.fail("A closed port cannot be used to transfer messages");
- }
- });
- }
-
- // Sends a new message channel from JS to Java.
- private static final String CHANNEL_FROM_JS =
- "<!DOCTYPE html><html><body>"
- + " <script>"
- + " var counter = 0;"
- + " var mc = new MessageChannel();"
- + " var received = '';"
- + " mc.port1.onmessage = function (e) {"
- + " received = e.data;"
- + " document.title = e.data;"
- + " };"
- + " onmessage = function (e) {"
- + " var myPort = e.ports[0];"
- + " myPort.postMessage('', [mc.port2]);"
- + " };"
- + " </script>"
- + "</body></html>";
-
- // Test a message port created in JS can be received and used for message transfer.
- @Test
- @SdkSuppress(minSdkVersion = 23) // TODO(gsennton) activate this test for pre-M devices when we
- // can pre-install a WebView APK containing support for the WebView Support Library, see
- // b/73454652.
- public void testReceiveMessagePort() throws Throwable {
- final String hello = "HELLO";
- loadPage(CHANNEL_FROM_JS);
- final WebMessagePortCompat[] channel = mOnUiThread.createWebMessageChannelCompat();
- WebMessageCompat message =
- new WebMessageCompat(WEBVIEW_MESSAGE, new WebMessagePortCompat[]{channel[1]});
- mOnUiThread.postWebMessageCompat(message, Uri.parse(BASE_URI));
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- channel[0].setWebMessageCallback(new WebMessageCallbackCompat() {
- @Override
- public void onMessage(WebMessagePortCompat port, WebMessageCompat message) {
- message.getPorts()[0].postMessage(new WebMessageCompat(hello));
- }
- });
- }
- });
- waitForTitle(hello);
- }
-}
diff --git a/webkit/src/androidTest/java/androidx/webkit/ServiceWorkerClientCompatTest.java b/webkit/src/androidTest/java/androidx/webkit/ServiceWorkerClientCompatTest.java
index d3a55ae..aecbc34 100644
--- a/webkit/src/androidTest/java/androidx/webkit/ServiceWorkerClientCompatTest.java
+++ b/webkit/src/androidTest/java/androidx/webkit/ServiceWorkerClientCompatTest.java
@@ -17,8 +17,8 @@
package androidx.webkit;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assume.assumeTrue;
+import android.os.Build;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.webkit.JavascriptInterface;
@@ -141,9 +141,9 @@
// Test correct invocation of shouldInterceptRequest for Service Workers.
@Test
public void testServiceWorkerClientInterceptCallback() throws Exception {
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE));
- assumeTrue(WebViewFeature.isFeatureSupported(
- WebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST));
+ // TODO(gsennton) activate this test for pre-N devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return;
final InterceptServiceWorkerClient mInterceptServiceWorkerClient =
new InterceptServiceWorkerClient();
diff --git a/webkit/src/androidTest/java/androidx/webkit/WebSettingsCompatTest.java b/webkit/src/androidTest/java/androidx/webkit/WebSettingsCompatTest.java
index 5dd9b54..1e5c152 100644
--- a/webkit/src/androidTest/java/androidx/webkit/WebSettingsCompatTest.java
+++ b/webkit/src/androidTest/java/androidx/webkit/WebSettingsCompatTest.java
@@ -19,8 +19,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
+import android.os.Build;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.webkit.WebSettings;
@@ -41,7 +41,9 @@
@Test
public void testOffscreenPreRaster() {
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.OFF_SCREEN_PRERASTER));
+ // TODO(gsennton) activate this test for pre-M devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;
assertFalse(WebSettingsCompat.getOffscreenPreRaster(mWebViewOnUiThread.getSettings()));
@@ -51,7 +53,9 @@
@Test
public void testEnableSafeBrowsing() throws Throwable {
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_ENABLE));
+ // TODO(gsennton) activate this test for old devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;
WebSettingsCompat.setSafeBrowsingEnabled(mWebViewOnUiThread.getSettings(), false);
assertFalse(WebSettingsCompat.getSafeBrowsingEnabled(mWebViewOnUiThread.getSettings()));
@@ -59,8 +63,9 @@
@Test
public void testDisabledActionModeMenuItems() throws Throwable {
- assumeTrue(
- WebViewFeature.isFeatureSupported(WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS));
+ // TODO(gsennton) activate this test for old devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return;
assertEquals(WebSettings.MENU_ITEM_NONE,
WebSettingsCompat.getDisabledActionModeMenuItems(mWebViewOnUiThread.getSettings()));
diff --git a/webkit/src/androidTest/java/androidx/webkit/WebViewClientCompatTest.java b/webkit/src/androidTest/java/androidx/webkit/WebViewClientCompatTest.java
deleted file mode 100644
index 1344f4b..0000000
--- a/webkit/src/androidTest/java/androidx/webkit/WebViewClientCompatTest.java
+++ /dev/null
@@ -1,393 +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;
-
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.webkit.ValueCallback;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebResourceResponse;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class WebViewClientCompatTest {
- private WebViewOnUiThread mWebViewOnUiThread;
-
- private static final long TEST_TIMEOUT = 20000L;
- private static final String TEST_URL = "http://www.example.com/";
- private static final String TEST_SAFE_BROWSING_URL =
- "chrome://safe-browsing/match?type=malware";
-
- @Before
- public void setUp() {
- mWebViewOnUiThread = new WebViewOnUiThread();
- }
-
- @Test
- public void testShouldOverrideUrlLoadingDefault() {
- // This never calls into chromium, so we don't need to do any feature checks.
-
- final MockWebViewClient webViewClient = new MockWebViewClient();
-
- // Create any valid WebResourceRequest, the return values don't matter much.
- final WebResourceRequest resourceRequest = new WebResourceRequest() {
- @Override
- public Uri getUrl() {
- return Uri.parse(TEST_URL);
- }
-
- @Override
- public boolean isForMainFrame() {
- return false;
- }
-
- @Override
- public boolean isRedirect() {
- return false;
- }
-
- @Override
- public boolean hasGesture() {
- return false;
- }
-
- @Override
- public String getMethod() {
- return "GET";
- }
-
- @Override
- public Map<String, String> getRequestHeaders() {
- return new HashMap<String, String>();
- }
- };
-
- Assert.assertFalse(webViewClient.shouldOverrideUrlLoading(
- mWebViewOnUiThread.getWebViewOnCurrentThread(), resourceRequest));
- }
-
- @Test
- public void testShouldOverrideUrlLoading() throws InterruptedException {
- Assume.assumeTrue(
- WebViewFeature.isFeatureSupported(WebViewFeature.SHOULD_OVERRIDE_WITH_REDIRECTS));
- Assume.assumeTrue(
- WebViewFeature.isFeatureSupported(WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT));
-
- String data = "<html><body>"
- + "<a href=\"" + TEST_URL + "\" id=\"link\">new page</a>"
- + "</body></html>";
- mWebViewOnUiThread.loadDataAndWaitForCompletion(data, "text/html", null);
- final CountDownLatch pageFinishedLatch = new CountDownLatch(1);
- final MockWebViewClient webViewClient = new MockWebViewClient() {
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- pageFinishedLatch.countDown();
- }
- };
- mWebViewOnUiThread.setWebViewClient(webViewClient);
- mWebViewOnUiThread.getSettings().setJavaScriptEnabled(true);
- clickOnLinkUsingJs("link", mWebViewOnUiThread);
- pageFinishedLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
- Assert.assertEquals(TEST_URL,
- webViewClient.getLastShouldOverrideResourceRequest().getUrl().toString());
-
- WebResourceRequest request = webViewClient.getLastShouldOverrideResourceRequest();
- Assert.assertNotNull(request);
- Assert.assertTrue(request.isForMainFrame());
- Assert.assertFalse(WebResourceRequestCompat.isRedirect(request));
- Assert.assertFalse(request.hasGesture());
- }
-
- private void clickOnLinkUsingJs(final String linkId, WebViewOnUiThread webViewOnUiThread)
- throws InterruptedException {
- final CountDownLatch callbackLatch = new CountDownLatch(1);
- ValueCallback<String> callback = new ValueCallback<String>() {
- @Override
- public void onReceiveValue(String value) {
- callbackLatch.countDown();
- }
- };
- webViewOnUiThread.evaluateJavascript(
- "document.getElementById('" + linkId + "').click();"
- + "console.log('element with id [" + linkId + "] clicked');", callback);
- Assert.assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testOnReceivedError() throws Exception {
- Assume.assumeTrue(
- WebViewFeature.isFeatureSupported(WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR));
- Assume.assumeTrue(
- WebViewFeature.isFeatureSupported(WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE));
-
- final MockWebViewClient webViewClient = new MockWebViewClient();
- mWebViewOnUiThread.setWebViewClient(webViewClient);
-
- String wrongUri = "invalidscheme://some/resource";
- Assert.assertNull(webViewClient.getOnReceivedResourceError());
- mWebViewOnUiThread.loadUrlAndWaitForCompletion(wrongUri);
- Assert.assertNotNull(webViewClient.getOnReceivedResourceError());
- Assert.assertEquals(WebViewClient.ERROR_UNSUPPORTED_SCHEME,
- webViewClient.getOnReceivedResourceError().getErrorCode());
- }
-
- @Test
- public void testOnReceivedErrorForSubresource() throws Exception {
- Assume.assumeTrue(
- WebViewFeature.isFeatureSupported(WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR));
-
- final MockWebViewClient webViewClient = new MockWebViewClient();
- mWebViewOnUiThread.setWebViewClient(webViewClient);
-
- Assert.assertNull(webViewClient.getOnReceivedResourceError());
- String data = "<html>"
- + " <body>"
- + " <img src=\"invalidscheme://some/resource\" />"
- + " </body>"
- + "</html>";
-
- mWebViewOnUiThread.loadDataAndWaitForCompletion(data, "text/html", null);
- Assert.assertNotNull(webViewClient.getOnReceivedResourceError());
- Assert.assertEquals(WebViewClient.ERROR_UNSUPPORTED_SCHEME,
- webViewClient.getOnReceivedResourceError().getErrorCode());
- }
-
- @Test
- public void testOnSafeBrowsingHitBackToSafety() throws Throwable {
- Assume.assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_HIT));
- Assume.assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_ENABLE));
- Assume.assumeTrue(WebViewFeature.isFeatureSupported(
- WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY));
- Assume.assumeTrue(
- WebViewFeature.isFeatureSupported(WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE));
-
- final SafeBrowsingBackToSafetyClient backToSafetyWebViewClient =
- new SafeBrowsingBackToSafetyClient();
- mWebViewOnUiThread.setWebViewClient(backToSafetyWebViewClient);
- WebSettingsCompat.setSafeBrowsingEnabled(mWebViewOnUiThread.getSettings(), true);
-
- // Load any page
- String data = "<html><body>some safe page</body></html>";
- mWebViewOnUiThread.loadDataAndWaitForCompletion(data, "text/html", null);
- final String originalUrl = mWebViewOnUiThread.getUrl();
-
- enableSafeBrowsingAndLoadUnsafePage(backToSafetyWebViewClient);
-
- // Back to safety should produce a network error
- Assert.assertNotNull(backToSafetyWebViewClient.getOnReceivedResourceError());
- Assert.assertEquals(WebViewClient.ERROR_UNSAFE_RESOURCE,
- backToSafetyWebViewClient.getOnReceivedResourceError().getErrorCode());
-
- // Check that we actually navigated backward
- Assert.assertEquals(originalUrl, mWebViewOnUiThread.getUrl());
- }
-
- @Test
- public void testOnSafeBrowsingHitProceed() throws Throwable {
- Assume.assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_HIT));
- Assume.assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_ENABLE));
- Assume.assumeTrue(WebViewFeature.isFeatureSupported(
- WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED));
-
- final SafeBrowsingProceedClient proceedWebViewClient = new SafeBrowsingProceedClient();
- mWebViewOnUiThread.setWebViewClient(proceedWebViewClient);
- WebSettingsCompat.setSafeBrowsingEnabled(mWebViewOnUiThread.getSettings(), true);
-
- // Load any page
- String data = "<html><body>some safe page</body></html>";
- mWebViewOnUiThread.loadDataAndWaitForCompletion(data, "text/html", null);
-
- enableSafeBrowsingAndLoadUnsafePage(proceedWebViewClient);
-
- // Check that we actually proceeded
- Assert.assertEquals(TEST_SAFE_BROWSING_URL, mWebViewOnUiThread.getUrl());
- }
-
- private void enableSafeBrowsingAndLoadUnsafePage(SafeBrowsingClient client) throws Throwable {
- // Note: Safe Browsing depends on user opt-in as well, so we can't assume it's actually
- // enabled. #getSafeBrowsingEnabled will tell us the true state of whether Safe Browsing is
- // enabled.
- boolean deviceSupportsSafeBrowsing =
- WebSettingsCompat.getSafeBrowsingEnabled(mWebViewOnUiThread.getSettings());
- Assume.assumeTrue(deviceSupportsSafeBrowsing);
-
- Assert.assertNull(client.getOnReceivedResourceError());
- mWebViewOnUiThread.loadUrlAndWaitForCompletion(TEST_SAFE_BROWSING_URL);
-
- Assert.assertEquals(TEST_SAFE_BROWSING_URL,
- client.getOnSafeBrowsingHitRequest().getUrl().toString());
- Assert.assertTrue(client.getOnSafeBrowsingHitRequest().isForMainFrame());
- }
-
- @Test
- public void testOnPageCommitVisibleCalled() throws Exception {
- Assume.assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.VISUAL_STATE_CALLBACK));
-
- final CountDownLatch callbackLatch = new CountDownLatch(1);
-
- mWebViewOnUiThread.setWebViewClient(new WebViewClientCompat() {
- @Override
- public void onPageCommitVisible(WebView view, String url) {
- Assert.assertEquals(url, "about:blank");
- callbackLatch.countDown();
- }
- });
-
- mWebViewOnUiThread.loadUrl("about:blank");
- Assert.assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
- }
-
- private class MockWebViewClient extends WebViewOnUiThread.WaitForLoadedClient {
- private boolean mOnPageStartedCalled;
- private boolean mOnPageFinishedCalled;
- private boolean mOnLoadResourceCalled;
- private WebResourceErrorCompat mOnReceivedResourceError;
- private WebResourceResponse mOnReceivedHttpError;
- private WebResourceRequest mLastShouldOverrideResourceRequest;
-
- MockWebViewClient() {
- super(mWebViewOnUiThread);
- }
-
- public WebResourceErrorCompat getOnReceivedResourceError() {
- return mOnReceivedResourceError;
- }
-
- public WebResourceResponse getOnReceivedHttpError() {
- return mOnReceivedHttpError;
- }
-
- public WebResourceRequest getLastShouldOverrideResourceRequest() {
- return mLastShouldOverrideResourceRequest;
- }
-
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- super.onPageStarted(view, url, favicon);
- mOnPageStartedCalled = true;
- }
-
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- Assert.assertTrue(mOnPageStartedCalled);
- Assert.assertTrue(mOnLoadResourceCalled);
- mOnPageFinishedCalled = true;
- }
-
- @Override
- public void onLoadResource(WebView view, String url) {
- super.onLoadResource(view, url);
- Assert.assertTrue(mOnPageStartedCalled);
- mOnLoadResourceCalled = true;
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public void onReceivedError(WebView view, int errorCode,
- String description, String failingUrl) {
- // This can be called if a test runs for a WebView which does not support the {@link
- // WebViewFeature#RECEIVE_WEB_RESOURCE_ERROR} feature.
- }
-
- @Override
- public void onReceivedError(WebView view, WebResourceRequest request,
- WebResourceErrorCompat error) {
- mOnReceivedResourceError = error;
- }
-
- @Override
- public void onReceivedHttpError(WebView view, WebResourceRequest request,
- WebResourceResponse errorResponse) {
- super.onReceivedHttpError(view, request, errorResponse);
- mOnReceivedHttpError = errorResponse;
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- // This can be called if a test runs for a WebView which does not support the {@link
- // WebViewFeature#SHOULD_OVERRIDE_WITH_REDIRECTS} feature.
- return false;
- }
-
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
- mLastShouldOverrideResourceRequest = request;
- return false;
- }
- }
-
- private class SafeBrowsingClient extends MockWebViewClient {
- private WebResourceRequest mOnSafeBrowsingHitRequest;
- private int mOnSafeBrowsingHitThreatType;
-
- public WebResourceRequest getOnSafeBrowsingHitRequest() {
- return mOnSafeBrowsingHitRequest;
- }
-
- public void setOnSafeBrowsingHitRequest(WebResourceRequest request) {
- mOnSafeBrowsingHitRequest = request;
- }
-
- public int getOnSafeBrowsingHitThreatType() {
- return mOnSafeBrowsingHitThreatType;
- }
-
- public void setOnSafeBrowsingHitThreatType(int type) {
- mOnSafeBrowsingHitThreatType = type;
- }
- }
-
- private class SafeBrowsingBackToSafetyClient extends SafeBrowsingClient {
- @Override
- public void onSafeBrowsingHit(WebView view, WebResourceRequest request,
- int threatType, SafeBrowsingResponseCompat response) {
- // Immediately go back to safety to return the network error code
- setOnSafeBrowsingHitRequest(request);
- setOnSafeBrowsingHitThreatType(threatType);
- response.backToSafety(/* report */ true);
- }
- }
-
- private class SafeBrowsingProceedClient extends SafeBrowsingClient {
- @Override
- public void onSafeBrowsingHit(WebView view, WebResourceRequest request,
- int threatType, SafeBrowsingResponseCompat response) {
- // Proceed through Safe Browsing warnings
- setOnSafeBrowsingHitRequest(request);
- setOnSafeBrowsingHitThreatType(threatType);
- response.proceed(/* report */ true);
- }
- }
-}
diff --git a/webkit/src/androidTest/java/androidx/webkit/WebViewCompatTest.java b/webkit/src/androidTest/java/androidx/webkit/WebViewCompatTest.java
index 03aa946..bd77fdb 100644
--- a/webkit/src/androidTest/java/androidx/webkit/WebViewCompatTest.java
+++ b/webkit/src/androidTest/java/androidx/webkit/WebViewCompatTest.java
@@ -22,7 +22,6 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
import android.content.Context;
import android.content.ContextWrapper;
@@ -30,10 +29,15 @@
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;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import androidx.core.os.BuildCompat;
import org.junit.Assert;
import org.junit.Before;
@@ -61,7 +65,9 @@
@Test
public void testVisualStateCallbackCalled() throws Exception {
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.VISUAL_STATE_CALLBACK));
+ // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (!BuildCompat.isAtLeastP()) return;
final CountDownLatch callbackLatch = new CountDownLatch(1);
final long kRequest = 100;
@@ -79,10 +85,9 @@
assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
}
+ @Suppress // TODO(gsennton) remove @Suppress when b/76202025 has been resolved
@Test
public void testCheckThread() {
- // Skip this test if VisualStateCallback is not supported.
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.VISUAL_STATE_CALLBACK));
try {
WebViewCompat.postVisualStateCallback(mWebViewOnUiThread.getWebViewOnCurrentThread(), 5,
new WebViewCompat.VisualStateCallback() {
@@ -115,7 +120,9 @@
@Test
public void testStartSafeBrowsingUseApplicationContext() throws Exception {
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING));
+ // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
final MockContext ctx =
new MockContext(InstrumentationRegistry.getTargetContext().getApplicationContext());
@@ -133,14 +140,18 @@
@Test
public void testStartSafeBrowsingWithNullCallbackDoesntCrash() throws Exception {
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING));
+ // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
WebViewCompat.startSafeBrowsing(InstrumentationRegistry.getTargetContext(), null);
}
@Test
public void testStartSafeBrowsingInvokesCallback() throws Exception {
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING));
+ // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
final CountDownLatch resultLatch = new CountDownLatch(1);
WebViewCompat.startSafeBrowsing(
@@ -158,7 +169,9 @@
@Test
public void testSetSafeBrowsingWhitelistWithMalformedList() throws Exception {
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_WHITELIST));
+ // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
List whitelist = new ArrayList<String>();
// Protocols are not supported in the whitelist
@@ -176,9 +189,9 @@
@Test
public void testSetSafeBrowsingWhitelistWithValidList() throws Exception {
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_WHITELIST));
- // This test relies on the onSafeBrowsingHit callback to verify correctness.
- assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_HIT));
+ // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
List whitelist = new ArrayList<String>();
whitelist.add("safe-browsing");
@@ -193,7 +206,7 @@
assertTrue(resultLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
final CountDownLatch resultLatch2 = new CountDownLatch(1);
- mWebViewOnUiThread.setWebViewClient(new WebViewClientCompat() {
+ mWebViewOnUiThread.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
resultLatch2.countDown();
@@ -201,7 +214,7 @@
@Override
public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType,
- SafeBrowsingResponseCompat callback) {
+ SafeBrowsingResponse callback) {
Assert.fail("Should not invoke onSafeBrowsingHit");
}
});
@@ -214,8 +227,9 @@
@Test
public void testGetSafeBrowsingPrivacyPolicyUrl() throws Exception {
- assumeTrue(
- WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL));
+ // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
+ // containing support for the WebView Support Library, see b/73454652.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
assertNotNull(WebViewCompat.getSafeBrowsingPrivacyPolicyUrl());
try {
diff --git a/webkit/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java b/webkit/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java
index bd83752..6e817c3 100644
--- a/webkit/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java
+++ b/webkit/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java
@@ -20,7 +20,6 @@
import static org.junit.Assert.fail;
import android.graphics.Bitmap;
-import android.net.Uri;
import android.os.Looper;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
@@ -28,9 +27,7 @@
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
+import android.webkit.WebViewClient;
import java.util.concurrent.Callable;
@@ -68,6 +65,52 @@
});
}
+ public void loadUrl(final String url) {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.loadUrl(url);
+ }
+ });
+ }
+
+ public void setWebViewClient(final WebViewClient webviewClient) {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.setWebViewClient(webviewClient);
+ }
+ });
+ }
+
+ public void postVisualStateCallbackCompat(final long requestId,
+ final WebViewCompat.VisualStateCallback callback) {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ WebViewCompat.postVisualStateCallback(mWebView, requestId, callback);
+ }
+ });
+ }
+
+ public WebSettings getSettings() {
+ return getValue(new ValueGetter<WebSettings>() {
+ @Override
+ public WebSettings capture() {
+ return mWebView.getSettings();
+ }
+ });
+ }
+
+ public void addJavascriptInterface(final Object object, final String name) {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.addJavascriptInterface(object, name);
+ }
+ });
+ }
+
/**
* Called after a test is complete and the WebView should be disengaged from
* the tests.
@@ -85,6 +128,10 @@
});
}
+ WebView getWebViewOnCurrentThread() {
+ return mWebView;
+ }
+
/**
* Called from WaitForLoadedClient.
*/
@@ -109,45 +156,9 @@
this.notifyAll();
}
- public void setWebViewClient(final WebViewClientCompat webviewClient) {
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(webviewClient);
- }
- });
- }
-
- public WebMessagePortCompat[] createWebMessageChannelCompat() {
- return getValue(new ValueGetter<WebMessagePortCompat[]>() {
- @Override
- public WebMessagePortCompat[] capture() {
- return WebViewCompat.createWebMessageChannel(mWebView);
- }
- });
- }
-
- public void postWebMessageCompat(final WebMessageCompat message, final Uri targetOrigin) {
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- WebViewCompat.postWebMessage(mWebView, message, targetOrigin);
- }
- });
- }
-
- public void addJavascriptInterface(final Object object, final String name) {
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mWebView.addJavascriptInterface(object, name);
- }
- });
- }
-
/**
- * Calls loadUrl on the WebView and then waits onPageFinished
- * and onProgressChange to reach 100.
+ * Calls loadUrl on the WebView and then waits onPageFinished,
+ * onNewPicture and onProgressChange to reach 100.
* Test fails if the load timeout elapses.
* @param url The URL to load.
*/
@@ -160,45 +171,6 @@
});
}
- public void loadUrl(final String url) {
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl(url);
- }
- });
- }
-
- /**
- * Calls {@link WebView#loadData} on the WebView and then waits onPageFinished
- * and onProgressChange to reach 100.
- * Test fails if the load timeout elapses.
- * @param data The data to load.
- * @param mimeType The mimeType to pass to loadData.
- * @param encoding The encoding to pass to loadData.
- */
- public void loadDataAndWaitForCompletion(@NonNull final String data,
- @Nullable final String mimeType, @Nullable final String encoding) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadData(data, mimeType, encoding);
- }
- });
- }
-
- public void loadDataWithBaseURLAndWaitForCompletion(final String baseUrl,
- final String data, final String mimeType, final String encoding,
- final String historyUrl) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding,
- historyUrl);
- }
- });
- }
-
/**
* Use this only when JavaScript causes a page load to wait for the
* page load to complete. Otherwise use loadUrlAndWaitForCompletion or
@@ -223,43 +195,6 @@
}
}
- public String getTitle() {
- return getValue(new ValueGetter<String>() {
- @Override
- public String capture() {
- return mWebView.getTitle();
- }
- });
- }
-
- public WebSettings getSettings() {
- return getValue(new ValueGetter<WebSettings>() {
- @Override
- public WebSettings capture() {
- return mWebView.getSettings();
- }
- });
- }
-
- public String getUrl() {
- return getValue(new ValueGetter<String>() {
- @Override
- public String capture() {
- return mWebView.getUrl();
- }
- });
- }
-
- public void postVisualStateCallbackCompat(final long requestId,
- final WebViewCompat.VisualStateCallback callback) {
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- WebViewCompat.postVisualStateCallback(mWebView, requestId, callback);
- }
- });
- }
-
void evaluateJavascript(final String script, final ValueCallback<String> result) {
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@Override
@@ -269,30 +204,6 @@
});
}
- WebView getWebViewOnCurrentThread() {
- return mWebView;
- }
-
- private <T> T getValue(ValueGetter<T> getter) {
- InstrumentationRegistry.getInstrumentation().runOnMainSync(getter);
- return getter.getValue();
- }
-
- private abstract class ValueGetter<T> implements Runnable {
- private T mValue;
-
- @Override
- public void run() {
- mValue = capture();
- }
-
- protected abstract T capture();
-
- public T getValue() {
- return mValue;
- }
- }
-
/**
* Returns true if the current thread is the UI thread based on the
* Looper.
@@ -393,6 +304,26 @@
}
}
+ private <T> T getValue(ValueGetter<T> getter) {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(getter);
+ return getter.getValue();
+ }
+
+ private abstract class ValueGetter<T> implements Runnable {
+ private T mValue;
+
+ @Override
+ public void run() {
+ mValue = capture();
+ }
+
+ protected abstract T capture();
+
+ public T getValue() {
+ return mValue;
+ }
+ }
+
/**
* A WebChromeClient used to capture the onProgressChanged for use
* in waitFor functions. If a test must override the WebChromeClient,
@@ -420,7 +351,7 @@
* needs the waitForCompletion capability then it should derive from
* WaitForLoadedClient or call WebViewOnUiThread.onPageFinished.
*/
- public static class WaitForLoadedClient extends WebViewClientCompat {
+ public static class WaitForLoadedClient extends WebViewClient {
private WebViewOnUiThread mOnUiThread;
WaitForLoadedClient(WebViewOnUiThread onUiThread) {
diff --git a/webkit/src/main/java/androidx/webkit/SafeBrowsingResponseCompat.java b/webkit/src/main/java/androidx/webkit/SafeBrowsingResponseCompat.java
deleted file mode 100644
index 76121f3..0000000
--- a/webkit/src/main/java/androidx/webkit/SafeBrowsingResponseCompat.java
+++ /dev/null
@@ -1,147 +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;
-
-import android.webkit.SafeBrowsingResponse;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.annotation.RequiresFeature;
-import androidx.webkit.internal.WebViewFeatureInternal;
-
-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.
- */
- @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
- 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.
- */
- @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
- public abstract void proceed(boolean report);
-
- /**
- * Act as if the user clicked "back to safety."
- *
- * @param report {@code true} to enable Safe Browsing reporting.
- */
- @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
- 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) {
- final WebViewFeatureInternal webViewFeature =
- WebViewFeatureInternal.getFeature(
- WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL);
- if (!webViewFeature.isSupportedByWebView()) {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- responseDelegate.showInterstitial(allowReporting);
- }
-
- @Override
- public void proceed(boolean report) {
- final WebViewFeatureInternal webViewFeature =
- WebViewFeatureInternal.getFeature(
- WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED);
- if (!webViewFeature.isSupportedByWebView()) {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- responseDelegate.proceed(report);
- }
-
- @Override
- public void backToSafety(boolean report) {
- final WebViewFeatureInternal webViewFeature =
- WebViewFeatureInternal.getFeature(
- WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY);
- if (!webViewFeature.isSupportedByWebView()) {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- 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) {
- // Frameworks support is implied by the API level.
- 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 5c3c5ff..19aab8c 100644
--- a/webkit/src/main/java/androidx/webkit/ServiceWorkerClientCompat.java
+++ b/webkit/src/main/java/androidx/webkit/ServiceWorkerClientCompat.java
@@ -43,10 +43,6 @@
* @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 79b714a..3eb55d2 100644
--- a/webkit/src/main/java/androidx/webkit/ServiceWorkerControllerCompat.java
+++ b/webkit/src/main/java/androidx/webkit/ServiceWorkerControllerCompat.java
@@ -16,11 +16,18 @@
package androidx.webkit;
+import android.os.Build;
+import android.webkit.ServiceWorkerController;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresFeature;
+import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
-import androidx.webkit.internal.ServiceWorkerControllerImpl;
+import androidx.webkit.internal.FrameworkServiceWorkerController;
+import androidx.webkit.internal.ServiceWorkerControllerAdapter;
+import androidx.webkit.internal.WebViewGlueCommunicator;
+
+// TODO(gsennton) guard APIs with isFeatureSupported(String)
/**
* Manages Service Workers used by WebView.
@@ -54,14 +61,28 @@
* @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 = new ServiceWorkerControllerImpl();
+ 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());
}
/**
diff --git a/webkit/src/main/java/androidx/webkit/ServiceWorkerWebSettingsCompat.java b/webkit/src/main/java/androidx/webkit/ServiceWorkerWebSettingsCompat.java
index 6763db4..61c46c3 100644
--- a/webkit/src/main/java/androidx/webkit/ServiceWorkerWebSettingsCompat.java
+++ b/webkit/src/main/java/androidx/webkit/ServiceWorkerWebSettingsCompat.java
@@ -19,7 +19,6 @@
import android.webkit.WebSettings;
import androidx.annotation.IntDef;
-import androidx.annotation.RequiresFeature;
import androidx.annotation.RestrictTo;
import java.lang.annotation.Retention;
@@ -59,8 +58,6 @@
* {@link WebSettings#LOAD_DEFAULT}.
*
*/
- @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_CACHE_MODE,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public abstract void setCacheMode(@CacheMode int mode);
/**
@@ -71,8 +68,6 @@
* @see #setCacheMode
*
*/
- @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_CACHE_MODE,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public abstract @CacheMode int getCacheMode();
/**
@@ -81,8 +76,6 @@
* {@link WebSettings#setAllowContentAccess}.
*
*/
- @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public abstract void setAllowContentAccess(boolean allow);
/**
@@ -92,8 +85,6 @@
* @see #setAllowContentAccess
*
*/
- @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public abstract boolean getAllowContentAccess();
/**
@@ -102,8 +93,6 @@
* {@link WebSettings#setAllowFileAccess}.
*
*/
- @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_FILE_ACCESS,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public abstract void setAllowFileAccess(boolean allow);
/**
@@ -113,8 +102,6 @@
* @see #setAllowFileAccess
*
*/
- @RequiresFeature(name = WebViewFeature.SERVICE_WORKER_FILE_ACCESS,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public abstract boolean getAllowFileAccess();
/**
@@ -125,8 +112,6 @@
* @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);
/**
@@ -138,7 +123,5 @@
* @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/WebMessageCompat.java b/webkit/src/main/java/androidx/webkit/WebMessageCompat.java
deleted file mode 100644
index e1b1193..0000000
--- a/webkit/src/main/java/androidx/webkit/WebMessageCompat.java
+++ /dev/null
@@ -1,64 +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;
-
-import androidx.annotation.Nullable;
-
-/**
- * The Java representation of the HTML5 PostMessage event. See
- * https://html.spec.whatwg.org/multipage/comms.html#the-messageevent-interfaces
- * for definition of a MessageEvent in HTML5.
- */
-public class WebMessageCompat {
-
- private String mData;
- private WebMessagePortCompat[] mPorts;
-
- /**
- * Creates a WebMessage.
- * @param data the data of the message.
- */
- public WebMessageCompat(@Nullable String data) {
- mData = data;
- }
-
- /**
- * Creates a WebMessage.
- * @param data the data of the message.
- * @param ports the ports that are sent with the message.
- */
- public WebMessageCompat(@Nullable String data, @Nullable WebMessagePortCompat[] ports) {
- mData = data;
- mPorts = ports;
- }
-
- /**
- * Returns the data of the message.
- */
- public @Nullable String getData() {
- return mData;
- }
-
- /**
- * Returns the ports that are sent with the message, or {@code null} if no port
- * is sent.
- */
- @Nullable
- public WebMessagePortCompat[] getPorts() {
- return mPorts;
- }
-}
diff --git a/webkit/src/main/java/androidx/webkit/WebMessagePortCompat.java b/webkit/src/main/java/androidx/webkit/WebMessagePortCompat.java
deleted file mode 100644
index f6efd0a..0000000
--- a/webkit/src/main/java/androidx/webkit/WebMessagePortCompat.java
+++ /dev/null
@@ -1,119 +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;
-
-import android.os.Handler;
-import android.webkit.WebMessagePort;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
-
-/**
- * <p>The Java representation of the
- * <a href="https://html.spec.whatwg.org/multipage/comms.html#messageport">
- * HTML5 message ports.</a>
- *
- * <p>A Message port represents one endpoint of a Message Channel. In Android
- * webview, there is no separate Message Channel object. When a message channel
- * is created, both ports are tangled to each other and started, and then
- * returned in a MessagePort array, see {@link WebViewCompat#createWebMessageChannel}
- * for creating a message channel.
- *
- * <p>When a message port is first created or received via transfer, it does not
- * have a WebMessageCallback to receive web messages. The messages are queued until
- * a WebMessageCallback is set.
- *
- * <p>A message port should be closed when it is not used by the embedder application
- * anymore. A closed port cannot be transferred or cannot be reopened to send
- * messages. Close can be called multiple times.
- *
- * <p>When a port is transferred to JS, it cannot be used to send or receive messages
- * at the Java side anymore. Different from HTML5 Spec, a port cannot be transferred
- * if one of these has ever happened: i. a message callback was set, ii. a message was
- * posted on it. A transferred port cannot be closed by the application, since
- * the ownership is also transferred.
- *
- * <p>It is possible to transfer both ports of a channel to JS, for example for
- * communication between subframes.
- */
-public abstract class WebMessagePortCompat {
- /**
- * The listener for handling MessagePort events. The message callback
- * methods are called on the main thread. If the embedder application
- * wants to receive the messages on a different thread, it can do this
- * by passing a Handler in
- * {@link WebMessagePortCompat#setWebMessageCallback(Handler, WebMessageCallbackCompat)}.
- * In the latter case, the application should be extra careful for thread safety
- * since WebMessagePort methods should be called on main thread.
- */
- public abstract static class WebMessageCallbackCompat {
- /**
- * Message callback for receiving onMessage events.
- *
- * @param port the WebMessagePort that the message is destined for
- * @param message the message from the entangled port.
- */
- public void onMessage(@NonNull WebMessagePortCompat port,
- @Nullable WebMessageCompat message) { }
- }
-
- /**
- * @hide disallow app devs to extend this class.
- */
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- public WebMessagePortCompat() { }
-
- /**
- * Post a WebMessage to the entangled port.
- *
- * @param message the message from Java to JS.
- *
- * @throws IllegalStateException If message port is already transferred or closed.
- */
- public abstract void postMessage(@NonNull WebMessageCompat message);
-
- /**
- * Close the message port and free any resources associated with it.
- */
- public abstract void close();
-
- /**
- * Sets a callback to receive message events on the main thread.
- *
- * @param callback the message callback.
- */
- public abstract void setWebMessageCallback(@NonNull WebMessageCallbackCompat callback);
-
- /**
- * Sets a callback to receive message events on the handler that is provided
- * by the application. If the handler is null the message events are received on the main
- * thread.
- *
- * @param handler the handler to receive the message events.
- * @param callback the message callback.
- */
- public abstract void setWebMessageCallback(@Nullable Handler handler,
- @NonNull WebMessageCallbackCompat callback);
-
- /**
- * Internal getter returning the private {@link WebMessagePort} implementing this class.
- * @hide
- */
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- public abstract WebMessagePort getFrameworkPort();
-}
diff --git a/webkit/src/main/java/androidx/webkit/WebResourceErrorCompat.java b/webkit/src/main/java/androidx/webkit/WebResourceErrorCompat.java
deleted file mode 100644
index 3d8b99a..0000000
--- a/webkit/src/main/java/androidx/webkit/WebResourceErrorCompat.java
+++ /dev/null
@@ -1,85 +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;
-
-import android.webkit.WebResourceError;
-import android.webkit.WebViewClient;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresFeature;
-import androidx.annotation.RestrictTo;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * 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
- */
- @RequiresFeature(name = WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
- 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
- @RequiresFeature(name = WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION,
- enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
- public abstract CharSequence getDescription();
-
- /**
- * This class cannot be created by applications.
- * @hide
- */
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- public WebResourceErrorCompat() {
- }
-}
diff --git a/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java b/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java
deleted file mode 100644
index 783efca..0000000
--- a/webkit/src/main/java/androidx/webkit/WebResourceRequestCompat.java
+++ /dev/null
@@ -1,60 +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;
-
-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 bff6170..12d7e63 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.annotation.SuppressLint;
+import android.os.Build;
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,18 +50,11 @@
* 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) {
- WebViewFeatureInternal webviewFeature =
- WebViewFeatureInternal.getFeature(WebViewFeature.OFF_SCREEN_PRERASTER);
- if (webviewFeature.isSupportedByFramework()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
webSettings.setOffscreenPreRaster(enabled);
- } else if (webviewFeature.isSupportedByWebView()) {
- getAdapter(webSettings).setOffscreenPreRaster(enabled);
} else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
+ getAdapter(webSettings).setOffscreenPreRaster(enabled);
}
}
@@ -71,18 +64,11 @@
* @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) {
- WebViewFeatureInternal webviewFeature =
- WebViewFeatureInternal.getFeature(WebViewFeature.OFF_SCREEN_PRERASTER);
- if (webviewFeature.isSupportedByFramework()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return webSettings.getOffscreenPreRaster();
- } else if (webviewFeature.isSupportedByWebView()) {
- return getAdapter(webSettings).getOffscreenPreRaster();
} else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
+ return getAdapter(webSettings).getOffscreenPreRaster();
}
}
@@ -100,18 +86,11 @@
*
* @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) {
- WebViewFeatureInternal webviewFeature =
- WebViewFeatureInternal.getFeature(WebViewFeature.SAFE_BROWSING_ENABLE);
- if (webviewFeature.isSupportedByFramework()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
webSettings.setSafeBrowsingEnabled(enabled);
- } else if (webviewFeature.isSupportedByWebView()) {
- getAdapter(webSettings).setSafeBrowsingEnabled(enabled);
} else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
+ getAdapter(webSettings).setSafeBrowsingEnabled(enabled);
}
}
@@ -121,18 +100,11 @@
*
* @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) {
- WebViewFeatureInternal webviewFeature =
- WebViewFeatureInternal.getFeature(WebViewFeature.SAFE_BROWSING_ENABLE);
- if (webviewFeature.isSupportedByFramework()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return webSettings.getSafeBrowsingEnabled();
- } else if (webviewFeature.isSupportedByWebView()) {
- return getAdapter(webSettings).getSafeBrowsingEnabled();
} else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
+ return getAdapter(webSettings).getSafeBrowsingEnabled();
}
}
@@ -154,19 +126,12 @@
* 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) {
- WebViewFeatureInternal webviewFeature =
- WebViewFeatureInternal.getFeature(WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS);
- if (webviewFeature.isSupportedByFramework()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
webSettings.setDisabledActionModeMenuItems(menuItems);
- } else if (webviewFeature.isSupportedByWebView()) {
- getAdapter(webSettings).setDisabledActionModeMenuItems(menuItems);
} else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
+ getAdapter(webSettings).setDisabledActionModeMenuItems(menuItems);
}
}
@@ -176,18 +141,11 @@
*
* @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) {
- WebViewFeatureInternal webviewFeature =
- WebViewFeatureInternal.getFeature(WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS);
- if (webviewFeature.isSupportedByFramework()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return webSettings.getDisabledActionModeMenuItems();
- } else if (webviewFeature.isSupportedByWebView()) {
- return getAdapter(webSettings).getDisabledActionModeMenuItems();
} else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
+ return getAdapter(webSettings).getDisabledActionModeMenuItems();
}
}
diff --git a/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java b/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java
index 3dcfcc5..8c690f9 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java
@@ -17,8 +17,6 @@
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,11 +26,8 @@
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
-import androidx.webkit.internal.WebResourceErrorImpl;
-import androidx.webkit.internal.WebViewFeatureInternal;
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;
@@ -46,14 +41,6 @@
// 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 = {
@@ -65,141 +52,33 @@
@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 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.
+ * 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.
*
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@Override
- @RequiresApi(21)
public final void onReceivedError(@NonNull WebView view, @NonNull WebResourceRequest request,
- /* WebResourceError */ @NonNull InvocationHandler handler) {
- onReceivedError(view, request, new WebResourceErrorImpl(handler));
+ /* WebResourceError */ @NonNull InvocationHandler error) {
+ // TODO(ntfschr): implement this (b/73151460).
}
- /**
- * 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, new WebResourceErrorImpl(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 (!WebViewFeature.isFeatureSupported(WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE)
- || !WebViewFeature.isFeatureSupported(
- WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION)) {
- // If the WebView APK drops supports for these APIs in the future, simply do nothing.
- 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 >= 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 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.
+ * 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.
*
* @hide
*/
@@ -207,85 +86,14 @@
@Override
public final void onSafeBrowsingHit(@NonNull WebView view, @NonNull WebResourceRequest request,
@SafeBrowsingThreat int threatType,
- /* SafeBrowsingResponse */ @NonNull InvocationHandler handler) {
- onSafeBrowsingHit(view, request, threatType,
- SafeBrowsingResponseCompat.fromInvocationHandler(handler));
+ /* SafeBrowsingResponse */ @NonNull InvocationHandler callback) {
+ // TODO(ntfschr): implement this (b/73151460).
}
- /**
- * 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)
+ // Default behavior in WebViewClient is to invoke the other (deprecated)
+ // shouldOverrideUrlLoading method.
@Override
- @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) {
- if (WebViewFeature.isFeatureSupported(
- WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL)) {
- callback.showInterstitial(true);
- } else {
- // This should not happen, but in case the WebView APK eventually drops support for
- // showInterstitial(), raise a runtime exception and require the WebView APK to handle
- // this.
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- }
-
- /**
- * 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 "method".</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.
+ @SuppressWarnings("deprecation")
@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 1172997..88de335 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewCompat.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewCompat.java
@@ -16,7 +16,6 @@
package androidx.webkit;
-import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -30,11 +29,10 @@
import androidx.annotation.Nullable;
import androidx.annotation.RequiresFeature;
import androidx.core.os.BuildCompat;
-import androidx.webkit.internal.WebMessagePortImpl;
import androidx.webkit.internal.WebViewFeatureInternal;
import androidx.webkit.internal.WebViewGlueCommunicator;
import androidx.webkit.internal.WebViewProviderAdapter;
-import androidx.webkit.internal.WebViewProviderFactory;
+import androidx.webkit.internal.WebViewProviderFactoryAdapter;
import org.chromium.support_lib_boundary.WebViewProviderBoundaryInterface;
@@ -46,9 +44,6 @@
* Compatibility version of {@link android.webkit.WebView}
*/
public class WebViewCompat {
- private static final Uri WILDCARD_URI = Uri.parse("*");
- private static final Uri EMPTY_URI = Uri.parse("");
-
private WebViewCompat() {} // Don't allow instances of this class to be constructed.
/**
@@ -140,7 +135,7 @@
checkThread(webview);
getProvider(webview).insertVisualStateCallback(requestId, callback);
} else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
+ WebViewFeatureInternal.throwUnsupportedOperationException("postVisualStateCallback");
}
}
@@ -162,19 +157,12 @@
* @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) {
- WebViewFeatureInternal webviewFeature =
- WebViewFeatureInternal.getFeature(WebViewFeature.START_SAFE_BROWSING);
- if (webviewFeature.isSupportedByFramework()) {
+ if (Build.VERSION.SDK_INT >= 27) {
WebView.startSafeBrowsing(context, callback);
- } else if (webviewFeature.isSupportedByWebView()) {
+ } else { // TODO(gsennton): guard with WebViewApk.hasFeature(SafeBrowsing)
getFactory().getStatics().initSafeBrowsing(context, callback);
- } else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
}
}
@@ -201,19 +189,12 @@
* 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) {
- WebViewFeatureInternal webviewFeature =
- WebViewFeatureInternal.getFeature(WebViewFeature.SAFE_BROWSING_WHITELIST);
- if (webviewFeature.isSupportedByFramework()) {
+ if (Build.VERSION.SDK_INT >= 27) {
WebView.setSafeBrowsingWhitelist(hosts, callback);
- } else if (webviewFeature.isSupportedByWebView()) {
+ } else { // TODO(gsennton): guard with WebViewApk.hasFeature(SafeBrowsing)
getFactory().getStatics().setSafeBrowsingWhitelist(hosts, callback);
- } else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
}
}
@@ -222,19 +203,12 @@
*
* @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() {
- WebViewFeatureInternal webviewFeature =
- WebViewFeatureInternal.getFeature(WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL);
- if (webviewFeature.isSupportedByFramework()) {
+ if (Build.VERSION.SDK_INT >= 27) {
return WebView.getSafeBrowsingPrivacyPolicyUrl();
- } else if (webviewFeature.isSupportedByWebView()) {
+ } else { // TODO(gsennton): guard with WebViewApk.hasFeature(SafeBrowsing)
return getFactory().getStatics().getSafeBrowsingPrivacyPolicyUrl();
- } else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
}
}
@@ -284,7 +258,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);
@@ -300,13 +274,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);
@@ -333,58 +307,7 @@
return new WebViewProviderAdapter(createProvider(webview));
}
- /**
- * Creates a message channel to communicate with JS and returns the message
- * ports that represent the endpoints of this message channel. The HTML5 message
- * channel functionality is described
- * <a href="https://html.spec.whatwg.org/multipage/comms.html#messagechannel">here
- * </a>
- *
- * <p>The returned message channels are entangled and already in started state.
- *
- * @return an array of size two, containing the two message ports that form the message channel.
- */
- public static @NonNull WebMessagePortCompat[] createWebMessageChannel(
- @NonNull WebView webview) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- return WebMessagePortImpl.portsToCompat(webview.createWebMessageChannel());
- } else { // TODO(gsennton) add reflection-based implementation
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- }
-
- /**
- * Post a message to main frame. The embedded application can restrict the
- * messages to a certain target origin. See
- * <a href="https://html.spec.whatwg.org/multipage/comms.html#posting-messages">
- * HTML5 spec</a> for how target origin can be used.
- * <p>
- * A target origin can be set as a wildcard ("*"). However this is not recommended.
- * See the page above for security issues.
- *
- * @param message the WebMessage
- * @param targetOrigin the target origin.
- */
- public static void postWebMessage(@NonNull WebView webview, @NonNull WebMessageCompat message,
- @NonNull Uri targetOrigin) {
- // The wildcard ("*") Uri was first supported in WebView 60, see
- // crrev/5ec5b67cbab33cea51b0ee11a286c885c2de4d5d, so on some Android versions using "*"
- // won't work. WebView has always supported using an empty Uri "" as a wildcard - so convert
- // "*" into "" here.
- if (WILDCARD_URI.equals(targetOrigin)) {
- targetOrigin = EMPTY_URI;
- }
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- webview.postWebMessage(
- WebMessagePortImpl.compatToFrameworkMessage(message),
- targetOrigin);
- } else { // TODO(gsennton) add reflection-based implementation
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- }
-
- private static WebViewProviderFactory getFactory() {
+ private static WebViewProviderFactoryAdapter getFactory() {
return WebViewGlueCommunicator.getFactory();
}
@@ -399,7 +322,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.getWebViewLooper() + " called on "
+ + "(Expected Looper " + webview.getLooper() + " 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 e750295..d514477 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewFeature.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewFeature.java
@@ -16,11 +16,6 @@
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;
@@ -32,7 +27,6 @@
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.
@@ -47,28 +41,6 @@
@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,
- WEB_RESOURCE_ERROR_GET_DESCRIPTION,
- WEB_RESOURCE_ERROR_GET_CODE,
- SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY,
- SAFE_BROWSING_RESPONSE_PROCEED,
- SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL
})
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.PARAMETER, ElementType.METHOD})
@@ -78,190 +50,11 @@
* Feature for {@link #isFeatureSupported(String)}.
* This feature covers
* {@link androidx.webkit.WebViewCompat#postVisualStateCallback(android.webkit.WebView, long,
- * WebViewCompat.VisualStateCallback)}, and {@link
- * WebViewClientCompat#onPageCommitVisible(
- * android.webkit.WebView, String)}.
+ * WebViewCompat.VisualStateCallback)}.
*/
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;
-
- /**
- * Feature for {@link #isFeatureSupported(String)}.
- * This feature covers
- * {@link WebResourceErrorCompat#getDescription()}.
- */
- public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION =
- Features.WEB_RESOURCE_ERROR_GET_DESCRIPTION;
-
- /**
- * Feature for {@link #isFeatureSupported(String)}.
- * This feature covers
- * {@link WebResourceErrorCompat#getErrorCode()}.
- */
- public static final String WEB_RESOURCE_ERROR_GET_CODE =
- Features.WEB_RESOURCE_ERROR_GET_CODE;
-
- /**
- * Feature for {@link #isFeatureSupported(String)}.
- * This feature covers
- * {@link SafeBrowsingResponseCompat#backToSafety(boolean)}.
- */
- public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY =
- Features.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY;
-
- /**
- * Feature for {@link #isFeatureSupported(String)}.
- * This feature covers
- * {@link SafeBrowsingResponseCompat#proceed(boolean)}.
- */
- public static final String SAFE_BROWSING_RESPONSE_PROCEED =
- Features.SAFE_BROWSING_RESPONSE_PROCEED;
-
- /**
- * Feature for {@link #isFeatureSupported(String)}.
- * This feature covers
- * {@link SafeBrowsingResponseCompat#showInterstitial(boolean)}.
- */
- public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL =
- Features.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL;
-
- /**
* 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
new file mode 100644
index 0000000..2e02777
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/FrameworkServiceWorkerController.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.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
new file mode 100644
index 0000000..4373756
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/FrameworksServiceWorkerWebSettings.java
@@ -0,0 +1,77 @@
+/*
+ * 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
deleted file mode 100644
index 71d5768..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/IncompatibleApkWebViewProviderFactory.java
+++ /dev/null
@@ -1,62 +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.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 f96bbd1..3ffeb83 100644
--- a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerClientAdapter.java
+++ b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerClientAdapter.java
@@ -22,7 +22,6 @@
import androidx.webkit.ServiceWorkerClientCompat;
import org.chromium.support_lib_boundary.ServiceWorkerClientBoundaryInterface;
-import org.chromium.support_lib_boundary.util.Features;
/**
* Adapter between {@link ServiceWorkerClientCompat} and
@@ -40,9 +39,4 @@
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
new file mode 100644
index 0000000..4baa3ea
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerControllerAdapter.java
@@ -0,0 +1,54 @@
+/*
+ * 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
deleted file mode 100644
index 3787a92..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerControllerImpl.java
+++ /dev/null
@@ -1,94 +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.annotation.SuppressLint;
-import android.webkit.ServiceWorkerController;
-
-import androidx.annotation.RequiresApi;
-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.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 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());
- } else if (feature.isSupportedByWebView()) {
- mFrameworksImpl = null;
- mBoundaryInterface = WebViewGlueCommunicator.getFactory().getServiceWorkerController();
- mWebSettings = new ServiceWorkerWebSettingsImpl(
- mBoundaryInterface.getServiceWorkerWebSettings());
- } else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- }
-
- @RequiresApi(24)
- private ServiceWorkerController getFrameworksImpl() {
- if (mFrameworksImpl == null) {
- mFrameworksImpl = ServiceWorkerController.getInstance();
- }
- return mFrameworksImpl;
- }
-
- private ServiceWorkerControllerBoundaryInterface getBoundaryInterface() {
- if (mBoundaryInterface == null) {
- 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()) {
- getFrameworksImpl().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
new file mode 100644
index 0000000..fd49396
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerWebSettingsAdapter.java
@@ -0,0 +1,74 @@
+/*
+ * 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
deleted file mode 100644
index cad3ccb..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/ServiceWorkerWebSettingsImpl.java
+++ /dev/null
@@ -1,195 +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.annotation.SuppressLint;
-import android.webkit.ServiceWorkerWebSettings;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.webkit.ServiceWorkerWebSettingsCompat;
-
-import org.chromium.support_lib_boundary.ServiceWorkerWebSettingsBoundaryInterface;
-import org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-
-/**
- * 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 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(@NonNull ServiceWorkerWebSettings settings) {
- mFrameworksImpl = settings;
- }
-
- public ServiceWorkerWebSettingsImpl(@NonNull InvocationHandler invocationHandler) {
- mBoundaryInterface = BoundaryInterfaceReflectionUtil.castToSuppLibClass(
- ServiceWorkerWebSettingsBoundaryInterface.class, invocationHandler);
- }
-
- @RequiresApi(24)
- private ServiceWorkerWebSettings getFrameworksImpl() {
- if (mFrameworksImpl == null) {
- mFrameworksImpl =
- WebViewGlueCommunicator.getCompatConverter().convertServiceWorkerSettings(
- Proxy.getInvocationHandler(mBoundaryInterface));
- }
- return mFrameworksImpl;
- }
-
- private ServiceWorkerWebSettingsBoundaryInterface getBoundaryInterface() {
- if (mBoundaryInterface == null) {
- // If the boundary interface is null we must have a working frameworks implementation to
- // convert into a boundary interface.
- // The case of the boundary interface being null here only occurs if we created the
- // ServiceWorkerWebSettingsImpl using a frameworks API, but now want to call an API on
- // the ServiceWorkerWebSettingsImpl that is only supported by the support library glue.
- // This could happen for example if we introduce a new ServiceWorkerWebSettings API in
- // level 30 and we run the support library on an N device (whose framework supports
- // ServiceWorkerWebSettings).
- mBoundaryInterface = BoundaryInterfaceReflectionUtil.castToSuppLibClass(
- ServiceWorkerWebSettingsBoundaryInterface.class,
- 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()) {
- getFrameworksImpl().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 getFrameworksImpl().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()) {
- getFrameworksImpl().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 getFrameworksImpl().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()) {
- getFrameworksImpl().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 getFrameworksImpl().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()) {
- getFrameworksImpl().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 getFrameworksImpl().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
new file mode 100644
index 0000000..da8a02c
--- /dev/null
+++ b/webkit/src/main/java/androidx/webkit/internal/SupportLibraryInfo.java
@@ -0,0 +1,38 @@
+/*
+ * 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/WebMessagePortImpl.java b/webkit/src/main/java/androidx/webkit/internal/WebMessagePortImpl.java
deleted file mode 100644
index 2de5105..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/WebMessagePortImpl.java
+++ /dev/null
@@ -1,145 +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.annotation.SuppressLint;
-import android.os.Build;
-import android.os.Handler;
-import android.webkit.WebMessage;
-import android.webkit.WebMessagePort;
-
-import androidx.annotation.RequiresApi;
-import androidx.webkit.WebMessageCompat;
-import androidx.webkit.WebMessagePortCompat;
-
-/**
- * Implementation of {@link WebMessagePortCompat}.
- * This class uses either the framework, the WebView APK, or both, to implement
- * {@link WebMessagePortCompat} functionality.
- */
-public class WebMessagePortImpl extends WebMessagePortCompat {
- private final WebMessagePort mFrameworksImpl;
- // TODO(gsennton) add WebMessagePortBoundaryInterface variable
-
- public WebMessagePortImpl(WebMessagePort frameworksImpl) {
- mFrameworksImpl = frameworksImpl;
- }
-
- @SuppressLint("NewApi")
- @Override
- public void postMessage(WebMessageCompat message) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mFrameworksImpl.postMessage(compatToFrameworkMessage(message));
- } else { // TODO(gsennton) add reflection-based implementation
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- }
-
- @SuppressLint("NewApi")
- @Override
- public void close() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mFrameworksImpl.close();
- } else { // TODO(gsennton) add reflection-based implementation
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- }
-
- @Override
- public void setWebMessageCallback(final WebMessageCallbackCompat callback) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mFrameworksImpl.setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
- @Override
- @SuppressWarnings("NewApi")
- public void onMessage(WebMessagePort port, WebMessage message) {
- callback.onMessage(new WebMessagePortImpl(port),
- frameworkMessageToCompat(message));
- }
- });
- } else { // TODO(gsennton) add reflection-based implementation
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- }
-
- @Override
- public void setWebMessageCallback(Handler handler, final WebMessageCallbackCompat callback) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mFrameworksImpl.setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
- @Override
- @SuppressWarnings("NewApi")
- public void onMessage(WebMessagePort port, WebMessage message) {
- callback.onMessage(new WebMessagePortImpl(port),
- frameworkMessageToCompat(message));
- }
- }, handler);
- } else { // TODO(gsennton) add reflection-based implementation
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- }
-
- @Override
- public WebMessagePort getFrameworkPort() {
- return mFrameworksImpl;
- }
-
- /**
- * Convert an array of {@link WebMessagePort} objects into an array containing objects of the
- * corresponding support library class {@link WebMessagePortCompat}.
- */
- public static WebMessagePortCompat[] portsToCompat(WebMessagePort[] ports) {
- if (ports == null) return null;
- WebMessagePortCompat[] compatPorts = new WebMessagePortCompat[ports.length];
- for (int n = 0; n < ports.length; n++) {
- compatPorts[n] = new WebMessagePortImpl(ports[n]);
- }
- return compatPorts;
- }
-
- /**
- * Convert an array of {@link WebMessagePortCompat} objects into an array containing objects of
- * the corresponding framework class {@link WebMessagePort}.
- */
- public static WebMessagePort[] compatToPorts(WebMessagePortCompat[] compatPorts) {
- if (compatPorts == null) return null;
- WebMessagePort[] ports = new WebMessagePort[compatPorts.length];
- for (int n = 0; n < ports.length; n++) {
- ports[n] = compatPorts[n].getFrameworkPort();
- }
- return ports;
- }
-
- /**
- * Convert a {@link WebMessageCompat} into the corresponding framework class {@link WebMessage}.
- */
- @RequiresApi(23)
- public static WebMessage compatToFrameworkMessage(WebMessageCompat message) {
- return new WebMessage(
- message.getData(),
- compatToPorts(message.getPorts()));
- }
-
- /**
- * Convert a {@link WebMessage} into the corresponding support library class
- * {@link WebMessageCompat}.
- */
- @RequiresApi(23)
- public static WebMessageCompat frameworkMessageToCompat(WebMessage message) {
- return new WebMessageCompat(
- message.getData(),
- portsToCompat(message.getPorts()));
- }
-}
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebResourceErrorImpl.java b/webkit/src/main/java/androidx/webkit/internal/WebResourceErrorImpl.java
deleted file mode 100644
index a27f61c..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/WebResourceErrorImpl.java
+++ /dev/null
@@ -1,106 +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.annotation.SuppressLint;
-import android.webkit.WebResourceError;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.webkit.WebResourceErrorCompat;
-import androidx.webkit.WebViewFeature;
-
-import org.chromium.support_lib_boundary.WebResourceErrorBoundaryInterface;
-import org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-
-/**
- * Implementation of {@link WebResourceErrorCompat}.
- * This class uses either the framework, the WebView APK, or both, to implement
- * {@link WebResourceErrorCompat} functionality.
- *
- */
-public class WebResourceErrorImpl extends WebResourceErrorCompat {
- /**
- * Frameworks implementation - do not use this directly, instead use
- * {@link #getFrameworksImpl()} to ensure this variable has been instantiated correctly.
- */
- private WebResourceError mFrameworksImpl;
-
- /**
- * Support library glue implementation - do not use this directly, instead use
- * {@link #getBoundaryInterface()} to ensure this variable has been instantiated correctly.
- */
- private WebResourceErrorBoundaryInterface mBoundaryInterface;
-
- public WebResourceErrorImpl(@NonNull InvocationHandler invocationHandler) {
- mBoundaryInterface = BoundaryInterfaceReflectionUtil.castToSuppLibClass(
- WebResourceErrorBoundaryInterface.class, invocationHandler);
- }
-
- public WebResourceErrorImpl(@NonNull WebResourceError error) {
- mFrameworksImpl = error;
- }
-
- @RequiresApi(23)
- private WebResourceError getFrameworksImpl() {
- if (mFrameworksImpl == null) {
- mFrameworksImpl = WebViewGlueCommunicator.getCompatConverter().convertWebResourceError(
- Proxy.getInvocationHandler(mBoundaryInterface));
- }
- return mFrameworksImpl;
- }
-
- private WebResourceErrorBoundaryInterface getBoundaryInterface() {
- if (mBoundaryInterface == null) {
- mBoundaryInterface = BoundaryInterfaceReflectionUtil.castToSuppLibClass(
- WebResourceErrorBoundaryInterface.class,
- WebViewGlueCommunicator.getCompatConverter().convertWebResourceError(
- mFrameworksImpl));
- }
- return mBoundaryInterface;
- }
-
- @SuppressLint("NewApi")
- @Override
- public int getErrorCode() {
- final WebViewFeatureInternal feature =
- WebViewFeatureInternal.getFeature(WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE);
- if (feature.isSupportedByFramework()) {
- return getFrameworksImpl().getErrorCode();
- } else if (feature.isSupportedByWebView()) {
- return getBoundaryInterface().getErrorCode();
- } else {
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
- }
-
- @SuppressLint("NewApi")
- @Override
- public CharSequence getDescription() {
- final WebViewFeatureInternal feature = WebViewFeatureInternal.getFeature(
- WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION);
- if (feature.isSupportedByFramework()) {
- return getFrameworksImpl().getDescription();
- } else if (feature.isSupportedByWebView()) {
- return getBoundaryInterface().getDescription();
- }
- throw WebViewFeatureInternal.getUnsupportedOperationException();
- }
-}
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebResourceRequestAdapter.java b/webkit/src/main/java/androidx/webkit/internal/WebResourceRequestAdapter.java
deleted file mode 100644
index 0d6a05d..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/WebResourceRequestAdapter.java
+++ /dev/null
@@ -1,41 +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.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 916da9d..d16713c 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
@@ -16,21 +16,11 @@
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.
@@ -39,166 +29,9 @@
/**
* This feature covers
* {@link androidx.webkit.WebViewCompat#postVisualStateCallback(android.webkit.WebView, long,
- * androidx.webkit.WebViewCompat.VisualStateCallback)}, and
- * {@link WebViewClientCompat#onPageCommitVisible(android.webkit.WebView, String)}.
+ * androidx.webkit.WebViewCompat.VisualStateCallback)}.
*/
- 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),
-
- /**
- * This feature covers
- * {@link WebResourceErrorCompat#getDescription()}.
- */
- WEB_RESOURCE_ERROR_GET_DESCRIPTION(WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION,
- Build.VERSION_CODES.M),
-
- /**
- * This feature covers
- * {@link WebResourceErrorCompat#getErrorCode()}.
- */
- WEB_RESOURCE_ERROR_GET_CODE(WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE,
- Build.VERSION_CODES.M),
-
- /**
- * This feature covers
- * {@link SafeBrowsingResponseCompat#backToSafety(boolean)}.
- */
- SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY(WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY,
- Build.VERSION_CODES.O_MR1),
-
- /**
- * This feature covers
- * {@link SafeBrowsingResponseCompat#proceed(boolean)}.
- */
- SAFE_BROWSING_RESPONSE_PROCEED(WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED,
- Build.VERSION_CODES.O_MR1),
-
- /**
- * This feature covers
- * {@link SafeBrowsingResponseCompat#showInterstitial(boolean)}.
- */
- SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL(
- WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL,
- Build.VERSION_CODES.O_MR1);
+ VISUAL_STATE_CALLBACK_FEATURE(WebViewFeature.VISUAL_STATE_CALLBACK, Build.VERSION_CODES.M);
private final String mFeatureValue;
private final int mOsVersion;
@@ -212,10 +45,12 @@
* Return the {@link WebViewFeatureInternal} corresponding to {@param feature}.
*/
public static WebViewFeatureInternal getFeature(@WebViewSupportFeature String feature) {
- for (WebViewFeatureInternal internalFeature : WebViewFeatureInternal.values()) {
- if (internalFeature.mFeatureValue.equals(feature)) return internalFeature;
+ switch (feature) {
+ case WebViewFeature.VISUAL_STATE_CALLBACK:
+ return VISUAL_STATE_CALLBACK_FEATURE;
+ default:
+ throw new RuntimeException("Unknown feature " + feature);
}
- throw new RuntimeException("Unknown feature " + feature);
}
/**
@@ -242,17 +77,12 @@
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 UnsupportedOperationException getUnsupportedOperationException() {
- return new UnsupportedOperationException("This method is not supported by the current "
- + "version of the framework and the current WebView APK");
+ public static void throwUnsupportedOperationException(String feature) {
+ throw new UnsupportedOperationException("Feature " + feature
+ + " is not supported by the current version of the framework and 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 ea4460f..33ac145 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebViewGlueCommunicator.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebViewGlueCommunicator.java
@@ -16,7 +16,6 @@
package androidx.webkit.internal;
-import android.os.Build;
import android.webkit.WebView;
import androidx.core.os.BuildCompat;
@@ -40,57 +39,49 @@
/**
* Fetch the one global support library WebViewProviderFactory from the WebView glue layer.
*/
- public static WebViewProviderFactory getFactory() {
+ public static WebViewProviderFactoryAdapter getFactory() {
return LAZY_FACTORY_HOLDER.INSTANCE;
}
public static WebkitToCompatConverter getCompatConverter() {
- return LAZY_COMPAT_CONVERTER_HOLDER.INSTANCE;
+ return LAZY_FACTORY_HOLDER.COMPAT_CONVERTER;
}
private static class LAZY_FACTORY_HOLDER {
- private static final WebViewProviderFactory INSTANCE =
- WebViewGlueCommunicator.createGlueProviderFactory();
+ static final WebViewProviderFactoryAdapter INSTANCE =
+ new WebViewProviderFactoryAdapter(
+ WebViewGlueCommunicator.createGlueProviderFactory());
+ static final WebkitToCompatConverter COMPAT_CONVERTER =
+ new WebkitToCompatConverter(
+ INSTANCE.getWebkitToCompatConverter());
}
- 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() {
- // We do not support pre-L devices since their WebView APKs cannot be updated.
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
- return new IncompatibleApkWebViewProviderFactory();
- }
- InvocationHandler invocationHandler;
+ private static InvocationHandler fetchGlueProviderFactoryImpl() {
try {
- 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.
+ 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()));
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException 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();
+ throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
- return new WebViewProviderFactoryAdapter(BoundaryInterfaceReflectionUtil.castToSuppLibClass(
- WebViewProviderFactoryBoundaryInterface.class, invocationHandler));
+ // 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);
}
/**
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactory.java b/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactory.java
deleted file mode 100644
index 5e4669a..0000000
--- a/webkit/src/main/java/androidx/webkit/internal/WebViewProviderFactory.java
+++ /dev/null
@@ -1,60 +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.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 43e5eae..efe0e64 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 implements WebViewProviderFactory {
+public class WebViewProviderFactoryAdapter {
WebViewProviderFactoryBoundaryInterface mImpl;
public WebViewProviderFactoryAdapter(WebViewProviderFactoryBoundaryInterface impl) {
@@ -41,7 +41,6 @@
* {@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));
@@ -52,7 +51,6 @@
* {@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());
@@ -62,7 +60,6 @@
* 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());
@@ -71,7 +68,6 @@
/**
* Adapter method for fetching the features supported by the current WebView APK.
*/
- @Override
public String[] getWebViewFeatures() {
return mImpl.getSupportedFeatures();
}
@@ -80,7 +76,6 @@
* 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 2e18bb9..a07cf07 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebkitToCompatConverter.java
@@ -16,22 +16,12 @@
package androidx.webkit.internal;
-import android.webkit.ServiceWorkerWebSettings;
-import android.webkit.WebResourceError;
-import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
-import androidx.annotation.RequiresApi;
-import androidx.webkit.WebResourceErrorCompat;
-
-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;
-import java.lang.reflect.InvocationHandler;
-
/**
* A class providing functionality for converting android.webkit classes into support library
* classes.
@@ -52,55 +42,4 @@
return new WebSettingsAdapter(BoundaryInterfaceReflectionUtil.castToSuppLibClass(
WebSettingsBoundaryInterface.class, mImpl.convertSettings(webSettings)));
}
-
- /**
- * 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)));
- }
-
- /**
- * Return a {@link ServiceWorkerWebSettingsBoundaryInterface} linked to the given
- * {@link ServiceWorkerWebSettings} such that calls on either of those objects affect the other
- * object.
- */
- public InvocationHandler convertServiceWorkerSettings(
- ServiceWorkerWebSettings settings) {
- return mImpl.convertServiceWorkerSettings(settings);
- }
-
- /**
- * Convert from an {@link InvocationHandler} representing an
- * {@link androidx.webkit.ServiceWorkerWebSettingsCompat} into a
- * {@link ServiceWorkerWebSettings}.
- */
- @RequiresApi(24)
- public ServiceWorkerWebSettings convertServiceWorkerSettings(
- /* SupportLibServiceWorkerSettings */ InvocationHandler serviceWorkerSettings) {
- return (ServiceWorkerWebSettings) mImpl.convertServiceWorkerSettings(serviceWorkerSettings);
- }
-
- /**
- * Return a {@link InvocationHandler} linked to the given
- * {@link WebResourceError}such that calls on either of those objects affect the other
- * object.
- */
- InvocationHandler convertWebResourceError(WebResourceError webResourceError) {
- return mImpl.convertWebResourceError(webResourceError);
- }
-
-
- /**
- * Convert from an {@link InvocationHandler} representing a {@link WebResourceErrorCompat} into
- * a {@link WebResourceError}.
- */
- @RequiresApi(23)
- WebResourceError convertWebResourceError(
- /* SupportLibWebResourceError */ InvocationHandler webResourceError) {
- return (WebResourceError) mImpl.convertWebResourceError(webResourceError);
- }
}