am 60d5509d: Merge "Tidy up styling and tinting in NavigationView" into lmp-mr1-ub-dev
* commit '60d5509d4ce055532645a889d29f4201e6bc4512':
Tidy up styling and tinting in NavigationView
diff --git a/.gitignore b/.gitignore
index 08a55c0..dbc32d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,7 @@
+.classpath
.gradle
+.project
+.settings/
+project.properties
+**/bin
+**/gen
diff --git a/annotations/src/android/support/annotation/AnimRes.java b/annotations/src/android/support/annotation/AnimRes.java
index d613ba9..906461b 100644
--- a/annotations/src/android/support/annotation/AnimRes.java
+++ b/annotations/src/android/support/annotation/AnimRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be an anim resource reference (e.g. {@link android.R.anim#fade_in}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface AnimRes {
}
diff --git a/annotations/src/android/support/annotation/AnimatorRes.java b/annotations/src/android/support/annotation/AnimatorRes.java
index b7843c0..4681236 100644
--- a/annotations/src/android/support/annotation/AnimatorRes.java
+++ b/annotations/src/android/support/annotation/AnimatorRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be an animator resource reference (e.g. {@link android.R.animator#fade_in}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface AnimatorRes {
}
diff --git a/annotations/src/android/support/annotation/AnyRes.java b/annotations/src/android/support/annotation/AnyRes.java
index 50f9e27..e831289 100644
--- a/annotations/src/android/support/annotation/AnyRes.java
+++ b/annotations/src/android/support/annotation/AnyRes.java
@@ -20,9 +20,10 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
@@ -31,7 +32,7 @@
* {@link DrawableRes}.
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface AnyRes {
}
diff --git a/annotations/src/android/support/annotation/ArrayRes.java b/annotations/src/android/support/annotation/ArrayRes.java
index 0fb4fdb..347de36 100644
--- a/annotations/src/android/support/annotation/ArrayRes.java
+++ b/annotations/src/android/support/annotation/ArrayRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be an array resource reference (e.g. {@link android.R.array#phoneTypes}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface ArrayRes {
}
diff --git a/annotations/src/android/support/annotation/AttrRes.java b/annotations/src/android/support/annotation/AttrRes.java
index 2902597..7ba1f0d 100644
--- a/annotations/src/android/support/annotation/AttrRes.java
+++ b/annotations/src/android/support/annotation/AttrRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be an attribute reference (e.g. {@link android.R.attr#action}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface AttrRes {
}
diff --git a/annotations/src/android/support/annotation/BinderThread.java b/annotations/src/android/support/annotation/BinderThread.java
new file mode 100644
index 0000000..4bb6754
--- /dev/null
+++ b/annotations/src/android/support/annotation/BinderThread.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * 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() { ... }
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({METHOD,CONSTRUCTOR,TYPE})
+public @interface BinderThread {
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/BoolRes.java b/annotations/src/android/support/annotation/BoolRes.java
index 32cb4d1..bef8071 100644
--- a/annotations/src/android/support/annotation/BoolRes.java
+++ b/annotations/src/android/support/annotation/BoolRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a boolean resource reference.
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface BoolRes {
}
diff --git a/annotations/src/android/support/annotation/CallSuper.java b/annotations/src/android/support/annotation/CallSuper.java
new file mode 100644
index 0000000..7180417
--- /dev/null
+++ b/annotations/src/android/support/annotation/CallSuper.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that any overriding methods should invoke this method as well.
+ * <p>
+ * Example:
+ * <pre>{@code
+ * @CallSuper
+ * public abstract void onFocusLost();
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({METHOD})
+public @interface CallSuper {
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/CheckResult.java b/annotations/src/android/support/annotation/CheckResult.java
new file mode 100644
index 0000000..d527edc
--- /dev/null
+++ b/annotations/src/android/support/annotation/CheckResult.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated method returns a result that it typically is
+ * an error to ignore. This is usually used for methods that have no side effect,
+ * so calling it without actually looking at the result usually means the developer
+ * has misunderstood what the method does.
+ * <p>
+ * Example:
+ * <pre>{@code
+ * public @CheckResult String trim(String s) { return s.trim(); }
+ * ...
+ * s.trim(); // this is probably an error
+ * s = s.trim(); // ok
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({METHOD})
+public @interface CheckResult {
+ /** Defines the name of the suggested method to use instead, if applicable (using
+ * the same signature format as javadoc.) If there is more than one possibility,
+ * list them all separated by commas.
+ * <p>
+ * For example, ProcessBuilder has a method named {@code redirectErrorStream()}
+ * which sounds like it might redirect the error stream. It does not. It's just
+ * a getter which returns whether the process builder will redirect the error stream,
+ * and to actually set it, you must call {@code redirectErrorStream(boolean)}.
+ * In that case, the method should be defined like this:
+ * <pre>
+ * @CheckResult(suggest="#redirectErrorStream(boolean)")
+ * public boolean redirectErrorStream() { ... }
+ * </pre>
+ */
+ String suggest() default "";
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/ColorInt.java b/annotations/src/android/support/annotation/ColorInt.java
new file mode 100644
index 0000000..9b3cb7e
--- /dev/null
+++ b/annotations/src/android/support/annotation/ColorInt.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element represents a packed color
+ * int, {@code AARRGGBB}. If applied to an int array, every element
+ * in the array represents a color integer.
+ * <p>
+ * Example:
+ * <pre>{@code
+ * public abstract void setTextColor(@ColorInt int color);
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({PARAMETER,METHOD,LOCAL_VARIABLE,FIELD})
+public @interface ColorInt {
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/ColorRes.java b/annotations/src/android/support/annotation/ColorRes.java
index d3d560a..eb273c4 100644
--- a/annotations/src/android/support/annotation/ColorRes.java
+++ b/annotations/src/android/support/annotation/ColorRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a color resource reference (e.g. {@link android.R.color#black}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface ColorRes {
}
diff --git a/annotations/src/android/support/annotation/DimenRes.java b/annotations/src/android/support/annotation/DimenRes.java
index 1aae6a3..c3492a5 100644
--- a/annotations/src/android/support/annotation/DimenRes.java
+++ b/annotations/src/android/support/annotation/DimenRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a dimension resource reference (e.g. {@link android.R.dimen#app_icon_size}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface DimenRes {
}
diff --git a/annotations/src/android/support/annotation/DrawableRes.java b/annotations/src/android/support/annotation/DrawableRes.java
index b85e253..0ea1bca 100644
--- a/annotations/src/android/support/annotation/DrawableRes.java
+++ b/annotations/src/android/support/annotation/DrawableRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a drawable resource reference (e.g. {@link android.R.attr#alertDialogIcon}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface DrawableRes {
}
diff --git a/annotations/src/android/support/annotation/FloatRange.java b/annotations/src/android/support/annotation/FloatRange.java
new file mode 100644
index 0000000..130d834
--- /dev/null
+++ b/annotations/src/android/support/annotation/FloatRange.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element should be a float or double in the given range
+ * <p>
+ * Example:
+ * <pre>{@code
+ * @FloatRange(from=0.0,to=1.0)
+ * public float getAlpha() {
+ * ...
+ * }
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE})
+public @interface FloatRange {
+ /** Smallest value. Whether it is inclusive or not is determined
+ * by {@link #fromInclusive} */
+ double from() default Double.NEGATIVE_INFINITY;
+ /** Largest value. Whether it is inclusive or not is determined
+ * by {@link #toInclusive} */
+ double to() default Double.POSITIVE_INFINITY;
+
+ /** Whether the from value is included in the range */
+ boolean fromInclusive() default true;
+
+ /** Whether the to value is included in the range */
+ boolean toInclusive() default true;
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/FractionRes.java b/annotations/src/android/support/annotation/FractionRes.java
index f78ca4e..1404866 100644
--- a/annotations/src/android/support/annotation/FractionRes.java
+++ b/annotations/src/android/support/annotation/FractionRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a fraction resource reference.
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface FractionRes {
}
diff --git a/annotations/src/android/support/annotation/IdRes.java b/annotations/src/android/support/annotation/IdRes.java
index 21d0a80..9a0060f 100644
--- a/annotations/src/android/support/annotation/IdRes.java
+++ b/annotations/src/android/support/annotation/IdRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be an id resource reference (e.g. {@link android.R.id#copy}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface IdRes {
}
diff --git a/annotations/src/android/support/annotation/IntDef.java b/annotations/src/android/support/annotation/IntDef.java
index 57a782b..fedd7b4 100644
--- a/annotations/src/android/support/annotation/IntDef.java
+++ b/annotations/src/android/support/annotation/IntDef.java
@@ -23,7 +23,6 @@
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.CLASS;
import static java.lang.annotation.RetentionPolicy.SOURCE;
/**
@@ -52,7 +51,7 @@
* value = {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
* }</pre>
*/
-@Retention(CLASS)
+@Retention(SOURCE)
@Target({ANNOTATION_TYPE})
public @interface IntDef {
/** Defines the allowed constants for this element */
diff --git a/annotations/src/android/support/annotation/IntRange.java b/annotations/src/android/support/annotation/IntRange.java
new file mode 100644
index 0000000..6011276
--- /dev/null
+++ b/annotations/src/android/support/annotation/IntRange.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element should be an int or long in the given range
+ * <p>
+ * Example:
+ * <pre>{@code
+ * @IntRange(from=0,to=255)
+ * public int getAlpha() {
+ * ...
+ * }
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE})
+public @interface IntRange {
+ /** Smallest value, inclusive */
+ long from() default Long.MIN_VALUE;
+ /** Largest value, inclusive */
+ long to() default Long.MAX_VALUE;
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/IntegerRes.java b/annotations/src/android/support/annotation/IntegerRes.java
index 95938f8..6bfcc37 100644
--- a/annotations/src/android/support/annotation/IntegerRes.java
+++ b/annotations/src/android/support/annotation/IntegerRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be an integer resource reference (e.g. {@link android.R.integer#config_shortAnimTime}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface IntegerRes {
}
diff --git a/annotations/src/android/support/annotation/InterpolatorRes.java b/annotations/src/android/support/annotation/InterpolatorRes.java
index 7068684..20f42b8 100644
--- a/annotations/src/android/support/annotation/InterpolatorRes.java
+++ b/annotations/src/android/support/annotation/InterpolatorRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be an interpolator resource reference (e.g. {@link android.R.interpolator#cycle}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface InterpolatorRes {
}
diff --git a/annotations/src/android/support/annotation/Keep.java b/annotations/src/android/support/annotation/Keep.java
new file mode 100644
index 0000000..de1c9e5
--- /dev/null
+++ b/annotations/src/android/support/annotation/Keep.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element should not be removed when
+ * the code is minified at build time. This is typically used
+ * on methods and classes that are accessed only via reflection
+ * so a compiler may think that the code is unused.
+ * <p>
+ * Example:
+ * <pre>{@code
+ * @Keep
+ * public void foo() {
+ * ...
+ * }
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({PACKAGE,TYPE,ANNOTATION_TYPE,CONSTRUCTOR,METHOD,FIELD})
+public @interface Keep {
+}
diff --git a/annotations/src/android/support/annotation/LayoutRes.java b/annotations/src/android/support/annotation/LayoutRes.java
index 51780a9..ad04ef0 100644
--- a/annotations/src/android/support/annotation/LayoutRes.java
+++ b/annotations/src/android/support/annotation/LayoutRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a layout resource reference (e.g. {@link android.R.layout#list_content}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface LayoutRes {
}
diff --git a/annotations/src/android/support/annotation/MainThread.java b/annotations/src/android/support/annotation/MainThread.java
new file mode 100644
index 0000000..28aee06
--- /dev/null
+++ b/annotations/src/android/support/annotation/MainThread.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * 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) { ... }
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({METHOD,CONSTRUCTOR,TYPE})
+public @interface MainThread {
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/MenuRes.java b/annotations/src/android/support/annotation/MenuRes.java
index b28ad95..0529049 100644
--- a/annotations/src/android/support/annotation/MenuRes.java
+++ b/annotations/src/android/support/annotation/MenuRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a menu resource reference.
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface MenuRes {
}
diff --git a/annotations/src/android/support/annotation/PluralsRes.java b/annotations/src/android/support/annotation/PluralsRes.java
index 00a9c84..509bc7b 100644
--- a/annotations/src/android/support/annotation/PluralsRes.java
+++ b/annotations/src/android/support/annotation/PluralsRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a plurals resource reference.
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface PluralsRes {
}
diff --git a/annotations/src/android/support/annotation/RawRes.java b/annotations/src/android/support/annotation/RawRes.java
index 7db9e0c..b1bb47b 100644
--- a/annotations/src/android/support/annotation/RawRes.java
+++ b/annotations/src/android/support/annotation/RawRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a raw resource reference.
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface RawRes {
}
diff --git a/annotations/src/android/support/annotation/RequiresPermission.java b/annotations/src/android/support/annotation/RequiresPermission.java
new file mode 100644
index 0000000..bb9afb2
--- /dev/null
+++ b/annotations/src/android/support/annotation/RequiresPermission.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element requires (or may require) one or more permissions.
+ * <p/>
+ * Example of requiring a single permission:
+ * <pre>{@code
+ * @RequiresPermission(Manifest.permission.SET_WALLPAPER)
+ * public abstract void setWallpaper(Bitmap bitmap) throws IOException;
+ *
+ * @RequiresPermission(ACCESS_COARSE_LOCATION)
+ * public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring at least one permission from a set:
+ * <pre>{@code
+ * @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+ * public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring multiple permissions:
+ * <pre>{@code
+ * @RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+ * public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring separate read and write permissions for a content provider:
+ * <pre>{@code
+ * @RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
+ * @RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
+ * public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
+ * }</pre>
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE,METHOD,CONSTRUCTOR,FIELD})
+public @interface RequiresPermission {
+ /**
+ * The name of the permission that is required, if precisely one permission
+ * is required. If more than one permission is required, specify either
+ * {@link #allOf()} or {@link #anyOf()} instead.
+ * <p>
+ * If specified, {@link #anyOf()} and {@link #allOf()} must both be null.
+ */
+ String value() default "";
+
+ /**
+ * Specifies a list of permission names that are all required.
+ * <p>
+ * If specified, {@link #anyOf()} and {@link #value()} must both be null.
+ */
+ String[] allOf() default {};
+
+ /**
+ * Specifies a list of permission names where at least one is required
+ * <p>
+ * If specified, {@link #allOf()} and {@link #value()} must both be null.
+ */
+ String[] anyOf() default {};
+
+ /**
+ * If true, the permission may not be required in all cases (e.g. it may only be
+ * enforced on certain platforms, or for certain call parameters, etc.
+ */
+ boolean conditional() default false;
+
+ /**
+ * Specifies that the given permission is required for read operations
+ */
+ @Target(FIELD)
+ @interface Read {
+ RequiresPermission value();
+ }
+
+ /**
+ * Specifies that the given permission is required for write operations
+ */
+ @Target(FIELD)
+ @interface Write {
+ RequiresPermission value();
+ }
+}
diff --git a/annotations/src/android/support/annotation/Size.java b/annotations/src/android/support/annotation/Size.java
new file mode 100644
index 0000000..306fdf3
--- /dev/null
+++ b/annotations/src/android/support/annotation/Size.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element should have a given size or length.
+ * Note that "-1" means "unset". Typically used with a parameter or
+ * return value of type array or collection.
+ * <p>
+ * Example:
+ * <pre>{@code
+ * public void getLocationInWindow(@Size(2) int[] location) {
+ * ...
+ * }
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({PARAMETER,LOCAL_VARIABLE,METHOD,FIELD})
+public @interface Size {
+ /** An exact size (or -1 if not specified) */
+ long value() default -1;
+ /** A minimum size, inclusive */
+ long min() default Long.MIN_VALUE;
+ /** A maximum size, inclusive */
+ long max() default Long.MAX_VALUE;
+ /** The size must be a multiple of this factor */
+ long multiple() default 1;
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/StringDef.java b/annotations/src/android/support/annotation/StringDef.java
index 72039a5..cae227e 100644
--- a/annotations/src/android/support/annotation/StringDef.java
+++ b/annotations/src/android/support/annotation/StringDef.java
@@ -22,7 +22,6 @@
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.CLASS;
import static java.lang.annotation.RetentionPolicy.SOURCE;
/**
@@ -45,7 +44,7 @@
* public abstract Object getSystemService(@ServiceName String name);
* }</pre>
*/
-@Retention(CLASS)
+@Retention(SOURCE)
@Target({ANNOTATION_TYPE})
public @interface StringDef {
/** Defines the allowed constants for this element */
diff --git a/annotations/src/android/support/annotation/StringRes.java b/annotations/src/android/support/annotation/StringRes.java
index 28b79b0..2c1149c 100644
--- a/annotations/src/android/support/annotation/StringRes.java
+++ b/annotations/src/android/support/annotation/StringRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be a String resource reference (e.g. {@link android.R.string#ok}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface StringRes {
}
diff --git a/annotations/src/android/support/annotation/StyleRes.java b/annotations/src/android/support/annotation/StyleRes.java
index 5e6f454..6d931bf 100644
--- a/annotations/src/android/support/annotation/StyleRes.java
+++ b/annotations/src/android/support/annotation/StyleRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
- * Denotes that a integer parameter, field or method return value is expected
+ * Denotes that an integer parameter, field or method return value is expected
* to be a style resource reference (e.g. {@link android.R.style#TextAppearance}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface StyleRes {
}
diff --git a/annotations/src/android/support/annotation/StyleableRes.java b/annotations/src/android/support/annotation/StyleableRes.java
index 617dfae..d7902d1 100644
--- a/annotations/src/android/support/annotation/StyleableRes.java
+++ b/annotations/src/android/support/annotation/StyleableRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
- * Denotes that a integer parameter, field or method return value is expected
+ * Denotes that an integer parameter, field or method return value is expected
* to be a styleable resource reference (e.g. {@link android.R.styleable#TextView_text}).
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface StyleableRes {
}
diff --git a/annotations/src/android/support/annotation/TransitionRes.java b/annotations/src/android/support/annotation/TransitionRes.java
new file mode 100644
index 0000000..d1c5208
--- /dev/null
+++ b/annotations/src/android/support/annotation/TransitionRes.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a transition resource reference.
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface TransitionRes {
+}
diff --git a/annotations/src/android/support/annotation/UiThread.java b/annotations/src/android/support/annotation/UiThread.java
new file mode 100644
index 0000000..a603740
--- /dev/null
+++ b/annotations/src/android/support/annotation/UiThread.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * 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
+ *
+ * public abstract void setText(@NonNull String text) { ... }
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({METHOD,CONSTRUCTOR,TYPE})
+public @interface UiThread {
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/VisibleForTesting.java b/annotations/src/android/support/annotation/VisibleForTesting.java
new file mode 100644
index 0000000..bb02ab4
--- /dev/null
+++ b/annotations/src/android/support/annotation/VisibleForTesting.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that the class, method or field has its visibility relaxed, so that it is more widely
+ * visible than otherwise necessary to make code testable.
+ */
+@Retention(SOURCE)
+public @interface VisibleForTesting {
+}
diff --git a/annotations/src/android/support/annotation/WorkerThread.java b/annotations/src/android/support/annotation/WorkerThread.java
new file mode 100644
index 0000000..31e34b4
--- /dev/null
+++ b/annotations/src/android/support/annotation/WorkerThread.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * 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);
+ * }</pre>
+ */
+@Retention(CLASS)
+@Target({METHOD,CONSTRUCTOR,TYPE})
+public @interface WorkerThread {
+}
\ No newline at end of file
diff --git a/annotations/src/android/support/annotation/XmlRes.java b/annotations/src/android/support/annotation/XmlRes.java
index 66713a8..2b8b9fa 100644
--- a/annotations/src/android/support/annotation/XmlRes.java
+++ b/annotations/src/android/support/annotation/XmlRes.java
@@ -20,16 +20,17 @@
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Denotes that an integer parameter, field or method return value is expected
* to be an XML resource reference.
*/
@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface XmlRes {
}
diff --git a/design/src/android/support/design/widget/CoordinatorLayout.java b/design/src/android/support/design/widget/CoordinatorLayout.java
index 6b97618..bcda20a 100644
--- a/design/src/android/support/design/widget/CoordinatorLayout.java
+++ b/design/src/android/support/design/widget/CoordinatorLayout.java
@@ -411,6 +411,7 @@
final Class<Behavior> clazz = (Class<Behavior>) Class.forName(fullName, true,
context.getClassLoader());
c = clazz.getConstructor(CONSTRUCTOR_PARAMS);
+ c.setAccessible(true);
constructors.put(fullName, c);
}
return c.newInstance(context, attrs);
diff --git a/design/src/android/support/design/widget/FloatingActionButton.java b/design/src/android/support/design/widget/FloatingActionButton.java
index c2db0cf..f8e04dd 100644
--- a/design/src/android/support/design/widget/FloatingActionButton.java
+++ b/design/src/android/support/design/widget/FloatingActionButton.java
@@ -24,6 +24,7 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.support.design.R;
import android.support.v4.view.ViewCompat;
@@ -150,7 +151,7 @@
*
* @param color ARGB color to use for the ripple.
*/
- public void setRippleColor(int color) {
+ public void setRippleColor(@ColorInt int color) {
if (mRippleColor != color) {
mRippleColor = color;
mImpl.setRippleColor(color);
diff --git a/design/src/android/support/design/widget/TabLayout.java b/design/src/android/support/design/widget/TabLayout.java
index 05cb354..d743340 100755
--- a/design/src/android/support/design/widget/TabLayout.java
+++ b/design/src/android/support/design/widget/TabLayout.java
@@ -24,6 +24,7 @@
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.support.annotation.ColorInt;
import android.support.annotation.IntDef;
import android.support.design.R;
import android.support.v4.view.GravityCompat;
diff --git a/graphics/Android.mk b/graphics/Android.mk
new file mode 100644
index 0000000..365b3b1
--- /dev/null
+++ b/graphics/Android.mk
@@ -0,0 +1,16 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/graphics/drawable/Android.mk b/graphics/drawable/Android.mk
new file mode 100644
index 0000000..63e93b7
--- /dev/null
+++ b/graphics/drawable/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH := $(call my-dir)
+
+#static vector drawable library
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v7-vectordrawable
+LOCAL_SDK_VERSION := 7
+LOCAL_SRC_FILES := $(call all-java-files-under, static)
+
+LOCAL_JAVA_LIBRARIES := android-support-v4
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res \
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+#Animated vector drawable library
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v11-animatedvectordrawable
+LOCAL_SDK_VERSION := 11
+LOCAL_SRC_FILES := $(call all-java-files-under, animated)
+
+LOCAL_JAVA_LIBRARIES := android-support-v4
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res \
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v7-vectordrawable
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/graphics/drawable/AndroidManifest.xml b/graphics/drawable/AndroidManifest.xml
new file mode 100644
index 0000000..83124c7
--- /dev/null
+++ b/graphics/drawable/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.support.graphics.drawable">
+ <application />
+</manifest>
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
new file mode 100644
index 0000000..78ef62d
--- /dev/null
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
@@ -0,0 +1,504 @@
+/*
+ * Copyright (C) 2015 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.graphics.drawable;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.Rect;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.DrawableRes;
+import android.support.v4.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * This class uses {@link android.animation.ObjectAnimator} and
+ * {@link android.animation.AnimatorSet} to animate the properties of a
+ * {@link android.graphics.drawable.VectorDrawableCompat} to create an animated drawable.
+ * <p>
+ * AnimatedVectorDrawableCompat are normally defined as 3 separate XML files.
+ * </p>
+ * <p>
+ * First is the XML file for {@link android.graphics.drawable.VectorDrawableCompat}. Note that we
+ * allow the animation to happen on the group's attributes and path's attributes, which requires they
+ * are uniquely named in this XML file. Groups and paths without animations do not need names.
+ * </p>
+ * <li>Here is a simple VectorDrawable in this vectordrawable.xml file.
+ * <pre>
+ * <vector xmlns:android="http://schemas.android.com/apk/res/android"
+ * android:height="64dp"
+ * android:width="64dp"
+ * android:viewportHeight="600"
+ * android:viewportWidth="600" >
+ * <group
+ * android:name="rotationGroup"
+ * android:pivotX="300.0"
+ * android:pivotY="300.0"
+ * android:rotation="45.0" >
+ * <path
+ * android:name="v"
+ * android:fillColor="#000000"
+ * android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
+ * </group>
+ * </vector>
+ * </pre></li>
+ * <p>
+ * Second is the AnimatedVectorDrawableCompat's XML file, which defines the target
+ * VectorDrawableCompat, the target paths and groups to animate, the properties of the path and
+ * group to animate and the animations defined as the ObjectAnimators or AnimatorSets.
+ * </p>
+ * <li>Here is a simple AnimatedVectorDrawable defined in this avd.xml file.
+ * Note how we use the names to refer to the groups and paths in the vectordrawable.xml.
+ * <pre>
+ * <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ * android:drawable="@drawable/vectordrawable" >
+ * <target
+ * android:name="rotationGroup"
+ * android:animation="@anim/rotation" />
+ * <target
+ * android:name="v"
+ * android:animation="@anim/path_morph" />
+ * </animated-vector>
+ * </pre></li>
+ * <p>
+ * Last is the Animator XML file, which is the same as a normal ObjectAnimator or AnimatorSet. To
+ * complete this example, here are the 2 animator files used in avd.xml: rotation.xml and
+ * path_morph.xml.
+ * </p>
+ * <li>Here is the rotation.xml, which will rotate the target group for 360 degrees.
+ * <pre>
+ * <objectAnimator
+ * android:duration="6000"
+ * android:propertyName="rotation"
+ * android:valueFrom="0"
+ * android:valueTo="360" />
+ * </pre></li>
+ * <li>Here is the path_morph.xml, which will morph the path from one shape to
+ * the other. Note that the paths must be compatible for morphing.
+ * In more details, the paths should have exact same length of commands, and
+ * exact same length of parameters for each commands.
+ * Note that the path strings are better stored in strings.xml for reusing.
+ * <pre>
+ * <set xmlns:android="http://schemas.android.com/apk/res/android">
+ * <objectAnimator
+ * android:duration="3000"
+ * android:propertyName="pathData"
+ * android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"
+ * android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z"
+ * android:valueType="pathType"/>
+ * </set>
+ * </pre></li>
+ *
+ * @attr ref android.R.styleable#AnimatedVectorDrawableCompat_drawable
+ * @attr ref android.R.styleable#AnimatedVectorDrawableCompatTarget_name
+ * @attr ref android.R.styleable#AnimatedVectorDrawableCompatTarget_animation
+ */
+public class AnimatedVectorDrawableCompat extends Drawable implements Animatable {
+ private static final String LOGTAG = "AnimatedVectorDrawableCompat";
+
+ private static final String ANIMATED_VECTOR = "animated-vector";
+ private static final String TARGET = "target";
+
+ private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false;
+
+ private AnimatedVectorDrawableCompatState mAnimatedVectorState;
+
+ private boolean mMutated;
+
+ private Context mContext;
+
+ // Currently the only useful ctor.
+ public AnimatedVectorDrawableCompat(Context context) {
+ this(context, null, null);
+ }
+
+ private AnimatedVectorDrawableCompat(Context context, AnimatedVectorDrawableCompatState state,
+ Resources res) {
+ mContext = context;
+ if (state != null) {
+ mAnimatedVectorState = state;
+ } else {
+ mAnimatedVectorState = new AnimatedVectorDrawableCompatState(context, state, mCallback,
+ res);
+ }
+ }
+
+ @Override
+ public Drawable mutate() {
+ if (!mMutated && super.mutate() == this) {
+ mAnimatedVectorState =
+ new AnimatedVectorDrawableCompatState(null, mAnimatedVectorState, mCallback,
+ null);
+ mMutated = true;
+ }
+ return this;
+ }
+
+
+ /**
+ * Create a AnimatedVectorDrawableCompat object.
+ *
+ * @param context the context for creating the animators.
+ * @param resId the resource ID for AnimatedVectorDrawableCompat object.
+ * @return a new AnimatedVectorDrawableCompat or null if parsing error is found.
+ */
+ @Nullable
+ public static AnimatedVectorDrawableCompat create(@NonNull Context context,
+ @DrawableRes int resId) {
+ Resources resources = context.getResources();
+ try {
+ final XmlPullParser parser = resources.getXml(resId);
+ final AttributeSet attrs = Xml.asAttributeSet(parser);
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ // Empty loop
+ }
+ if (type != XmlPullParser.START_TAG) {
+ throw new XmlPullParserException("No start tag found");
+ }
+
+ final AnimatedVectorDrawableCompat drawable = new AnimatedVectorDrawableCompat(context);
+ drawable.inflate(resources, parser, attrs, context.getTheme());
+
+ return drawable;
+ } catch (XmlPullParserException e) {
+ Log.e(LOGTAG, "parser error", e);
+ } catch (IOException e) {
+ Log.e(LOGTAG, "parser error", e);
+ }
+ return null;
+ }
+
+ @Override
+ public ConstantState getConstantState() {
+ mAnimatedVectorState.mChangingConfigurations = getChangingConfigurations();
+ return mAnimatedVectorState;
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return super.getChangingConfigurations() | mAnimatedVectorState.mChangingConfigurations;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ mAnimatedVectorState.mVectorDrawable.draw(canvas);
+ if (isStarted()) {
+ invalidateSelf();
+ }
+ }
+
+ @Override
+ protected void onBoundsChange(Rect bounds) {
+ mAnimatedVectorState.mVectorDrawable.setBounds(bounds);
+ }
+
+ @Override
+ protected boolean onStateChange(int[] state) {
+ return mAnimatedVectorState.mVectorDrawable.setState(state);
+ }
+
+ @Override
+ protected boolean onLevelChange(int level) {
+ return mAnimatedVectorState.mVectorDrawable.setLevel(level);
+ }
+
+ // @Override
+ public int getAlpha() {
+ return mAnimatedVectorState.mVectorDrawable.getAlpha();
+ }
+
+ // @Override
+ public void setAlpha(int alpha) {
+ mAnimatedVectorState.mVectorDrawable.setAlpha(alpha);
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ mAnimatedVectorState.mVectorDrawable.setColorFilter(colorFilter);
+ }
+
+ public void setTintList(ColorStateList tint) {
+ mAnimatedVectorState.mVectorDrawable.setTintList(tint);
+ }
+
+ public void setTintMode(Mode tintMode) {
+ mAnimatedVectorState.mVectorDrawable.setTintMode(tintMode);
+ }
+
+ @Override
+ public boolean setVisible(boolean visible, boolean restart) {
+ mAnimatedVectorState.mVectorDrawable.setVisible(visible, restart);
+ return super.setVisible(visible, restart);
+ }
+
+ @Override
+ public boolean isStateful() {
+ return mAnimatedVectorState.mVectorDrawable.isStateful();
+ }
+
+ @Override
+ public int getOpacity() {
+ return mAnimatedVectorState.mVectorDrawable.getOpacity();
+ }
+
+ public int getIntrinsicWidth() {
+ return mAnimatedVectorState.mVectorDrawable.getIntrinsicWidth();
+ }
+
+ public int getIntrinsicHeight() {
+ return mAnimatedVectorState.mVectorDrawable.getIntrinsicHeight();
+ }
+
+ /**
+ * Obtains styled attributes from the theme, if available, or unstyled
+ * resources if the theme is null.
+ */
+ static TypedArray obtainAttributes(
+ Resources res, Theme theme, AttributeSet set, int[] attrs) {
+ if (theme == null) {
+ return res.obtainAttributes(set, attrs);
+ }
+ return theme.obtainStyledAttributes(set, attrs, 0, 0);
+ }
+
+ public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
+ throws XmlPullParserException, IOException {
+ int eventType = parser.getEventType();
+ float pathErrorScale = 1;
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ final String tagName = parser.getName();
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.v(LOGTAG, "tagName is " + tagName);
+ }
+ if (ANIMATED_VECTOR.equals(tagName)) {
+ final TypedArray a =
+ obtainAttributes(res, theme, attrs, R.styleable.AnimatedVectorDrawable);
+
+ int drawableRes = a.getResourceId(R.styleable.AnimatedVectorDrawable_drawable,
+ 0);
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.v(LOGTAG, "drawableRes is " + drawableRes);
+ }
+ if (drawableRes != 0) {
+ VectorDrawableCompat vectorDrawable = VectorDrawableCompat.create(res,
+ drawableRes, theme);
+ vectorDrawable.setAllowCaching(false);
+ vectorDrawable.setCallback(mCallback);
+ pathErrorScale = vectorDrawable.getPixelSize();
+ if (mAnimatedVectorState.mVectorDrawable != null) {
+ mAnimatedVectorState.mVectorDrawable.setCallback(null);
+ }
+ mAnimatedVectorState.mVectorDrawable = vectorDrawable;
+ }
+ a.recycle();
+ } else if (TARGET.equals(tagName)) {
+ final TypedArray a =
+ res.obtainAttributes(attrs, R.styleable.AnimatedVectorDrawableTarget);
+ final String target = a.getString(
+ R.styleable.AnimatedVectorDrawableTarget_name);
+
+ int id = a.getResourceId(R.styleable.AnimatedVectorDrawableTarget_animation, 0);
+ if (id != 0) {
+ Animator objectAnimator = AnimatorInflater.loadAnimator(mContext, id);
+ setupAnimatorsForTarget(target, objectAnimator);
+ }
+ a.recycle();
+ }
+ }
+
+ eventType = parser.next();
+ }
+ }
+
+ @Override
+ public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs)
+ throws XmlPullParserException, IOException {
+ inflate(res, parser, attrs, null);
+ }
+
+ public boolean canApplyTheme() {
+ return false;
+ }
+
+ private static class AnimatedVectorDrawableCompatState extends ConstantState {
+ int mChangingConfigurations;
+ VectorDrawableCompat mVectorDrawable;
+ ArrayList<Animator> mAnimators;
+ ArrayMap<Animator, String> mTargetNameMap;
+ Context mContext;
+
+ public AnimatedVectorDrawableCompatState(Context context,
+ AnimatedVectorDrawableCompatState copy, Callback owner, Resources res) {
+ if (copy != null) {
+ mChangingConfigurations = copy.mChangingConfigurations;
+ if (copy.mVectorDrawable != null) {
+ final ConstantState cs = copy.mVectorDrawable.getConstantState();
+ if (res != null) {
+ mVectorDrawable = (VectorDrawableCompat) cs.newDrawable(res);
+ } else {
+ mVectorDrawable = (VectorDrawableCompat) cs.newDrawable();
+ }
+ mVectorDrawable = (VectorDrawableCompat) mVectorDrawable.mutate();
+ mVectorDrawable.setCallback(owner);
+ mVectorDrawable.setBounds(copy.mVectorDrawable.getBounds());
+ mVectorDrawable.setAllowCaching(false);
+ }
+ if (copy.mAnimators != null) {
+ final int numAnimators = copy.mAnimators.size();
+ mAnimators = new ArrayList<Animator>(numAnimators);
+ mTargetNameMap = new ArrayMap<Animator, String>(numAnimators);
+ for (int i = 0; i < numAnimators; ++i) {
+ Animator anim = copy.mAnimators.get(i);
+ Animator animClone = anim.clone();
+ String targetName = copy.mTargetNameMap.get(anim);
+ Object targetObject = mVectorDrawable.getTargetByName(targetName);
+ animClone.setTarget(targetObject);
+ mAnimators.add(animClone);
+ mTargetNameMap.put(animClone, targetName);
+ }
+ }
+ }
+
+ if (context != null) {
+ mContext = context;
+ } else {
+ mContext = copy.mContext;
+ }
+
+ }
+
+ @Override
+ public Drawable newDrawable() {
+ return new AnimatedVectorDrawableCompat(mContext, this, null);
+ }
+
+ @Override
+ public Drawable newDrawable(Resources res) {
+ return new AnimatedVectorDrawableCompat(mContext, this, res);
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return mChangingConfigurations;
+ }
+ }
+
+ private void setupAnimatorsForTarget(String name, Animator animator) {
+ Object target = mAnimatedVectorState.mVectorDrawable.getTargetByName(name);
+ animator.setTarget(target);
+ if (mAnimatedVectorState.mAnimators == null) {
+ mAnimatedVectorState.mAnimators = new ArrayList<Animator>();
+ mAnimatedVectorState.mTargetNameMap = new ArrayMap<Animator, String>();
+ }
+ mAnimatedVectorState.mAnimators.add(animator);
+ mAnimatedVectorState.mTargetNameMap.put(animator, name);
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.v(LOGTAG, "add animator for target " + name + " " + animator);
+ }
+ }
+
+ @Override
+ public boolean isRunning() {
+ final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
+ final int size = animators.size();
+ for (int i = 0; i < size; i++) {
+ final Animator animator = animators.get(i);
+ if (animator.isRunning()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isStarted() {
+ final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
+ if (animators == null) {
+ return false;
+ }
+ final int size = animators.size();
+ for (int i = 0; i < size; i++) {
+ final Animator animator = animators.get(i);
+ if (animator.isRunning()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void start() {
+ // If any one of the animator has not ended, do nothing.
+ if (isStarted()) {
+ return;
+ }
+ // Otherwise, kick off every animator.
+ final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
+ final int size = animators.size();
+ for (int i = 0; i < size; i++) {
+ final Animator animator = animators.get(i);
+ animator.start();
+ }
+ invalidateSelf();
+ }
+
+ @Override
+ public void stop() {
+ final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
+ final int size = animators.size();
+ for (int i = 0; i < size; i++) {
+ final Animator animator = animators.get(i);
+ animator.end();
+ }
+ }
+
+ private final Callback mCallback = new Callback() {
+ @Override
+ public void invalidateDrawable(Drawable who) {
+ invalidateSelf();
+ }
+
+ @Override
+ public void scheduleDrawable(Drawable who, Runnable what, long when) {
+ scheduleSelf(what, when);
+ }
+
+ @Override
+ public void unscheduleDrawable(Drawable who, Runnable what) {
+ unscheduleSelf(what);
+ }
+ };
+}
diff --git a/graphics/drawable/res/values/attrs.xml b/graphics/drawable/res/values/attrs.xml
new file mode 100644
index 0000000..b54c9a6
--- /dev/null
+++ b/graphics/drawable/res/values/attrs.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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>
+ <!-- If set, specifies the color to apply to the drawable as a tint. By default,
+ no tint is applied. May be a color state list. -->
+ <attr name="tint" format="color" />
+ <!-- When a tint color is set, specifies its Porter-Duff blending mode. The
+ default value is src_in, which treats the drawable as an alpha mask. -->
+ <attr name="tintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
+ </attr>
+ <!-- Animation to use on each child. -->
+ <attr name="animation" format="reference" />
+ <!-- alpha property of the view, as a value between 0 (completely transparent) and 1
+ (completely opaque). -->
+ <attr name="alpha" format="float" />
+ <attr name="pivotX" format="float|fraction" />
+ <attr name="pivotY" format="float|fraction" />
+ <!-- rotation of the view, in degrees. -->
+ <attr name="rotation" format="float" />
+
+ <!-- scale of the view in the x direction. -->
+ <attr name="scaleX" format="float" />
+
+ <!-- scale of the view in the y direction. -->
+ <attr name="scaleY" format="float" />
+ <!-- Makes the TextView be exactly this many pixels tall.
+ You could get the same effect by specifying this number in the
+ layout parameters. -->
+ <attr name="height" format="dimension" />
+ <!-- Makes the TextView be exactly this many pixels wide.
+ You could get the same effect by specifying this number in the
+ layout parameters. -->
+ <attr name="width" format="dimension" />
+ <!-- A unique name for the given item. This must use a Java-style naming
+ convention to ensure the name is unique, for example
+ "com.mycompany.MyName". -->
+ <attr name="name" format="string" />
+
+ <!-- ========================== -->
+ <!-- VectorDrawable class -->
+ <!-- ========================== -->
+ <eat-comment />
+
+ <!-- Drawable used to draw vector paths. -->
+ <declare-styleable name="VectorDrawable">
+ <!-- If set, specifies the color to apply to the drawable as a tint. By default,
+ no tint is applied. May be a color state list. -->
+ <attr name="tint" />
+ <!-- When a tint color is set, specifies its Porter-Duff blending mode. The
+ default value is src_in, which treats the drawable as an alpha mask. -->
+ <attr name="tintMode" />
+ <!-- Indicates if the drawable needs to be mirrored when its layout direction is
+ RTL (right-to-left). -->
+ <attr name="autoMirrored" format="boolean" />
+ <!-- The intrinsic width of the Vector Drawable. -->
+ <attr name="width" />
+ <!-- The intrinsic height of the Vector Drawable. -->
+ <attr name="height" />
+ <!-- The width of the canvas the drawing is on. -->
+ <attr name="viewportWidth" format="float"/>
+ <!-- The height of the canvas the drawing is on. -->
+ <attr name="viewportHeight" format="float"/>
+ <!-- The name of this vector drawable -->
+ <attr name="name" />
+ <!-- The opacity of the whole vector drawable, as a value between 0
+ (completely transparent) and 1 (completely opaque). -->
+ <attr name="alpha" />
+ </declare-styleable>
+
+ <!-- Defines the group used in VectorDrawables. -->
+ <declare-styleable name="VectorDrawableGroup">
+ <!-- The name of this group -->
+ <attr name="name" />
+ <!-- The amount to rotate the group -->
+ <attr name="rotation" />
+ <!-- The X coordinate of the center of rotation of a group -->
+ <attr name="pivotX" />
+ <!-- The Y coordinate of the center of rotation of a group -->
+ <attr name="pivotY" />
+ <!-- The amount to translate the group on X coordinate -->
+ <attr name="translateX" format="float"/>
+ <!-- The amount to translate the group on Y coordinate -->
+ <attr name="translateY" format="float"/>
+ <!-- The amount to scale the group on X coordinate -->
+ <attr name="scaleX" />
+ <!-- The amount to scale the group on X coordinate -->
+ <attr name="scaleY" />
+ </declare-styleable>
+
+ <!-- Defines the path used in VectorDrawables. -->
+ <declare-styleable name="VectorDrawablePath">
+ <!-- The name of this path -->
+ <attr name="name" />
+ <!-- The width a path stroke -->
+ <attr name="strokeWidth" format="float" />
+ <!-- The color to stroke the path if not defined implies no stroke-->
+ <attr name="strokeColor" format="color" />
+ <!-- The opacity of a path stroke, as a value between 0 (completely transparent)
+ and 1 (completely opaque) -->
+ <attr name="strokeAlpha" format="float" />
+ <!-- The color to fill the path if not defined implies no fill-->
+ <attr name="fillColor" format="color" />
+ <!-- The alpha of the path fill, as a value between 0 (completely transparent)
+ and 1 (completely opaque)-->
+ <attr name="fillAlpha" format="float" />
+ <!-- The specification of the operations that define the path -->
+ <attr name="pathData" format="string" />
+ <!-- The fraction of the path to trim from the start from 0 to 1 -->
+ <attr name="trimPathStart" format="float" />
+ <!-- The fraction of the path to trim from the end from 0 to 1 -->
+ <attr name="trimPathEnd" format="float" />
+ <!-- Shift trim region (allows visible region to include the start and end) from 0 to 1 -->
+ <attr name="trimPathOffset" format="float" />
+ <!-- The linecap for a stroked path -->
+ <attr name="strokeLineCap" format="enum">
+ <enum name="butt" value="0"/>
+ <enum name="round" value="1"/>
+ <enum name="square" value="2"/>
+ </attr>
+ <!-- The lineJoin for a stroked path -->
+ <attr name="strokeLineJoin" format="enum">
+ <enum name="miter" value="0"/>
+ <enum name="round" value="1"/>
+ <enum name="bevel" value="2"/>
+ </attr>
+ <!-- The Miter limit for a stroked path -->
+ <attr name="strokeMiterLimit" format="float"/>
+ </declare-styleable>
+
+ <!-- Defines the clip path used in VectorDrawables. -->
+ <declare-styleable name="VectorDrawableClipPath">
+ <!-- The Name of this path -->
+ <attr name="name" />
+ <!-- The specification of the operations that define the path -->
+ <attr name="pathData"/>
+ </declare-styleable>
+
+ <!-- ========================== -->
+ <!-- AnimatedVectorDrawable class -->
+ <!-- ========================== -->
+ <eat-comment />
+
+ <!-- Define the AnimatedVectorDrawable. -->
+ <declare-styleable name="AnimatedVectorDrawable">
+ <!-- The static vector drawable. -->
+ <attr name="drawable" format="reference" />
+ </declare-styleable>
+
+ <!-- Defines the target used in the AnimatedVectorDrawable. -->
+ <declare-styleable name="AnimatedVectorDrawableTarget">
+ <!-- The name of the target path, group or vector drawable -->
+ <attr name="name" />
+ <!-- The animation for the target path, group or vector drawable -->
+ <attr name="animation" />
+ </declare-styleable>
+</resources>
diff --git a/graphics/drawable/runavdtest.sh b/graphics/drawable/runavdtest.sh
new file mode 100755
index 0000000..023ad3e
--- /dev/null
+++ b/graphics/drawable/runavdtest.sh
@@ -0,0 +1,5 @@
+. ../../../../build/envsetup.sh
+mmm -j20 . && mmm -j20 ./testanimated/ && \
+adb install -r $OUT/data/app/AndroidAnimatedVectorDrawableTests/AndroidAnimatedVectorDrawableTests.apk && \
+adb shell am start -n android.support.test.vectordrawable/android.support.test.vectordrawable.TestAVDActivity
+
diff --git a/graphics/drawable/runtest.sh b/graphics/drawable/runtest.sh
new file mode 100755
index 0000000..6f69780
--- /dev/null
+++ b/graphics/drawable/runtest.sh
@@ -0,0 +1,5 @@
+. ../../../../build/envsetup.sh
+mmm -j20 . && mmm -j20 ./teststatic/ && \
+adb install -r $OUT/data/app/AndroidVectorDrawableTests/AndroidVectorDrawableTests.apk && \
+adb shell am start -n android.support.test.vectordrawable/android.support.test.vectordrawable.TestActivity
+
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java b/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java
new file mode 100644
index 0000000..a92c3e5
--- /dev/null
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java
@@ -0,0 +1,718 @@
+/*
+ * Copyright (C) 2015 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.graphics.drawable;
+
+import android.graphics.Path;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+// This class is a duplicate from the PathParser.java of frameworks/base, with slight
+// update on incompatible API like copyOfRange().
+class PathParser {
+ private static final String LOGTAG = "PathParser";
+
+ // Copy from Arrays.copyOfRange() which is only available from API level 9.
+ /**
+ * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+ * end (exclusive). The original order of elements is preserved.
+ * If {@code end} is greater than {@code original.length}, the result is padded
+ * with the value {@code 0.0f}.
+ *
+ * @param original the original array
+ * @param start the start index, inclusive
+ * @param end the end index, exclusive
+ * @return the new array
+ * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+ * @throws IllegalArgumentException if {@code start > end}
+ * @throws NullPointerException if {@code original == null}
+ */
+ private static float[] copyOfRange(float[] original, int start, int end) {
+ if (start > end) {
+ throw new IllegalArgumentException();
+ }
+ int originalLength = original.length;
+ if (start < 0 || start > originalLength) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ int resultLength = end - start;
+ int copyLength = Math.min(resultLength, originalLength - start);
+ float[] result = new float[resultLength];
+ System.arraycopy(original, start, result, 0, copyLength);
+ return result;
+ }
+
+ /**
+ * @param pathData The string representing a path, the same as "d" string in svg file.
+ * @return the generated Path object.
+ */
+ public static Path createPathFromPathData(String pathData) {
+ Path path = new Path();
+ PathDataNode[] nodes = createNodesFromPathData(pathData);
+ if (nodes != null) {
+ try {
+ PathDataNode.nodesToPath(nodes, path);
+ } catch (RuntimeException e) {
+ throw new RuntimeException("Error in parsing " + pathData, e);
+ }
+ return path;
+ }
+ return null;
+ }
+
+ /**
+ * @param pathData The string representing a path, the same as "d" string in svg file.
+ * @return an array of the PathDataNode.
+ */
+ public static PathDataNode[] createNodesFromPathData(String pathData) {
+ if (pathData == null) {
+ return null;
+ }
+ int start = 0;
+ int end = 1;
+
+ ArrayList<PathDataNode> list = new ArrayList<PathDataNode>();
+ while (end < pathData.length()) {
+ end = nextStart(pathData, end);
+ String s = pathData.substring(start, end).trim();
+ if (s.length() > 0) {
+ float[] val = getFloats(s);
+ addNode(list, s.charAt(0), val);
+ }
+
+ start = end;
+ end++;
+ }
+ if ((end - start) == 1 && start < pathData.length()) {
+ addNode(list, pathData.charAt(start), new float[0]);
+ }
+ return list.toArray(new PathDataNode[list.size()]);
+ }
+
+ /**
+ * @param source The array of PathDataNode to be duplicated.
+ * @return a deep copy of the <code>source</code>.
+ */
+ public static PathDataNode[] deepCopyNodes(PathDataNode[] source) {
+ if (source == null) {
+ return null;
+ }
+ PathDataNode[] copy = new PathParser.PathDataNode[source.length];
+ for (int i = 0; i < source.length; i ++) {
+ copy[i] = new PathDataNode(source[i]);
+ }
+ return copy;
+ }
+
+ /**
+ * @param nodesFrom The source path represented in an array of PathDataNode
+ * @param nodesTo The target path represented in an array of PathDataNode
+ * @return whether the <code>nodesFrom</code> can morph into <code>nodesTo</code>
+ */
+ public static boolean canMorph(PathDataNode[] nodesFrom, PathDataNode[] nodesTo) {
+ if (nodesFrom == null || nodesTo == null) {
+ return false;
+ }
+
+ if (nodesFrom.length != nodesTo.length) {
+ return false;
+ }
+
+ for (int i = 0; i < nodesFrom.length; i ++) {
+ if (nodesFrom[i].mType != nodesTo[i].mType
+ || nodesFrom[i].mParams.length != nodesTo[i].mParams.length) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Update the target's data to match the source.
+ * Before calling this, make sure canMorph(target, source) is true.
+ *
+ * @param target The target path represented in an array of PathDataNode
+ * @param source The source path represented in an array of PathDataNode
+ */
+ public static void updateNodes(PathDataNode[] target, PathDataNode[] source) {
+ for (int i = 0; i < source.length; i ++) {
+ target[i].mType = source[i].mType;
+ for (int j = 0; j < source[i].mParams.length; j ++) {
+ target[i].mParams[j] = source[i].mParams[j];
+ }
+ }
+ }
+
+ private static int nextStart(String s, int end) {
+ char c;
+
+ while (end < s.length()) {
+ c = s.charAt(end);
+ // Note that 'e' or 'E' are not valid path commands, but could be
+ // used for floating point numbers' scientific notation.
+ // Therefore, when searching for next command, we should ignore 'e'
+ // and 'E'.
+ if ((((c - 'A') * (c - 'Z') <= 0) || ((c - 'a') * (c - 'z') <= 0))
+ && c != 'e' && c != 'E') {
+ return end;
+ }
+ end++;
+ }
+ return end;
+ }
+
+ private static void addNode(ArrayList<PathDataNode> list, char cmd, float[] val) {
+ list.add(new PathDataNode(cmd, val));
+ }
+
+ private static class ExtractFloatResult {
+ // We need to return the position of the next separator and whether the
+ // next float starts with a '-' or a '.'.
+ int mEndPosition;
+ boolean mEndWithNegOrDot;
+ }
+
+ /**
+ * Parse the floats in the string.
+ * This is an optimized version of parseFloat(s.split(",|\\s"));
+ *
+ * @param s the string containing a command and list of floats
+ * @return array of floats
+ */
+ private static float[] getFloats(String s) {
+ if (s.charAt(0) == 'z' | s.charAt(0) == 'Z') {
+ return new float[0];
+ }
+ try {
+ float[] results = new float[s.length()];
+ int count = 0;
+ int startPosition = 1;
+ int endPosition = 0;
+
+ ExtractFloatResult result = new ExtractFloatResult();
+ int totalLength = s.length();
+
+ // The startPosition should always be the first character of the
+ // current number, and endPosition is the character after the current
+ // number.
+ while (startPosition < totalLength) {
+ extract(s, startPosition, result);
+ endPosition = result.mEndPosition;
+
+ if (startPosition < endPosition) {
+ results[count++] = Float.parseFloat(
+ s.substring(startPosition, endPosition));
+ }
+
+ if (result.mEndWithNegOrDot) {
+ // Keep the '-' or '.' sign with next number.
+ startPosition = endPosition;
+ } else {
+ startPosition = endPosition + 1;
+ }
+ }
+ return copyOfRange(results, 0, count);
+ } catch (NumberFormatException e) {
+ throw new RuntimeException("error in parsing \"" + s + "\"", e);
+ }
+ }
+
+ /**
+ * Calculate the position of the next comma or space or negative sign
+ * @param s the string to search
+ * @param start the position to start searching
+ * @param result the result of the extraction, including the position of the
+ * the starting position of next number, whether it is ending with a '-'.
+ */
+ private static void extract(String s, int start, ExtractFloatResult result) {
+ // Now looking for ' ', ',', '.' or '-' from the start.
+ int currentIndex = start;
+ boolean foundSeparator = false;
+ result.mEndWithNegOrDot = false;
+ boolean secondDot = false;
+ boolean isExponential = false;
+ for (; currentIndex < s.length(); currentIndex++) {
+ boolean isPrevExponential = isExponential;
+ isExponential = false;
+ char currentChar = s.charAt(currentIndex);
+ switch (currentChar) {
+ case ' ':
+ case ',':
+ foundSeparator = true;
+ break;
+ case '-':
+ // The negative sign following a 'e' or 'E' is not a separator.
+ if (currentIndex != start && !isPrevExponential) {
+ foundSeparator = true;
+ result.mEndWithNegOrDot = true;
+ }
+ break;
+ case '.':
+ if (!secondDot) {
+ secondDot = true;
+ } else {
+ // This is the second dot, and it is considered as a separator.
+ foundSeparator = true;
+ result.mEndWithNegOrDot = true;
+ }
+ break;
+ case 'e':
+ case 'E':
+ isExponential = true;
+ break;
+ }
+ if (foundSeparator) {
+ break;
+ }
+ }
+ // When there is nothing found, then we put the end position to the end
+ // of the string.
+ result.mEndPosition = currentIndex;
+ }
+
+ /**
+ * Each PathDataNode represents one command in the "d" attribute of the svg
+ * file.
+ * An array of PathDataNode can represent the whole "d" attribute.
+ */
+ public static class PathDataNode {
+ private char mType;
+ private float[] mParams;
+
+ private PathDataNode(char type, float[] params) {
+ mType = type;
+ mParams = params;
+ }
+
+ private PathDataNode(PathDataNode n) {
+ mType = n.mType;
+ mParams = copyOfRange(n.mParams, 0, n.mParams.length);
+ }
+
+ /**
+ * Convert an array of PathDataNode to Path.
+ *
+ * @param node The source array of PathDataNode.
+ * @param path The target Path object.
+ */
+ public static void nodesToPath(PathDataNode[] node, Path path) {
+ float[] current = new float[6];
+ char previousCommand = 'm';
+ for (int i = 0; i < node.length; i++) {
+ addCommand(path, current, previousCommand, node[i].mType, node[i].mParams);
+ previousCommand = node[i].mType;
+ }
+ }
+
+ /**
+ * The current PathDataNode will be interpolated between the
+ * <code>nodeFrom</code> and <code>nodeTo</code> according to the
+ * <code>fraction</code>.
+ *
+ * @param nodeFrom The start value as a PathDataNode.
+ * @param nodeTo The end value as a PathDataNode
+ * @param fraction The fraction to interpolate.
+ */
+ public void interpolatePathDataNode(PathDataNode nodeFrom,
+ PathDataNode nodeTo, float fraction) {
+ for (int i = 0; i < nodeFrom.mParams.length; i++) {
+ mParams[i] = nodeFrom.mParams[i] * (1 - fraction)
+ + nodeTo.mParams[i] * fraction;
+ }
+ }
+
+ private static void addCommand(Path path, float[] current,
+ char previousCmd, char cmd, float[] val) {
+
+ int incr = 2;
+ float currentX = current[0];
+ float currentY = current[1];
+ float ctrlPointX = current[2];
+ float ctrlPointY = current[3];
+ float currentSegmentStartX = current[4];
+ float currentSegmentStartY = current[5];
+ float reflectiveCtrlPointX;
+ float reflectiveCtrlPointY;
+
+ switch (cmd) {
+ case 'z':
+ case 'Z':
+ path.close();
+ // Path is closed here, but we need to move the pen to the
+ // closed position. So we cache the segment's starting position,
+ // and restore it here.
+ currentX = currentSegmentStartX;
+ currentY = currentSegmentStartY;
+ ctrlPointX = currentSegmentStartX;
+ ctrlPointY = currentSegmentStartY;
+ path.moveTo(currentX, currentY);
+ break;
+ case 'm':
+ case 'M':
+ case 'l':
+ case 'L':
+ case 't':
+ case 'T':
+ incr = 2;
+ break;
+ case 'h':
+ case 'H':
+ case 'v':
+ case 'V':
+ incr = 1;
+ break;
+ case 'c':
+ case 'C':
+ incr = 6;
+ break;
+ case 's':
+ case 'S':
+ case 'q':
+ case 'Q':
+ incr = 4;
+ break;
+ case 'a':
+ case 'A':
+ incr = 7;
+ break;
+ }
+
+ for (int k = 0; k < val.length; k += incr) {
+ switch (cmd) {
+ case 'm': // moveto - Start a new sub-path (relative)
+ path.rMoveTo(val[k + 0], val[k + 1]);
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+ currentSegmentStartX = currentX;
+ currentSegmentStartY = currentY;
+ break;
+ case 'M': // moveto - Start a new sub-path
+ path.moveTo(val[k + 0], val[k + 1]);
+ currentX = val[k + 0];
+ currentY = val[k + 1];
+ currentSegmentStartX = currentX;
+ currentSegmentStartY = currentY;
+ break;
+ case 'l': // lineto - Draw a line from the current point (relative)
+ path.rLineTo(val[k + 0], val[k + 1]);
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+ break;
+ case 'L': // lineto - Draw a line from the current point
+ path.lineTo(val[k + 0], val[k + 1]);
+ currentX = val[k + 0];
+ currentY = val[k + 1];
+ break;
+ case 'h': // horizontal lineto - Draws a horizontal line (relative)
+ path.rLineTo(val[k + 0], 0);
+ currentX += val[k + 0];
+ break;
+ case 'H': // horizontal lineto - Draws a horizontal line
+ path.lineTo(val[k + 0], currentY);
+ currentX = val[k + 0];
+ break;
+ case 'v': // vertical lineto - Draws a vertical line from the current point (r)
+ path.rLineTo(0, val[k + 0]);
+ currentY += val[k + 0];
+ break;
+ case 'V': // vertical lineto - Draws a vertical line from the current point
+ path.lineTo(currentX, val[k + 0]);
+ currentY = val[k + 0];
+ break;
+ case 'c': // curveto - Draws a cubic Bézier curve (relative)
+ path.rCubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
+ val[k + 4], val[k + 5]);
+
+ ctrlPointX = currentX + val[k + 2];
+ ctrlPointY = currentY + val[k + 3];
+ currentX += val[k + 4];
+ currentY += val[k + 5];
+
+ break;
+ case 'C': // curveto - Draws a cubic Bézier curve
+ path.cubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
+ val[k + 4], val[k + 5]);
+ currentX = val[k + 4];
+ currentY = val[k + 5];
+ ctrlPointX = val[k + 2];
+ ctrlPointY = val[k + 3];
+ break;
+ case 's': // smooth curveto - Draws a cubic Bézier curve (reflective cp)
+ reflectiveCtrlPointX = 0;
+ reflectiveCtrlPointY = 0;
+ if (previousCmd == 'c' || previousCmd == 's'
+ || previousCmd == 'C' || previousCmd == 'S') {
+ reflectiveCtrlPointX = currentX - ctrlPointX;
+ reflectiveCtrlPointY = currentY - ctrlPointY;
+ }
+ path.rCubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+ val[k + 0], val[k + 1],
+ val[k + 2], val[k + 3]);
+
+ ctrlPointX = currentX + val[k + 0];
+ ctrlPointY = currentY + val[k + 1];
+ currentX += val[k + 2];
+ currentY += val[k + 3];
+ break;
+ case 'S': // shorthand/smooth curveto Draws a cubic Bézier curve(reflective cp)
+ reflectiveCtrlPointX = currentX;
+ reflectiveCtrlPointY = currentY;
+ if (previousCmd == 'c' || previousCmd == 's'
+ || previousCmd == 'C' || previousCmd == 'S') {
+ reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
+ reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
+ }
+ path.cubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+ val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
+ ctrlPointX = val[k + 0];
+ ctrlPointY = val[k + 1];
+ currentX = val[k + 2];
+ currentY = val[k + 3];
+ break;
+ case 'q': // Draws a quadratic Bézier (relative)
+ path.rQuadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
+ ctrlPointX = currentX + val[k + 0];
+ ctrlPointY = currentY + val[k + 1];
+ currentX += val[k + 2];
+ currentY += val[k + 3];
+ break;
+ case 'Q': // Draws a quadratic Bézier
+ path.quadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
+ ctrlPointX = val[k + 0];
+ ctrlPointY = val[k + 1];
+ currentX = val[k + 2];
+ currentY = val[k + 3];
+ break;
+ case 't': // Draws a quadratic Bézier curve(reflective control point)(relative)
+ reflectiveCtrlPointX = 0;
+ reflectiveCtrlPointY = 0;
+ if (previousCmd == 'q' || previousCmd == 't'
+ || previousCmd == 'Q' || previousCmd == 'T') {
+ reflectiveCtrlPointX = currentX - ctrlPointX;
+ reflectiveCtrlPointY = currentY - ctrlPointY;
+ }
+ path.rQuadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+ val[k + 0], val[k + 1]);
+ ctrlPointX = currentX + reflectiveCtrlPointX;
+ ctrlPointY = currentY + reflectiveCtrlPointY;
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+ break;
+ case 'T': // Draws a quadratic Bézier curve (reflective control point)
+ reflectiveCtrlPointX = currentX;
+ reflectiveCtrlPointY = currentY;
+ if (previousCmd == 'q' || previousCmd == 't'
+ || previousCmd == 'Q' || previousCmd == 'T') {
+ reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
+ reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
+ }
+ path.quadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+ val[k + 0], val[k + 1]);
+ ctrlPointX = reflectiveCtrlPointX;
+ ctrlPointY = reflectiveCtrlPointY;
+ currentX = val[k + 0];
+ currentY = val[k + 1];
+ break;
+ case 'a': // Draws an elliptical arc
+ // (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
+ drawArc(path,
+ currentX,
+ currentY,
+ val[k + 5] + currentX,
+ val[k + 6] + currentY,
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3] != 0,
+ val[k + 4] != 0);
+ currentX += val[k + 5];
+ currentY += val[k + 6];
+ ctrlPointX = currentX;
+ ctrlPointY = currentY;
+ break;
+ case 'A': // Draws an elliptical arc
+ drawArc(path,
+ currentX,
+ currentY,
+ val[k + 5],
+ val[k + 6],
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3] != 0,
+ val[k + 4] != 0);
+ currentX = val[k + 5];
+ currentY = val[k + 6];
+ ctrlPointX = currentX;
+ ctrlPointY = currentY;
+ break;
+ }
+ previousCmd = cmd;
+ }
+ current[0] = currentX;
+ current[1] = currentY;
+ current[2] = ctrlPointX;
+ current[3] = ctrlPointY;
+ current[4] = currentSegmentStartX;
+ current[5] = currentSegmentStartY;
+ }
+
+ private static void drawArc(Path p,
+ float x0,
+ float y0,
+ float x1,
+ float y1,
+ float a,
+ float b,
+ float theta,
+ boolean isMoreThanHalf,
+ boolean isPositiveArc) {
+
+ /* Convert rotation angle from degrees to radians */
+ double thetaD = Math.toRadians(theta);
+ /* Pre-compute rotation matrix entries */
+ double cosTheta = Math.cos(thetaD);
+ double sinTheta = Math.sin(thetaD);
+ /* Transform (x0, y0) and (x1, y1) into unit space */
+ /* using (inverse) rotation, followed by (inverse) scale */
+ double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
+ double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
+ double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
+ double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
+
+ /* Compute differences and averages */
+ double dx = x0p - x1p;
+ double dy = y0p - y1p;
+ double xm = (x0p + x1p) / 2;
+ double ym = (y0p + y1p) / 2;
+ /* Solve for intersecting unit circles */
+ double dsq = dx * dx + dy * dy;
+ if (dsq == 0.0) {
+ Log.w(LOGTAG, " Points are coincident");
+ return; /* Points are coincident */
+ }
+ double disc = 1.0 / dsq - 1.0 / 4.0;
+ if (disc < 0.0) {
+ Log.w(LOGTAG, "Points are too far apart " + dsq);
+ float adjust = (float) (Math.sqrt(dsq) / 1.99999);
+ drawArc(p, x0, y0, x1, y1, a * adjust,
+ b * adjust, theta, isMoreThanHalf, isPositiveArc);
+ return; /* Points are too far apart */
+ }
+ double s = Math.sqrt(disc);
+ double sdx = s * dx;
+ double sdy = s * dy;
+ double cx;
+ double cy;
+ if (isMoreThanHalf == isPositiveArc) {
+ cx = xm - sdy;
+ cy = ym + sdx;
+ } else {
+ cx = xm + sdy;
+ cy = ym - sdx;
+ }
+
+ double eta0 = Math.atan2((y0p - cy), (x0p - cx));
+
+ double eta1 = Math.atan2((y1p - cy), (x1p - cx));
+
+ double sweep = (eta1 - eta0);
+ if (isPositiveArc != (sweep >= 0)) {
+ if (sweep > 0) {
+ sweep -= 2 * Math.PI;
+ } else {
+ sweep += 2 * Math.PI;
+ }
+ }
+
+ cx *= a;
+ cy *= b;
+ double tcx = cx;
+ cx = cx * cosTheta - cy * sinTheta;
+ cy = tcx * sinTheta + cy * cosTheta;
+
+ arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
+ }
+
+ /**
+ * Converts an arc to cubic Bezier segments and records them in p.
+ *
+ * @param p The target for the cubic Bezier segments
+ * @param cx The x coordinate center of the ellipse
+ * @param cy The y coordinate center of the ellipse
+ * @param a The radius of the ellipse in the horizontal direction
+ * @param b The radius of the ellipse in the vertical direction
+ * @param e1x E(eta1) x coordinate of the starting point of the arc
+ * @param e1y E(eta2) y coordinate of the starting point of the arc
+ * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
+ * @param start The start angle of the arc on the ellipse
+ * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
+ */
+ private static void arcToBezier(Path p,
+ double cx,
+ double cy,
+ double a,
+ double b,
+ double e1x,
+ double e1y,
+ double theta,
+ double start,
+ double sweep) {
+ // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
+ // and http://www.spaceroots.org/documents/ellipse/node22.html
+
+ // Maximum of 45 degrees per cubic Bezier segment
+ int numSegments = Math.abs((int) Math.ceil(sweep * 4 / Math.PI));
+
+ double eta1 = start;
+ double cosTheta = Math.cos(theta);
+ double sinTheta = Math.sin(theta);
+ double cosEta1 = Math.cos(eta1);
+ double sinEta1 = Math.sin(eta1);
+ double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
+ double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
+
+ double anglePerSegment = sweep / numSegments;
+ for (int i = 0; i < numSegments; i++) {
+ double eta2 = eta1 + anglePerSegment;
+ double sinEta2 = Math.sin(eta2);
+ double cosEta2 = Math.cos(eta2);
+ double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
+ double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
+ double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
+ double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
+ double tanDiff2 = Math.tan((eta2 - eta1) / 2);
+ double alpha =
+ Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
+ double q1x = e1x + alpha * ep1x;
+ double q1y = e1y + alpha * ep1y;
+ double q2x = e2x - alpha * ep2x;
+ double q2y = e2y - alpha * ep2y;
+
+ p.cubicTo((float) q1x,
+ (float) q1y,
+ (float) q2x,
+ (float) q2y,
+ (float) e2x,
+ (float) e2y);
+ eta1 = eta2;
+ e1x = e2x;
+ e1y = e2y;
+ ep1x = ep2x;
+ ep1y = ep2y;
+ }
+ }
+ }
+}
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
new file mode 100644
index 0000000..d33c204
--- /dev/null
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
@@ -0,0 +1,1470 @@
+/*
+ * Copyright (C) 2015 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.graphics.drawable;
+
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.DrawableRes;
+import android.support.v4.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Stack;
+
+/**
+ * This lets you create a drawable based on an XML vector graphic. It can be defined in an XML file
+ * with the <code><vector></code> element.
+ * <p/>
+ * The vector drawable has the following elements:
+ * <p/>
+ * <dt><code><vector></code></dt>
+ * <dl>
+ * <dd>Used to define a vector drawable
+ * <dl>
+ * <dt><code>android:name</code></dt>
+ * <dd>Defines the name of this vector drawable.</dd>
+ * <dt><code>android:width</code></dt>
+ * <dd>Used to define the intrinsic width of the drawable. This support all the dimension units,
+ * normally specified with dp.</dd>
+ * <dt><code>android:height</code></dt>
+ * <dd>Used to define the intrinsic height the drawable. This support all the dimension units,
+ * normally specified with dp.</dd>
+ * <dt><code>android:viewportWidth</code></dt>
+ * <dd>Used to define the width of the viewport space. Viewport is basically the virtual canvas
+ * where the paths are drawn on.</dd>
+ * <dt><code>android:viewportHeight</code></dt>
+ * <dd>Used to define the height of the viewport space. Viewport is basically the virtual canvas
+ * where the paths are drawn on.</dd>
+ * <dt><code>android:tint</code></dt>
+ * <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd>
+ * <dt><code>android:tintMode</code></dt>
+ * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd>
+ * <dt><code>android:autoMirrored</code></dt>
+ * <dd>Indicates if the drawable needs to be mirrored when its layout direction is RTL
+ * (right-to-left).</dd>
+ * <dt><code>android:alpha</code></dt>
+ * <dd>The opacity of this drawable.</dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ * <dl>
+ * <dt><code><group></code></dt>
+ * <dd>Defines a group of paths or subgroups, plus transformation information. The transformations
+ * are defined in the same coordinates as the viewport. And the transformations are applied in the
+ * order of scale, rotate then translate.
+ * <dl>
+ * <dt><code>android:name</code></dt>
+ * <dd>Defines the name of the group.</dd>
+ * <dt><code>android:rotation</code></dt>
+ * <dd>The degrees of rotation of the group.</dd>
+ * <dt><code>android:pivotX</code></dt>
+ * <dd>The X coordinate of the pivot for the scale and rotation of the group. This is defined in the
+ * viewport space.</dd>
+ * <dt><code>android:pivotY</code></dt>
+ * <dd>The Y coordinate of the pivot for the scale and rotation of the group. This is defined in the
+ * viewport space.</dd>
+ * <dt><code>android:scaleX</code></dt>
+ * <dd>The amount of scale on the X Coordinate.</dd>
+ * <dt><code>android:scaleY</code></dt>
+ * <dd>The amount of scale on the Y coordinate.</dd>
+ * <dt><code>android:translateX</code></dt>
+ * <dd>The amount of translation on the X coordinate. This is defined in the viewport space.</dd>
+ * <dt><code>android:translateY</code></dt>
+ * <dd>The amount of translation on the Y coordinate. This is defined in the viewport space.</dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ * <dl>
+ * <dt><code><path></code></dt>
+ * <dd>Defines paths to be drawn.
+ * <dl>
+ * <dt><code>android:name</code></dt>
+ * <dd>Defines the name of the path.</dd>
+ * <dt><code>android:pathData</code></dt>
+ * <dd>Defines path data using exactly same format as "d" attribute in the SVG's path
+ * data. This is defined in the viewport space.</dd>
+ * <dt><code>android:fillColor</code></dt>
+ * <dd>Defines the color to fill the path (none if not present).</dd>
+ * <dt><code>android:strokeColor</code></dt>
+ * <dd>Defines the color to draw the path outline (none if not present).</dd>
+ * <dt><code>android:strokeWidth</code></dt>
+ * <dd>The width a path stroke.</dd>
+ * <dt><code>android:strokeAlpha</code></dt>
+ * <dd>The opacity of a path stroke.</dd>
+ * <dt><code>android:fillAlpha</code></dt>
+ * <dd>The opacity to fill the path with.</dd>
+ * <dt><code>android:trimPathStart</code></dt>
+ * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd>
+ * <dt><code>android:trimPathEnd</code></dt>
+ * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd>
+ * <dt><code>android:trimPathOffset</code></dt>
+ * <dd>Shift trim region (allows showed region to include the start and end), in the range from 0 to
+ * 1.</dd>
+ * <dt><code>android:strokeLineCap</code></dt>
+ * <dd>Sets the linecap for a stroked path: butt, round, square.</dd>
+ * <dt><code>android:strokeLineJoin</code></dt>
+ * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd>
+ * <dt><code>android:strokeMiterLimit</code></dt>
+ * <dd>Sets the Miter limit for a stroked path.</dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ * <dl>
+ * <dt><code><clip-path></code></dt>
+ * <dd>Defines path to be the current clip.
+ * <dl>
+ * <dt><code>android:name</code></dt>
+ * <dd>Defines the name of the clip path.</dd>
+ * <dt><code>android:pathData</code></dt>
+ * <dd>Defines clip path data using the same format as "d" attribute in the SVG's
+ * path data.</dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ * <li>Here is a simple VectorDrawable in this vectordrawable.xml file.
+ * <pre>
+ * <vector xmlns:android="http://schemas.android.com/apk/res/android"
+ * android:height="64dp"
+ * android:width="64dp"
+ * android:viewportHeight="600"
+ * android:viewportWidth="600" >
+ * <group
+ * android:name="rotationGroup"
+ * android:pivotX="300.0"
+ * android:pivotY="300.0"
+ * android:rotation="45.0" >
+ * <path
+ * android:name="v"
+ * android:fillColor="#000000"
+ * android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
+ * </group>
+ * </vector>
+ * </pre></li>
+ */
+public class VectorDrawableCompat extends Drawable {
+ static final String LOGTAG = "VectorDrawableCompat";
+
+ static final PorterDuff.Mode DEFAULT_TINT_MODE = PorterDuff.Mode.SRC_IN;
+
+ private static final String SHAPE_CLIP_PATH = "clip-path";
+ private static final String SHAPE_GROUP = "group";
+ private static final String SHAPE_PATH = "path";
+ private static final String SHAPE_VECTOR = "vector";
+
+ private static final int LINECAP_BUTT = 0;
+ private static final int LINECAP_ROUND = 1;
+ private static final int LINECAP_SQUARE = 2;
+
+ private static final int LINEJOIN_MITER = 0;
+ private static final int LINEJOIN_ROUND = 1;
+ private static final int LINEJOIN_BEVEL = 2;
+
+ private static final boolean DBG_VECTOR_DRAWABLE = true;
+
+ private VectorDrawableState mVectorState;
+
+ private PorterDuffColorFilter mTintFilter;
+ private ColorFilter mColorFilter;
+
+ private boolean mMutated;
+
+ // AnimatedVectorDrawable needs to turn off the cache all the time, otherwise,
+ // caching the bitmap by default is allowed.
+ private boolean mAllowCaching = true;
+
+ private VectorDrawableCompat() {
+ mVectorState = new VectorDrawableState();
+ }
+
+ private VectorDrawableCompat(VectorDrawableState state) {
+ mVectorState = state;
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ }
+
+ @Override
+ public Drawable mutate() {
+ if (!mMutated && super.mutate() == this) {
+ mVectorState = new VectorDrawableState(mVectorState);
+ mMutated = true;
+ }
+ return this;
+ }
+
+ Object getTargetByName(String name) {
+ return mVectorState.mVPathRenderer.mVGTargetsMap.get(name);
+ }
+
+ @Override
+ public ConstantState getConstantState() {
+ mVectorState.mChangingConfigurations = getChangingConfigurations();
+ return mVectorState;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ final Rect bounds = getBounds();
+ if (bounds.width() == 0 || bounds.height() == 0) {
+ // too small to draw
+ return;
+ }
+
+ final int saveCount = canvas.save();
+ final boolean needMirroring = needMirroring();
+
+ canvas.translate(bounds.left, bounds.top);
+ if (needMirroring) {
+ canvas.translate(bounds.width(), 0);
+ canvas.scale(-1.0f, 1.0f);
+ }
+
+ // Color filters always override tint filters.
+ final ColorFilter colorFilter = mColorFilter == null ? mTintFilter : mColorFilter;
+
+ if (!mAllowCaching) {
+ // AnimatedVectorDrawable
+ if (!mVectorState.hasTranslucentRoot()) {
+ mVectorState.mVPathRenderer.draw(
+ canvas, bounds.width(), bounds.height(), colorFilter);
+ } else {
+ mVectorState.createCachedBitmapIfNeeded(bounds);
+ mVectorState.updateCachedBitmap(bounds);
+ mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter);
+ }
+ } else {
+ // Static Vector Drawable case.
+ mVectorState.createCachedBitmapIfNeeded(bounds);
+ if (!mVectorState.canReuseCache()) {
+ mVectorState.updateCachedBitmap(bounds);
+ mVectorState.updateCacheStates();
+ }
+ mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter);
+ }
+
+ canvas.restoreToCount(saveCount);
+ }
+
+ public int getAlpha() {
+ return mVectorState.mVPathRenderer.getRootAlpha();
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) {
+ mVectorState.mVPathRenderer.setRootAlpha(alpha);
+ invalidateSelf();
+ }
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ mColorFilter = colorFilter;
+ invalidateSelf();
+ }
+
+ /**
+ * Ensures the tint filter is consistent with the current tint color and
+ * mode.
+ */
+ PorterDuffColorFilter updateTintFilter(PorterDuffColorFilter tintFilter, ColorStateList tint,
+ PorterDuff.Mode tintMode) {
+ if (tint == null || tintMode == null) {
+ return null;
+ }
+ // setMode, setColor of PorterDuffColorFilter are not public method in SDK v7.
+ // Therefore we create a new one all the time here. Don't expect this is called often.
+ final int color = tint.getColorForState(getState(), Color.TRANSPARENT);
+ return new PorterDuffColorFilter(color, tintMode);
+ }
+
+ public void setTint(int tint) {
+ setTintList(ColorStateList.valueOf(tint));
+ }
+
+ public void setTintList(ColorStateList tint) {
+ final VectorDrawableState state = mVectorState;
+ if (state.mTint != tint) {
+ state.mTint = tint;
+ mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode);
+ invalidateSelf();
+ }
+ }
+
+ public void setTintMode(Mode tintMode) {
+ final VectorDrawableState state = mVectorState;
+ if (state.mTintMode != tintMode) {
+ state.mTintMode = tintMode;
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode);
+ invalidateSelf();
+ }
+ }
+
+ @Override
+ public boolean isStateful() {
+ return super.isStateful() || (mVectorState != null && mVectorState.mTint != null
+ && mVectorState.mTint.isStateful());
+ }
+
+ @Override
+ protected boolean onStateChange(int[] stateSet) {
+ final VectorDrawableState state = mVectorState;
+ if (state.mTint != null && state.mTintMode != null) {
+ // mTintFilter = updateTintFilter(this, mTintFilter, state.mTint, state.mTintMode);
+ invalidateSelf();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return (int) mVectorState.mVPathRenderer.mBaseWidth;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return (int) mVectorState.mVPathRenderer.mBaseHeight;
+ }
+
+ // Don't support re-applying themes. The initial theme loading is working.
+ public boolean canApplyTheme() {
+ return false;
+ }
+
+ /**
+ * The size of a pixel when scaled from the intrinsic dimension to the viewport dimension. This
+ * is used to calculate the path animation accuracy.
+ *
+ * @hide
+ */
+ public float getPixelSize() {
+ if (mVectorState == null && mVectorState.mVPathRenderer == null ||
+ mVectorState.mVPathRenderer.mBaseWidth == 0 ||
+ mVectorState.mVPathRenderer.mBaseHeight == 0 ||
+ mVectorState.mVPathRenderer.mViewportHeight == 0 ||
+ mVectorState.mVPathRenderer.mViewportWidth == 0) {
+ return 1; // fall back to 1:1 pixel mapping.
+ }
+ float intrinsicWidth = mVectorState.mVPathRenderer.mBaseWidth;
+ float intrinsicHeight = mVectorState.mVPathRenderer.mBaseHeight;
+ float viewportWidth = mVectorState.mVPathRenderer.mViewportWidth;
+ float viewportHeight = mVectorState.mVPathRenderer.mViewportHeight;
+ float scaleX = viewportWidth / intrinsicWidth;
+ float scaleY = viewportHeight / intrinsicHeight;
+ return Math.min(scaleX, scaleY);
+ }
+
+ /**
+ * Create a VectorDrawableCompat object.
+ *
+ * @param res the resources.
+ * @param resId the resource ID for VectorDrawableCompat object.
+ * @param theme the theme of this vector drawable, it can be null.
+ * @return a new VectorDrawableCompat or null if parsing error is found.
+ */
+ @Nullable
+ public static VectorDrawableCompat create(@NonNull Resources res, @DrawableRes int resId,
+ @Nullable Theme theme) {
+ try {
+ final XmlPullParser parser = res.getXml(resId);
+ final AttributeSet attrs = Xml.asAttributeSet(parser);
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG &&
+ type != XmlPullParser.END_DOCUMENT) {
+ // Empty loop
+ }
+ if (type != XmlPullParser.START_TAG) {
+ throw new XmlPullParserException("No start tag found");
+ }
+
+ final VectorDrawableCompat drawable = new VectorDrawableCompat();
+ drawable.inflate(res, parser, attrs, theme);
+
+ return drawable;
+ } catch (XmlPullParserException e) {
+ Log.e(LOGTAG, "parser error", e);
+ } catch (IOException e) {
+ Log.e(LOGTAG, "parser error", e);
+ }
+ return null;
+ }
+
+ private static int applyAlpha(int color, float alpha) {
+ int alphaBytes = Color.alpha(color);
+ color &= 0x00FFFFFF;
+ color |= ((int) (alphaBytes * alpha)) << 24;
+ return color;
+ }
+
+ /**
+ * Obtains styled attributes from the theme, if available, or unstyled
+ * resources if the theme is null.
+ */
+ static TypedArray obtainAttributes(
+ Resources res, Theme theme, AttributeSet set, int[] attrs) {
+ if (theme == null) {
+ return res.obtainAttributes(set, attrs);
+ }
+ return theme.obtainStyledAttributes(set, attrs, 0, 0);
+ }
+
+
+ @Override
+ public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs)
+ throws XmlPullParserException, IOException {
+ inflate(res, parser, attrs, null);
+ }
+
+ public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
+ throws XmlPullParserException, IOException {
+ final VectorDrawableState state = mVectorState;
+ final VPathRenderer pathRenderer = new VPathRenderer();
+ state.mVPathRenderer = pathRenderer;
+
+ final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable);
+ updateStateFromTypedArray(a);
+ a.recycle();
+ state.mChangingConfigurations = getChangingConfigurations();
+ state.mCacheDirty = true;
+ inflateInternal(res, parser, attrs, theme);
+
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ }
+
+ private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
+ final VectorDrawableState state = mVectorState;
+ final VPathRenderer pathRenderer = state.mVPathRenderer;
+
+ // Account for any configuration changes.
+ // state.mChangingConfigurations |= Utils.getChangingConfigurations(a);
+
+ final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1);
+ // if (tintMode != -1) {
+ // state.mTintMode = Utils.parseTintMode(tintMode, DEFAULT_TINT_MODE);
+ // }
+
+ final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint);
+ if (tint != null) {
+ state.mTint = tint;
+ }
+
+ state.mAutoMirrored = a.getBoolean(
+ R.styleable.VectorDrawable_autoMirrored, state.mAutoMirrored);
+
+ pathRenderer.mViewportWidth = a.getFloat(
+ R.styleable.VectorDrawable_viewportWidth, pathRenderer.mViewportWidth);
+ pathRenderer.mViewportHeight = a.getFloat(
+ R.styleable.VectorDrawable_viewportHeight, pathRenderer.mViewportHeight);
+
+ if (pathRenderer.mViewportWidth <= 0) {
+ throw new XmlPullParserException(a.getPositionDescription() +
+ "<vector> tag requires viewportWidth > 0");
+ } else if (pathRenderer.mViewportHeight <= 0) {
+ throw new XmlPullParserException(a.getPositionDescription() +
+ "<vector> tag requires viewportHeight > 0");
+ }
+
+ pathRenderer.mBaseWidth = a.getDimension(
+ R.styleable.VectorDrawable_width, pathRenderer.mBaseWidth);
+ pathRenderer.mBaseHeight = a.getDimension(
+ R.styleable.VectorDrawable_height, pathRenderer.mBaseHeight);
+
+ if (pathRenderer.mBaseWidth <= 0) {
+ throw new XmlPullParserException(a.getPositionDescription() +
+ "<vector> tag requires width > 0");
+ } else if (pathRenderer.mBaseHeight <= 0) {
+ throw new XmlPullParserException(a.getPositionDescription() +
+ "<vector> tag requires height > 0");
+ }
+
+ final float alphaInFloat = a.getFloat(R.styleable.VectorDrawable_alpha,
+ pathRenderer.getAlpha());
+ pathRenderer.setAlpha(alphaInFloat);
+
+ final String name = a.getString(R.styleable.VectorDrawable_name);
+ if (name != null) {
+ pathRenderer.mRootName = name;
+ pathRenderer.mVGTargetsMap.put(name, pathRenderer);
+ }
+ }
+
+ private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
+ final VectorDrawableState state = mVectorState;
+ final VPathRenderer pathRenderer = state.mVPathRenderer;
+ boolean noPathTag = true;
+
+ // Use a stack to help to build the group tree.
+ // The top of the stack is always the current group.
+ final Stack<VGroup> groupStack = new Stack<VGroup>();
+ groupStack.push(pathRenderer.mRootGroup);
+
+ int eventType = parser.getEventType();
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ final String tagName = parser.getName();
+ final VGroup currentGroup = groupStack.peek();
+ Log.v(LOGTAG, tagName);
+ if (SHAPE_PATH.equals(tagName)) {
+ final VFullPath path = new VFullPath();
+ path.inflate(res, attrs, theme);
+ currentGroup.mChildren.add(path);
+ if (path.getPathName() != null) {
+ pathRenderer.mVGTargetsMap.put(path.getPathName(), path);
+ }
+ noPathTag = false;
+ state.mChangingConfigurations |= path.mChangingConfigurations;
+ } else if (SHAPE_CLIP_PATH.equals(tagName)) {
+ final VClipPath path = new VClipPath();
+ path.inflate(res, attrs, theme);
+ currentGroup.mChildren.add(path);
+ if (path.getPathName() != null) {
+ pathRenderer.mVGTargetsMap.put(path.getPathName(), path);
+ }
+ state.mChangingConfigurations |= path.mChangingConfigurations;
+ } else if (SHAPE_GROUP.equals(tagName)) {
+ VGroup newChildGroup = new VGroup();
+ newChildGroup.inflate(res, attrs, theme);
+ currentGroup.mChildren.add(newChildGroup);
+ groupStack.push(newChildGroup);
+ if (newChildGroup.getGroupName() != null) {
+ pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(),
+ newChildGroup);
+ }
+ state.mChangingConfigurations |= newChildGroup.mChangingConfigurations;
+ }
+ } else if (eventType == XmlPullParser.END_TAG) {
+ final String tagName = parser.getName();
+ if (SHAPE_GROUP.equals(tagName)) {
+ groupStack.pop();
+ }
+ }
+ eventType = parser.next();
+ }
+
+ // Print the tree out for debug.
+ if (DBG_VECTOR_DRAWABLE) {
+ printGroupTree(pathRenderer.mRootGroup, 0);
+ }
+
+ if (noPathTag) {
+ final StringBuffer tag = new StringBuffer();
+
+ if (tag.length() > 0) {
+ tag.append(" or ");
+ }
+ tag.append(SHAPE_PATH);
+
+ throw new XmlPullParserException("no " + tag + " defined");
+ }
+ }
+
+ private void printGroupTree(VGroup currentGroup, int level) {
+ String indent = "";
+ for (int i = 0; i < level; i++) {
+ indent += " ";
+ }
+ // Print the current node
+ Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName()
+ + " rotation is " + currentGroup.mRotate);
+ Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString());
+ // Then print all the children groups
+ for (int i = 0; i < currentGroup.mChildren.size(); i++) {
+ Object child = currentGroup.mChildren.get(i);
+ if (child instanceof VGroup) {
+ printGroupTree((VGroup) child, level + 1);
+ }
+ }
+ }
+
+ void setAllowCaching(boolean allowCaching) {
+ mAllowCaching = allowCaching;
+ }
+
+ // We don't support RTL auto mirroring since the getLayoutDirection() is for API 17+.
+ private boolean needMirroring() {
+ return false;
+ }
+
+ private static class VectorDrawableState extends ConstantState {
+ int mChangingConfigurations;
+ VPathRenderer mVPathRenderer;
+ ColorStateList mTint = null;
+ Mode mTintMode = DEFAULT_TINT_MODE;
+ boolean mAutoMirrored;
+
+ Bitmap mCachedBitmap;
+ int[] mCachedThemeAttrs;
+ ColorStateList mCachedTint;
+ Mode mCachedTintMode;
+ int mCachedRootAlpha;
+ boolean mCachedAutoMirrored;
+ boolean mCacheDirty;
+
+ /** Temporary paint object used to draw cached bitmaps. */
+ Paint mTempPaint;
+
+ // Deep copy for mutate() or implicitly mutate.
+ public VectorDrawableState(VectorDrawableState copy) {
+ if (copy != null) {
+ mChangingConfigurations = copy.mChangingConfigurations;
+ mVPathRenderer = new VPathRenderer(copy.mVPathRenderer);
+ if (copy.mVPathRenderer.mFillPaint != null) {
+ mVPathRenderer.mFillPaint = new Paint(copy.mVPathRenderer.mFillPaint);
+ }
+ if (copy.mVPathRenderer.mStrokePaint != null) {
+ mVPathRenderer.mStrokePaint = new Paint(copy.mVPathRenderer.mStrokePaint);
+ }
+ mTint = copy.mTint;
+ mTintMode = copy.mTintMode;
+ mAutoMirrored = copy.mAutoMirrored;
+ }
+ }
+
+ public void drawCachedBitmapWithRootAlpha(Canvas canvas, ColorFilter filter) {
+ // The bitmap's size is the same as the bounds.
+ final Paint p = getPaint(filter);
+ canvas.drawBitmap(mCachedBitmap, 0, 0, p);
+ }
+
+ public boolean hasTranslucentRoot() {
+ return mVPathRenderer.getRootAlpha() < 255;
+ }
+
+ /**
+ * @return null when there is no need for alpha paint.
+ */
+ public Paint getPaint(ColorFilter filter) {
+ if (!hasTranslucentRoot() && filter == null) {
+ return null;
+ }
+
+ if (mTempPaint == null) {
+ mTempPaint = new Paint();
+ mTempPaint.setFilterBitmap(true);
+ }
+ mTempPaint.setAlpha(mVPathRenderer.getRootAlpha());
+ mTempPaint.setColorFilter(filter);
+ return mTempPaint;
+ }
+
+ public void updateCachedBitmap(Rect bounds) {
+ mCachedBitmap.eraseColor(Color.TRANSPARENT);
+ Canvas tmpCanvas = new Canvas(mCachedBitmap);
+ mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height(), null);
+ }
+
+ public void createCachedBitmapIfNeeded(Rect bounds) {
+ if (mCachedBitmap == null || !canReuseBitmap(bounds.width(),
+ bounds.height())) {
+ mCachedBitmap = Bitmap.createBitmap(bounds.width(), bounds.height(),
+ Bitmap.Config.ARGB_8888);
+ mCacheDirty = true;
+ }
+
+ }
+
+ public boolean canReuseBitmap(int width, int height) {
+ if (width == mCachedBitmap.getWidth()
+ && height == mCachedBitmap.getHeight()) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean canReuseCache() {
+ if (!mCacheDirty
+ && mCachedTint == mTint
+ && mCachedTintMode == mTintMode
+ && mCachedAutoMirrored == mAutoMirrored
+ && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) {
+ return true;
+ }
+ return false;
+ }
+
+ public void updateCacheStates() {
+ // Use shallow copy here and shallow comparison in canReuseCache(),
+ // likely hit cache miss more, but practically not much difference.
+ mCachedTint = mTint;
+ mCachedTintMode = mTintMode;
+ mCachedRootAlpha = mVPathRenderer.getRootAlpha();
+ mCachedAutoMirrored = mAutoMirrored;
+ mCacheDirty = false;
+ }
+
+ public VectorDrawableState() {
+ mVPathRenderer = new VPathRenderer();
+ }
+
+ @Override
+ public Drawable newDrawable() {
+ return new VectorDrawableCompat(this);
+ }
+
+ @Override
+ public Drawable newDrawable(Resources res) {
+ return new VectorDrawableCompat(this);
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return mChangingConfigurations;
+ }
+ }
+
+ private static class VPathRenderer {
+ /* Right now the internal data structure is organized as a tree.
+ * Each node can be a group node, or a path.
+ * A group node can have groups or paths as children, but a path node has
+ * no children.
+ * One example can be:
+ * Root Group
+ * / | \
+ * Group Path Group
+ * / \ |
+ * Path Path Path
+ *
+ */
+ // Variables that only used temporarily inside the draw() call, so there
+ // is no need for deep copying.
+ private final Path mPath;
+ private final Path mRenderPath;
+ private static final Matrix IDENTITY_MATRIX = new Matrix();
+ private final Matrix mFinalPathMatrix = new Matrix();
+
+ private Paint mStrokePaint;
+ private Paint mFillPaint;
+ private PathMeasure mPathMeasure;
+
+ /////////////////////////////////////////////////////
+ // Variables below need to be copied (deep copy if applicable) for mutation.
+ private int mChangingConfigurations;
+ private final VGroup mRootGroup;
+ float mBaseWidth = 0;
+ float mBaseHeight = 0;
+ float mViewportWidth = 0;
+ float mViewportHeight = 0;
+ int mRootAlpha = 0xFF;
+ String mRootName = null;
+
+ final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>();
+
+ public VPathRenderer() {
+ mRootGroup = new VGroup();
+ mPath = new Path();
+ mRenderPath = new Path();
+ }
+
+ public void setRootAlpha(int alpha) {
+ mRootAlpha = alpha;
+ }
+
+ public int getRootAlpha() {
+ return mRootAlpha;
+ }
+
+ // setAlpha() and getAlpha() are used mostly for animation purpose, since
+ // Animator like to use alpha from 0 to 1.
+ public void setAlpha(float alpha) {
+ setRootAlpha((int) (alpha * 255));
+ }
+
+ @SuppressWarnings("unused")
+ public float getAlpha() {
+ return getRootAlpha() / 255.0f;
+ }
+
+ public VPathRenderer(VPathRenderer copy) {
+ mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
+ mPath = new Path(copy.mPath);
+ mRenderPath = new Path(copy.mRenderPath);
+ mBaseWidth = copy.mBaseWidth;
+ mBaseHeight = copy.mBaseHeight;
+ mViewportWidth = copy.mViewportWidth;
+ mViewportHeight = copy.mViewportHeight;
+ mChangingConfigurations = copy.mChangingConfigurations;
+ mRootAlpha = copy.mRootAlpha;
+ mRootName = copy.mRootName;
+ if (copy.mRootName != null) {
+ mVGTargetsMap.put(copy.mRootName, this);
+ }
+ }
+
+ private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix,
+ Canvas canvas, int w, int h, ColorFilter filter) {
+ // Calculate current group's matrix by preConcat the parent's and
+ // and the current one on the top of the stack.
+ // Basically the Mfinal = Mviewport * M0 * M1 * M2;
+ // Mi the local matrix at level i of the group tree.
+ currentGroup.mStackedMatrix.set(currentMatrix);
+
+ currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
+
+ // Draw the group tree in the same order as the XML file.
+ for (int i = 0; i < currentGroup.mChildren.size(); i++) {
+ Object child = currentGroup.mChildren.get(i);
+ if (child instanceof VGroup) {
+ VGroup childGroup = (VGroup) child;
+ drawGroupTree(childGroup, currentGroup.mStackedMatrix,
+ canvas, w, h, filter);
+ } else if (child instanceof VPath) {
+ VPath childPath = (VPath) child;
+ drawPath(currentGroup, childPath, canvas, w, h, filter);
+ }
+ }
+ }
+
+ public void draw(Canvas canvas, int w, int h, ColorFilter filter) {
+ // Travese the tree in pre-order to draw.
+ drawGroupTree(mRootGroup, IDENTITY_MATRIX, canvas, w, h, filter);
+ }
+
+ private void drawPath(VGroup vGroup, VPath vPath, Canvas canvas, int w, int h,
+ ColorFilter filter) {
+ final float scaleX = w / mViewportWidth;
+ final float scaleY = h / mViewportHeight;
+ final float minScale = Math.min(scaleX, scaleY);
+
+ mFinalPathMatrix.set(vGroup.mStackedMatrix);
+ mFinalPathMatrix.postScale(scaleX, scaleY);
+
+ vPath.toPath(mPath);
+ final Path path = mPath;
+
+ mRenderPath.reset();
+
+ if (vPath.isClipPath()) {
+ mRenderPath.addPath(path, mFinalPathMatrix);
+ canvas.clipPath(mRenderPath, Region.Op.REPLACE);
+ } else {
+ VFullPath fullPath = (VFullPath) vPath;
+ if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) {
+ float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f;
+ float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f;
+
+ if (mPathMeasure == null) {
+ mPathMeasure = new PathMeasure();
+ }
+ mPathMeasure.setPath(mPath, false);
+
+ float len = mPathMeasure.getLength();
+ start = start * len;
+ end = end * len;
+ path.reset();
+ if (start > end) {
+ mPathMeasure.getSegment(start, len, path, true);
+ mPathMeasure.getSegment(0f, end, path, true);
+ } else {
+ mPathMeasure.getSegment(start, end, path, true);
+ }
+ path.rLineTo(0, 0); // fix bug in measure
+ }
+ mRenderPath.addPath(path, mFinalPathMatrix);
+
+ if (fullPath.mFillColor != Color.TRANSPARENT) {
+ if (mFillPaint == null) {
+ mFillPaint = new Paint();
+ mFillPaint.setStyle(Paint.Style.FILL);
+ mFillPaint.setAntiAlias(true);
+ }
+
+ final Paint fillPaint = mFillPaint;
+ fillPaint.setColor(applyAlpha(fullPath.mFillColor, fullPath.mFillAlpha));
+ fillPaint.setColorFilter(filter);
+ canvas.drawPath(mRenderPath, fillPaint);
+ }
+
+ if (fullPath.mStrokeColor != Color.TRANSPARENT) {
+ if (mStrokePaint == null) {
+ mStrokePaint = new Paint();
+ mStrokePaint.setStyle(Paint.Style.STROKE);
+ mStrokePaint.setAntiAlias(true);
+ }
+
+ final Paint strokePaint = mStrokePaint;
+ if (fullPath.mStrokeLineJoin != null) {
+ strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin);
+ }
+
+ if (fullPath.mStrokeLineCap != null) {
+ strokePaint.setStrokeCap(fullPath.mStrokeLineCap);
+ }
+
+ strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
+ strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, fullPath.mStrokeAlpha));
+ strokePaint.setColorFilter(filter);
+ strokePaint.setStrokeWidth(fullPath.mStrokeWidth * minScale);
+ canvas.drawPath(mRenderPath, strokePaint);
+ }
+ }
+ }
+ }
+
+ private static class VGroup {
+ // mStackedMatrix is only used temporarily when drawing, it combines all
+ // the parents' local matrices with the current one.
+ private final Matrix mStackedMatrix = new Matrix();
+
+ /////////////////////////////////////////////////////
+ // Variables below need to be copied (deep copy if applicable) for mutation.
+ final ArrayList<Object> mChildren = new ArrayList<Object>();
+
+ private float mRotate = 0;
+ private float mPivotX = 0;
+ private float mPivotY = 0;
+ private float mScaleX = 1;
+ private float mScaleY = 1;
+ private float mTranslateX = 0;
+ private float mTranslateY = 0;
+
+ // mLocalMatrix is updated based on the update of transformation information,
+ // either parsed from the XML or by animation.
+ private final Matrix mLocalMatrix = new Matrix();
+ private int mChangingConfigurations;
+ private int[] mThemeAttrs;
+ private String mGroupName = null;
+
+ public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) {
+ mRotate = copy.mRotate;
+ mPivotX = copy.mPivotX;
+ mPivotY = copy.mPivotY;
+ mScaleX = copy.mScaleX;
+ mScaleY = copy.mScaleY;
+ mTranslateX = copy.mTranslateX;
+ mTranslateY = copy.mTranslateY;
+ mThemeAttrs = copy.mThemeAttrs;
+ mGroupName = copy.mGroupName;
+ mChangingConfigurations = copy.mChangingConfigurations;
+ if (mGroupName != null) {
+ targetsMap.put(mGroupName, this);
+ }
+
+ mLocalMatrix.set(copy.mLocalMatrix);
+
+ final ArrayList<Object> children = copy.mChildren;
+ for (int i = 0; i < children.size(); i++) {
+ Object copyChild = children.get(i);
+ if (copyChild instanceof VGroup) {
+ VGroup copyGroup = (VGroup) copyChild;
+ mChildren.add(new VGroup(copyGroup, targetsMap));
+ } else {
+ VPath newPath = null;
+ if (copyChild instanceof VFullPath) {
+ newPath = new VFullPath((VFullPath) copyChild);
+ } else if (copyChild instanceof VClipPath) {
+ newPath = new VClipPath((VClipPath) copyChild);
+ } else {
+ throw new IllegalStateException("Unknown object in the tree!");
+ }
+ mChildren.add(newPath);
+ if (newPath.mPathName != null) {
+ targetsMap.put(newPath.mPathName, newPath);
+ }
+ }
+ }
+ }
+
+ public VGroup() {
+ }
+
+ public String getGroupName() {
+ return mGroupName;
+ }
+
+ public Matrix getLocalMatrix() {
+ return mLocalMatrix;
+ }
+
+ public void inflate(Resources res, AttributeSet attrs, Theme theme) {
+ final TypedArray a = obtainAttributes(res, theme, attrs,
+ R.styleable.VectorDrawableGroup);
+ updateStateFromTypedArray(a);
+ a.recycle();
+ }
+
+ private void updateStateFromTypedArray(TypedArray a) {
+ // Account for any configuration changes.
+ // mChangingConfigurations |= Utils.getChangingConfigurations(a);
+
+ // Extract the theme attributes, if any.
+ mThemeAttrs = null; // TODO TINT THEME Not supported yet a.extractThemeAttrs();
+
+ mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate);
+ mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX);
+ mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY);
+ mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX);
+ mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY);
+ mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX);
+ mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
+
+ final String groupName = a.getString(R.styleable.VectorDrawableGroup_name);
+ if (groupName != null) {
+ mGroupName = groupName;
+ }
+
+ updateLocalMatrix();
+ }
+
+ private void updateLocalMatrix() {
+ // The order we apply is the same as the
+ // RenderNode.cpp::applyViewPropertyTransforms().
+ mLocalMatrix.reset();
+ mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
+ mLocalMatrix.postScale(mScaleX, mScaleY);
+ mLocalMatrix.postRotate(mRotate, 0, 0);
+ mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
+ }
+
+ /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
+ @SuppressWarnings("unused")
+ public float getRotation() {
+ return mRotate;
+ }
+
+ @SuppressWarnings("unused")
+ public void setRotation(float rotation) {
+ if (rotation != mRotate) {
+ mRotate = rotation;
+ updateLocalMatrix();
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public float getPivotX() {
+ return mPivotX;
+ }
+
+ @SuppressWarnings("unused")
+ public void setPivotX(float pivotX) {
+ if (pivotX != mPivotX) {
+ mPivotX = pivotX;
+ updateLocalMatrix();
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public float getPivotY() {
+ return mPivotY;
+ }
+
+ @SuppressWarnings("unused")
+ public void setPivotY(float pivotY) {
+ if (pivotY != mPivotY) {
+ mPivotY = pivotY;
+ updateLocalMatrix();
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public float getScaleX() {
+ return mScaleX;
+ }
+
+ @SuppressWarnings("unused")
+ public void setScaleX(float scaleX) {
+ if (scaleX != mScaleX) {
+ mScaleX = scaleX;
+ updateLocalMatrix();
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public float getScaleY() {
+ return mScaleY;
+ }
+
+ @SuppressWarnings("unused")
+ public void setScaleY(float scaleY) {
+ if (scaleY != mScaleY) {
+ mScaleY = scaleY;
+ updateLocalMatrix();
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public float getTranslateX() {
+ return mTranslateX;
+ }
+
+ @SuppressWarnings("unused")
+ public void setTranslateX(float translateX) {
+ if (translateX != mTranslateX) {
+ mTranslateX = translateX;
+ updateLocalMatrix();
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public float getTranslateY() {
+ return mTranslateY;
+ }
+
+ @SuppressWarnings("unused")
+ public void setTranslateY(float translateY) {
+ if (translateY != mTranslateY) {
+ mTranslateY = translateY;
+ updateLocalMatrix();
+ }
+ }
+ }
+
+ /**
+ * Common Path information for clip path and normal path.
+ */
+ private static class VPath {
+ protected PathParser.PathDataNode[] mNodes = null;
+ String mPathName;
+ int mChangingConfigurations;
+
+ public VPath() {
+ // Empty constructor.
+ }
+
+ public VPath(VPath copy) {
+ mPathName = copy.mPathName;
+ mChangingConfigurations = copy.mChangingConfigurations;
+ mNodes = PathParser.deepCopyNodes(copy.mNodes);
+ }
+
+ public void toPath(Path path) {
+ path.reset();
+ if (mNodes != null) {
+ PathParser.PathDataNode.nodesToPath(mNodes, path);
+ }
+ }
+
+ public String getPathName() {
+ return mPathName;
+ }
+
+ public boolean canApplyTheme() {
+ return false;
+ }
+
+ public void applyTheme(Theme t) {
+ }
+
+ public boolean isClipPath() {
+ return false;
+ }
+
+ /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
+ @SuppressWarnings("unused")
+ public PathParser.PathDataNode[] getPathData() {
+ return mNodes;
+ }
+
+ @SuppressWarnings("unused")
+ public void setPathData(PathParser.PathDataNode[] nodes) {
+ if (!PathParser.canMorph(mNodes, nodes)) {
+ // This should not happen in the middle of animation.
+ mNodes = PathParser.deepCopyNodes(nodes);
+ } else {
+ PathParser.updateNodes(mNodes, nodes);
+ }
+ }
+ }
+
+ /**
+ * Clip path, which only has name and pathData.
+ */
+ private static class VClipPath extends VPath {
+ public VClipPath() {
+ // Empty constructor.
+ }
+
+ public VClipPath(VClipPath copy) {
+ super(copy);
+ }
+
+ public void inflate(Resources r, AttributeSet attrs, Theme theme) {
+ // TODO TINT THEME Not supported yet
+ final TypedArray a = obtainAttributes(r, theme, attrs,
+ R.styleable.VectorDrawableClipPath);
+ updateStateFromTypedArray(a);
+ a.recycle();
+ }
+
+ private void updateStateFromTypedArray(TypedArray a) {
+ // Account for any configuration changes.
+ // mChangingConfigurations |= Utils.getChangingConfigurations(a);;
+
+ final String pathName = a.getString(R.styleable.VectorDrawableClipPath_name);
+ if (pathName != null) {
+ mPathName = pathName;
+ }
+
+ final String pathData = a.getString(R.styleable.VectorDrawableClipPath_pathData);
+ if (pathData != null) {
+ mNodes = PathParser.createNodesFromPathData(pathData);
+ }
+ }
+
+ @Override
+ public boolean isClipPath() {
+ return true;
+ }
+ }
+
+ /**
+ * Normal path, which contains all the fill / paint information.
+ */
+ private static class VFullPath extends VPath {
+ /////////////////////////////////////////////////////
+ // Variables below need to be copied (deep copy if applicable) for mutation.
+ private int[] mThemeAttrs;
+
+ int mStrokeColor = Color.TRANSPARENT;
+ float mStrokeWidth = 0;
+
+ int mFillColor = Color.TRANSPARENT;
+ float mStrokeAlpha = 1.0f;
+ int mFillRule;
+ float mFillAlpha = 1.0f;
+ float mTrimPathStart = 0;
+ float mTrimPathEnd = 1;
+ float mTrimPathOffset = 0;
+
+ Paint.Cap mStrokeLineCap = Paint.Cap.BUTT;
+ Paint.Join mStrokeLineJoin = Paint.Join.MITER;
+ float mStrokeMiterlimit = 4;
+
+ public VFullPath() {
+ // Empty constructor.
+ }
+
+ public VFullPath(VFullPath copy) {
+ super(copy);
+ mThemeAttrs = copy.mThemeAttrs;
+
+ mStrokeColor = copy.mStrokeColor;
+ mStrokeWidth = copy.mStrokeWidth;
+ mStrokeAlpha = copy.mStrokeAlpha;
+ mFillColor = copy.mFillColor;
+ mFillRule = copy.mFillRule;
+ mFillAlpha = copy.mFillAlpha;
+ mTrimPathStart = copy.mTrimPathStart;
+ mTrimPathEnd = copy.mTrimPathEnd;
+ mTrimPathOffset = copy.mTrimPathOffset;
+
+ mStrokeLineCap = copy.mStrokeLineCap;
+ mStrokeLineJoin = copy.mStrokeLineJoin;
+ mStrokeMiterlimit = copy.mStrokeMiterlimit;
+ }
+
+ private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) {
+ switch (id) {
+ case LINECAP_BUTT:
+ return Paint.Cap.BUTT;
+ case LINECAP_ROUND:
+ return Paint.Cap.ROUND;
+ case LINECAP_SQUARE:
+ return Paint.Cap.SQUARE;
+ default:
+ return defValue;
+ }
+ }
+
+ private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) {
+ switch (id) {
+ case LINEJOIN_MITER:
+ return Paint.Join.MITER;
+ case LINEJOIN_ROUND:
+ return Paint.Join.ROUND;
+ case LINEJOIN_BEVEL:
+ return Paint.Join.BEVEL;
+ default:
+ return defValue;
+ }
+ }
+
+ @Override
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null;
+ }
+
+ public void inflate(Resources r, AttributeSet attrs, Theme theme) {
+ final TypedArray a = obtainAttributes(r, theme, attrs,
+ R.styleable.VectorDrawablePath);
+ updateStateFromTypedArray(a);
+ a.recycle();
+ }
+
+ private void updateStateFromTypedArray(TypedArray a) {
+ // Account for any configuration changes.
+ // mChangingConfigurations |= Utils.getChangingConfigurations(a);
+
+ // Extract the theme attributes, if any.
+ mThemeAttrs = null; // TODO TINT THEME Not supported yet a.extractThemeAttrs();
+
+ final String pathName = a.getString(R.styleable.VectorDrawablePath_name);
+ if (pathName != null) {
+ mPathName = pathName;
+ }
+
+ final String pathData = a.getString(R.styleable.VectorDrawablePath_pathData);
+ if (pathData != null) {
+ mNodes = PathParser.createNodesFromPathData(pathData);
+ }
+
+ mFillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor,
+ mFillColor);
+ mFillAlpha = a.getFloat(R.styleable.VectorDrawablePath_fillAlpha,
+ mFillAlpha);
+ mStrokeLineCap = getStrokeLineCap(a.getInt(
+ R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap);
+ mStrokeLineJoin = getStrokeLineJoin(a.getInt(
+ R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin);
+ mStrokeMiterlimit = a.getFloat(
+ R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit);
+ mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor,
+ mStrokeColor);
+ mStrokeAlpha = a.getFloat(R.styleable.VectorDrawablePath_strokeAlpha,
+ mStrokeAlpha);
+ mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth,
+ mStrokeWidth);
+ mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd,
+ mTrimPathEnd);
+ mTrimPathOffset = a.getFloat(
+ R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset);
+ mTrimPathStart = a.getFloat(
+ R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart);
+ }
+
+ @Override
+ public void applyTheme(Theme t) {
+ if (mThemeAttrs == null) {
+ return;
+ }
+
+ /*
+ * TODO TINT THEME Not supported yet final TypedArray a =
+ * t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath);
+ * updateStateFromTypedArray(a); a.recycle();
+ */
+ }
+
+ /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
+ @SuppressWarnings("unused")
+ int getStrokeColor() {
+ return mStrokeColor;
+ }
+
+ @SuppressWarnings("unused")
+ void setStrokeColor(int strokeColor) {
+ mStrokeColor = strokeColor;
+ }
+
+ @SuppressWarnings("unused")
+ float getStrokeWidth() {
+ return mStrokeWidth;
+ }
+
+ @SuppressWarnings("unused")
+ void setStrokeWidth(float strokeWidth) {
+ mStrokeWidth = strokeWidth;
+ }
+
+ @SuppressWarnings("unused")
+ float getStrokeAlpha() {
+ return mStrokeAlpha;
+ }
+
+ @SuppressWarnings("unused")
+ void setStrokeAlpha(float strokeAlpha) {
+ mStrokeAlpha = strokeAlpha;
+ }
+
+ @SuppressWarnings("unused")
+ int getFillColor() {
+ return mFillColor;
+ }
+
+ @SuppressWarnings("unused")
+ void setFillColor(int fillColor) {
+ mFillColor = fillColor;
+ }
+
+ @SuppressWarnings("unused")
+ float getFillAlpha() {
+ return mFillAlpha;
+ }
+
+ @SuppressWarnings("unused")
+ void setFillAlpha(float fillAlpha) {
+ mFillAlpha = fillAlpha;
+ }
+
+ @SuppressWarnings("unused")
+ float getTrimPathStart() {
+ return mTrimPathStart;
+ }
+
+ @SuppressWarnings("unused")
+ void setTrimPathStart(float trimPathStart) {
+ mTrimPathStart = trimPathStart;
+ }
+
+ @SuppressWarnings("unused")
+ float getTrimPathEnd() {
+ return mTrimPathEnd;
+ }
+
+ @SuppressWarnings("unused")
+ void setTrimPathEnd(float trimPathEnd) {
+ mTrimPathEnd = trimPathEnd;
+ }
+
+ @SuppressWarnings("unused")
+ float getTrimPathOffset() {
+ return mTrimPathOffset;
+ }
+
+ @SuppressWarnings("unused")
+ void setTrimPathOffset(float trimPathOffset) {
+ mTrimPathOffset = trimPathOffset;
+ }
+ }
+}
diff --git a/graphics/drawable/testanimated/Android.mk b/graphics/drawable/testanimated/Android.mk
new file mode 100644
index 0000000..c888d9e
--- /dev/null
+++ b/graphics/drawable/testanimated/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SDK_VERSION := 11
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_RESOURCE_DIR = \
+ $(LOCAL_PATH)/res \
+ frameworks/support/graphics/drawable/res \
+
+LOCAL_PACKAGE_NAME := AndroidAnimatedVectorDrawableTests
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v11-animatedvectordrawable android-support-v4
+
+LOCAL_AAPT_FLAGS += --auto-add-overlay --extra-packages android.support.graphics.drawable
+
+include $(BUILD_PACKAGE)
diff --git a/graphics/drawable/testanimated/AndroidManifest.xml b/graphics/drawable/testanimated/AndroidManifest.xml
new file mode 100644
index 0000000..16171f2
--- /dev/null
+++ b/graphics/drawable/testanimated/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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="android.support.test.vectordrawable" >
+
+ <uses-sdk android:minSdkVersion="11" />
+
+ <application android:icon="@drawable/app_sample_code" android:label="AnimatedVectorDrawableCompatTest" >
+ <activity android:name="android.support.test.vectordrawable.TestAVDActivity" />
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/graphics/drawable/testanimated/res/anim/alpha_animation_progress_bar.xml b/graphics/drawable/testanimated/res/anim/alpha_animation_progress_bar.xml
new file mode 100644
index 0000000..2463a89
--- /dev/null
+++ b/graphics/drawable/testanimated/res/anim/alpha_animation_progress_bar.xml
@@ -0,0 +1,24 @@
+<!-- Copyright (C) 2015 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ android:duration="3350"
+ android:propertyName="alpha"
+ android:valueFrom="1"
+ android:valueTo="0.2" />
+
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/testanimated/res/anim/animation_grouping_1_01.xml b/graphics/drawable/testanimated/res/anim/animation_grouping_1_01.xml
new file mode 100644
index 0000000..36c297f
--- /dev/null
+++ b/graphics/drawable/testanimated/res/anim/animation_grouping_1_01.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:duration="3300"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="450" />
diff --git a/graphics/drawable/testanimated/res/anim/trim_path_animation_progress_bar.xml b/graphics/drawable/testanimated/res/anim/trim_path_animation_progress_bar.xml
new file mode 100644
index 0000000..388c759
--- /dev/null
+++ b/graphics/drawable/testanimated/res/anim/trim_path_animation_progress_bar.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ android:duration="1300"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:propertyName="trimPathStart"
+ android:repeatCount="-1"
+ android:valueFrom="0"
+ android:valueTo="0.75"
+ android:valueType="floatType" />
+ <objectAnimator
+ android:duration="1300"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:propertyName="trimPathEnd"
+ android:repeatCount="-1"
+ android:valueFrom="0.25"
+ android:valueTo="1.0"
+ android:valueType="floatType" />
+ <objectAnimator
+ android:duration="1300"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:propertyName="trimPathOffset"
+ android:repeatCount="-1"
+ android:valueFrom="0"
+ android:valueTo="0.25"
+ android:valueType="floatType" />
+
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/testanimated/res/drawable/animation_vector_drawable_grouping_1.xml b/graphics/drawable/testanimated/res/drawable/animation_vector_drawable_grouping_1.xml
new file mode 100644
index 0000000..7c3b1de
--- /dev/null
+++ b/graphics/drawable/testanimated/res/drawable/animation_vector_drawable_grouping_1.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2015 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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:drawable="@drawable/vector_drawable_grouping_1" >
+
+ <target
+ auto:name="sun"
+ auto:animation="@anim/animation_grouping_1_01" />
+ <target
+ auto:name="earth"
+ auto:animation="@anim/animation_grouping_1_01" />
+
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/testanimated/res/drawable/animation_vector_progress_bar.xml b/graphics/drawable/testanimated/res/drawable/animation_vector_progress_bar.xml
new file mode 100644
index 0000000..e37d2a1
--- /dev/null
+++ b/graphics/drawable/testanimated/res/drawable/animation_vector_progress_bar.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2015 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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:drawable="@drawable/vector_drawable_progress_bar" >
+
+ <target
+ auto:name="pie1"
+ auto:animation="@anim/trim_path_animation_progress_bar" />
+ <target
+ auto:name="root_bar"
+ auto:animation="@anim/alpha_animation_progress_bar" />
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/testanimated/res/drawable/app_sample_code.png b/graphics/drawable/testanimated/res/drawable/app_sample_code.png
new file mode 100755
index 0000000..66a1984
--- /dev/null
+++ b/graphics/drawable/testanimated/res/drawable/app_sample_code.png
Binary files differ
diff --git a/graphics/drawable/testanimated/res/drawable/vector_drawable_grouping_1.xml b/graphics/drawable/testanimated/res/drawable/vector_drawable_grouping_1.xml
new file mode 100644
index 0000000..eceda71
--- /dev/null
+++ b/graphics/drawable/testanimated/res/drawable/vector_drawable_grouping_1.xml
@@ -0,0 +1,53 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="256"
+ auto:viewportWidth="256" >
+
+ <group
+ auto:name="shape_layer_1"
+ auto:translateX="128"
+ auto:translateY="128" >
+ <group auto:name="sun" >
+ <path
+ auto:name="ellipse_path_1"
+ auto:fillColor="#ffff8000"
+ auto:pathData="m -25 0 a 25,25 0 1,0 50,0 a 25,25 0 1,0 -50,0" />
+
+ <group
+ auto:name="earth"
+ auto:translateX="75" >
+ <path
+ auto:name="ellipse_path_1_1"
+ auto:fillColor="#ff5656ea"
+ auto:pathData="m -10 0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0" />
+
+ <group
+ auto:name="moon"
+ auto:translateX="25" >
+ <path
+ auto:name="ellipse_path_1_2"
+ auto:fillColor="#ffadadad"
+ auto:pathData="m -5 0 a 5,5 0 1,0 10,0 a 5,5 0 1,0 -10,0" />
+ </group>
+ </group>
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/testanimated/res/drawable/vector_drawable_progress_bar.xml b/graphics/drawable/testanimated/res/drawable/vector_drawable_progress_bar.xml
new file mode 100644
index 0000000..0b8884b
--- /dev/null
+++ b/graphics/drawable/testanimated/res/drawable/vector_drawable_progress_bar.xml
@@ -0,0 +1,50 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="64"
+ auto:viewportWidth="64"
+ auto:name="root_bar" >
+
+ <group
+ auto:name="root"
+ auto:pivotX="0.0"
+ auto:pivotY="0.0"
+ auto:rotation="0"
+ auto:translateX="32.0"
+ auto:translateY="32.0" >
+ <group
+ auto:name="rotationGroup"
+ auto:pivotX="0.0"
+ auto:pivotY="0.0"
+ auto:rotation="0" >
+ <path
+ auto:name="pie1"
+ auto:fillColor="#00000000"
+ auto:pathData="M0, 0 m 0, -9.5 a 9.5,9.5 0 1,1 0,19 a 9.5,9.5 0 1,1 0,-19"
+ auto:strokeColor="#FF00FFFF"
+ auto:strokeLineCap="round"
+ auto:strokeLineJoin="miter"
+ auto:strokeWidth="2"
+ auto:trimPathEnd="0.1"
+ auto:trimPathOffset="0"
+ auto:trimPathStart="0" />
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/testanimated/res/values/strings.xml b/graphics/drawable/testanimated/res/values/strings.xml
new file mode 100644
index 0000000..c5451c8
--- /dev/null
+++ b/graphics/drawable/testanimated/res/values/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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>
+
+ <string name="twoLinePathData">"M 0,0 v 100 M 0,0 h 100"</string>
+ <string name="triangle"> "M300,70 l 0,-70 70,70 0,0 -70,70z"</string>
+ <string name="rectangle">"M300,70 l 0,-70 70,0 0,140 -70,0 z"</string>
+ <string name="rectangle2">"M300,70 l 0,-70 70,0 0,70z M300,70 l 70,0 0,70 -70,0z"</string>
+ <string name="equal2"> "M300,35 l 0,-35 70,0 0,35z M300,105 l 70,0 0,35 -70,0z"</string>
+ <string name="round_box">"m2.10001,-6c-1.9551,0 -0.5,0.02499 -2.10001,0.02499c-1.575,0 0.0031,-0.02499 -1.95,-0.02499c-2.543,0 -4,2.2816 -4,4.85001c0,3.52929 0.25,6.25 5.95,6.25c5.7,0 6,-2.72071 6,-6.25c0,-2.56841 -1.35699,-4.85001 -3.89999,-4.85001"</string>
+ <string name="heart"> "m4.5,-7c-1.95509,0 -3.83009,1.26759 -4.5,3c-0.66991,-1.73241 -2.54691,-3 -4.5,-3c-2.543,0 -4.5,1.93159 -4.5,4.5c0,3.5293 3.793,6.2578 9,11.5c5.207,-5.2422 9,-7.9707 9,-11.5c0,-2.56841 -1.957,-4.5 -4.5,-4.5"</string>
+ <string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
+</resources>
\ No newline at end of file
diff --git a/graphics/drawable/testanimated/src/android/support/test/vectordrawable/TestAVDActivity.java b/graphics/drawable/testanimated/src/android/support/test/vectordrawable/TestAVDActivity.java
new file mode 100644
index 0000000..c63c69f
--- /dev/null
+++ b/graphics/drawable/testanimated/src/android/support/test/vectordrawable/TestAVDActivity.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2015 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.test.vectordrawable;
+
+import android.animation.ObjectAnimator;
+import android.app.Activity;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import java.text.DecimalFormat;
+
+public class TestAVDActivity extends Activity implements View.OnClickListener{
+ private static final String LOG_TAG = "TestActivity";
+
+ private static final String LOGCAT = "VectorDrawable1";
+ protected int[] icon = {
+ R.drawable.animation_vector_drawable_grouping_1,
+ R.drawable.animation_vector_progress_bar,
+ };
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ ObjectAnimator oa = new ObjectAnimator();
+ super.onCreate(savedInstanceState);
+ ScrollView scrollView = new ScrollView(this);
+ LinearLayout container = new LinearLayout(this);
+ scrollView.addView(container);
+ container.setOrientation(LinearLayout.VERTICAL);
+ Resources res = this.getResources();
+ container.setBackgroundColor(0xFF888888);
+ AnimatedVectorDrawableCompat []d = new AnimatedVectorDrawableCompat[icon.length];
+ long time = android.os.SystemClock.currentThreadTimeMillis();
+ for (int i = 0; i < icon.length; i++) {
+ d[i] = AnimatedVectorDrawableCompat.create(this, icon[i]);
+ }
+ time = android.os.SystemClock.currentThreadTimeMillis()-time;
+ TextView t = new TextView(this);
+ DecimalFormat df = new DecimalFormat("#.##");
+ t.setText("avgL=" + df.format(time / (icon.length)) + " ms");
+ container.addView(t);
+
+ addDrawableButtons(container, d);
+
+ // Now test constant state and mutate a bit.
+ AnimatedVectorDrawableCompat []copies = new AnimatedVectorDrawableCompat[3];
+ copies[0] = (AnimatedVectorDrawableCompat) d[0].getConstantState().newDrawable();
+ copies[1] = (AnimatedVectorDrawableCompat) d[0].getConstantState().newDrawable();
+ copies[2] = (AnimatedVectorDrawableCompat) d[0].getConstantState().newDrawable();
+ copies[0].setAlpha(128);
+
+ // Expect to see the copies[0, 1] are showing alpha 128, and [2] are showing 255.
+ copies[2].mutate();
+ copies[2].setAlpha(255);
+
+ addDrawableButtons(container, copies);
+
+ setContentView(scrollView);
+ }
+
+ private void addDrawableButtons(LinearLayout container, AnimatedVectorDrawableCompat[] d) {
+ for (int i = 0; i < d.length; i++) {
+ Button button = new Button(this);
+ button.setWidth(200);
+ button.setHeight(200);
+ button.setBackgroundDrawable(d[i]);
+ container.addView(button);
+ button.setOnClickListener(this);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ AnimatedVectorDrawableCompat d = (AnimatedVectorDrawableCompat) v.getBackground();
+ d.start();
+ }
+}
diff --git a/graphics/drawable/teststatic/Android.mk b/graphics/drawable/teststatic/Android.mk
new file mode 100644
index 0000000..d8a0fd7
--- /dev/null
+++ b/graphics/drawable/teststatic/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SDK_VERSION := 7
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_RESOURCE_DIR = \
+ $(LOCAL_PATH)/res \
+ frameworks/support/graphics/drawable/res \
+
+LOCAL_PACKAGE_NAME := AndroidVectorDrawableTests
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v7-vectordrawable android-support-v4
+
+LOCAL_AAPT_FLAGS := \
+ --auto-add-overlay \
+ --extra-packages android.support.graphics.drawable
+
+include $(BUILD_PACKAGE)
+
diff --git a/graphics/drawable/teststatic/AndroidManifest.xml b/graphics/drawable/teststatic/AndroidManifest.xml
new file mode 100644
index 0000000..19586fb
--- /dev/null
+++ b/graphics/drawable/teststatic/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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="android.support.test.vectordrawable" >
+
+ <uses-sdk android:minSdkVersion="7" />
+
+ <application android:icon="@drawable/app_sample_code" android:label="VectorDrawableCompatTest" >
+ <activity android:name="android.support.test.vectordrawable.TestActivity" />
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/app_sample_code.png b/graphics/drawable/teststatic/res/drawable/app_sample_code.png
new file mode 100755
index 0000000..66a1984
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/app_sample_code.png
Binary files differ
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable01.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable01.xml
new file mode 100644
index 0000000..12357ef
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable01.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="48dp"
+ auto:viewportHeight="480"
+ auto:viewportWidth="480"
+ auto:width="48dp" >
+
+ <group>
+ <path
+ auto:name="box1"
+ auto:fillColor="?android:attr/textColorPrimary"
+ auto:pathData="m20,200l100,90l180-180l-35-35l-145,145l-60-60l-40,40z"
+ auto:strokeColor="?android:attr/colorBackground"
+ auto:strokeLineCap="round"
+ auto:strokeLineJoin="round" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable02.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable02.xml
new file mode 100644
index 0000000..cb6b9df
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable02.xml
@@ -0,0 +1,37 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:viewportHeight="320"
+ auto:viewportWidth="320"
+ auto:width="64dp" >
+
+ <group
+ auto:pivotX="70"
+ auto:pivotY="120"
+ auto:rotation="180" >
+ <path
+ auto:name="house"
+ auto:fillColor="#ff440000"
+ auto:pathData="M 130,225 L 130,115 L 130,115 L 70,15 L 10,115 L 10,115 L 10,225 z"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="10"
+ auto:trimPathEnd=".9"
+ auto:trimPathStart=".1" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable03.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable03.xml
new file mode 100644
index 0000000..37d0086
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable03.xml
@@ -0,0 +1,72 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:viewportHeight="12.25"
+ auto:viewportWidth="7.30625"
+ auto:width="64dp" >
+
+ <group
+ auto:pivotX="3.65"
+ auto:pivotY="6.125"
+ auto:rotation="-30" >
+ <clip-path
+ auto:name="clip1"
+ auto:pathData="
+ M 0, 6.125
+ l 7.3, 0
+ l 0, 12.25
+ l-7.3, 0
+ z" />
+ </group>
+ <group>
+ <path
+ auto:name="one"
+ auto:fillColor="#ff88ff"
+ auto:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125
+ l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l-5.046875,0.0 0.0-1.0Z" />
+ </group>
+ <group
+ auto:pivotX="3.65"
+ auto:pivotY="6.125"
+ auto:rotation="-30" >
+ <clip-path
+ auto:name="clip2"
+ auto:pathData="
+ M 0, 0
+ l 7.3, 0
+ l 0, 6.125
+ l-7.3, 0
+ z" />
+ </group>
+ <group>
+ <path
+ auto:name="two"
+ auto:fillColor="#ff88ff"
+ auto:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375
+ q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625
+ q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625
+ q-0.484375-0.4375-1.2656252-0.4375-0.5625,0.0-1.1875,0.1875
+ q-0.609375,0.1875-1.3125,0.59375l 0.0-1.203125q 0.71875-0.28125 1.328125-0.421875
+ q 0.625-0.15625 1.140625-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125-0.203125,1.015625
+ q-0.203125,0.484375-0.734375,1.140625-0.15625,0.171875-0.9375,0.984375
+ q-0.78125024,0.8125-2.2187502,2.265625Z" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable04.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable04.xml
new file mode 100644
index 0000000..4e2086f
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable04.xml
@@ -0,0 +1,58 @@
+<!-- Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:width="64dp"
+ auto:height="64dp"
+ auto:viewportWidth="7.30625"
+ auto:viewportHeight="12.25"
+ auto:autoMirrored="true">
+
+ <group>
+ <clip-path
+ auto:name="clip1"
+ auto:pathData="
+ M 3.65, 6.125
+ m-.001, 0
+ a .001,.001 0 1,0 .002,0
+ a .001,.001 0 1,0-.002,0z"/>
+ <path
+ auto:name="one"
+ auto:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125
+ l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l-5.046875,0.0 0.0-1.0Z"
+ auto:fillColor="#ff88ff"/>
+
+ <clip-path
+ auto:name="clip2"
+ auto:pathData="
+ M 3.65, 6.125
+ m-6, 0
+ a 6,6 0 1,0 12,0
+ a 6,6 0 1,0-12,0z"/>
+ <path
+ auto:name="two"
+ auto:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375
+ q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625
+ q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625
+ q-0.484375-0.4375-1.2656252-0.4375-0.5625,0.0-1.1875,0.1875
+ q-0.609375,0.1875-1.3125,0.59375l 0.0-1.203125q 0.71875-0.28125 1.328125-0.421875
+ q 0.625-0.15625 1.140625-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125-0.203125,1.015625
+ q-0.203125,0.484375-0.734375,1.140625-0.15625,0.171875-0.9375,0.984375
+ q-0.78125024,0.8125-2.2187502,2.265625Z"
+ auto:fillColor="#ff88ff"/>
+ </group>
+</vector>
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable05.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable05.xml
new file mode 100644
index 0000000..48801e3
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable05.xml
@@ -0,0 +1,44 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="12.25"
+ auto:viewportWidth="7.30625" >
+
+ <group>
+ <path
+ auto:name="one"
+ auto:fillColor="#ffff00"
+ auto:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125
+ l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l-5.046875,0.0 0.0-1.0Z" />
+ <path
+ auto:name="two"
+ auto:fillColor="#ffff00"
+ auto:fillAlpha="0"
+ auto:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375
+ q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625
+ q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625
+ q-0.484375-0.4375-1.2656252-0.4375-0.5625,0.0-1.1875,0.1875
+ q-0.609375,0.1875-1.3125,0.59375l 0.0-1.203125q 0.71875-0.28125 1.328125-0.421875
+ q 0.625-0.15625 1.140625-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125-0.203125,1.015625
+ q-0.203125,0.484375-0.734375,1.140625-0.15625,0.171875-0.9375,0.984375
+ q-0.78125024,0.8125-2.2187502,2.265625Z" />
+ </group>
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable06.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable06.xml
new file mode 100644
index 0000000..24173e2
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable06.xml
@@ -0,0 +1,49 @@
+<!-- Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:width="64dp"
+ auto:height="64dp"
+ auto:viewportWidth="700"
+ auto:viewportHeight="700">
+
+ <group>
+ <path auto:pathData="M 569.374 461.472L 569.374 160.658L 160.658 160.658L 160.658 461.472L 569.374 461.472z"
+ auto:name="path2451"
+ auto:fillColor="#00000000"
+ auto:strokeColor="#FF000000"
+ auto:strokeWidth="30.65500000000000"/>
+ <path auto:pathData="M 365.015 311.066"
+ auto:name="path2453"
+ auto:fillColor="#00000000"
+ auto:strokeColor="#FF000000"
+ auto:strokeWidth="30.655000000000001"/>
+ <path auto:pathData="M 164.46 164.49L 340.78 343.158C 353.849 356.328 377.63 356.172 390.423 343.278L 566.622 165.928"
+ auto:name="path2455"
+ auto:strokeColor="#FF000000"
+ auto:fillColor="#FFFFFFFF"
+ auto:strokeWidth="30.655000000000001"/>
+ <path auto:pathData="M 170.515 451.566L 305.61 313.46"
+ auto:name="path2457"
+ auto:fillColor="#00000000"
+ auto:strokeColor="#000000"
+ auto:strokeWidth="30.655000000000001"/>
+ <path auto:pathData="M 557.968 449.974L 426.515 315.375"
+ auto:name="path2459"
+ auto:fillColor="#00000000"
+ auto:strokeColor="#000000"
+ auto:strokeWidth="30.655000000000001"/>
+ </group>
+</vector>
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable07.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable07.xml
new file mode 100644
index 0000000..90435d3
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable07.xml
@@ -0,0 +1,30 @@
+<!-- Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:width="64dp"
+ auto:height="64dp" auto:viewportWidth="140"
+ auto:viewportHeight="110">
+
+ <group>
+ <path
+ auto:name="back"
+ auto:pathData="M 20,55 l 35.3-35.3 7.07,7.07-35.3,35.3 z
+ M 27,50 l 97,0 0,10-97,0 z
+ M 20,55 l 7.07-7.07 35.3,35.3-7.07,7.07 z"
+ auto:fillColor="#ffffffff"
+ />
+ </group>
+</vector>
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable08.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable08.xml
new file mode 100644
index 0000000..251d694
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable08.xml
@@ -0,0 +1,30 @@
+<!-- Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:width="64dp"
+ auto:height="64dp" auto:viewportWidth="600"
+ auto:viewportHeight="600">
+
+ <group>
+ <path
+ auto:name="pie1"
+ auto:pathData="M535.441,412.339A280.868,280.868 0 1,1 536.186,161.733L284.493,286.29Z"
+ auto:fillColor="#ffffcc00"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="1"/>
+ </group>
+
+</vector>
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable09.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable09.xml
new file mode 100644
index 0000000..eccb0d0
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable09.xml
@@ -0,0 +1,33 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="200"
+ auto:viewportWidth="200" >
+
+ <group
+ auto:pivotX="100"
+ auto:pivotY="100"
+ auto:rotation="90">
+ <path
+ auto:name="house"
+ auto:fillColor="#ffffffff"
+ auto:pathData="M 100,20 l 0,0 0,140-80,0 z M 100,20 l 0,0 80,140-80,0 z"/>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable10.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable10.xml
new file mode 100644
index 0000000..b26d30d
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable10.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportWidth="200"
+ auto:viewportHeight="200">
+
+ <group>
+ <path
+ auto:name="bar3"
+ auto:fillColor="#FFFFFFFF"
+ auto:pathData="M49.001,60c-5.466,0-9.899,4.478-9.899,10s4.434,10,9.899,10c5.468,0,9.899-4.478,9.899-10S54.469,60,49.001,60z" />
+ <path
+ auto:name="bar2"
+ auto:fillColor="#FFFFFFFF"
+ auto:pathData="M28.001,48.787l7,7.07c7.731-7.811,20.269-7.81,28.001,0l6.999-7.07C58.403,37.071,39.599,37.071,28.001,48.787z" />
+ <path
+ auto:name="bar1"
+ auto:fillColor="#FF555555"
+ auto:pathData="M14.001,34.645 L21,41.716c15.464-15.621,40.536-15.621,56,0l7.001-7.071C64.672,15.119,33.33,15.119,14.001,34.645z" />
+ <path
+ auto:name="bar0"
+ auto:fillColor="#FF555555"
+ auto:pathData="M0,20.502l6.999,7.071 c23.196-23.431,60.806-23.431,84.002,0L98,20.503C70.938-6.834,27.063-6.834,0,20.502z" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable11.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable11.xml
new file mode 100644
index 0000000..eb440f5
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable11.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="80"
+ auto:viewportWidth="40" >
+
+ <group>
+ <path
+ auto:name="battery"
+ auto:fillColor="#3388ff"
+ auto:pathData="M 20.28125,2.0000002 C 17.352748,2.0000002 15,4.3527485 15,7.2812502 L 15,8.0000002 L 13.15625,8.0000002 C 9.7507553,8.0000002 7,10.750759 7,14.15625 L 7,39.84375 C 7,43.24924 9.7507558,46 13.15625,46 L 33.84375,46 C 37.249245,46 39.999999,43.24924 40,39.84375 L 40,14.15625 C 40,10.75076 37.249243,8.0000002 33.84375,8.0000002 L 32,8.0000002 L 32,7.2812502 C 32,4.3527485 29.647252,2.0000002 26.71875,2.0000002 L 20.28125,2.0000002 z"
+ auto:strokeColor="#ff8833"
+ auto:strokeWidth="1" />
+ <path
+ auto:name="spark"
+ auto:fillColor="#FFFF0000"
+ auto:pathData="M 30,18.031528 L 25.579581,23.421071 L 29.370621,26.765348 L 20.096792,37 L 21.156922,28.014053 L 17,24.902844 L 20.880632,18 L 30,18.031528 z" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable12.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable12.xml
new file mode 100644
index 0000000..94a23e8
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable12.xml
@@ -0,0 +1,98 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:name="rootGroup"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="600"
+ auto:viewportWidth="600"
+ auto:alpha="0.5" >
+
+ <group
+ auto:name="rotationGroup"
+ auto:pivotX="300.0"
+ auto:pivotY="300.0"
+ auto:rotation="45.0" >
+ <path
+ auto:name="pie1"
+ auto:fillColor="#00000000"
+ auto:pathData="M300,70 a230,230 0 1,0 1,0 z"
+ auto:strokeColor="#FF777777"
+ auto:strokeWidth="70"
+ auto:trimPathEnd=".75"
+ auto:trimPathOffset="0"
+ auto:trimPathStart="0" />
+ <path
+ auto:name="v"
+ auto:fillColor="#000000"
+ auto:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
+
+ <group
+ auto:name="translateToCenterGroup"
+ auto:rotation="0.0"
+ auto:translateX="200.0"
+ auto:translateY="200.0" >
+ <group
+ auto:name="rotationGroup2"
+ auto:pivotX="0.0"
+ auto:pivotY="0.0"
+ auto:rotation="-45.0" >
+ <path
+ auto:name="twoLines1"
+ auto:pathData="@string/twoLinePathData"
+ auto:strokeColor="#FFFF0000"
+ auto:strokeWidth="20" />
+
+ <group
+ auto:name="translateGroupHalf"
+ auto:translateX="65.0"
+ auto:translateY="80.0" >
+ <group
+ auto:name="rotationGroup3"
+ auto:pivotX="-65.0"
+ auto:pivotY="-80.0"
+ auto:rotation="-45.0" >
+ <path
+ auto:name="twoLines2"
+ auto:fillColor="#FF00FF00"
+ auto:pathData="@string/twoLinePathData"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="20" />
+
+ <group
+ auto:name="translateGroup"
+ auto:translateX="65.0"
+ auto:translateY="80.0" >
+ <group
+ auto:name="rotationGroupBlue"
+ auto:pivotX="-65.0"
+ auto:pivotY="-80.0"
+ auto:rotation="-45.0" >
+ <path
+ auto:name="twoLines3"
+ auto:pathData="@string/twoLinePathData"
+ auto:strokeColor="#FF0000FF"
+ auto:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+ </group>
+ </group>
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable13.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable13.xml
new file mode 100644
index 0000000..43fc7ea
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable13.xml
@@ -0,0 +1,38 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="400"
+ auto:viewportWidth="600" >
+
+ <group>
+ <path
+ auto:name="pie1"
+ auto:fillColor="#ffffffff"
+ auto:pathData="M300,200 h-150 a150,150 0 1,0 150,-150 z"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="1" />
+ <path
+ auto:name="half"
+ auto:fillColor="#FFFF0000"
+ auto:pathData="M275,175 v-150 a150,150 0 0,0 -150,150 z"
+ auto:strokeColor="#FF0000FF"
+ auto:strokeWidth="5" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable14.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable14.xml
new file mode 100644
index 0000000..5b4fdd1
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable14.xml
@@ -0,0 +1,39 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="500"
+ auto:viewportWidth="800" >
+
+ <group
+ auto:pivotX="90"
+ auto:pivotY="100"
+ auto:rotation="20">
+ <path
+ auto:name="pie2"
+ auto:pathData="M200,350 l 50,-25
+ a25,12 -30 0,1 100,-50 l 50,-25
+ a25,25 -30 0,1 100,-50 l 50,-25
+ a25,37 -30 0,1 100,-50 l 50,-25
+ a25,50 -30 0,1 100,-50 l 50,-25"
+ auto:fillColor="#00000000"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="10" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable15.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable15.xml
new file mode 100644
index 0000000..f4ef87f
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable15.xml
@@ -0,0 +1,35 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="400"
+ auto:viewportWidth="500" >
+
+ <group
+ auto:pivotX="250"
+ auto:pivotY="200"
+ auto:rotation="180">
+ <path
+ auto:name="house"
+ auto:fillColor="#ff440000"
+ auto:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ auto:strokeColor="#FFFF0000"
+ auto:strokeWidth="10" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable16.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable16.xml
new file mode 100644
index 0000000..0c64bca
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable16.xml
@@ -0,0 +1,48 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="200"
+ auto:viewportWidth="200" >
+
+ <group>
+ <path
+ auto:name="background1"
+ auto:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z"
+ auto:fillColor="#FF000000"/>
+ <path
+ auto:name="background2"
+ auto:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z"
+ auto:fillColor="#FF000000"/>
+ </group>
+ <group
+ auto:pivotX="100"
+ auto:pivotY="100"
+ auto:rotation="90"
+ auto:scaleX="0.75"
+ auto:scaleY="0.5"
+ auto:translateX="0.0"
+ auto:translateY="100.0">
+ <path
+ auto:name="twoLines"
+ auto:pathData="M 100,10 v 90 M 10,100 h 90"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="10" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable17.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable17.xml
new file mode 100644
index 0000000..28cf09a
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable17.xml
@@ -0,0 +1,30 @@
+<!-- Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:width="64dp"
+ auto:height="64dp" auto:viewportWidth="1200"
+ auto:viewportHeight="600">
+
+ <group>
+ <path
+ auto:name="house"
+ auto:pathData="M200,300 Q400,50 600,300 T1000,300"
+ auto:fillColor="#00000000"
+ auto:strokeColor="#FFFF0000"
+ auto:strokeWidth="10"/>
+ </group>
+
+</vector>
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable18.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable18.xml
new file mode 100644
index 0000000..d66d4ff
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable18.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="400"
+ auto:viewportWidth="500" >
+
+ <group>
+ <path
+ auto:name="house"
+ auto:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ auto:fillColor="#00000000"
+ auto:strokeColor="#FFFFFF00"
+ auto:strokeWidth="10" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable19.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable19.xml
new file mode 100644
index 0000000..3a6559d
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable19.xml
@@ -0,0 +1,34 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="800"
+ auto:viewportWidth="1000" >
+
+ <group>
+ <path
+ auto:name="house"
+ auto:pathData="M10,300 Q400,550 600,300 T1000,300"
+ auto:pivotX="90"
+ auto:pivotY="100"
+ auto:fillColor="#00000000"
+ auto:strokeColor="#FFFF0000"
+ auto:strokeWidth="60" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable20.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable20.xml
new file mode 100644
index 0000000..d6fd704
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable20.xml
@@ -0,0 +1,35 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="480"
+ auto:viewportWidth="480" >
+
+ <group>
+ <path
+ auto:name="edit"
+ auto:fillColor="#FF00FFFF"
+ auto:pathData="M406.667,180c0,0 -100 -100 -113.334 -113.333
+ c-13.333 -13.334 -33.333,0 -33.333,0l-160,160c0,0 -40,153.333 -40,173.333c0,13.333,13.333,13.333,13.333,13.333l173.334 -40
+ c0,0,146.666 -146.666,160 -160C420,200,406.667,180,406.667,180z M226.399,356.823L131.95,378.62l-38.516 -38.522
+ c7.848 -34.675,20.152 -82.52,23.538 -95.593l3.027,2.162l106.667,106.666L226.399,356.823z"
+ auto:strokeColor="#FF000000"
+ auto:strokeWidth="10" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable21.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable21.xml
new file mode 100644
index 0000000..9136b73
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable21.xml
@@ -0,0 +1,48 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="200"
+ auto:viewportWidth="200" >
+
+ <group>
+ <path
+ auto:name="background1"
+ auto:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z"
+ auto:fillColor="#FF000000"/>
+ <path
+ auto:name="background2"
+ auto:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z"
+ auto:fillColor="#FF000000"/>
+ </group>
+ <group
+ auto:pivotX="0"
+ auto:pivotY="0"
+ auto:rotation="90"
+ auto:scaleX="0.75"
+ auto:scaleY="0.5"
+ auto:translateX="100.0"
+ auto:translateY="100.0">
+ <path
+ auto:name="twoLines"
+ auto:pathData="M 100,10 v 90 M 10,100 h 90"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="10" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable22.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable22.xml
new file mode 100644
index 0000000..2b33a89
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable22.xml
@@ -0,0 +1,69 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="400"
+ auto:viewportWidth="400" >
+
+ <group auto:name="backgroundGroup" >
+ <path
+ auto:name="background1"
+ auto:fillColor="#80000000"
+ auto:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ auto:name="background2"
+ auto:fillColor="#80000000"
+ auto:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ </group>
+ <group
+ auto:name="translateToCenterGroup"
+ auto:translateX="50.0"
+ auto:translateY="90.0" >
+ <path
+ auto:name="twoLines"
+ auto:pathData="M 0,0 v 100 M 0,0 h 100"
+ auto:strokeColor="#FFFF0000"
+ auto:strokeWidth="20" />
+
+ <group
+ auto:name="rotationGroup"
+ auto:pivotX="0.0"
+ auto:pivotY="0.0"
+ auto:rotation="-45.0" >
+ <path
+ auto:name="twoLines1"
+ auto:pathData="M 0,0 v 100 M 0,0 h 100"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="20" />
+
+ <group
+ auto:name="translateGroup"
+ auto:translateX="130.0"
+ auto:translateY="160.0" >
+ <group auto:name="scaleGroup" >
+ <path
+ auto:name="twoLines2"
+ auto:pathData="M 0,0 v 100 M 0,0 h 100"
+ auto:strokeColor="#FF0000FF"
+ auto:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable23.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable23.xml
new file mode 100644
index 0000000..d5759f9
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable23.xml
@@ -0,0 +1,83 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="400"
+ auto:viewportWidth="400" >
+
+ <group auto:name="backgroundGroup" >
+ <path
+ auto:name="background1"
+ auto:fillColor="#80000000"
+ auto:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ auto:name="background2"
+ auto:fillColor="#80000000"
+ auto:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ </group>
+ <group
+ auto:name="translateToCenterGroup"
+ auto:translateX="50.0"
+ auto:translateY="90.0" >
+ <path
+ auto:name="twoLines"
+ auto:pathData="@string/twoLinePathData"
+ auto:strokeColor="#FFFF0000"
+ auto:strokeWidth="20" />
+
+ <group
+ auto:name="rotationGroup"
+ auto:pivotX="0.0"
+ auto:pivotY="0.0"
+ auto:rotation="-45.0" >
+ <path
+ auto:name="twoLines1"
+ auto:pathData="@string/twoLinePathData"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="20" />
+
+ <group
+ auto:name="translateGroup"
+ auto:translateX="130.0"
+ auto:translateY="160.0" >
+ <group auto:name="scaleGroup" >
+ <path
+ auto:name="twoLines3"
+ auto:pathData="@string/twoLinePathData"
+ auto:strokeColor="#FF0000FF"
+ auto:strokeWidth="20" />
+ </group>
+ </group>
+
+ <group
+ auto:name="translateGroupHalf"
+ auto:translateX="65.0"
+ auto:translateY="80.0" >
+ <group auto:name="scaleGroup" >
+ <path
+ auto:name="twoLines2"
+ auto:pathData="@string/twoLinePathData"
+ auto:fillColor="#FFFFFFFF"
+ auto:strokeColor="#FFFFFFFF"
+ auto:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable24.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable24.xml
new file mode 100644
index 0000000..b054692
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable24.xml
@@ -0,0 +1,83 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="400"
+ auto:viewportWidth="400" >
+
+ <group auto:name="backgroundGroup">
+ <path
+ auto:name="background1"
+ auto:fillColor="#FF000000"
+ auto:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ auto:name="background2"
+ auto:fillColor="#FF000000"
+ auto:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ </group>
+ <group
+ auto:name="translateToCenterGroup"
+ auto:translateX="50.0"
+ auto:translateY="90.0" >
+ <path
+ auto:name="twoLines"
+ auto:pathData="@string/twoLinePathData"
+ auto:strokeColor="#FFFF0000"
+ auto:strokeWidth="20" />
+
+ <group
+ auto:name="rotationGroup"
+ auto:pivotX="0.0"
+ auto:pivotY="0.0"
+ auto:rotation="-45.0">
+ <path
+ auto:name="twoLines1"
+ auto:pathData="@string/twoLinePathData"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeWidth="20" />
+
+ <group
+ auto:name="translateGroup"
+ auto:translateX="130.0"
+ auto:translateY="160.0">
+ <group auto:name="scaleGroup" >
+ <path
+ auto:name="twoLines3"
+ auto:pathData="@string/twoLinePathData"
+ auto:strokeColor="#FF0000FF"
+ auto:strokeWidth="20" />
+ </group>
+ </group>
+
+ <group
+ auto:name="translateGroupHalf"
+ auto:translateX="65.0"
+ auto:translateY="80.0">
+ <group auto:name="scaleGroup" >
+ <path
+ auto:name="twoLines2"
+ auto:pathData="@string/twoLinePathData"
+ auto:fillColor="#FFFFFFFF"
+ auto:strokeColor="#FFFFFFFF"
+ auto:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable25.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable25.xml
new file mode 100644
index 0000000..7a94ed6
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable25.xml
@@ -0,0 +1,83 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:width="64dp"
+ auto:viewportHeight="400"
+ auto:viewportWidth="400" >
+
+ <group
+ auto:name="FirstLevelGroup"
+ auto:translateX="100.0"
+ auto:translateY="0.0" >
+ <group
+ auto:name="SecondLevelGroup1"
+ auto:translateX="-100.0"
+ auto:translateY="50.0" >
+ <path
+ auto:fillColor="#FF00FF00"
+ auto:pathData="@string/rectangle200" />
+
+ <group
+ auto:name="ThridLevelGroup1"
+ auto:translateX="-100.0"
+ auto:translateY="50.0" >
+ <path
+ auto:fillColor="#FF0000FF"
+ auto:pathData="@string/rectangle200" />
+ </group>
+ <group
+ auto:name="ThridLevelGroup2"
+ auto:translateX="100.0"
+ auto:translateY="50.0" >
+ <path
+ auto:fillColor="#FF000000"
+ auto:pathData="@string/rectangle200" />
+ </group>
+ </group>
+ <group
+ auto:name="SecondLevelGroup2"
+ auto:translateX="100.0"
+ auto:translateY="50.0" >
+ <path
+ auto:fillColor="#FF0000FF"
+ auto:pathData="@string/rectangle200" />
+
+ <group
+ auto:name="ThridLevelGroup3"
+ auto:translateX="-100.0"
+ auto:translateY="50.0" >
+ <path
+ auto:fillColor="#FFFF0000"
+ auto:pathData="@string/rectangle200" />
+ </group>
+ <group
+ auto:name="ThridLevelGroup4"
+ auto:translateX="100.0"
+ auto:translateY="50.0" >
+ <path
+ auto:fillColor="#FF00FF00"
+ auto:pathData="@string/rectangle200" />
+ </group>
+ </group>
+
+ <path
+ auto:fillColor="#FFFF0000"
+ auto:pathData="@string/rectangle200" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable26.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable26.xml
new file mode 100644
index 0000000..b2dd4a3
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable26.xml
@@ -0,0 +1,46 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:viewportHeight="200"
+ auto:viewportWidth="200"
+ auto:width="64dp" >
+
+ <group>
+ <path
+ auto:name="background1"
+ auto:fillColor="#FF000000"
+ auto:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+ <path
+ auto:name="background2"
+ auto:fillColor="#FF000000"
+ auto:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+ </group>
+ <group
+ auto:translateX="50"
+ auto:translateY="50" >
+ <path
+ auto:name="twoLines"
+ auto:pathData="M 100,20 l 0 80 l -30 -80"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeLineCap="butt"
+ auto:strokeLineJoin="miter"
+ auto:strokeMiterLimit="5"
+ auto:strokeWidth="20" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable27.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable27.xml
new file mode 100644
index 0000000..b8f88ce
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable27.xml
@@ -0,0 +1,46 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:viewportHeight="200"
+ auto:viewportWidth="200"
+ auto:width="64dp" >
+
+ <group>
+ <path
+ auto:name="background1"
+ auto:fillColor="#FF000000"
+ auto:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+ <path
+ auto:name="background2"
+ auto:fillColor="#FF000000"
+ auto:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+ </group>
+ <group
+ auto:translateX="50"
+ auto:translateY="50" >
+ <path
+ auto:name="twoLines"
+ auto:pathData="M 100,20 l 0 80 l -30 -80"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeLineCap="round"
+ auto:strokeLineJoin="round"
+ auto:strokeMiterLimit="10"
+ auto:strokeWidth="20" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable28.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable28.xml
new file mode 100644
index 0000000..30c7fce
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable28.xml
@@ -0,0 +1,47 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="64dp"
+ auto:viewportHeight="200"
+ auto:viewportWidth="200"
+ auto:width="64dp"
+ auto:autoMirrored="true" >
+
+ <group>
+ <path
+ auto:name="background1"
+ auto:fillColor="#FF000000"
+ auto:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+ <path
+ auto:name="background2"
+ auto:fillColor="#FF000000"
+ auto:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+ </group>
+ <group
+ auto:translateX="50"
+ auto:translateY="50" >
+ <path
+ auto:name="twoLines"
+ auto:pathData="M 100,20 l 0 80 l -30 -80"
+ auto:strokeColor="#FF00FF00"
+ auto:strokeLineCap="square"
+ auto:strokeLineJoin="bevel"
+ auto:strokeMiterLimit="10"
+ auto:strokeWidth="20" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable29.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable29.xml
new file mode 100644
index 0000000..2ac1d42
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable29.xml
@@ -0,0 +1,29 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="48dp"
+ auto:width="48dp"
+ auto:viewportHeight="1"
+ auto:viewportWidth="1" >
+
+ <group>
+ <path
+ auto:name="box1"
+ auto:pathData="l0.0.0.5.0.0.5-0.5.0.0-.5z"
+ auto:fillColor="#ff00ff00"/>
+ </group>
+</vector>
diff --git a/graphics/drawable/teststatic/res/drawable/vector_drawable30.xml b/graphics/drawable/teststatic/res/drawable/vector_drawable30.xml
new file mode 100644
index 0000000..6abb455
--- /dev/null
+++ b/graphics/drawable/teststatic/res/drawable/vector_drawable30.xml
@@ -0,0 +1,29 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ auto:height="48dp"
+ auto:width="48dp"
+ auto:viewportHeight="48"
+ auto:viewportWidth="48" >
+
+ <group>
+ <path
+ auto:name="plus1"
+ auto:pathData="M20 16h-4v8h-8v4h8v8h4v-8h8v-4h-8zm9-3.84v3.64l5-1v21.2h4v-26z"
+ auto:fillColor="#ff00ff00"/>
+ </group>
+</vector>
diff --git a/graphics/drawable/teststatic/res/raw/vector_drawable01.xml b/graphics/drawable/teststatic/res/raw/vector_drawable01.xml
new file mode 100644
index 0000000..baa3fc7
--- /dev/null
+++ b/graphics/drawable/teststatic/res/raw/vector_drawable01.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright (C) 2015 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"
+ xmlns:auto="http://schemas.android.com/apk/res-auto"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="480"
+ android:viewportWidth="480" >
+
+ <group>
+ <path
+ android:name="box1"
+ android:pathData="m20,200l100,90l180-180l-35-35l-145,145l-60-60l-40,40z"
+ android:fillColor="?android:attr/colorControlActivated"
+ android:strokeColor="?android:attr/colorControlActivated"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round" />
+ </group>
+</vector>
diff --git a/graphics/drawable/teststatic/res/values/strings.xml b/graphics/drawable/teststatic/res/values/strings.xml
new file mode 100644
index 0000000..c5451c8
--- /dev/null
+++ b/graphics/drawable/teststatic/res/values/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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>
+
+ <string name="twoLinePathData">"M 0,0 v 100 M 0,0 h 100"</string>
+ <string name="triangle"> "M300,70 l 0,-70 70,70 0,0 -70,70z"</string>
+ <string name="rectangle">"M300,70 l 0,-70 70,0 0,140 -70,0 z"</string>
+ <string name="rectangle2">"M300,70 l 0,-70 70,0 0,70z M300,70 l 70,0 0,70 -70,0z"</string>
+ <string name="equal2"> "M300,35 l 0,-35 70,0 0,35z M300,105 l 70,0 0,35 -70,0z"</string>
+ <string name="round_box">"m2.10001,-6c-1.9551,0 -0.5,0.02499 -2.10001,0.02499c-1.575,0 0.0031,-0.02499 -1.95,-0.02499c-2.543,0 -4,2.2816 -4,4.85001c0,3.52929 0.25,6.25 5.95,6.25c5.7,0 6,-2.72071 6,-6.25c0,-2.56841 -1.35699,-4.85001 -3.89999,-4.85001"</string>
+ <string name="heart"> "m4.5,-7c-1.95509,0 -3.83009,1.26759 -4.5,3c-0.66991,-1.73241 -2.54691,-3 -4.5,-3c-2.543,0 -4.5,1.93159 -4.5,4.5c0,3.5293 3.793,6.2578 9,11.5c5.207,-5.2422 9,-7.9707 9,-11.5c0,-2.56841 -1.957,-4.5 -4.5,-4.5"</string>
+ <string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
+</resources>
\ No newline at end of file
diff --git a/graphics/drawable/teststatic/src/android/support/test/vectordrawable/TestActivity.java b/graphics/drawable/teststatic/src/android/support/test/vectordrawable/TestActivity.java
new file mode 100644
index 0000000..8bb766e
--- /dev/null
+++ b/graphics/drawable/teststatic/src/android/support/test/vectordrawable/TestActivity.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2015 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.test.vectordrawable;
+
+import android.app.Activity;
+import android.content.res.Resources;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.drawable.Drawable.ConstantState;
+import android.os.Bundle;
+import android.support.graphics.drawable.VectorDrawableCompat;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import java.text.DecimalFormat;
+
+public class TestActivity extends Activity {
+ private static final String LOG_TAG = "TestActivity";
+
+ private static final String LOGCAT = "VectorDrawable1";
+ protected int[] icon = {
+ R.drawable.vector_drawable01,
+ R.drawable.vector_drawable02,
+ R.drawable.vector_drawable03,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable05,
+ R.drawable.vector_drawable06,
+ R.drawable.vector_drawable07,
+ R.drawable.vector_drawable08,
+ R.drawable.vector_drawable09,
+ R.drawable.vector_drawable10,
+ R.drawable.vector_drawable11,
+ R.drawable.vector_drawable12,
+ R.drawable.vector_drawable13,
+ R.drawable.vector_drawable14,
+ R.drawable.vector_drawable15,
+ R.drawable.vector_drawable16,
+ R.drawable.vector_drawable17,
+ R.drawable.vector_drawable18,
+ R.drawable.vector_drawable19,
+ R.drawable.vector_drawable20,
+ R.drawable.vector_drawable21,
+ R.drawable.vector_drawable22,
+ R.drawable.vector_drawable23,
+ R.drawable.vector_drawable24,
+ R.drawable.vector_drawable25,
+ R.drawable.vector_drawable26,
+ R.drawable.vector_drawable27,
+ R.drawable.vector_drawable28,
+ R.drawable.vector_drawable29,
+ R.drawable.vector_drawable30,
+ };
+
+ private static final int EXTRA_TESTS = 2;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ScrollView scrollView = new ScrollView(this);
+ LinearLayout container = new LinearLayout(this);
+ scrollView.addView(container);
+ container.setOrientation(LinearLayout.VERTICAL);
+ Resources res = this.getResources();
+ container.setBackgroundColor(0xFF888888);
+ VectorDrawableCompat []d = new VectorDrawableCompat[icon.length];
+ long time = android.os.SystemClock.currentThreadTimeMillis();
+ for (int i = 0; i < icon.length; i++) {
+ d[i] = VectorDrawableCompat.create(res, icon[i], getTheme());
+ }
+ time = android.os.SystemClock.currentThreadTimeMillis()-time;
+
+ // Testing Tint on one particular case.
+ d[3].setTint(0x8000FF00);
+ d[3].setTintMode(Mode.MULTIPLY);
+
+ // Testing Constant State like operation by creating the first 2 icons
+ // from the 3rd one's constant state.
+ VectorDrawableCompat []extras = new VectorDrawableCompat[EXTRA_TESTS];
+ ConstantState state = d[0].getConstantState();
+ extras[0] = (VectorDrawableCompat) state.newDrawable();
+ extras[1] = (VectorDrawableCompat) state.newDrawable();
+
+ // This alpha change is expected to affect both extra 0, 1, and d0.
+ extras[0].setAlpha(128);
+
+ d[0].mutate();
+ d[0].setAlpha(255);
+
+ // Just show the average create time as the first view.
+ TextView t = new TextView(this);
+ DecimalFormat df = new DecimalFormat("#.##");
+ t.setText("avgL=" + df.format(time / (icon.length)) + " ms");
+ container.addView(t);
+
+ addDrawableButtons(container, extras);
+
+ addDrawableButtons(container, d);
+
+ setContentView(scrollView);
+ }
+
+ private void addDrawableButtons(LinearLayout container, VectorDrawableCompat[] d) {
+ // Add the VD into consequent views.
+ for (int i = 0; i < d.length; i++) {
+ Button button = new Button(this);
+ button.setWidth(200);
+ // Note that setBackgroundResource() will fail b/c createFromXmlInner() failed
+ // to recognize <vector> pre-L.
+ button.setBackgroundDrawable(d[i]);
+ container.addView(button);
+ }
+ }
+}
diff --git a/media/Android.mk b/media/Android.mk
new file mode 100644
index 0000000..14ff0aa
--- /dev/null
+++ b/media/Android.mk
@@ -0,0 +1,16 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/protocols/Android.mk b/media/protocols/Android.mk
new file mode 100644
index 0000000..08a4d96
--- /dev/null
+++ b/media/protocols/Android.mk
@@ -0,0 +1,31 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-media-protocols
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_JAVA_LIBRARIES := android-support-annotations
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# API Check
+# ---------------------------------------------
+support_module := $(LOCAL_MODULE)
+support_module_api_dir := $(LOCAL_PATH)/api
+support_module_src_files := $(LOCAL_SRC_FILES)
+support_module_java_libraries := $(LOCAL_JAVA_LIBRARIES)
+support_module_java_packages := android.support.media.protocols
+include $(SUPPORT_API_CHECK)
diff --git a/media/protocols/README.txt b/media/protocols/README.txt
new file mode 100644
index 0000000..12c24cd
--- /dev/null
+++ b/media/protocols/README.txt
@@ -0,0 +1,8 @@
+Media protocol declarations.
+
+This library contains declarations for protocols used by
+applications to communicate with services provided by media
+routes. For example, the MediaPlayerProtocol defines a protocol
+by which an application may enqueue content to play on a
+remote media device.
+
diff --git a/media/protocols/api/current.txt b/media/protocols/api/current.txt
new file mode 100644
index 0000000..52dd3d9
--- /dev/null
+++ b/media/protocols/api/current.txt
@@ -0,0 +1,278 @@
+package android.support.media.protocols {
+
+ public class MediaPlayerProtocol extends android.support.media.protocols.MediaRouteProtocol {
+ ctor public MediaPlayerProtocol(android.os.IBinder);
+ method public void load(android.support.media.protocols.MediaPlayerProtocol.MediaInfo, boolean, long, android.os.Bundle);
+ method public void pause(android.os.Bundle);
+ method public void play(android.os.Bundle);
+ method public void requestStatus(android.os.Bundle);
+ method public void seek(long, int, android.os.Bundle);
+ method public void setActiveMediaTracks(long[], android.os.Bundle);
+ method public void setStreamMute(boolean, android.os.Bundle);
+ method public void setStreamVolume(int, android.os.Bundle);
+ method public void setTextTrackStyle(android.support.media.protocols.MediaPlayerProtocol.TextTrackStyle, android.os.Bundle);
+ method public void stop(android.os.Bundle);
+ field public static final int RESUME_STATE_PAUSE = 2; // 0x2
+ field public static final int RESUME_STATE_PLAY = 1; // 0x1
+ field public static final int RESUME_STATE_UNCHANGED = 0; // 0x0
+ }
+
+ public static abstract class MediaPlayerProtocol.Callback extends android.support.media.protocols.MediaRouteProtocol.Callback {
+ ctor public MediaPlayerProtocol.Callback();
+ method public void onStatusUpdated(android.support.media.protocols.MediaPlayerProtocol.MediaStatus, android.os.Bundle);
+ }
+
+ public static final class MediaPlayerProtocol.MediaInfo {
+ ctor public MediaPlayerProtocol.MediaInfo(java.lang.String, int, java.lang.String);
+ method public static android.support.media.protocols.MediaPlayerProtocol.MediaInfo fromBundle(android.os.Bundle);
+ method public java.lang.String getContentId();
+ method public java.lang.String getContentType();
+ method public android.os.Bundle getExtras();
+ method public java.util.List<android.support.media.protocols.MediaPlayerProtocol.MediaTrack> getMediaTracks();
+ method public android.support.media.protocols.MediaPlayerProtocol.MediaMetadata getMetadata();
+ method public long getStreamDuration();
+ method public int getStreamType();
+ method public android.support.media.protocols.MediaPlayerProtocol.TextTrackStyle getTextTrackStyle();
+ method public void setExtras(android.os.Bundle);
+ method public void setMediaTracks(java.util.List<android.support.media.protocols.MediaPlayerProtocol.MediaTrack>);
+ method public void setMetadata(android.support.media.protocols.MediaPlayerProtocol.MediaMetadata);
+ method public void setStreamDuration(long);
+ method public void setTextTrackStyle(android.support.media.protocols.MediaPlayerProtocol.TextTrackStyle);
+ method public android.os.Bundle toBundle();
+ field public static final int STREAM_TYPE_BUFFERED = 1; // 0x1
+ field public static final int STREAM_TYPE_INVALID = -1; // 0xffffffff
+ field public static final int STREAM_TYPE_LIVE = 2; // 0x2
+ field public static final int STREAM_TYPE_NONE = 0; // 0x0
+ }
+
+ public static final class MediaPlayerProtocol.MediaMetadata {
+ ctor public MediaPlayerProtocol.MediaMetadata();
+ ctor public MediaPlayerProtocol.MediaMetadata(int);
+ method public void addImage(android.support.media.protocols.MediaPlayerProtocol.WebImage);
+ method public void clear();
+ method public void clearImages();
+ method public boolean containsKey(java.lang.String);
+ method public static android.support.media.protocols.MediaPlayerProtocol.MediaMetadata fromBundle(android.os.Bundle);
+ method public java.util.Calendar getDate(java.lang.String);
+ method public double getDouble(java.lang.String);
+ method public java.util.List<android.support.media.protocols.MediaPlayerProtocol.WebImage> getImages();
+ method public int getInt(java.lang.String);
+ method public int getMediaType();
+ method public java.lang.String getString(java.lang.String);
+ method public boolean hasImages();
+ method public java.util.Set<java.lang.String> keySet();
+ method public void putDate(java.lang.String, java.util.Calendar);
+ method public void putDouble(java.lang.String, double);
+ method public void putInt(java.lang.String, int);
+ method public void putString(java.lang.String, java.lang.String);
+ method public android.os.Bundle toBundle();
+ field public static final java.lang.String KEY_ALBUM_ARTIST = "android.support.media.protocols.metadata.ALBUM_ARTIST";
+ field public static final java.lang.String KEY_ALBUM_TITLE = "android.support.media.protocols.metadata.ALBUM_TITLE";
+ field public static final java.lang.String KEY_ARTIST = "android.support.media.protocols.metadata.ARTIST";
+ field public static final java.lang.String KEY_BROADCAST_DATE = "android.support.media.protocols.metadata.BROADCAST_DATE";
+ field public static final java.lang.String KEY_COMPOSER = "android.support.media.protocols.metadata.COMPOSER";
+ field public static final java.lang.String KEY_CREATION_DATE = "android.support.media.protocols.metadata.CREATION_DATE";
+ field public static final java.lang.String KEY_DISC_NUMBER = "android.support.media.protocols.metadata.DISC_NUMBER";
+ field public static final java.lang.String KEY_EPISODE_NUMBER = "android.support.media.protocols.metadata.EPISODE_NUMBER";
+ field public static final java.lang.String KEY_HEIGHT = "android.support.media.protocols.metadata.HEIGHT";
+ field public static final java.lang.String KEY_LOCATION_LATITUDE = "android.support.media.protocols.metadata.LOCATION_LATITUDE";
+ field public static final java.lang.String KEY_LOCATION_LONGITUDE = "android.support.media.protocols.metadata.LOCATION_LONGITUDE";
+ field public static final java.lang.String KEY_LOCATION_NAME = "android.support.media.protocols.metadata.LOCATION_NAME";
+ field public static final java.lang.String KEY_RELEASE_DATE = "android.support.media.protocols.metadata.RELEASE_DATE";
+ field public static final java.lang.String KEY_SEASON_NUMBER = "android.support.media.protocols.metadata.SEASON_NUMBER";
+ field public static final java.lang.String KEY_SERIES_TITLE = "android.support.media.protocols.metadata.SERIES_TITLE";
+ field public static final java.lang.String KEY_STUDIO = "android.support.media.protocols.metadata.STUDIO";
+ field public static final java.lang.String KEY_SUBTITLE = "android.support.media.protocols.metadata.SUBTITLE";
+ field public static final java.lang.String KEY_TITLE = "android.support.media.protocols.metadata.TITLE";
+ field public static final java.lang.String KEY_TRACK_NUMBER = "android.support.media.protocols.metadata.TRACK_NUMBER";
+ field public static final java.lang.String KEY_WIDTH = "android.support.media.protocols.metadata.WIDTH";
+ field public static final int MEDIA_TYPE_GENERIC = 0; // 0x0
+ field public static final int MEDIA_TYPE_MOVIE = 1; // 0x1
+ field public static final int MEDIA_TYPE_MUSIC_TRACK = 3; // 0x3
+ field public static final int MEDIA_TYPE_PHOTO = 4; // 0x4
+ field public static final int MEDIA_TYPE_TV_SHOW = 2; // 0x2
+ field public static final int MEDIA_TYPE_USER = 100; // 0x64
+ }
+
+ public static final class MediaPlayerProtocol.MediaStatus {
+ ctor public MediaPlayerProtocol.MediaStatus(long, android.support.media.protocols.MediaPlayerProtocol.MediaInfo);
+ method public static android.support.media.protocols.MediaPlayerProtocol.MediaStatus fromBundle(android.os.Bundle);
+ method public long[] getActiveTrackIds();
+ method public android.os.Bundle getExtras();
+ method public int getIdleReason();
+ method public android.support.media.protocols.MediaPlayerProtocol.MediaInfo getMediaInfo();
+ method public long getMediaSessionId();
+ method public double getPlaybackRate();
+ method public int getPlayerState();
+ method public long getStreamPosition();
+ method public double getStreamVolume();
+ method public boolean isMediaCommandSupported(long);
+ method public boolean isMute();
+ method public void setActiveTrackIds(long[]);
+ method public void setExtras(android.os.Bundle);
+ method public void setIdleReason(int);
+ method public void setMute(boolean);
+ method public void setPlaybackRate(double);
+ method public void setPlayerState(int);
+ method public void setStreamPosition(long);
+ method public void setStreamVolume(double);
+ method public void setSupportedMediaCommands(long);
+ method public android.os.Bundle toBundle();
+ field public static final long COMMAND_PAUSE = 1L; // 0x1L
+ field public static final long COMMAND_SEEK = 2L; // 0x2L
+ field public static final long COMMAND_SET_VOLUME = 4L; // 0x4L
+ field public static final long COMMAND_SKIP_BACKWARD = 32L; // 0x20L
+ field public static final long COMMAND_SKIP_FORWARD = 16L; // 0x10L
+ field public static final long COMMAND_TOGGLE_MUTE = 8L; // 0x8L
+ field public static final int IDLE_REASON_CANCELED = 2; // 0x2
+ field public static final int IDLE_REASON_ERROR = 4; // 0x4
+ field public static final int IDLE_REASON_FINISHED = 1; // 0x1
+ field public static final int IDLE_REASON_INTERRUPTED = 3; // 0x3
+ field public static final int IDLE_REASON_NONE = 0; // 0x0
+ field public static final int PLAYER_STATE_BUFFERING = 4; // 0x4
+ field public static final int PLAYER_STATE_IDLE = 1; // 0x1
+ field public static final int PLAYER_STATE_PAUSED = 3; // 0x3
+ field public static final int PLAYER_STATE_PLAYING = 2; // 0x2
+ field public static final int PLAYER_STATE_UNKNOWN = 0; // 0x0
+ }
+
+ public static final class MediaPlayerProtocol.MediaTrack {
+ ctor public MediaPlayerProtocol.MediaTrack(long, int);
+ method public static android.support.media.protocols.MediaPlayerProtocol.MediaTrack fromBundle(android.os.Bundle);
+ method public java.lang.String getContentId();
+ method public java.lang.String getContentType();
+ method public android.os.Bundle getExtras();
+ method public long getId();
+ method public java.lang.String getLanguage();
+ method public java.lang.String getName();
+ method public int getSubtype();
+ method public int getType();
+ method public void setContentId(java.lang.String);
+ method public void setContentType(java.lang.String);
+ method public void setExtras(android.os.Bundle);
+ method public void setLanguage(java.lang.String);
+ method public void setName(java.lang.String);
+ method public void setSubtype(int);
+ method public android.os.Bundle toBundle();
+ field public static final int SUBTYPE_CAPTIONS = 2; // 0x2
+ field public static final int SUBTYPE_CHAPTERS = 4; // 0x4
+ field public static final int SUBTYPE_DESCRIPTIONS = 3; // 0x3
+ field public static final int SUBTYPE_METADATA = 5; // 0x5
+ field public static final int SUBTYPE_NONE = 0; // 0x0
+ field public static final int SUBTYPE_SUBTITLES = 1; // 0x1
+ field public static final int SUBTYPE_UNKNOWN = -1; // 0xffffffff
+ field public static final int TYPE_AUDIO = 2; // 0x2
+ field public static final int TYPE_TEXT = 1; // 0x1
+ field public static final int TYPE_UNKNOWN = 0; // 0x0
+ field public static final int TYPE_VIDEO = 3; // 0x3
+ }
+
+ public static abstract class MediaPlayerProtocol.Stub extends android.support.media.protocols.MediaRouteProtocol.Stub {
+ ctor public MediaPlayerProtocol.Stub(android.os.Handler);
+ method public void onLoad(android.support.media.protocols.MediaPlayerProtocol.MediaInfo, boolean, long, android.os.Bundle);
+ method public void onPause(android.os.Bundle);
+ method public void onPlay(android.os.Bundle);
+ method public void onRequestStatus(android.os.Bundle);
+ method public void onSeek(long, int, android.os.Bundle);
+ method public void onSetActiveMediaTracks(long[], android.os.Bundle);
+ method public void onSetStreamMute(boolean, android.os.Bundle);
+ method public void onSetStreamVolume(int, android.os.Bundle);
+ method public void onSetTextTrackStyle(android.support.media.protocols.MediaPlayerProtocol.TextTrackStyle, android.os.Bundle);
+ method public void onStop(android.os.Bundle);
+ method public void sendStatusUpdatedEvent(android.support.media.protocols.MediaPlayerProtocol.MediaStatus, android.os.Bundle);
+ }
+
+ public static final class MediaPlayerProtocol.TextTrackStyle {
+ ctor public MediaPlayerProtocol.TextTrackStyle();
+ method public static android.support.media.protocols.MediaPlayerProtocol.TextTrackStyle fromBundle(android.os.Bundle);
+ method public static android.support.media.protocols.MediaPlayerProtocol.TextTrackStyle fromSystemSettings(android.content.Context);
+ method public int getBackgroundColor();
+ method public int getEdgeColor();
+ method public int getEdgeType();
+ method public android.os.Bundle getExtras();
+ method public java.lang.String getFontFamily();
+ method public int getFontGenericFamily();
+ method public float getFontScale();
+ method public int getFontStyle();
+ method public int getForegroundColor();
+ method public int getWindowColor();
+ method public int getWindowCornerRadius();
+ method public int getWindowType();
+ method public void setBackgroundColor(int);
+ method public void setEdgeColor(int);
+ method public void setEdgeType(int);
+ method public void setExtras(android.os.Bundle);
+ method public void setFontFamily(java.lang.String);
+ method public void setFontGenericFamily(int);
+ method public void setFontScale(float);
+ method public void setFontStyle(int);
+ method public void setForegroundColor(int);
+ method public void setWindowColor(int);
+ method public void setWindowCornerRadius(int);
+ method public void setWindowType(int);
+ method public android.os.Bundle toBundle();
+ field public static final int COLOR_UNSPECIFIED = 0; // 0x0
+ field public static final float DEFAULT_FONT_SCALE = 1.0f;
+ field public static final int EDGE_TYPE_DEPRESSED = 4; // 0x4
+ field public static final int EDGE_TYPE_DROP_SHADOW = 2; // 0x2
+ field public static final int EDGE_TYPE_NONE = 0; // 0x0
+ field public static final int EDGE_TYPE_OUTLINE = 1; // 0x1
+ field public static final int EDGE_TYPE_RAISED = 3; // 0x3
+ field public static final int EDGE_TYPE_UNSPECIFIED = -1; // 0xffffffff
+ field public static final int FONT_FAMILY_CASUAL = 4; // 0x4
+ field public static final int FONT_FAMILY_CURSIVE = 5; // 0x5
+ field public static final int FONT_FAMILY_MONOSPACED_SANS_SERIF = 1; // 0x1
+ field public static final int FONT_FAMILY_MONOSPACED_SERIF = 3; // 0x3
+ field public static final int FONT_FAMILY_SANS_SERIF = 0; // 0x0
+ field public static final int FONT_FAMILY_SERIF = 2; // 0x2
+ field public static final int FONT_FAMILY_SMALL_CAPITALS = 6; // 0x6
+ field public static final int FONT_FAMILY_UNSPECIFIED = -1; // 0xffffffff
+ field public static final int FONT_STYLE_BOLD = 1; // 0x1
+ field public static final int FONT_STYLE_BOLD_ITALIC = 3; // 0x3
+ field public static final int FONT_STYLE_ITALIC = 2; // 0x2
+ field public static final int FONT_STYLE_NORMAL = 0; // 0x0
+ field public static final int FONT_STYLE_UNSPECIFIED = -1; // 0xffffffff
+ field public static final int WINDOW_TYPE_NONE = 0; // 0x0
+ field public static final int WINDOW_TYPE_NORMAL = 1; // 0x1
+ field public static final int WINDOW_TYPE_ROUNDED = 2; // 0x2
+ field public static final int WINDOW_TYPE_UNSPECIFIED = -1; // 0xffffffff
+ }
+
+ public static final class MediaPlayerProtocol.WebImage {
+ ctor public MediaPlayerProtocol.WebImage(android.net.Uri) throws java.lang.IllegalArgumentException;
+ ctor public MediaPlayerProtocol.WebImage(android.net.Uri, int, int) throws java.lang.IllegalArgumentException;
+ method public static android.support.media.protocols.MediaPlayerProtocol.WebImage fromBundle(android.os.Bundle);
+ method public int getHeight();
+ method public android.net.Uri getUrl();
+ method public int getWidth();
+ method public android.os.Bundle toBundle();
+ }
+
+ public abstract class MediaRouteProtocol {
+ ctor public MediaRouteProtocol(android.os.IBinder);
+ method public void sendRequest(java.lang.String, android.os.Bundle);
+ method public void setCallback(android.support.media.protocols.MediaRouteProtocol.Callback, android.os.Handler);
+ field public static final java.lang.String ERROR_DISCONNECTED = "android.support.errors.DISCONNECTED";
+ field public static final java.lang.String ERROR_UNKNOWN = "android.support.errors.UNKNOWN";
+ field public static final java.lang.String ERROR_UNSUPPORTED_OPERATION = "android.support.errors.UNSUPPORTED_OPERATION";
+ }
+
+ public static abstract class MediaRouteProtocol.Callback {
+ ctor public MediaRouteProtocol.Callback();
+ method public void onError(java.lang.String, android.os.Bundle);
+ method public void onEvent(java.lang.String, android.os.Bundle);
+ }
+
+ public static abstract class MediaRouteProtocol.Stub implements android.os.IInterface {
+ ctor public MediaRouteProtocol.Stub(android.os.Handler);
+ method public android.os.IBinder asBinder();
+ method public void close();
+ method public void onClientAttached();
+ method public void onClientDetached();
+ method public void onRequest(java.lang.String, android.os.Bundle) throws java.lang.UnsupportedOperationException;
+ method public boolean sendError(java.lang.String, android.os.Bundle);
+ method public boolean sendEvent(java.lang.String, android.os.Bundle);
+ }
+
+}
+
diff --git a/media/protocols/api/removed.txt b/media/protocols/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/protocols/api/removed.txt
diff --git a/media/protocols/build.gradle b/media/protocols/build.gradle
new file mode 100644
index 0000000..254770c
--- /dev/null
+++ b/media/protocols/build.gradle
@@ -0,0 +1,34 @@
+apply plugin: 'java'
+
+archivesBaseName = 'support-media-protocols'
+
+sourceSets {
+ main.java.srcDir 'src'
+}
+
+jar {
+ from sourceSets.main.output
+}
+
+// configuration for the javadoc to include all source sets.
+javadoc {
+ source sourceSets.main.allJava
+}
+
+// custom tasks for creating source/javadoc jars
+task sourcesJar(type: Jar, dependsOn:classes) {
+ classifier = 'sources'
+ from sourceSets.main.allSource
+}
+
+task javadocJar(type: Jar, dependsOn:javadoc) {
+ classifier 'javadoc'
+ from javadoc.destinationDir
+}
+
+// add javadoc/source jar tasks as artifacts
+artifacts {
+ archives jar
+ archives sourcesJar
+ archives javadocJar
+}
diff --git a/media/protocols/src/android/support/media/protocols/MediaPlayerProtocol.java b/media/protocols/src/android/support/media/protocols/MediaPlayerProtocol.java
new file mode 100644
index 0000000..3dc72dc
--- /dev/null
+++ b/media/protocols/src/android/support/media/protocols/MediaPlayerProtocol.java
@@ -0,0 +1,2179 @@
+/*
+ * 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.
+ */
+package android.support.media.protocols;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Parcelable;
+import android.support.annotation.IntDef;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.view.accessibility.CaptioningManager;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Media route protocol for managing a queue of media to be played remotely
+ * by a media device.
+ */
+public class MediaPlayerProtocol extends MediaRouteProtocol {
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = { RESUME_STATE_UNCHANGED, RESUME_STATE_PLAY,
+ RESUME_STATE_PAUSE })
+ public @interface ResumeState { }
+
+ /**
+ * A resume state indicating that the player state should be left unchanged.
+ */
+ public static final int RESUME_STATE_UNCHANGED = 0;
+
+ /**
+ * A resume state indicating that the player should be playing,
+ * regardless of its current state.
+ */
+ public static final int RESUME_STATE_PLAY = 1;
+
+ /**
+ * A resume state indicating that the player should be paused,
+ * regardless of its current state.
+ */
+ public static final int RESUME_STATE_PAUSE = 2;
+
+ /**
+ * Creates the protocol client object for an application to use to send
+ * messages to a media route.
+ * <p>
+ * This constructor is called automatically if you use
+ * {@link android.media.routing.MediaRouter.ConnectionInfo#getProtocolObject getProtocolObject}
+ * to obtain a protocol object from a media route connection.
+ * </p>
+ *
+ * @param binder The remote binder supplied by the media route service. May be
+ * obtained using {@link android.media.routing.MediaRouter.ConnectionInfo#getProtocolBinder}
+ * on a route connection.
+ */
+ public MediaPlayerProtocol(@NonNull IBinder binder) {
+ super(binder);
+ }
+
+ /**
+ * Loads and optionally starts playback of a new media item.
+ * The media item starts playback at playPosition.
+ *
+ * @param mediaInfo An object describing the media item to load.
+ * @param autoplay Whether playback should start immediately.
+ * @param playPosition The initial playback position, in milliseconds from the
+ * beginning of the stream.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void load(@NonNull MediaInfo mediaInfo, boolean autoplay,
+ long playPosition, @Nullable Bundle extras) {
+ if (mediaInfo == null) {
+ throw new IllegalArgumentException("mediaInfo must not be null");
+ }
+ Bundle args = new Bundle();
+ args.putBundle("mediaInfo", mediaInfo.toBundle());
+ args.putBoolean("autoplay", autoplay);
+ args.putLong("playPosition", playPosition);
+ args.putBundle("extras", extras);
+ sendRequest("load", args);
+ }
+
+ /**
+ * Begins or resumes playback of the current media item.
+ *
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void play(@Nullable Bundle extras) {
+ Bundle args = new Bundle();
+ args.putBundle("extras", extras);
+ sendRequest("play", args);
+ }
+
+ /**
+ * Pauses playback of the current media item.
+ *
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void pause(@Nullable Bundle extras) {
+ Bundle args = new Bundle();
+ args.putBundle("extras", extras);
+ sendRequest("pause", args);
+ }
+
+ /**
+ * Requests updated media status information from the receiver.
+ *
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void requestStatus(@Nullable Bundle extras) {
+ Bundle args = new Bundle();
+ args.putBundle("extras", extras);
+ sendRequest("requestStatus", args);
+ }
+
+ /**
+ * Seeks to a new position within the current media item.
+ *
+ * @param position The new position, in milliseconds from the beginning of the stream.
+ * @param resumeState The action to take after the seek operation has finished.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void seek(long position, @ResumeState int resumeState, @Nullable Bundle extras) {
+ Bundle args = new Bundle();
+ args.putLong("position", position);
+ args.putInt("resumeState", resumeState);
+ args.putBundle("extras", extras);
+ sendRequest("seek", args);
+ }
+
+ /**
+ * Sets the active media tracks.
+ *
+ * @param trackIds The media track IDs.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void setActiveMediaTracks(@NonNull long[] trackIds, @Nullable Bundle extras) {
+ if (trackIds == null) {
+ throw new IllegalArgumentException("trackIds must not be null");
+ }
+ Bundle args = new Bundle();
+ args.putLongArray("trackIds", trackIds);
+ args.putBundle("extras", extras);
+ sendRequest("setActiveMediaTracks", args);
+ }
+
+ /**
+ * Toggles the stream muting.
+ *
+ * @param muteState Whether the stream should be muted or unmuted.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void setStreamMute(boolean muteState, @Nullable Bundle extras) {
+ Bundle args = new Bundle();
+ args.putBoolean("muteState", muteState);
+ args.putBundle("extras", extras);
+ sendRequest("setStreamMute", args);
+ }
+
+ /**
+ * Sets the stream volume.
+ * If volume is outside of the range [0.0, 1.0], then the value will be clipped.
+ *
+ * @param volume The new volume, in the range [0.0 - 1.0].
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void setStreamVolume(int volume, @Nullable Bundle extras) {
+ Bundle args = new Bundle();
+ args.putInt("volume", volume);
+ args.putBundle("extras", extras);
+ sendRequest("setStreamVolume", args);
+ }
+
+ /**
+ * Sets the text track style.
+ *
+ * @param trackStyle The track style.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void setTextTrackStyle(@NonNull TextTrackStyle trackStyle, @Nullable Bundle extras) {
+ if (trackStyle == null) {
+ throw new IllegalArgumentException("trackStyle must not be null");
+ }
+ Bundle args = new Bundle();
+ args.putBundle("trackStyle", trackStyle.toBundle());
+ args.putBundle("extras", extras);
+ sendRequest("setTextTrackStyle", args);
+ }
+
+ /**
+ * Stops playback of the current media item.
+ *
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void stop(@Nullable Bundle extras) {
+ Bundle args = new Bundle();
+ args.putBundle("extras", extras);
+ sendRequest("stop", args);
+ }
+
+ /**
+ * Media player callbacks.
+ */
+ public static abstract class Callback extends MediaRouteProtocol.Callback {
+ /**
+ * Called when updated player status information is received.
+ *
+ * @param status The updated status, or null if none.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onStatusUpdated(@Nullable MediaStatus status,
+ @Nullable Bundle extras) { }
+
+ @Override
+ public void onEvent(String event, Bundle args) {
+ switch (event) {
+ case "statusUpdated":
+ onStatusUpdated(MediaStatus.fromBundle(args.getBundle("status")),
+ args.getBundle("extras"));
+ return;
+ }
+ super.onEvent(event, args);
+ }
+ }
+
+ /**
+ * Media player stubs.
+ */
+ public static abstract class Stub extends MediaRouteProtocol.Stub {
+ /**
+ * Creates an implementation of a media route protocol.
+ *
+ * @param handler The handler on which to receive requests, or null to use
+ * the current looper thread.
+ */
+ public Stub(@Nullable Handler handler) {
+ super(handler);
+ }
+
+ /**
+ * Loads and optionally starts playback of a new media item.
+ * The media item starts playback at playPosition.
+ *
+ * @param mediaInfo An object describing the media item to load.
+ * @param autoplay Whether playback should start immediately.
+ * @param playPosition The initial playback position, in milliseconds from the
+ * beginning of the stream.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onLoad(@NonNull MediaInfo mediaInfo, boolean autoplay,
+ long playPosition, @Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Begins or resumes playback of the current media item.
+ *
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onPlay(@Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Pauses playback of the current media item.
+ *
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onPause(@Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Requests updated media status information from the receiver.
+ *
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onRequestStatus(@Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Seeks to a new position within the current media item.
+ *
+ * @param position The new position, in milliseconds from the beginning of the stream.
+ * @param resumeState The action to take after the seek operation has finished.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onSeek(long position, @ResumeState int resumeState, @Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Sets the active media tracks.
+ *
+ * @param trackIds The media track IDs.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onSetActiveMediaTracks(long[] trackIds, @Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Toggles the stream muting.
+ *
+ * @param muteState Whether the stream should be muted or unmuted.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onSetStreamMute(boolean muteState, @Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Sets the stream volume.
+ * If volume is outside of the range [0.0, 1.0], then the value will be clipped.
+ *
+ * @param volume The new volume, in the range [0.0 - 1.0].
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onSetStreamVolume(int volume, @Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Sets the text track style.
+ *
+ * @param trackStyle The track style.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onSetTextTrackStyle(@NonNull TextTrackStyle trackStyle,
+ @Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Stops playback of the current media item.
+ *
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void onStop(@Nullable Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Sends a status updated event.
+ *
+ * @param status The updated media status, or null if none.
+ * @param extras Custom application-specific data to pass along with the request.
+ */
+ public void sendStatusUpdatedEvent(@Nullable MediaStatus status,
+ @Nullable Bundle extras) {
+ Bundle args = new Bundle();
+ args.putBundle("status", status.toBundle());
+ args.putBundle("extras", extras);
+ sendEvent("statusUpdated", args);
+ }
+
+ @Override
+ public void onRequest(String request, Bundle args)
+ throws UnsupportedOperationException {
+ switch (request) {
+ case "load":
+ onLoad(MediaInfo.fromBundle(args.getBundle("mediaInfo")),
+ args.getBoolean("autoplay"), args.getLong("playPosition"),
+ args.getBundle("extras"));
+ return;
+ case "play":
+ onPlay(args.getBundle("extras"));
+ return;
+ case "pause":
+ onPause(args.getBundle("extras"));
+ return;
+ case "requestStatus":
+ onRequestStatus(args.getBundle("extras"));
+ return;
+ case "seek":
+ onSeek(args.getLong("position"), args.getInt("resumeState"),
+ args.getBundle("extras"));
+ return;
+ case "setActiveMediaTracks":
+ onSetActiveMediaTracks(args.getLongArray("trackIds"), args.getBundle("extras"));
+ return;
+ case "setStreamMute":
+ onSetStreamMute(args.getBoolean("muteState"), args.getBundle("extras"));
+ return;
+ case "setStreamVolume":
+ onSetStreamVolume(args.getInt("volume"), args.getBundle("extras"));
+ return;
+ case "setTextTrackStyle":
+ onSetTextTrackStyle(TextTrackStyle.fromBundle(args.getBundle("trackStyle")),
+ args.getBundle("extras"));
+ return;
+ case "stop":
+ onStop(args.getBundle("extras"));
+ return;
+ }
+ super.onRequest(request, args);
+ }
+ }
+
+ /**
+ * A class that aggregates information about a media item.
+ */
+ public static final class MediaInfo {
+ /** A stream type of "none". */
+ public static final int STREAM_TYPE_NONE = 0;
+
+ /** A buffered stream type. */
+ public static final int STREAM_TYPE_BUFFERED = 1;
+
+ /** A live stream type. */
+ public static final int STREAM_TYPE_LIVE = 2;
+
+ /** An invalid (unknown) stream type. */
+ public static final int STREAM_TYPE_INVALID = -1;
+
+ private static final int STREAM_TYPE_MAX = STREAM_TYPE_LIVE;
+
+ private static final String KEY_CONTENT_ID = "contentId";
+ private static final String KEY_CONTENT_TYPE = "contentType";
+ private static final String KEY_EXTRAS = "extras";
+ private static final String KEY_DURATION = "duration";
+ private static final String KEY_METADATA = "metadata";
+ private static final String KEY_STREAM_TYPE = "streamType";
+ private static final String KEY_TEXT_TRACK_STYLE = "textTrackStyle";
+ private static final String KEY_TRACKS = "tracks";
+
+ private final String mContentId;
+ private final int mStreamType;
+ private final String mContentType;
+ private MediaMetadata mMediaMetadata;
+ private long mStreamDuration;
+ private final ArrayList<MediaTrack> mMediaTracks = new ArrayList<MediaTrack>();
+ private TextTrackStyle mTextTrackStyle;
+ private Bundle mExtras;
+
+ /**
+ * Constructs a new MediaInfo with the given content ID.
+ *
+ * @throws IllegalArgumentException If the content ID or content type
+ * is {@code null} or empty, or if the stream type is invalid.
+ */
+ public MediaInfo(@NonNull String contentId, int streamType,
+ @NonNull String contentType) {
+ if (TextUtils.isEmpty(contentId)) {
+ throw new IllegalArgumentException("content ID cannot be null or empty");
+ }
+ if ((streamType < STREAM_TYPE_INVALID) || (streamType > STREAM_TYPE_MAX)) {
+ throw new IllegalArgumentException("invalid stream type");
+ }
+ if (TextUtils.isEmpty(contentType)) {
+ throw new IllegalArgumentException("content type cannot be null or empty");
+ }
+ mContentId = contentId;
+ mStreamType = streamType;
+ mContentType = contentType;
+ }
+
+ /**
+ * Returns the content ID.
+ */
+ public @NonNull String getContentId() {
+ return mContentId;
+ }
+
+ /**
+ * Returns the stream type.
+ */
+ public int getStreamType() {
+ return mStreamType;
+ }
+
+ /**
+ * Returns the content (MIME) type.
+ */
+ public @NonNull String getContentType() {
+ return mContentType;
+ }
+
+ /**
+ * Sets the media item metadata.
+ */
+ public void setMetadata(@Nullable MediaMetadata metadata) {
+ mMediaMetadata = metadata;
+ }
+
+ /**
+ * Returns the media item metadata.
+ */
+ public @Nullable MediaMetadata getMetadata() {
+ return mMediaMetadata;
+ }
+
+ /**
+ * Sets the stream duration, in milliseconds.
+ *
+ * @throws IllegalArgumentException If the duration is negative.
+ */
+ public void setStreamDuration(long streamDuration) {
+ if (streamDuration < 0) {
+ throw new IllegalArgumentException("Stream duration cannot be negative");
+ }
+ mStreamDuration = streamDuration;
+ }
+
+ /**
+ * Returns the stream duration, in milliseconds.
+ */
+ public long getStreamDuration() {
+ return mStreamDuration;
+ }
+
+ /**
+ * Sets the media tracks.
+ */
+ public void setMediaTracks(@NonNull List<MediaTrack> mediaTracks) {
+ mMediaTracks.clear();
+ mMediaTracks.addAll(mediaTracks);
+ }
+
+ /**
+ * Returns the list of media tracks, or {@code null} if none have been specified.
+ */
+ public @NonNull List<MediaTrack> getMediaTracks() {
+ return mMediaTracks;
+ }
+
+ /**
+ * Sets the text track style.
+ */
+ public void setTextTrackStyle(@Nullable TextTrackStyle textTrackStyle) {
+ mTextTrackStyle = textTrackStyle;
+ }
+
+ /**
+ * Returns the text track style, or {@code null} if none has been specified.
+ */
+ public @Nullable TextTrackStyle getTextTrackStyle() {
+ return mTextTrackStyle;
+ }
+
+ /**
+ * Sets the custom application-specific data.
+ */
+ public void setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ }
+
+ /**
+ * Returns the extras, if any.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Creates a bundle representation of the object.
+ */
+ public @NonNull Bundle toBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_CONTENT_ID, mContentId);
+ bundle.putInt(KEY_STREAM_TYPE, mStreamType);
+ bundle.putString(KEY_CONTENT_TYPE, mContentType);
+ if (mMediaMetadata != null) {
+ bundle.putBundle(KEY_METADATA, mMediaMetadata.toBundle());
+ }
+ bundle.putLong(KEY_DURATION, mStreamDuration);
+ if (mTextTrackStyle != null) {
+ bundle.putBundle(KEY_TEXT_TRACK_STYLE, mTextTrackStyle.toBundle());
+ }
+ if (mExtras != null) {
+ bundle.putBundle(KEY_EXTRAS, mExtras);
+ }
+ if (!mMediaTracks.isEmpty()) {
+ Parcelable[] trackBundles = new Parcelable[mMediaTracks.size()];
+ for (int i = 0; i < trackBundles.length; i++) {
+ trackBundles[i] = mMediaTracks.get(i).toBundle();
+ }
+ bundle.putParcelableArray(KEY_TRACKS, trackBundles);
+ }
+ return bundle;
+ }
+
+ /**
+ * Constructs a new {@link MediaInfo} object from a bundle.
+ */
+ public static @Nullable MediaInfo fromBundle(@Nullable Bundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+
+ String contentId = bundle.getString(KEY_CONTENT_ID);
+ int streamType = bundle.getInt(KEY_STREAM_TYPE, STREAM_TYPE_INVALID);
+ String contentType = bundle.getString(KEY_CONTENT_TYPE);
+
+ MediaInfo info = new MediaInfo(contentId, streamType, contentType);
+ info.setMetadata(MediaMetadata.fromBundle(bundle.getBundle(KEY_METADATA)));
+ info.setStreamDuration(bundle.getLong(KEY_DURATION));
+ info.setTextTrackStyle(TextTrackStyle.fromBundle(
+ bundle.getBundle(KEY_TEXT_TRACK_STYLE)));
+ info.setExtras(bundle.getBundle("extras"));
+
+ Parcelable[] trackBundles = bundle.getParcelableArray(KEY_TRACKS);
+ if (trackBundles != null) {
+ for (int i = 0; i < trackBundles.length; ++i) {
+ info.mMediaTracks.add(MediaTrack.fromBundle((Bundle)trackBundles[i]));
+ }
+ }
+
+ return info;
+ }
+ }
+
+ /**
+ * Container class for media metadata. Metadata has a media type, an optional
+ * list of images, and a collection of metadata fields. Keys for common
+ * metadata fields are predefined as constants, but the application is free to
+ * define and use additional fields of its own.
+ * <p>
+ * The values of the predefined fields have predefined types. For example, a track number is
+ * an <code>int</code> and a creation date is a <code>Calendar</code>. Attempting to
+ * store a value of an incorrect type in a field will result in a
+ * {@link IllegalArgumentException}.
+ */
+ public static final class MediaMetadata {
+ /** A media type representing generic media content. */
+ public static final int MEDIA_TYPE_GENERIC = 0;
+ /** A media type representing a movie. */
+ public static final int MEDIA_TYPE_MOVIE = 1;
+ /** A media type representing an TV show. */
+ public static final int MEDIA_TYPE_TV_SHOW = 2;
+ /** A media type representing a music track. */
+ public static final int MEDIA_TYPE_MUSIC_TRACK = 3;
+ /** A media type representing a photo. */
+ public static final int MEDIA_TYPE_PHOTO = 4;
+ /** The smallest media type value that can be assigned for application-defined media types. */
+ public static final int MEDIA_TYPE_USER = 100;
+
+ // Field types.
+ private static final int TYPE_NONE = 0;
+ private static final int TYPE_STRING = 1;
+ private static final int TYPE_INT = 2;
+ private static final int TYPE_DOUBLE = 3;
+ private static final int TYPE_DATE = 4;
+
+ // Field type names. Used when constructing exceptions.
+ private static final String[] sTypeNames = { null, "String", "int", "double", "Calendar" };
+
+ private final int mMediaType;
+ private final Bundle mFields;
+ private final ArrayList<WebImage> mImages;
+
+ private static final String BUNDLE_KEY_MEDIA_TYPE = "mediaType";
+ private static final String BUNDLE_KEY_FIELDS = "fields";
+ private static final String BUNDLE_KEY_IMAGES = "images";
+
+ /**
+ * String key: Creation date.
+ * <p>
+ * The value is the date and/or time at which the media was created.
+ * For example, this could be the date and time at which a photograph was taken or a piece of
+ * music was recorded.
+ */
+ public static final String KEY_CREATION_DATE =
+ "android.support.media.protocols.metadata.CREATION_DATE";
+
+ /**
+ * String key: Release date.
+ * <p>
+ * The value is the date and/or time at which the media was released.
+ * For example, this could be the date that a movie or music album was released.
+ */
+ public static final String KEY_RELEASE_DATE =
+ "android.support.media.protocols.metadata.RELEASE_DATE";
+
+ /**
+ * String key: Broadcast date.
+ * <p>
+ * The value is the date and/or time at which the media was first broadcast.
+ * For example, this could be the date that a TV show episode was first aired.
+ */
+ public static final String KEY_BROADCAST_DATE =
+ "android.support.media.protocols.metadata.BROADCAST_DATE";
+
+ /**
+ * String key: Title.
+ * <p>
+ * The title of the media. For example, this could be the title of a song, movie, or TV show
+ * episode. This value is suitable for display purposes.
+ */
+ public static final String KEY_TITLE =
+ "android.support.media.protocols.metadata.TITLE";
+
+ /**
+ * String key: Subtitle.
+ * <p>
+ * The subtitle of the media. This value is suitable for display purposes.
+ */
+ public static final String KEY_SUBTITLE =
+ "android.support.media.protocols.metadata.SUBTITLE";
+
+ /**
+ * String key: Artist.
+ * <p>
+ * The name of the artist who created the media. For example, this could be the name of a
+ * musician, performer, or photographer. This value is suitable for display purposes.
+ */
+ public static final String KEY_ARTIST =
+ "android.support.media.protocols.metadata.ARTIST";
+
+ /**
+ * String key: Album artist.
+ * <p>
+ * The name of the artist who produced an album. For example, in compilation albums such as DJ
+ * mixes, the album artist is not necessarily the same as the artist(s) of the individual songs
+ * on the album. This value is suitable for display purposes.
+ */
+ public static final String KEY_ALBUM_ARTIST =
+ "android.support.media.protocols.metadata.ALBUM_ARTIST";
+
+ /**
+ * String key: Album title.
+ * <p>
+ * The title of the album that a music track belongs to. This value is suitable for display
+ * purposes.
+ */
+ public static final String KEY_ALBUM_TITLE =
+ "android.support.media.protocols.metadata.ALBUM_TITLE";
+
+ /**
+ * String key: Composer.
+ * <p>
+ * The name of the composer of a music track. This value is suitable for display purposes.
+ */
+ public static final String KEY_COMPOSER =
+ "android.support.media.protocols.metadata.COMPOSER";
+
+ /**
+ * Integer key: Disc number.
+ * <p>
+ * The disc number (counting from 1) that a music track belongs to in a multi-disc album.
+ */
+ public static final String KEY_DISC_NUMBER =
+ "android.support.media.protocols.metadata.DISC_NUMBER";
+
+ /**
+ * Integer key: Track number.
+ * <p>
+ * The track number of a music track on an album disc. Typically track numbers are counted
+ * starting from 1, however this value may be 0 if it is a "hidden track" at the beginning of
+ * an album.
+ */
+ public static final String KEY_TRACK_NUMBER =
+ "android.support.media.protocols.metadata.TRACK_NUMBER";
+
+ /**
+ * Integer key: Season number.
+ * <p>
+ * The season number that a TV show episode belongs to. Typically season numbers are counted
+ * starting from 1, however this value may be 0 if it is a "pilot" episode that predates the
+ * official start of a TV series.
+ */
+ public static final String KEY_SEASON_NUMBER =
+ "android.support.media.protocols.metadata.SEASON_NUMBER";
+
+ /**
+ * Integer key: Episode number.
+ * <p>
+ * The number of an episode in a given season of a TV show. Typically episode numbers are
+ * counted starting from 1, however this value may be 0 if it is a "pilot" episode that is not
+ * considered to be an official episode of the first season.
+ */
+ public static final String KEY_EPISODE_NUMBER =
+ "android.support.media.protocols.metadata.EPISODE_NUMBER";
+
+ /**
+ * String key: Series title.
+ * <p>
+ * The name of a series. For example, this could be the name of a TV show or series of related
+ * music albums. This value is suitable for display purposes.
+ */
+ public static final String KEY_SERIES_TITLE =
+ "android.support.media.protocols.metadata.SERIES_TITLE";
+
+ /**
+ * String key: Studio.
+ * <p>
+ * The name of a recording studio that produced a piece of media. For example, this could be
+ * the name of a movie studio or music label. This value is suitable for display purposes.
+ */
+ public static final String KEY_STUDIO =
+ "android.support.media.protocols.metadata.STUDIO";
+
+ /**
+ * Integer key: Width.
+ *
+ * The width of a piece of media, in pixels. This would typically be used for providing the
+ * dimensions of a photograph.
+ */
+ public static final String KEY_WIDTH =
+ "android.support.media.protocols.metadata.WIDTH";
+
+ /**
+ * Integer key: Height.
+ *
+ * The height of a piece of media, in pixels. This would typically be used for providing the
+ * dimensions of a photograph.
+ */
+ public static final String KEY_HEIGHT =
+ "android.support.media.protocols.metadata.HEIGHT";
+
+ /**
+ * String key: Location name.
+ * <p>
+ * The name of a location where a piece of media was created. For example, this could be the
+ * location of a photograph or the principal filming location of a movie. This value is
+ * suitable for display purposes.
+ */
+ public static final String KEY_LOCATION_NAME =
+ "android.support.media.protocols.metadata.LOCATION_NAME";
+
+ /**
+ * Double key: Location latitude.
+ * <p>
+ * The latitude component of the geographical location where a piece of media was created.
+ * For example, this could be the location of a photograph or the principal filming location of
+ * a movie.
+ */
+ public static final String KEY_LOCATION_LATITUDE =
+ "android.support.media.protocols.metadata.LOCATION_LATITUDE";
+
+ /**
+ * Double key: Location longitude.
+ * <p>
+ * The longitude component of the geographical location where a piece of media was created.
+ * For example, this could be the location of a photograph or the principal filming location of
+ * a movie.
+ */
+ public static final String KEY_LOCATION_LONGITUDE =
+ "android.support.media.protocols.metadata.LOCATION_LONGITUDE";
+
+ /**
+ * Constructs a new, empty, MediaMetadata with a media type of {@link #MEDIA_TYPE_GENERIC}.
+ */
+ public MediaMetadata() {
+ this(MEDIA_TYPE_GENERIC);
+ }
+
+ /**
+ * Constructs a new, empty, MediaMetadata with the given media type.
+ *
+ * @param mediaType The media type; one of the {@code MEDIA_TYPE_*} constants, or a value
+ * greater than or equal to {@link #MEDIA_TYPE_USER} for custom media types.
+ */
+ public MediaMetadata(int mediaType) {
+ this(mediaType, null);
+ }
+
+ private MediaMetadata(int mediaType, Bundle fields) {
+ mMediaType = mediaType;
+ mFields = fields != null ? fields : new Bundle();
+ mImages = new ArrayList<WebImage>();
+ }
+
+ /**
+ * Gets the media type.
+ */
+ public int getMediaType() {
+ return mMediaType;
+ }
+
+ /**
+ * Clears this object. The media type is left unchanged.
+ */
+ public void clear() {
+ mFields.clear();
+ mImages.clear();
+ }
+
+ /**
+ * Tests if the object contains a field with the given key.
+ */
+ public boolean containsKey(@NonNull String key) {
+ return mFields.containsKey(key);
+ }
+
+ /**
+ * Returns a set of keys for all fields that are present in the object.
+ */
+ public @NonNull Set<String> keySet() {
+ return mFields.keySet();
+ }
+
+ /**
+ * Stores a value in a String field.
+ *
+ * @param key The key for the field.
+ * @param value The new value for the field.
+ * @throws IllegalArgumentException If the key is {@code null} or empty or refers to a
+ * predefined field which is not a {@code String} field.
+ */
+ public void putString(@NonNull String key, String value) {
+ throwIfWrongType(key, TYPE_STRING);
+ mFields.putString(key, value);
+ }
+
+ /**
+ * Reads the value of a String field.
+ *
+ * @return The value of the field, or {@code null} if the field has not been set.
+ * @throws IllegalArgumentException If the key is {@code null} or empty or refers to a
+ * predefined field which is not a {@code String} field.
+ */
+ public @Nullable String getString(@NonNull String key) {
+ throwIfWrongType(key, TYPE_STRING);
+ return mFields.getString(key);
+ }
+
+ /**
+ * Stores a value in an int field.
+ *
+ * @param key The key for the field.
+ * @param value The new value for the field.
+ * @throws IllegalArgumentException If the key is {@code null} or empty or refers to a
+ * predefined field which is not an {@code int} field.
+ */
+ public void putInt(@NonNull String key, int value) {
+ throwIfWrongType(key, TYPE_INT);
+ mFields.putInt(key, value);
+ }
+
+ /**
+ * Reads the value of an {@code int} field.
+ *
+ * @return The value of the field, or {@code null} if the field has not been set.
+ * @throws IllegalArgumentException If the key is {@code null} or empty or refers to a
+ * predefined field which is not an {@code int} field.
+ */
+ public int getInt(@NonNull String key) {
+ throwIfWrongType(key, TYPE_INT);
+ return mFields.getInt(key);
+ }
+
+ /**
+ * Stores a value in a {@code double} field.
+ *
+ * @param key The key for the field.
+ * @param value The new value for the field.
+ * @throws IllegalArgumentException If the key is {@code null} or empty or refers to a
+ * predefined field which is not a {@code double} field.
+ */
+ public void putDouble(@NonNull String key, double value) {
+ throwIfWrongType(key, TYPE_DOUBLE);
+ mFields.putDouble(key, value);
+ }
+
+ /**
+ * Reads the value of a {@code double} field.
+ *
+ * @return The value of the field, or {@code null} if the field has not been set.
+ * @throws IllegalArgumentException If the key is {@code null} or empty or refers to a
+ * predefined field which is not a {@code double} field.
+ */
+ public double getDouble(@NonNull String key) {
+ throwIfWrongType(key, TYPE_DOUBLE);
+ return mFields.getDouble(key);
+ }
+
+ /**
+ * Stores a value in a date field.
+ *
+ * @param key The key for the field.
+ * @param value The new value for the field.
+ * @throws IllegalArgumentException If the key is {@code null} or empty or refers to a
+ * predefined field which is not a date field.
+ */
+ public void putDate(@NonNull String key, @Nullable Calendar value) {
+ throwIfWrongType(key, TYPE_DATE);
+ if (value != null) {
+ mFields.putLong(key, value.getTimeInMillis());
+ } else {
+ mFields.remove(key);
+ }
+ }
+
+ /**
+ * Reads the value of a date field.
+ *
+ * @param key The field name.
+ * @return The date, as a {@link Calendar}, or {@code null} if this field has not been set.
+ * @throws IllegalArgumentException If the key is {@code null} or empty or the specified field's
+ * predefined type is not a date.
+ */
+ public @Nullable Calendar getDate(String key) {
+ throwIfWrongType(key, TYPE_DATE);
+ if (mFields.containsKey(key)) {
+ Calendar date = Calendar.getInstance();
+ date.setTimeInMillis(mFields.getLong(key));
+ return date;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the list of images. If there are no images, returns an empty list.
+ */
+ public List<WebImage> getImages() {
+ return mImages;
+ }
+
+ /**
+ * Checks if the metadata includes any images.
+ */
+ public boolean hasImages() {
+ return (mImages != null) && !mImages.isEmpty();
+ }
+
+ /**
+ * Clears the list of images.
+ */
+ public void clearImages() {
+ mImages.clear();
+ }
+
+ /**
+ * Adds an image to the list of images.
+ */
+ public void addImage(WebImage image) {
+ mImages.add(image);
+ }
+
+ /*
+ * Verifies that a key is not empty, and if the key is a predefined key, verifies that it has
+ * the specified type.
+ */
+ private void throwIfWrongType(String key, int type) {
+ if (TextUtils.isEmpty(key)) {
+ throw new IllegalArgumentException("null and empty keys are not allowed");
+ }
+ int actualType = getFieldType(key);
+ if ((actualType != type) && (actualType != TYPE_NONE))
+ throw new IllegalArgumentException("Value for " + key + " must be a "
+ + sTypeNames[type]);
+ }
+
+ /**
+ * Creates a bundle representation of the object.
+ */
+ public @NonNull Bundle toBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putInt(BUNDLE_KEY_MEDIA_TYPE, mMediaType);
+ bundle.putBundle(BUNDLE_KEY_FIELDS, mFields);
+
+ if (mImages.isEmpty()) {
+ Parcelable[] imageBundles = new Parcelable[mImages.size()];
+ for (int i = 0; i < imageBundles.length; i++) {
+ imageBundles[i] = mImages.get(i).toBundle();
+ }
+ bundle.putParcelableArray(BUNDLE_KEY_IMAGES, imageBundles);
+ }
+
+ return bundle;
+ }
+
+ /**
+ * Constructs a new {@link MediaMetadata} object from a bundle.
+ */
+ public static MediaMetadata fromBundle(Bundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+
+ int mediaType = bundle.getInt(BUNDLE_KEY_MEDIA_TYPE);
+ Bundle fields = bundle.getBundle(BUNDLE_KEY_FIELDS);
+ MediaMetadata metadata = new MediaMetadata(mediaType, fields);
+
+ Parcelable[] imageBundles = bundle.getParcelableArray(BUNDLE_KEY_IMAGES);
+ if (imageBundles != null) {
+ for (Parcelable imageBundle : imageBundles) {
+ metadata.addImage(WebImage.fromBundle((Bundle)imageBundle));
+ }
+ }
+
+ return metadata;
+ }
+
+ private static int getFieldType(String key) {
+ switch (key) {
+ case KEY_CREATION_DATE: return TYPE_DATE;
+ case KEY_RELEASE_DATE: return TYPE_DATE;
+ case KEY_BROADCAST_DATE: return TYPE_DATE;
+ case KEY_TITLE: return TYPE_STRING;
+ case KEY_SUBTITLE: return TYPE_STRING;
+ case KEY_ARTIST: return TYPE_STRING;
+ case KEY_ALBUM_ARTIST: return TYPE_STRING;
+ case KEY_ALBUM_TITLE: return TYPE_STRING;
+ case KEY_COMPOSER: return TYPE_STRING;
+ case KEY_DISC_NUMBER: return TYPE_INT;
+ case KEY_TRACK_NUMBER: return TYPE_INT;
+ case KEY_SEASON_NUMBER: return TYPE_INT;
+ case KEY_EPISODE_NUMBER: return TYPE_INT;
+ case KEY_SERIES_TITLE: return TYPE_STRING;
+ case KEY_STUDIO: return TYPE_STRING;
+ case KEY_WIDTH: return TYPE_INT;
+ case KEY_HEIGHT: return TYPE_INT;
+ case KEY_LOCATION_NAME: return TYPE_STRING;
+ case KEY_LOCATION_LATITUDE: return TYPE_DOUBLE;
+ case KEY_LOCATION_LONGITUDE: return TYPE_DOUBLE;
+ default: return TYPE_NONE;
+ }
+ }
+ }
+
+ /**
+ * A class that holds status information about some media.
+ */
+ public static final class MediaStatus {
+ private static final String KEY_ACTIVE_TRACK_IDS = "activeTrackIds";
+ private static final String KEY_CURRENT_TIME = "currentTime";
+ private static final String KEY_EXTRAS = "extras";
+ private static final String KEY_IDLE_REASON = "idleReason";
+ private static final String KEY_MEDIA = "media";
+ private static final String KEY_MEDIA_SESSION_ID = "mediaSessionId";
+ private static final String KEY_MUTED = "muted";
+ private static final String KEY_PLAYBACK_RATE = "playbackRate";
+ private static final String KEY_PLAYER_STATE = "playerState";
+ private static final String KEY_SUPPORTED_MEDIA_COMMANDS = "supportedMediaCommands";
+ private static final String KEY_VOLUME = "volume";
+
+ /** A flag (bitmask) indicating that a media item can be paused. */
+ public static final long COMMAND_PAUSE = 1 << 0;
+
+ /** A flag (bitmask) indicating that a media item supports seeking. */
+ public static final long COMMAND_SEEK = 1 << 1;
+
+ /** A flag (bitmask) indicating that a media item's audio volume can be changed. */
+ public static final long COMMAND_SET_VOLUME = 1 << 2;
+
+ /** A flag (bitmask) indicating that a media item's audio can be muted. */
+ public static final long COMMAND_TOGGLE_MUTE = 1 << 3;
+
+ /** A flag (bitmask) indicating that a media item supports skipping forward. */
+ public static final long COMMAND_SKIP_FORWARD = 1 << 4;
+
+ /** A flag (bitmask) indicating that a media item supports skipping backward. */
+ public static final long COMMAND_SKIP_BACKWARD = 1 << 5;
+
+ /** Constant indicating unknown player state. */
+ public static final int PLAYER_STATE_UNKNOWN = 0;
+
+ /** Constant indicating that the media player is idle. */
+ public static final int PLAYER_STATE_IDLE = 1;
+
+ /** Constant indicating that the media player is playing. */
+ public static final int PLAYER_STATE_PLAYING = 2;
+
+ /** Constant indicating that the media player is paused. */
+ public static final int PLAYER_STATE_PAUSED = 3;
+
+ /** Constant indicating that the media player is buffering. */
+ public static final int PLAYER_STATE_BUFFERING = 4;
+
+ /** Constant indicating that the player currently has no idle reason. */
+ public static final int IDLE_REASON_NONE = 0;
+
+ /** Constant indicating that the player is idle because playback has finished. */
+ public static final int IDLE_REASON_FINISHED = 1;
+
+ /**
+ * Constant indicating that the player is idle because playback has been canceled in
+ * response to a STOP command.
+ */
+ public static final int IDLE_REASON_CANCELED = 2;
+
+ /**
+ * Constant indicating that the player is idle because playback has been interrupted by
+ * a LOAD command.
+ */
+ public static final int IDLE_REASON_INTERRUPTED = 3;
+
+ /** Constant indicating that the player is idle because a playback error has occurred. */
+ public static final int IDLE_REASON_ERROR = 4;
+
+ private final long mMediaSessionId;
+ private final MediaInfo mMediaInfo;
+ private double mPlaybackRate;
+ private int mPlayerState;
+ private int mIdleReason;
+ private long mStreamPosition;
+ private long mSupportedMediaCommands;
+ private double mVolume;
+ private boolean mMuteState;
+ private long mActiveTrackIds[];
+ private Bundle mExtras;
+
+ /**
+ * Constructs a new {@link MediaStatus} object with the given properties.
+ */
+ public MediaStatus(long mediaSessionId, @NonNull MediaInfo mediaInfo) {
+ if (mediaInfo == null) {
+ throw new IllegalArgumentException("mediaInfo must not be null");
+ }
+
+ mMediaSessionId = mediaSessionId;
+ mMediaInfo = mediaInfo;
+ mPlayerState = PLAYER_STATE_UNKNOWN;
+ mIdleReason = IDLE_REASON_NONE;
+ }
+
+ /**
+ * Returns the media session ID for this item.
+ */
+ public long getMediaSessionId() {
+ return mMediaSessionId;
+ }
+
+ /**
+ * Returns the {@link MediaInfo} for this item.
+ */
+ public @NonNull MediaInfo getMediaInfo() {
+ return mMediaInfo;
+ }
+
+ /**
+ * Gets the current media player state.
+ */
+ public int getPlayerState() {
+ return mPlayerState;
+ }
+
+ /**
+ * Sets the current media player state.
+ */
+ public void setPlayerState(int playerState) {
+ mPlayerState = playerState;
+ }
+
+ /**
+ * Gets the player state idle reason. This value is only meaningful if the player state is
+ * in fact {@link #PLAYER_STATE_IDLE}.
+ */
+ public int getIdleReason() {
+ return mIdleReason;
+ }
+
+ /**
+ * Sets the player state idle reason. This value is only meaningful if the player state is
+ * in fact {@link #PLAYER_STATE_IDLE}.
+ */
+ public void setIdleReason(int idleReason) {
+ mIdleReason = idleReason;
+ }
+
+ /**
+ * Gets the current stream playback rate. This will be negative if the stream is seeking
+ * backwards, 0 if the stream is paused, 1 if the stream is playing normally, and some other
+ * positive value if the stream is seeking forwards.
+ */
+ public double getPlaybackRate() {
+ return mPlaybackRate;
+ }
+
+ /**
+ * Sets the current stream playback rate. This will be negative if the stream is seeking
+ * backwards, 0 if the stream is paused, 1 if the stream is playing normally, and some other
+ * positive value if the stream is seeking forwards.
+ */
+ public void setPlaybackRate(double playbackRate) {
+ mPlaybackRate = playbackRate;
+ }
+
+ /**
+ * Returns the current stream position, in milliseconds.
+ */
+ public long getStreamPosition() {
+ return mStreamPosition;
+ }
+
+ /**
+ * Sets the current stream position, in milliseconds.
+ */
+ public void setStreamPosition(long streamPosition) {
+ mStreamPosition = streamPosition;
+ }
+
+ /**
+ * Tests if the stream supports a given control command.
+ *
+ * @param mediaCommand The media command.
+ * @return {@code true} if the command is supported, {@code false} otherwise.
+ */
+ public boolean isMediaCommandSupported(long mediaCommand) {
+ return (mSupportedMediaCommands & mediaCommand) != 0;
+ }
+
+ /**
+ * Sets whether the stream supports a given control command.
+ */
+ public void setSupportedMediaCommands(long supportedMediaCommands) {
+ mSupportedMediaCommands = supportedMediaCommands;
+ }
+
+ /**
+ * Returns the stream's volume.
+ */
+ public double getStreamVolume() {
+ return mVolume;
+ }
+
+ /**
+ * Sets the stream's volume.
+ */
+ public void setStreamVolume(double volume) {
+ mVolume = volume;
+ }
+
+ /**
+ * Returns the stream's mute state.
+ */
+ public boolean isMute() {
+ return mMuteState;
+ }
+
+ /**
+ * Sets the stream's mute state.
+ */
+ public void setMute(boolean muteState) {
+ mMuteState = muteState;
+ }
+
+ /**
+ * Returns the list of active track IDs, if any, otherwise {@code null}.
+ */
+ public @Nullable long[] getActiveTrackIds() {
+ return mActiveTrackIds;
+ }
+
+ /**
+ * Sets the list of active track IDs, if any, otherwise {@code null}.
+ */
+ public void setActiveTrackIds(@Nullable long[] trackIds) {
+ mActiveTrackIds = trackIds;
+ }
+
+ /**
+ * Returns any extras that are is associated with the media item.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Sets any extras that are associated with the media item.
+ */
+ public void setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ }
+
+ /**
+ * Creates a bundle representation of the object.
+ */
+ public @NonNull Bundle toBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putLong(KEY_MEDIA_SESSION_ID, mMediaSessionId);
+ bundle.putBundle(KEY_MEDIA, mMediaInfo.toBundle());
+ bundle.putLongArray(KEY_ACTIVE_TRACK_IDS, mActiveTrackIds);
+ bundle.putLong(KEY_CURRENT_TIME, mStreamPosition);
+ bundle.putInt(KEY_IDLE_REASON, mIdleReason);
+ bundle.putBoolean(KEY_MUTED, mMuteState);
+ bundle.putDouble(KEY_PLAYBACK_RATE, mPlaybackRate);
+ bundle.putInt(KEY_PLAYER_STATE, mPlayerState);
+ bundle.putLong(KEY_SUPPORTED_MEDIA_COMMANDS, mSupportedMediaCommands);
+ bundle.putDouble(KEY_VOLUME, mVolume);
+ return bundle;
+ }
+
+ /**
+ * Constructs a new {@link MediaStatus} object from a bundle.
+ */
+ public static MediaStatus fromBundle(Bundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+
+ long mediaSessionId = bundle.getLong(KEY_MEDIA_SESSION_ID);
+ MediaInfo mediaInfo = MediaInfo.fromBundle(bundle.getBundle(KEY_MEDIA));
+ MediaStatus status = new MediaStatus(mediaSessionId, mediaInfo);
+
+ status.setActiveTrackIds(bundle.getLongArray(KEY_ACTIVE_TRACK_IDS));
+ status.setStreamPosition(bundle.getLong(KEY_CURRENT_TIME));
+ status.setIdleReason(bundle.getInt(KEY_IDLE_REASON));
+ status.setMute(bundle.getBoolean(KEY_MUTED));
+ status.setPlaybackRate(bundle.getDouble(KEY_PLAYBACK_RATE));
+ status.setPlayerState(bundle.getInt(KEY_PLAYER_STATE));
+ status.setSupportedMediaCommands(bundle.getLong(KEY_SUPPORTED_MEDIA_COMMANDS));
+ status.setStreamVolume(bundle.getDouble(KEY_VOLUME));
+ status.setExtras(bundle.getBundle(KEY_EXTRAS));
+ return status;
+ }
+ }
+
+ /**
+ * A class that represents a media track, such as a language track or closed caption text track
+ * in a video.
+ */
+ public static final class MediaTrack {
+ private static final String KEY_TRACK_ID = "trackId";
+ private static final String KEY_TYPE = "type";
+ private static final String KEY_TRACK_CONTENT_ID = "trackContentId";
+ private static final String KEY_TRACK_CONTENT_TYPE = "trackContentType";
+ private static final String KEY_NAME = "name";
+ private static final String KEY_LANGUAGE = "language";
+ private static final String KEY_SUBTYPE = "subtype";
+ private static final String KEY_EXTRAS = "extras";
+
+ /** A media track type indicating an unknown track type. */
+ public static final int TYPE_UNKNOWN = 0;
+ /** A media track type indicating a text track. */
+ public static final int TYPE_TEXT = 1;
+ /** A media track type indicating an audio track. */
+ public static final int TYPE_AUDIO = 2;
+ /** A media track type indicating a video track. */
+ public static final int TYPE_VIDEO = 3;
+
+ /** A media track subtype indicating an unknown subtype. */
+ public static final int SUBTYPE_UNKNOWN = -1;
+ /** A media track subtype indicating no subtype. */
+ public static final int SUBTYPE_NONE = 0;
+ /** A media track subtype indicating subtitles. */
+ public static final int SUBTYPE_SUBTITLES = 1;
+ /** A media track subtype indicating closed captions. */
+ public static final int SUBTYPE_CAPTIONS = 2;
+ /** A media track subtype indicating descriptions. */
+ public static final int SUBTYPE_DESCRIPTIONS = 3;
+ /** A media track subtype indicating chapters. */
+ public static final int SUBTYPE_CHAPTERS = 4;
+ /** A media track subtype indicating metadata. */
+ public static final int SUBTYPE_METADATA = 5;
+
+ private long mId;
+ private int mType;
+ private String mContentId;
+ private String mContentType;
+ private String mName;
+ private String mLanguage;
+ private int mSubtype;
+ private Bundle mExtras;
+
+ /**
+ * Constructs a new track with the given track ID and type.
+ *
+ * @throws IllegalArgumentException If the track type is invalid.
+ */
+ public MediaTrack(long id, int type) {
+ clear();
+ mId = id;
+ if ((type <= TYPE_UNKNOWN) || (type > TYPE_VIDEO)) {
+ throw new IllegalArgumentException("invalid type " + type);
+ }
+ mType = type;
+ }
+
+ /**
+ * Returns the unique ID of the media track.
+ */
+ public long getId() {
+ return mId;
+ }
+
+ /**
+ * Returns the type of the track; one of the {@code TYPE_} constants defined above.
+ */
+ public int getType() {
+ return mType;
+ }
+
+ /**
+ * Returns the content ID of the media track.
+ */
+ public String getContentId() {
+ return mContentId;
+ }
+
+ /**
+ * Sets the content ID for the media track.
+ */
+ public void setContentId(String contentId) {
+ mContentId = contentId;
+ }
+
+ /**
+ * Returns the content type (MIME type) of the media track, or {@code null} if none was
+ * specified.
+ */
+ public String getContentType() {
+ return mContentType;
+ }
+
+ /**
+ * Sets the content type (MIME type) of the media track.
+ */
+ public void setContentType(String contentType) {
+ mContentType = contentType;
+ }
+
+ /**
+ * Returns the name of the media track, or {@code null} if none was specified.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Sets the track name.
+ */
+ public void setName(String name) {
+ mName = name;
+ }
+
+ /**
+ * Returns the language of this media track, or {@code null} if none was specified.
+ */
+ public String getLanguage() {
+ return mLanguage;
+ }
+
+ /**
+ * Sets the track language.
+ */
+ public void setLanguage(String language) {
+ mLanguage = language;
+ }
+
+ /**
+ * Returns the subtype of this media track; one of the {@code SUBTYPE_}
+ * constants defined above.
+ */
+ public int getSubtype() {
+ return mSubtype;
+ }
+
+ /**
+ * Sets the track subtype.
+ *
+ * @throws IllegalArgumentException If the subtype is invalid.
+ */
+ public void setSubtype(int subtype) {
+ if ((subtype <= SUBTYPE_UNKNOWN) || (subtype > SUBTYPE_METADATA)) {
+ throw new IllegalArgumentException("invalid subtype " + subtype);
+ }
+ if ((subtype != SUBTYPE_NONE) && (mType != TYPE_TEXT)) {
+ throw new IllegalArgumentException("subtypes are only valid for text tracks");
+ }
+
+ mSubtype = subtype;
+ }
+
+ /**
+ * Returns the extras object for this media track, or {@code null} if none was
+ * specified.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Sets the track's extras object.
+ */
+ public void setExtras(Bundle extras) {
+ mExtras = extras;
+ }
+
+ private void clear() {
+ mId = 0;
+ mType = TYPE_UNKNOWN;
+ mContentId = null;
+ mName = null;
+ mLanguage = null;
+ mSubtype = SUBTYPE_UNKNOWN;
+ mExtras = null;
+ }
+
+ /**
+ * Creates a bundle representation of the object.
+ */
+ public @NonNull Bundle toBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putLong(KEY_TRACK_ID, mId);
+ bundle.putInt(KEY_TYPE, mType);
+ bundle.putString(KEY_TRACK_CONTENT_ID, mContentId);
+ bundle.putString(KEY_TRACK_CONTENT_TYPE, mContentType);
+ bundle.putString(KEY_NAME, mName);
+ bundle.putString(KEY_LANGUAGE, mLanguage);
+ bundle.putInt(KEY_SUBTYPE, mSubtype);
+ bundle.putBundle(KEY_EXTRAS, mExtras);
+ return bundle;
+ }
+
+ /**
+ * Constructs a new {@link MediaTrack} object from a bundle.
+ */
+ public static MediaTrack fromBundle(Bundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+
+ long trackId = bundle.getLong(KEY_TRACK_ID);
+ int type = bundle.getInt(KEY_TYPE);
+ MediaTrack track = new MediaTrack(trackId, type);
+
+ track.setContentId(bundle.getString(KEY_TRACK_CONTENT_ID));
+ track.setContentType(bundle.getString(KEY_TRACK_CONTENT_TYPE));
+ track.setName(bundle.getString(KEY_NAME));
+ track.setLanguage(bundle.getString(KEY_LANGUAGE));
+ track.setSubtype(bundle.getInt(KEY_SUBTYPE));
+ track.setExtras(bundle.getBundle(KEY_EXTRAS));
+ return track;
+ }
+ }
+
+ /**
+ * A class that specifies how a text track's text will be displayed on-screen. The text is
+ * displayed inside a rectangular "window". The appearance of both the text and the window are
+ * configurable.
+ * <p>
+ * With the exception of the font scale, which has a predefined default value, any attribute that
+ * is not explicitly set will remain "unspecified", and the player will select an appropriate
+ * value.
+ */
+ public static final class TextTrackStyle {
+ /** The default font scale. */
+ public static final float DEFAULT_FONT_SCALE = 1.0f;
+
+ /** A color value that indicates an unspecified (unset) color. */
+ public static final int COLOR_UNSPECIFIED = 0;
+
+ /** An edge type indicating an unspecified edge type. */
+ public static final int EDGE_TYPE_UNSPECIFIED = -1;
+ /** An edge type indicating no edge. */
+ public static final int EDGE_TYPE_NONE = 0;
+ /** An edge type indicating an outline edge. */
+ public static final int EDGE_TYPE_OUTLINE = 1;
+ /** An edge type indicating a drop shadow edge. */
+ public static final int EDGE_TYPE_DROP_SHADOW = 2;
+ /** An edge type indicating a raised edge. */
+ public static final int EDGE_TYPE_RAISED = 3;
+ /** An edge type indicating a depressed edge. */
+ public static final int EDGE_TYPE_DEPRESSED = 4;
+
+ /** A window type indicating an unspecified window type. */
+ public static final int WINDOW_TYPE_UNSPECIFIED = -1;
+ /** A window type indicating no window type. */
+ public static final int WINDOW_TYPE_NONE = 0;
+ /** A window type indicating a normal window. */
+ public static final int WINDOW_TYPE_NORMAL = 1;
+ /** A window type indicating a window with rounded corners. */
+ public static final int WINDOW_TYPE_ROUNDED = 2;
+
+ /** A font family indicating an unspecified font family. */
+ public static final int FONT_FAMILY_UNSPECIFIED = -1;
+ /** A font family indicating Sans Serif. */
+ public static final int FONT_FAMILY_SANS_SERIF = 0;
+ /** A font family indicating Monospaced Sans Serif. */
+ public static final int FONT_FAMILY_MONOSPACED_SANS_SERIF = 1;
+ /** A font family indicating Serif. */
+ public static final int FONT_FAMILY_SERIF = 2;
+ /** A font family indicating Monospaced Serif. */
+ public static final int FONT_FAMILY_MONOSPACED_SERIF = 3;
+ /** A font family indicating Casual. */
+ public static final int FONT_FAMILY_CASUAL = 4;
+ /** A font family indicating Cursive. */
+ public static final int FONT_FAMILY_CURSIVE = 5;
+ /** A font family indicating Small Capitals. */
+ public static final int FONT_FAMILY_SMALL_CAPITALS = 6;
+
+ /** A font style indicating an unspecified style. */
+ public static final int FONT_STYLE_UNSPECIFIED = -1;
+ /** A font style indicating a normal style. */
+ public static final int FONT_STYLE_NORMAL = 0;
+ /** A font style indicating a bold style. */
+ public static final int FONT_STYLE_BOLD = 1;
+ /** A font style indicating an italic style. */
+ public static final int FONT_STYLE_ITALIC = 2;
+ /** A font style indicating a bold and italic style. */
+ public static final int FONT_STYLE_BOLD_ITALIC = 3;
+
+ private static final String KEY_FONT_SCALE = "fontScale";
+ private static final String KEY_FOREGROUND_COLOR = "foregroundColor";
+ private static final String KEY_BACKGROUND_COLOR = "backgroundColor";
+ private static final String KEY_EDGE_TYPE = "edgeType";
+ private static final String KEY_EDGE_COLOR = "edgeColor";
+ private static final String KEY_WINDOW_TYPE = "windowType";
+ private static final String KEY_WINDOW_COLOR = "windowColor";
+ private static final String KEY_WINDOW_CORNER_RADIUS = "windowRoundedCornerRadius";
+ private static final String KEY_FONT_FAMILY = "fontFamily";
+ private static final String KEY_FONT_GENERIC_FAMILY = "fontGenericFamily";
+ private static final String KEY_FONT_STYLE = "fontStyle";
+ private static final String KEY_EXTRAS = "extras";
+
+ private float mFontScale;
+ private int mForegroundColor;
+ private int mBackgroundColor;
+ private int mEdgeType;
+ private int mEdgeColor;
+ private int mWindowType;
+ private int mWindowColor;
+ private int mWindowCornerRadius;
+ private String mFontFamily;
+ private int mFontGenericFamily;
+ private int mFontStyle;
+ private Bundle mExtras;
+
+ /**
+ * Constructs a new TextTrackStyle.
+ */
+ public TextTrackStyle() {
+ clear();
+ }
+
+ /**
+ * Sets the font scale factor. The default is {@link #DEFAULT_FONT_SCALE}.
+ */
+ public void setFontScale(float fontScale) {
+ mFontScale = fontScale;
+ }
+
+ /**
+ * Gets the font scale factor.
+ */
+ public float getFontScale() {
+ return mFontScale;
+ }
+
+ /**
+ * Sets the text's foreground color.
+ *
+ * @param foregroundColor The color, as an ARGB value.
+ */
+ public void setForegroundColor(int foregroundColor) {
+ mForegroundColor = foregroundColor;
+ }
+
+ /**
+ * Gets the text's foreground color.
+ */
+ public int getForegroundColor() {
+ return mForegroundColor;
+ }
+
+ /**
+ * Sets the text's background color.
+ *
+ * @param backgroundColor The color, as an ARGB value.
+ */
+ public void setBackgroundColor(int backgroundColor) {
+ mBackgroundColor = backgroundColor;
+ }
+
+ /**
+ * Gets the text's background color.
+ */
+ public int getBackgroundColor() {
+ return mBackgroundColor;
+ }
+
+ /**
+ * Sets the caption window's edge type.
+ *
+ * @param edgeType The edge type; one of the {@code EDGE_TYPE_} constants defined above.
+ */
+ public void setEdgeType(int edgeType) {
+ if ((edgeType < EDGE_TYPE_NONE) || (edgeType > EDGE_TYPE_DEPRESSED)) {
+ throw new IllegalArgumentException("invalid edgeType");
+ }
+ mEdgeType = edgeType;
+ }
+
+ /**
+ * Gets the caption window's edge type.
+ */
+ public int getEdgeType() {
+ return mEdgeType;
+ }
+
+ /**
+ * Sets the window's edge color.
+ *
+ * @param edgeColor The color, as an ARGB value.
+ */
+ public void setEdgeColor(int edgeColor) {
+ mEdgeColor = edgeColor;
+ }
+
+ /**
+ * Gets the window's edge color.
+ */
+ public int getEdgeColor() {
+ return mEdgeColor;
+ }
+
+ /**
+ * Sets the window type.
+ *
+ * @param windowType The window type; one of the {@code WINDOW_TYPE_} constants defined above.
+ */
+ public void setWindowType(int windowType) {
+ if ((windowType < WINDOW_TYPE_NONE) || (windowType > WINDOW_TYPE_ROUNDED)) {
+ throw new IllegalArgumentException("invalid windowType");
+ }
+ mWindowType = windowType;
+ }
+
+ /**
+ * Gets the caption window type.
+ */
+ public int getWindowType() {
+ return mWindowType;
+ }
+
+ /**
+ * Sets the window's color.
+ *
+ * @param windowColor The color, as an ARGB value.
+ */
+ public void setWindowColor(int windowColor) {
+ mWindowColor = windowColor;
+ }
+
+ /**
+ * Gets the window's color.
+ */
+ public int getWindowColor() {
+ return mWindowColor;
+ }
+
+ /**
+ * If the window type is {@link #WINDOW_TYPE_ROUNDED}, sets the radius for the window's
+ * corners.
+ *
+ * @param windowCornerRadius The radius, in pixels. Must be a positive value.
+ */
+ public void setWindowCornerRadius(int windowCornerRadius) {
+ if (windowCornerRadius < 0) {
+ throw new IllegalArgumentException("invalid windowCornerRadius");
+ }
+ mWindowCornerRadius = windowCornerRadius;
+ }
+
+ /**
+ * Gets the window corner radius.
+ */
+ public int getWindowCornerRadius() {
+ return mWindowCornerRadius;
+ }
+
+ /**
+ * Sets the text's font family.
+ *
+ * @param fontFamily The text font family.
+ */
+ public void setFontFamily(String fontFamily) {
+ mFontFamily = fontFamily;
+ }
+
+ /**
+ * Gets the text's font family.
+ */
+ public String getFontFamily() {
+ return mFontFamily;
+ }
+
+ /**
+ * Sets the text's generic font family. This will be used if the font family specified with
+ * {@link #setFontFamily} (if any) is unavailable.
+ *
+ * @param fontGenericFamily The generic family; one of the {@code FONT_FAMILY_} constants
+ * defined above.
+ */
+ public void setFontGenericFamily(int fontGenericFamily) {
+ if ((fontGenericFamily < FONT_FAMILY_SANS_SERIF)
+ || (fontGenericFamily > FONT_FAMILY_SMALL_CAPITALS)) {
+ throw new IllegalArgumentException("invalid fontGenericFamily");
+ }
+ mFontGenericFamily = fontGenericFamily;
+ }
+
+ /**
+ * Gets the text's generic font family.
+ */
+ public int getFontGenericFamily() {
+ return mFontGenericFamily;
+ }
+
+ /**
+ * Sets the text font style.
+ *
+ * @param fontStyle The font style; one of the {@code FONT_STYLE_} constants defined above.
+ */
+ public void setFontStyle(int fontStyle) {
+ if ((fontStyle < FONT_STYLE_NORMAL) || (fontStyle > FONT_STYLE_BOLD_ITALIC)) {
+ throw new IllegalArgumentException("invalid fontStyle");
+ }
+ mFontStyle = fontStyle;
+ }
+
+ /**
+ * Gets the text font style.
+ */
+ public int getFontStyle() {
+ return mFontStyle;
+ }
+
+ /**
+ * Sets the extras object.
+ */
+ public void setExtras(Bundle extras) {
+ mExtras = extras;
+ }
+
+ /**
+ * Gets the extras object.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ private void clear() {
+ mFontScale = DEFAULT_FONT_SCALE;
+ mForegroundColor = COLOR_UNSPECIFIED;
+ mBackgroundColor = COLOR_UNSPECIFIED;
+ mEdgeType = EDGE_TYPE_UNSPECIFIED;
+ mEdgeColor = COLOR_UNSPECIFIED;
+ mWindowType = WINDOW_TYPE_UNSPECIFIED;
+ mWindowColor = COLOR_UNSPECIFIED;
+ mWindowCornerRadius = 0;
+ mFontFamily = null;
+ mFontGenericFamily = FONT_FAMILY_UNSPECIFIED;
+ mFontStyle = FONT_STYLE_UNSPECIFIED;
+ mExtras = null;
+ }
+
+ /**
+ * Constructs a new TextTrackStyle based on the systems' current closed caption style settings.
+ * On platform levels below 19, this returns an object with "unspecified" values for all
+ * fields.
+ *
+ * @param context The calling context.
+ * @return The new TextTrackStyle.
+ */
+ public static TextTrackStyle fromSystemSettings(Context context) {
+ TextTrackStyle style = new TextTrackStyle();
+ if (Build.VERSION.SDK_INT >= 19) {
+ Impl19.loadSystemSettings(style, context);
+ }
+ return style;
+ }
+
+ /**
+ * Creates a bundle representation of the object.
+ */
+ public @NonNull Bundle toBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putFloat(KEY_FONT_SCALE, mFontScale);
+ bundle.putInt(KEY_FOREGROUND_COLOR, mForegroundColor);
+ bundle.putInt(KEY_BACKGROUND_COLOR, mBackgroundColor);
+ bundle.putInt(KEY_EDGE_TYPE, mEdgeType);
+ bundle.putInt(KEY_EDGE_COLOR, mEdgeColor);
+ bundle.putInt(KEY_WINDOW_TYPE, mWindowType);
+ bundle.putInt(KEY_WINDOW_COLOR, mWindowColor);
+ bundle.putInt(KEY_WINDOW_CORNER_RADIUS, mWindowCornerRadius);
+ bundle.putString(KEY_FONT_FAMILY, mFontFamily);
+ bundle.putInt(KEY_FONT_GENERIC_FAMILY, mFontGenericFamily);
+ bundle.putInt(KEY_FONT_STYLE, mFontStyle);
+ bundle.putBundle(KEY_EXTRAS, mExtras);
+ return bundle;
+ }
+
+ /**
+ * Constructs a new {@link MediaTrack} object from a bundle.
+ */
+ public static TextTrackStyle fromBundle(Bundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+
+ TextTrackStyle style = new TextTrackStyle();
+ style.setFontScale(bundle.getFloat(KEY_FONT_SCALE));
+ style.setForegroundColor(bundle.getInt(KEY_FOREGROUND_COLOR));
+ style.setBackgroundColor(bundle.getInt(KEY_BACKGROUND_COLOR));
+ style.setEdgeType(bundle.getInt(KEY_EDGE_TYPE));
+ style.setEdgeColor(bundle.getInt(KEY_EDGE_COLOR));
+ style.setWindowType(bundle.getInt(KEY_WINDOW_TYPE));
+ style.setWindowColor(bundle.getInt(KEY_WINDOW_COLOR));
+ style.setWindowCornerRadius(bundle.getInt(KEY_WINDOW_CORNER_RADIUS));
+ style.setFontFamily(bundle.getString(KEY_FONT_FAMILY));
+ style.setFontGenericFamily(bundle.getInt(KEY_FONT_GENERIC_FAMILY));
+ style.setFontStyle(bundle.getInt(KEY_FONT_STYLE));
+ style.setExtras(bundle.getBundle(KEY_EXTRAS));
+ return style;
+ }
+
+ // Compatibility for new platform features introduced in KitKat.
+ private static final class Impl19 {
+ public static void loadSystemSettings(TextTrackStyle style, Context context) {
+ CaptioningManager captioningManager =
+ (CaptioningManager)context.getSystemService(Context.CAPTIONING_SERVICE);
+ style.setFontScale(captioningManager.getFontScale());
+
+ CaptioningManager.CaptionStyle userStyle = captioningManager.getUserStyle();
+ style.setBackgroundColor(userStyle.backgroundColor);
+ style.setForegroundColor(userStyle.foregroundColor);
+
+ switch (userStyle.edgeType) {
+ case CaptioningManager.CaptionStyle.EDGE_TYPE_OUTLINE:
+ style.setEdgeType(EDGE_TYPE_OUTLINE);
+ break;
+
+ case CaptioningManager.CaptionStyle.EDGE_TYPE_DROP_SHADOW:
+ style.setEdgeType(EDGE_TYPE_DROP_SHADOW);
+ break;
+
+ case CaptioningManager.CaptionStyle.EDGE_TYPE_NONE: // Fall through
+ default:
+ style.setEdgeType(EDGE_TYPE_NONE);
+ }
+
+ style.setEdgeColor(userStyle.edgeColor);
+
+ Typeface typeface = userStyle.getTypeface();
+ if (typeface != null) {
+ if (Typeface.MONOSPACE.equals(typeface)) {
+ style.setFontGenericFamily(FONT_FAMILY_MONOSPACED_SANS_SERIF);
+ } else if (Typeface.SANS_SERIF.equals(typeface)) {
+ style.setFontGenericFamily(FONT_FAMILY_SANS_SERIF);
+ } else if (Typeface.SERIF.equals(typeface)) {
+ style.setFontGenericFamily(FONT_FAMILY_SERIF);
+ } else {
+ // Otherwise, assume sans-serif.
+ style.setFontGenericFamily(FONT_FAMILY_SANS_SERIF);
+ }
+
+ boolean bold = typeface.isBold();
+ boolean italic = typeface.isItalic();
+
+ if (bold && italic) {
+ style.setFontStyle(FONT_STYLE_BOLD_ITALIC);
+ } else if (bold) {
+ style.setFontStyle(FONT_STYLE_BOLD);
+ } else if (italic) {
+ style.setFontStyle(FONT_STYLE_ITALIC);
+ } else {
+ style.setFontStyle(FONT_STYLE_NORMAL);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * A class that represents an image that is located on a web server.
+ */
+ public static final class WebImage {
+ private final Uri mUrl;
+ private final int mWidth;
+ private final int mHeight;
+
+ private static final String KEY_URL = "url";
+ private static final String KEY_HEIGHT = "height";
+ private static final String KEY_WIDTH = "width";
+
+ /**
+ * Constructs a new {@link WebImage} with the given URL.
+ *
+ * @param url The URL of the image.
+ * @throws IllegalArgumentException If the URL is null or empty.
+ */
+ public WebImage(@NonNull Uri url) throws IllegalArgumentException {
+ this(url, 0, 0);
+ }
+
+ /**
+ * Constructs a new {@link WebImage} with the given URL and dimensions.
+ *
+ * @param url The URL of the image.
+ * @param width The width of the image, in pixels.
+ * @param height The height of the image, in pixels.
+ * @throws IllegalArgumentException If the URL is null or empty,
+ * or the dimensions are invalid.
+ */
+ public WebImage(@NonNull Uri url, int width, int height) throws IllegalArgumentException {
+ if (url == null) {
+ throw new IllegalArgumentException("url cannot be null");
+ }
+
+ if ((width < 0) || (height < 0)) {
+ throw new IllegalArgumentException("width and height must not be negative");
+ }
+
+ mUrl = url;
+ mWidth = width;
+ mHeight = height;
+ }
+
+ /**
+ * Gets the image URL.
+ */
+ public @NonNull Uri getUrl() {
+ return mUrl;
+ }
+
+ /**
+ * Gets the image width, in pixels.
+ */
+ public int getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * Gets the image height, in pixels.
+ */
+ public int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * Returns a string representation of this object.
+ */
+ @Override
+ public @NonNull String toString() {
+ return String.format("Image %dx%d %s", mWidth, mHeight, mUrl.toString());
+ }
+
+ /**
+ * Creates a bundle representation of this object.
+ */
+ public @NonNull Bundle toBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_URL, mUrl.toString());
+ bundle.putInt(KEY_WIDTH, mWidth);
+ bundle.putInt(KEY_HEIGHT, mHeight);
+ return bundle;
+ }
+
+ /**
+ * Creates a {@link WebImage} from a bundle.
+ */
+ public static @Nullable WebImage fromBundle(@Nullable Bundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+ return new WebImage(Uri.parse(bundle.getString(KEY_URL)),
+ bundle.getInt(KEY_WIDTH), bundle.getInt(KEY_HEIGHT));
+ }
+ }
+}
diff --git a/media/protocols/src/android/support/media/protocols/MediaRouteProtocol.java b/media/protocols/src/android/support/media/protocols/MediaRouteProtocol.java
new file mode 100644
index 0000000..cb49732
--- /dev/null
+++ b/media/protocols/src/android/support/media/protocols/MediaRouteProtocol.java
@@ -0,0 +1,574 @@
+/*
+ * 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.
+ */
+package android.support.media.protocols;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.Closeable;
+import java.lang.ref.WeakReference;
+
+/**
+ * Base class for media route protocols.
+ * <p>
+ * A media route protocol expresses an interface contract between an application and
+ * a media route that it would like to communicate with and control. By using
+ * a protocol to send messages to a media route, an application can
+ * ask the media route to perform functions such as creating a playlist of music
+ * to be played on behalf of the application.
+ * </p><p>
+ * Subclasses should extend this class to offer specialized protocols.
+ * </p><p>
+ * Instances of this class are thread-safe but event will only be received
+ * on the handler that was specified when the callback was registered.
+ * </p>
+ *
+ * <h3>Overview</h3>
+ * <p>
+ * A media route protocol is essentially just a binder-based messaging interface.
+ * Messages sent from the application to the media route service are called "requests"
+ * whereas messages sent from the media route service back to the application are
+ * called "events" or "errors" depending on their purpose.
+ * </p><p>
+ * All communication through a protocol is asynchronous and is dispatched to a
+ * a {@link android.os.Looper} of the application or the media route service's choice
+ * (separate for each end). Arguments are transferred through key/value pairs in
+ * {@link Bundle bundles}.
+ * </p><p>
+ * The overall interface is somewhat simpler than directly using AIDL and Binder which
+ * requires additional care to extend and maintain binary compatibility and to
+ * perform thread synchronization on either end of the communication channel.
+ * Media route protocols also support bidirectional asynchronous communication
+ * requests, events, and errors between the application and the media route service.
+ * </p>
+ *
+ * <h3>Using Protocols</h3>
+ * <p>
+ * To use a protocol, an application must do the following.
+ * </p><ul>
+ * <li>Create a {@link android.media.routing.MediaRouter media router}.
+ * <li>Add a {@link android.media.routing.MediaRouteSelector media route selector}
+ * that specifies the protocol as required or optional.
+ * <li>Show a media route button in the application's action bar to enable the
+ * user to choose a destination to connect to.
+ * <li>Once the connection has been established, obtain the protocol's
+ * binder from the {@link android.media.routing.MediaRouter.ConnectionInfo route connection}
+ * information and {@link MediaRouteProtocol#MediaRouteProtocol(IBinder) create} the protocol
+ * object. There is also a convenience method called
+ * {@link android.media.routing.MediaRouter.ConnectionInfo#getProtocolObject getProtocolObject}
+ * to do this all in one step.
+ * <li>Set a {@link Callback} on the protocol object to receive events.
+ * <li>At this point, the application can begin sending requests to the media route
+ * and receiving events in response via the protocol object.
+ * </ul>
+ *
+ * <h3>Providing Protocols</h3>
+ * <p>
+ * The provide a protocol, a media route service must do the following.
+ * </p><ul>
+ * <li>Upon receiving a
+ * {@link android.media.routing.MediaRouter.DiscoveryRequest discovery request}
+ * from an application that contains a
+ * {@link android.media.routing.MediaRouteSelector media route selector}
+ * which asks to find routes that support known protocols during discovery, the media
+ * route service should indicate that it supports this protocol by adding it to the list
+ * of supported protocols in the
+ * {@link android.media.routing.MediaRouter.RouteInfo route information} for those
+ * routes that support them.
+ * <li>Upon receiving a
+ * {@link android.media.routing.MediaRouter.ConnectionRequest connection request}
+ * from an application that requests to connect to a route for which the application
+ * previously requested support of known protocols, the media route service should
+ * {@link MediaRouteProtocol.Stub#MediaRouteProtocol.Stub(Handler) create} a subclass of the stub
+ * object that implements the protocol then add it to the list of protocol binders
+ * in the {@link android.media.routing.MediaRouter.ConnectionInfo route connection}
+ * object it returns to the application.
+ * <li>Once the route is connected, the media route service should handle incoming
+ * protocol requests from the client and respond accordingly.
+ * <li>Once the route is disconnected, the media route service should cease to
+ * handle incoming protocol requests from the client and should clean up its state
+ * accordingly.
+ * </ul>
+ *
+ * <h3>Creating Custom Protocols</h3>
+ * <p>
+ * Although the framework provides standard media route protocols to encourage
+ * interoperability, it may be useful to create and publish custom protocols to
+ * access extended functionality only supported by certain routes.
+ * </p><p>
+ * To create a custom protocol, create a subclass of the {@link MediaRouteProtocol}
+ * class to declare the new request methods and marshal their arguments. Also create
+ * a subclass of the {@link MediaRouteProtocol.Callback} class to decode any new kinds
+ * of events and subclass the {@link MediaRouteProtocol.Stub} class to decode
+ * incoming requests.
+ * </p><p>
+ * It may help to refer to the source code of the <code>android.support.media.protocol.jar</code>
+ * library for details.
+ * </p><p>
+ * Here is a simple example:
+ * </p><pre>
+ * public abstract class CustomProtocol extends MediaRouteProtocol {
+ * public CustomProtocol(IBinder binder) {
+ * super(binder);
+ * }
+ *
+ * // declare custom request
+ * public void tuneRadio(int station) {
+ * Bundle args = new Bundle();
+ * args.putInt("station", station);
+ * sendRequest("tuneRadio", args);
+ * }
+ *
+ * public static abstract class Callback extends MediaRouteProtocol.Callback {
+ * // declare custom event
+ * public void onStationTuned(int station, boolean hifi) { }
+ *
+ * @Override
+ * public void onEvent(String event, Bundle args) {
+ * switch (event) {
+ * case "radioTuned":
+ * onRadioTuned(args.getInt("station"), args.getBoolean("hifi"));
+ * return;
+ * }
+ * super.onEvent(event, args);
+ * }
+ * }
+ *
+ * public static abstract class Stub extends MediaRouteProtocol.Stub {
+ * // declare custom request stub
+ * public abstract void onTuneRadio(int station);
+ *
+ * @Override
+ * public void onRequest(String request, Bundle args) {
+ * switch (request) {
+ * case "tuneRadio":
+ * onTuneRadio(args.getInt("station"));
+ * return;
+ * }
+ * super.onRequest(request, args);
+ * }
+ * }
+ * }
+ * </pre>
+ */
+public abstract class MediaRouteProtocol {
+ private static final String TAG = "MediaRouteProtocol";
+
+ private static final int REQUEST_MSG_SUBSCRIBE = 1;
+ private static final int REQUEST_MSG_COMMAND = 2;
+
+ private static final int REPLY_MSG_ERROR = 1;
+ private static final int REPLY_MSG_EVENT = 2;
+
+ private final Object mLock = new Object();
+ private final Messenger mRequestMessenger;
+ private Messenger mReplyMessenger;
+ private volatile Callback mCallback;
+ private Looper mCallbackLooper;
+ private Handler mCallbackHandler;
+
+ /**
+ * Error code: Some other unknown error occurred.
+ */
+ public static final String ERROR_UNKNOWN =
+ "android.support.errors.UNKNOWN";
+
+ /**
+ * Error code: The media route has been disconnected.
+ */
+ public static final String ERROR_DISCONNECTED =
+ "android.support.errors.DISCONNECTED";
+
+ /**
+ * Error code: The application issued an unsupported request.
+ */
+ public static final String ERROR_UNSUPPORTED_OPERATION =
+ "android.support.errors.UNSUPPORTED_OPERATION";
+
+ /**
+ * Creates the protocol client object for an application to use to send
+ * messages to a media route.
+ * <p>
+ * This constructor is called automatically if you use
+ * {@link android.media.routing.MediaRouter.ConnectionInfo#getProtocolObject getProtocolObject}
+ * to obtain a protocol object from a media route connection.
+ * </p>
+ *
+ * @param binder The remote binder supplied by the media route service. May be
+ * obtained using {@link android.media.routing.MediaRouter.ConnectionInfo#getProtocolBinder}
+ * on a route connection.
+ */
+ public MediaRouteProtocol(@NonNull IBinder binder) {
+ if (binder == null) {
+ throw new IllegalArgumentException("binder must not be null");
+ }
+
+ mRequestMessenger = new Messenger(binder);
+ }
+
+ /**
+ * Sets the callback interface and handler on which to receive events and errors.
+ *
+ * @param callback The callback interface, or null if none.
+ * @param handler The handler on which to receive events and errors, or null to use
+ * the current looper thread.
+ */
+ public void setCallback(@Nullable Callback callback, @Nullable Handler handler) {
+ synchronized (mLock) {
+ Looper looper = callback != null ?
+ (handler != null ? handler.getLooper() : Looper.myLooper()) : null;
+ if (mCallback != callback || mCallbackLooper != looper) {
+ mCallback = callback;
+ if (mCallback != null) {
+ mCallbackLooper = looper;
+ mCallbackHandler = handler != null ? handler : new Handler();
+ mReplyMessenger = new Messenger(new ReplyHandler(this, looper));
+ } else {
+ mCallbackLooper = null;
+ mCallbackHandler = null;
+ mReplyMessenger = null;
+ }
+
+ Message msg = Message.obtain();
+ msg.what = REQUEST_MSG_SUBSCRIBE;
+ msg.replyTo = mReplyMessenger;
+ sendSafelyLocked(msg);
+ }
+ }
+ }
+
+ /**
+ * Sends an asynchronous request to the media route service.
+ * <p>
+ * If an error occurs, it will be reported to the callback's {@link Callback#onError}
+ * method.
+ * </p>
+ *
+ * @param request The request name.
+ * @param args The request arguments, or null if none.
+ */
+ public void sendRequest(@NonNull String request, @Nullable Bundle args) {
+ if (TextUtils.isEmpty(request)) {
+ throw new IllegalArgumentException("request must not be null or empty");
+ }
+
+ synchronized (mLock) {
+ Message msg = Message.obtain();
+ msg.what = REQUEST_MSG_COMMAND;
+ msg.obj = request;
+ msg.setData(args);
+ sendSafelyLocked(msg);
+ }
+ }
+
+ private void sendSafelyLocked(Message msg) {
+ if (mRequestMessenger != null) {
+ try {
+ mRequestMessenger.send(msg);
+ } catch (RemoteException ex) {
+ postErrorLocked(ERROR_DISCONNECTED, null);
+ }
+ } else {
+ postErrorLocked(ERROR_DISCONNECTED, null);
+ }
+ }
+
+ private void postErrorLocked(final String error, final Bundle args) {
+ final Callback callback = mCallback;
+ if (callback != null) {
+ mCallbackHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (callback != null) {
+ callback.onError(error, args);
+ }
+ }
+ });
+ }
+ }
+
+ private void handleReply(Message msg) {
+ Callback callback = mCallback; // note: racy
+ if (callback != null) {
+ // ignore unrecognized messages in case of future protocol extension
+ if (msg.what == REPLY_MSG_ERROR && msg.obj instanceof String) {
+ mCallback.onError((String)msg.obj, msg.peekData());
+ } else if (msg.what == REPLY_MSG_EVENT && msg.obj instanceof String) {
+ mCallback.onEvent((String)msg.obj, msg.peekData());
+ }
+ }
+ }
+
+ /*
+ * Only use this handler to handle replies coming back from the media route service
+ * because the service can send any message it wants to it.
+ * Validate arguments carefully.
+ */
+ private static final class ReplyHandler extends Handler {
+ // break hard reference cycles through binder
+ private final WeakReference<MediaRouteProtocol> mProtocolRef;
+
+ public ReplyHandler(MediaRouteProtocol protocol, Looper looper) {
+ super(looper);
+ mProtocolRef = new WeakReference<MediaRouteProtocol>(protocol);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ MediaRouteProtocol protocol = mProtocolRef.get();
+ if (protocol != null) {
+ protocol.handleReply(msg);
+ }
+ }
+ }
+
+ /**
+ * Base class for application callbacks from the media route service.
+ * <p>
+ * Subclasses should extend this class to offer events for specialized protocols.
+ * </p>
+ */
+ public static abstract class Callback {
+ /**
+ * Called when an event is received from the media route service.
+ *
+ * @param event The event name.
+ * @param args The event arguments, or null if none.
+ */
+ public void onEvent(@NonNull String event, @Nullable Bundle args) { }
+
+ /**
+ * Called when an error occurs in the media route service.
+ *
+ * @param error The error name.
+ * @param args The error arguments, or null if none.
+ */
+ public void onError(@NonNull String error, @Nullable Bundle args) { }
+ }
+
+ /**
+ * Base class for a media route protocol stub implemented by a media route service.
+ * <p>
+ * Subclasses should extend this class to offer implementation for specialized
+ * protocols.
+ * </p><p>
+ * Instances of this class are thread-safe but requests will only be received
+ * on the handler that was specified in the constructor.
+ * </p>
+ */
+ public static abstract class Stub implements IInterface, Closeable {
+ private final Object mLock = new Object();
+
+ private final Messenger mRequestMessenger;
+ private Messenger mReplyMessenger;
+ private volatile boolean mClosed;
+
+ /**
+ * Creates an implementation of a media route protocol.
+ *
+ * @param handler The handler on which to receive requests, or null to use
+ * the current looper thread.
+ */
+ public Stub(@Nullable Handler handler) {
+ mRequestMessenger = new Messenger(new RequestHandler(this,
+ handler != null ? handler.getLooper() : Looper.myLooper()));
+ }
+
+ /**
+ * Gets the underlying binder object for the stub.
+ */
+ @Override
+ public @NonNull IBinder asBinder() {
+ return mRequestMessenger.getBinder();
+ }
+
+ /**
+ * Closes the stub and prevents it from receiving any additional
+ * messages from the application.
+ */
+ @Override
+ public void close() {
+ synchronized (mLock) {
+ mClosed = true;
+ mReplyMessenger = null;
+ }
+ }
+
+ /**
+ * Called when the application sends a request to the media route service
+ * through this protocol.
+ * <p>
+ * The default implementation throws {@link UnsupportedOperationException}
+ * which is reported back to the application's error callback as
+ * {@link #ERROR_UNSUPPORTED_OPERATION}.
+ * </p>
+ *
+ * @param request The request name.
+ * @param args The request arguments, or null if none.
+ */
+ public void onRequest(@NonNull String request, @Nullable Bundle args)
+ throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Called when the application attaches a callback to receive events and errors.
+ */
+ public void onClientAttached() {
+ }
+
+ /**
+ * Called when the application removes its callback and can no longer receive
+ * events and errors.
+ */
+ public void onClientDetached() {
+ }
+
+ /**
+ * Sends an error to the application.
+ *
+ * @param error The error name.
+ * @param args The error arguments, or null if none.
+ * @return True if the message was sent, or false if the client is not
+ * attached, cannot be reached, or if the stub has been closed.
+ */
+ public boolean sendError(@NonNull String error, @Nullable Bundle args) {
+ if (TextUtils.isEmpty(error)) {
+ throw new IllegalArgumentException("error must not be null or empty");
+ }
+
+ synchronized (mLock) {
+ Message msg = Message.obtain();
+ msg.what = REPLY_MSG_ERROR;
+ msg.obj = error;
+ msg.setData(args);
+ return replySafelyLocked(msg);
+ }
+ }
+
+ /**
+ * Sends an event to the application.
+ *
+ * @param event The event name.
+ * @param args The event arguments, or null if none.
+ * @return True if the message was sent, or false if the client is not
+ * attached, cannot be reached, or if the stub has been closed.
+ */
+ public boolean sendEvent(@NonNull String event, @Nullable Bundle args) {
+ if (TextUtils.isEmpty(event)) {
+ throw new IllegalArgumentException("event must not be null or empty");
+ }
+
+ synchronized (mLock) {
+ Message msg = Message.obtain();
+ msg.what = REPLY_MSG_EVENT;
+ msg.obj = event;
+ msg.setData(args);
+ return replySafelyLocked(msg);
+ }
+ }
+
+ private boolean replySafelyLocked(Message msg) {
+ if (mClosed) {
+ Log.w(TAG, "Could not send reply message because the stub has been closed: "
+ + msg + ", in: " + getClass().getName());
+ return false;
+ }
+ if (mReplyMessenger == null) {
+ Log.w(TAG, "Could not send reply message because the client has not yet "
+ + "attached a callback: " + msg + ", in: " + getClass().getName());
+ return false;
+ }
+
+ try {
+ mReplyMessenger.send(msg);
+ return true;
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not send reply message because the client died: "
+ + msg + ", in: " + getClass().getName());
+ return false;
+ }
+ }
+
+ private void handleRequest(Message msg) {
+ if (mClosed) { // note: racy
+ Log.w(TAG, "Dropping request because the media route service has "
+ + "closed its end of the protocol: " + msg + ", in: " + getClass());
+ return;
+ }
+
+ // ignore unrecognized messages in case of future protocol extension
+ if (msg.what == REQUEST_MSG_COMMAND && msg.obj instanceof String) {
+ String command = (String)msg.obj;
+ try {
+ onRequest(command, msg.peekData());
+ } catch (UnsupportedOperationException ex) {
+ Log.w(TAG, "Client sent unsupported command request: "
+ + msg + ", in: " + getClass());
+ sendError(ERROR_UNSUPPORTED_OPERATION, null);
+ } catch (RuntimeException ex) {
+ Log.e(TAG, "Stub threw runtime exception while processing command "
+ + "request: " + msg + ", in: " + getClass());
+ sendError(ERROR_UNKNOWN, null);
+ }
+ } else if (msg.what == REQUEST_MSG_SUBSCRIBE) {
+ synchronized (mLock) {
+ if (mClosed) {
+ return; // fix possible race if close() is called on another thread
+ }
+ mReplyMessenger = msg.replyTo;
+ }
+ if (msg.replyTo != null) {
+ onClientAttached();
+ } else {
+ onClientDetached();
+ }
+ }
+ }
+
+ /*
+ * Use this handler only to handle requests coming from the application
+ * because the application can send any message it wants to it.
+ */
+ private static final class RequestHandler extends Handler {
+ // break hard reference cycles through binder
+ private final WeakReference<Stub> mStubRef;
+
+ public RequestHandler(Stub stub, Looper looper) {
+ super(looper);
+ mStubRef = new WeakReference<Stub>(stub);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ Stub stub = mStubRef.get();
+ if (stub != null) {
+ stub.handleRequest(msg);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 7e907c2..c4fdee2 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -22,6 +22,15 @@
include ':support-cardview-v7'
project(':support-cardview-v7').projectDir = new File(rootDir, 'v7/cardview')
+include ':support-preference-v7'
+project(':support-preference-v7').projectDir = new File(rootDir, 'v7/preference')
+
+include ':support-preference-v14'
+project(':support-preference-v14').projectDir = new File(rootDir, 'v14/preference')
+
+include ':support-preference-leanback-v17'
+project(':support-preference-leanback-v17').projectDir = new File(rootDir, 'v17/preference-leanback')
+
include ':support-v13'
project(':support-v13').projectDir = new File(rootDir, 'v13')
diff --git a/tests/java/android/support/v4/text/IcuCompatTest.java b/tests/java/android/support/v4/text/IcuCompatTest.java
new file mode 100644
index 0000000..6f7f459
--- /dev/null
+++ b/tests/java/android/support/v4/text/IcuCompatTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 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.v4.text;
+
+import junit.framework.TestCase;
+
+import java.util.Locale;
+
+public class IcuCompatTest extends TestCase {
+ public void testMaximizeAndGetScript() {
+ assertEquals("Latn", ICUCompat.maximizeAndGetScript(new Locale("en", "US")));
+ assertEquals("Visp", ICUCompat.maximizeAndGetScript(Locale.forLanguageTag("en-Visp-US")));
+ }
+}
diff --git a/v14/Android.mk b/v14/Android.mk
new file mode 100644
index 0000000..365b3b1
--- /dev/null
+++ b/v14/Android.mk
@@ -0,0 +1,16 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/v14/preference/Android.mk b/v14/preference/Android.mk
new file mode 100644
index 0000000..fc7a9aa
--- /dev/null
+++ b/v14/preference/Android.mk
@@ -0,0 +1,59 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# Build the resources using the current SDK version.
+# We do this here because the final static library must be compiled with an older
+# SDK version than the resources. The resources library and the R class that it
+# contains will not be linked into the final static library.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v14-preference-res
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, dummy)
+LOCAL_RESOURCE_DIR := \
+ frameworks/support/v7/appcompat/res \
+ frameworks/support/v7/preference/res \
+ $(LOCAL_PATH)/res
+LOCAL_AAPT_FLAGS := \
+ --auto-add-overlay
+LOCAL_JAR_EXCLUDE_FILES := none
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Here is the final static library that apps can link against.
+# The R class is automatically excluded from the generated library.
+# Applications that use this library must specify LOCAL_RESOURCE_DIR
+# in their makefiles to include the resources in their package.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v14-preference
+LOCAL_SDK_VERSION := 14
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+# LOCAL_STATIC_JAVA_LIBRARIES :=
+LOCAL_JAVA_LIBRARIES := \
+ android-support-v4 \
+ android-support-v7-appcompat \
+ android-support-v7-recyclerview \
+ android-support-v7-preference \
+ android-support-annotations \
+ android-support-v14-preference-res
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# API Check
+# ---------------------------------------------
+support_module := $(LOCAL_MODULE)
+support_module_api_dir := $(LOCAL_PATH)/api
+support_module_src_files := $(LOCAL_SRC_FILES)
+support_module_java_libraries := $(LOCAL_JAVA_LIBRARIES)
+support_module_java_packages := android.support.v14.preference
+include $(SUPPORT_API_CHECK)
\ No newline at end of file
diff --git a/v14/preference/AndroidManifest.xml b/v14/preference/AndroidManifest.xml
new file mode 100644
index 0000000..8b502c9
--- /dev/null
+++ b/v14/preference/AndroidManifest.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v14.preference"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="14" />
+ <application />
+</manifest>
diff --git a/v14/preference/api/current.txt b/v14/preference/api/current.txt
new file mode 100644
index 0000000..cbf8fe5
--- /dev/null
+++ b/v14/preference/api/current.txt
@@ -0,0 +1,95 @@
+package android.support.v14.preference {
+
+ public class EditTextPreferenceDialogFragment extends android.support.v14.preference.PreferenceDialogFragment {
+ ctor public EditTextPreferenceDialogFragment();
+ method public static android.support.v14.preference.EditTextPreferenceDialogFragment newInstance(java.lang.String);
+ method protected void onAddEditTextToDialogView(android.view.View, android.widget.EditText);
+ method public void onDialogClosed(boolean);
+ }
+
+ public class ListPreferenceDialogFragment extends android.support.v14.preference.PreferenceDialogFragment {
+ ctor public ListPreferenceDialogFragment();
+ method public static android.support.v14.preference.ListPreferenceDialogFragment newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
+ public class MultiSelectListPreference extends android.support.v7.preference.DialogPreference {
+ ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet);
+ ctor public MultiSelectListPreference(android.content.Context);
+ method public int findIndexOfValue(java.lang.String);
+ method public java.lang.CharSequence[] getEntries();
+ method public java.lang.CharSequence[] getEntryValues();
+ method protected boolean[] getSelectedItems();
+ method public java.util.Set<java.lang.String> getValues();
+ method public void setEntries(java.lang.CharSequence[]);
+ method public void setEntries(int);
+ method public void setEntryValues(java.lang.CharSequence[]);
+ method public void setEntryValues(int);
+ method public void setValues(java.util.Set<java.lang.String>);
+ }
+
+ public class MultiSelectListPreferenceDialogFragment extends android.support.v14.preference.PreferenceDialogFragment {
+ ctor public MultiSelectListPreferenceDialogFragment();
+ method public static android.support.v14.preference.MultiSelectListPreferenceDialogFragment newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
+ public abstract class PreferenceDialogFragment extends android.app.DialogFragment implements android.content.DialogInterface.OnClickListener {
+ ctor public PreferenceDialogFragment();
+ method public android.support.v7.preference.DialogPreference getPreference();
+ method protected void onBindDialogView(android.view.View);
+ method public void onClick(android.content.DialogInterface, int);
+ method protected android.view.View onCreateDialogView(android.content.Context);
+ method public abstract void onDialogClosed(boolean);
+ method protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder);
+ field protected static final java.lang.String ARG_KEY = "key";
+ }
+
+ public abstract class PreferenceFragment extends android.app.Fragment implements android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener {
+ ctor public PreferenceFragment();
+ method public void addPreferencesFromResource(int);
+ method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ method public final android.support.v7.widget.RecyclerView getListView();
+ method public android.support.v7.preference.PreferenceManager getPreferenceManager();
+ method public android.support.v7.preference.PreferenceScreen getPreferenceScreen();
+ method protected android.support.v7.widget.RecyclerView.Adapter onCreateAdapter(android.support.v7.preference.PreferenceScreen);
+ method public android.support.v7.widget.RecyclerView.LayoutManager onCreateLayoutManager();
+ method public abstract void onCreatePreferences(android.os.Bundle, java.lang.String);
+ method public android.support.v7.widget.RecyclerView onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void onDisplayPreferenceDialog(android.support.v7.preference.Preference);
+ method public void onNavigateToScreen(android.support.v7.preference.PreferenceScreen);
+ method public boolean onPreferenceTreeClick(android.support.v7.preference.Preference);
+ method public void setPreferenceScreen(android.support.v7.preference.PreferenceScreen);
+ method public void setPreferencesFromResource(int, java.lang.String);
+ field public static final java.lang.String ARG_PREFERENCE_ROOT = "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT";
+ }
+
+ public static abstract interface PreferenceFragment.OnPreferenceDisplayDialogCallback {
+ method public abstract boolean onPreferenceDisplayDialog(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceFragment.OnPreferenceStartFragmentCallback {
+ method public abstract boolean onPreferenceStartFragment(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceFragment.OnPreferenceStartScreenCallback {
+ method public abstract boolean onPreferenceStartScreen(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.PreferenceScreen);
+ }
+
+ public class SwitchPreference extends android.support.v7.preference.TwoStatePreference {
+ ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public SwitchPreference(android.content.Context, android.util.AttributeSet);
+ ctor public SwitchPreference(android.content.Context);
+ method public java.lang.CharSequence getSwitchTextOff();
+ method public java.lang.CharSequence getSwitchTextOn();
+ method public void setSwitchTextOff(java.lang.CharSequence);
+ method public void setSwitchTextOff(int);
+ method public void setSwitchTextOn(java.lang.CharSequence);
+ method public void setSwitchTextOn(int);
+ }
+
+}
+
diff --git a/v14/preference/api/removed.txt b/v14/preference/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/v14/preference/api/removed.txt
diff --git a/v14/preference/build.gradle b/v14/preference/build.gradle
new file mode 100644
index 0000000..772b353
--- /dev/null
+++ b/v14/preference/build.gradle
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 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
+ */
+
+
+
+apply plugin: 'android-library'
+
+archivesBaseName = 'preference-v14'
+
+dependencies {
+ compile project(':support-v4')
+ compile project(':support-appcompat-v7')
+ compile project(':support-recyclerview-v7')
+ compile project(':support-preference-v7')
+}
+
+android {
+ compileSdkVersion 'current'
+
+ sourceSets {
+ main.manifest.srcFile 'AndroidManifest.xml'
+ main.java.srcDir 'src'
+ main.res.srcDir 'res'
+ main.assets.srcDir 'assets'
+ main.resources.srcDir 'src'
+
+ // this moves src/instrumentTest to tests so all folders follow:
+ // tests/java, tests/res, tests/assets, ...
+ // This is a *reset* so it replaces the default paths
+ androidTest.setRoot('tests')
+ androidTest.java.srcDir 'tests/src'
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
+ lintOptions {
+ // TODO: fix errors and reenable.
+ abortOnError false
+ }
+}
diff --git a/v14/preference/res/layout-v21/preference_material.xml b/v14/preference/res/layout-v21/preference_material.xml
new file mode 100644
index 0000000..8d62cc2
--- /dev/null
+++ b/v14/preference/res/layout-v21/preference_material.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/activatedBackgroundIndicator"
+ android:clipToPadding="false">
+
+ <LinearLayout
+ android:id="@+id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="-4dp"
+ android:minWidth="60dp"
+ android:gravity="start|center_vertical"
+ android:orientation="horizontal"
+ android:paddingEnd="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+ <android.support.v7.internal.widget.PreferenceImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:maxWidth="48dp"
+ app:maxHeight="48dp" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp">
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee" />
+
+ <TextView android:id="@+id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/title"
+ android:layout_alignStart="@id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10" />
+
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout android:id="@+id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="end|center_vertical"
+ android:paddingStart="16dp"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/v14/preference/res/layout/preference_material.xml b/v14/preference/res/layout/preference_material.xml
new file mode 100644
index 0000000..b9d8f66
--- /dev/null
+++ b/v14/preference/res/layout/preference_material.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/activatedBackgroundIndicator"
+ android:clipToPadding="false">
+
+ <LinearLayout
+ android:id="@+id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="-4dp"
+ android:minWidth="60dp"
+ android:gravity="start|center_vertical"
+ android:orientation="horizontal"
+ android:paddingEnd="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+ <android.support.v7.internal.widget.PreferenceImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:maxWidth="48dp"
+ app:maxHeight="48dp" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp">
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee" />
+
+ <TextView android:id="@+id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/title"
+ android:layout_alignStart="@id/title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10" />
+
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout android:id="@+id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="end|center_vertical"
+ android:paddingStart="16dp"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/v14/preference/res/layout/preference_widget_switch.xml b/v14/preference/res/layout/preference_widget_switch.xml
new file mode 100644
index 0000000..ae83afa
--- /dev/null
+++ b/v14/preference/res/layout/preference_widget_switch.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<!-- Layout used by SwitchPreference for the switch widget style. This is inflated
+ inside android.R.layout.preference. -->
+<Switch xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/switchWidget"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:focusable="false"
+ android:clickable="false"
+ android:background="@null" />
diff --git a/v14/preference/res/values/attrs.xml b/v14/preference/res/values/attrs.xml
new file mode 100644
index 0000000..62d9e47
--- /dev/null
+++ b/v14/preference/res/values/attrs.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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>
+ <declare-styleable name="SwitchPreference">
+ <!-- The summary for the Preference in a PreferenceActivity screen when the
+ SwitchPreference is checked. If separate on/off summaries are not
+ needed, the summary attribute can be used instead. -->
+ <attr name="summaryOn" />
+ <attr name="android:summaryOn" />
+ <!-- The summary for the Preference in a PreferenceActivity screen when the
+ SwitchPreference is unchecked. If separate on/off summaries are not
+ needed, the summary attribute can be used instead. -->
+ <attr name="summaryOff" />
+ <attr name="android:summaryOff" />
+ <!-- The text used on the switch itself when in the "on" state.
+ This should be a very SHORT string, as it appears in a small space. -->
+ <attr name="switchTextOn"/>
+ <attr name="android:switchTextOn"/>
+ <!-- The text used on the switch itself when in the "off" state.
+ This should be a very SHORT string, as it appears in a small space. -->
+ <attr name="switchTextOff" />
+ <attr name="android:switchTextOff" />
+ <!-- The state (true for on, or false for off) that causes dependents to be disabled. By default,
+ dependents will be disabled when this is unchecked, so the value of this preference is false. -->
+ <attr name="disableDependentsState" />
+ <attr name="android:disableDependentsState" />
+ </declare-styleable>
+
+ <declare-styleable name="MultiSelectListPreference">
+ <!-- The human-readable array to present as a list. Each entry must have a corresponding
+ index in entryValues. -->
+ <attr name="entries" />
+ <attr name="android:entries" />
+ <!-- The array to find the value to save for a preference when an entry from
+ entries is selected. If a user clicks the second item in entries, the
+ second item in this array will be saved to the preference. -->
+ <attr name="entryValues" />
+ <attr name="android:entryValues" />
+ </declare-styleable>
+</resources>
diff --git a/v14/preference/res/values/styles.xml b/v14/preference/res/values/styles.xml
new file mode 100644
index 0000000..d7cc268
--- /dev/null
+++ b/v14/preference/res/values/styles.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<resources>
+ <style name="Preference.SwitchPreference">
+ <item name="widgetLayout">@layout/preference_widget_switch</item>
+ <item name="switchTextOn">@string/v7_preference_on</item>
+ <item name="switchTextOff">@string/v7_preference_off</item>
+ </style>
+
+</resources>
diff --git a/v14/preference/res/values/themes.xml b/v14/preference/res/values/themes.xml
new file mode 100644
index 0000000..88d25d2
--- /dev/null
+++ b/v14/preference/res/values/themes.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<resources>
+ <style name="PreferenceThemeOverlay.v14">
+ <item name="switchPreferenceStyle">@style/Preference.SwitchPreference</item>
+ </style>
+</resources>
diff --git a/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java
new file mode 100644
index 0000000..caf08a8
--- /dev/null
+++ b/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 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.v14.preference;
+
+import android.os.Bundle;
+import android.support.v7.preference.EditTextPreference;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.EditText;
+
+public class EditTextPreferenceDialogFragment extends PreferenceDialogFragment {
+
+ private EditText mEditText;
+
+ public static EditTextPreferenceDialogFragment newInstance(String key) {
+ final EditTextPreferenceDialogFragment
+ fragment = new EditTextPreferenceDialogFragment();
+ final Bundle b = new Bundle(1);
+ b.putString(ARG_KEY, key);
+ fragment.setArguments(b);
+ return fragment;
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ super.onBindDialogView(view);
+
+ mEditText = new EditText(view.getContext());
+ // Give it an ID so it can be saved/restored
+ mEditText.setId(android.R.id.edit);
+
+ mEditText.setText(getEditTextPreference().getText());
+
+ ViewParent oldParent = mEditText.getParent();
+ if (oldParent != view) {
+ if (oldParent != null) {
+ ((ViewGroup) oldParent).removeView(mEditText);
+ }
+ onAddEditTextToDialogView(view, mEditText);
+ }
+ }
+
+ private EditTextPreference getEditTextPreference() {
+ return (EditTextPreference) getPreference();
+ }
+
+ /** @hide */
+ @Override
+ protected boolean needInputMethod() {
+ // We want the input method to show, if possible, when dialog is displayed
+ return true;
+ }
+
+ /**
+ * Adds the EditText widget of this preference to the dialog's view.
+ *
+ * @param dialogView The dialog view.
+ */
+ protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
+ ViewGroup container = (ViewGroup) dialogView
+ .findViewById(R.id.edittext_container);
+ if (container != null) {
+ container.addView(editText, ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ }
+ }
+
+ @Override
+ public void onDialogClosed(boolean positiveResult) {
+
+ if (positiveResult) {
+ String value = mEditText.getText().toString();
+ if (getEditTextPreference().callChangeListener(value)) {
+ getEditTextPreference().setText(value);
+ }
+ }
+ }
+
+}
diff --git a/v14/preference/src/android/support/v14/preference/ListPreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/ListPreferenceDialogFragment.java
new file mode 100644
index 0000000..c4e922c
--- /dev/null
+++ b/v14/preference/src/android/support/v14/preference/ListPreferenceDialogFragment.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 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.v14.preference;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v7.preference.ListPreference;
+
+public class ListPreferenceDialogFragment extends PreferenceDialogFragment {
+
+ private int mClickedDialogEntryIndex;
+
+ public static ListPreferenceDialogFragment newInstance(String key) {
+ final ListPreferenceDialogFragment fragment = new ListPreferenceDialogFragment();
+ final Bundle b = new Bundle(1);
+ b.putString(ARG_KEY, key);
+ fragment.setArguments(b);
+ return fragment;
+ }
+
+ private ListPreference getListPreference() {
+ return (ListPreference) getPreference();
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+ super.onPrepareDialogBuilder(builder);
+
+ final ListPreference preference = getListPreference();
+
+ if (preference.getEntries() == null || preference.getEntryValues() == null) {
+ throw new IllegalStateException(
+ "ListPreference requires an entries array and an entryValues array.");
+ }
+
+ mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
+ builder.setSingleChoiceItems(preference.getEntries(), mClickedDialogEntryIndex,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mClickedDialogEntryIndex = which;
+
+ /*
+ * Clicking on an item simulates the positive button
+ * click, and dismisses the dialog.
+ */
+ ListPreferenceDialogFragment.this.onClick(dialog,
+ DialogInterface.BUTTON_POSITIVE);
+ dialog.dismiss();
+ }
+ });
+
+ /*
+ * The typical interaction for list-based dialogs is to have
+ * click-on-an-item dismiss the dialog instead of the user having to
+ * press 'Ok'.
+ */
+ builder.setPositiveButton(null, null);
+ }
+
+ @Override
+ public void onDialogClosed(boolean positiveResult) {
+ final ListPreference preference = getListPreference();
+ if (positiveResult && mClickedDialogEntryIndex >= 0 &&
+ preference.getEntryValues() != null) {
+ String value = preference.getEntryValues()[mClickedDialogEntryIndex].toString();
+ if (preference.callChangeListener(value)) {
+ preference.setValue(value);
+ }
+ }
+ }
+
+}
diff --git a/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
new file mode 100644
index 0000000..2a636fe
--- /dev/null
+++ b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2015 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.v14.preference;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.ArrayRes;
+import android.support.annotation.NonNull;
+import android.support.v4.content.SharedPreferencesCompat;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.support.v7.preference.DialogPreference;
+import android.util.AttributeSet;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A {@link android.support.v7.preference.Preference} that displays a list of entries as
+ * a dialog.
+ * <p>
+ * This preference will store a set of strings into the SharedPreferences.
+ * This set will contain one or more values from the
+ * {@link #setEntryValues(CharSequence[])} array.
+ *
+ * @attr ref android.R.styleable#MultiSelectListPreference_entries
+ * @attr ref android.R.styleable#MultiSelectListPreference_entryValues
+ */
+public class MultiSelectListPreference extends DialogPreference {
+ private CharSequence[] mEntries;
+ private CharSequence[] mEntryValues;
+ private Set<String> mValues = new HashSet<>();
+
+ public MultiSelectListPreference(
+ Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ final TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.MultiSelectListPreference, defStyleAttr,
+ defStyleRes);
+
+ mEntries = TypedArrayUtils.getTextArray(a,
+ R.styleable.MultiSelectListPreference_entries,
+ R.styleable.MultiSelectListPreference_android_entries);
+
+ mEntryValues = TypedArrayUtils.getTextArray(a,
+ R.styleable.MultiSelectListPreference_entryValues,
+ R.styleable.MultiSelectListPreference_android_entryValues);
+
+ a.recycle();
+ }
+
+ public MultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public MultiSelectListPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.dialogPreferenceStyle);
+ }
+
+ public MultiSelectListPreference(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Attempts to persist a set of Strings to the {@link android.content.SharedPreferences}.
+ * <p>
+ * This will check if this Preference is persistent, get an editor from
+ * the {@link android.preference.PreferenceManager}, put in the strings, and check if we should
+ * commit (and commit if so).
+ *
+ * @param values The values to persist.
+ * @return True if the Preference is persistent. (This is not whether the
+ * value was persisted, since we may not necessarily commit if there
+ * will be a batch commit later.)
+ * @see #getPersistedString
+ *
+ * @hide
+ */
+ protected boolean persistStringSet(Set<String> values) {
+ if (shouldPersist()) {
+ // Shouldn't store null
+ if (values.equals(getPersistedStringSet(null))) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ SharedPreferences.Editor editor = getPreferenceManager().getSharedPreferences().edit();
+ editor.putStringSet(getKey(), values);
+ SharedPreferencesCompat.EditorCompat.getInstance().apply(editor);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Attempts to get a persisted set of Strings from the
+ * {@link android.content.SharedPreferences}.
+ * <p>
+ * This will check if this Preference is persistent, get the SharedPreferences
+ * from the {@link android.preference.PreferenceManager}, and get the value.
+ *
+ * @param defaultReturnValue The default value to return if either the
+ * Preference is not persistent or the Preference is not in the
+ * shared preferences.
+ * @return The value from the SharedPreferences or the default return
+ * value.
+ * @see #persistStringSet(Set)
+ *
+ * @hide
+ */
+ protected Set<String> getPersistedStringSet(Set<String> defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ return getPreferenceManager().getSharedPreferences()
+ .getStringSet(getKey(), defaultReturnValue);
+ }
+
+ /**
+ * Sets the human-readable entries to be shown in the list. This will be
+ * shown in subsequent dialogs.
+ * <p>
+ * Each entry must have a corresponding index in
+ * {@link #setEntryValues(CharSequence[])}.
+ *
+ * @param entries The entries.
+ * @see #setEntryValues(CharSequence[])
+ */
+ public void setEntries(CharSequence[] entries) {
+ mEntries = entries;
+ }
+
+ /**
+ * @see #setEntries(CharSequence[])
+ * @param entriesResId The entries array as a resource.
+ */
+ public void setEntries(@ArrayRes int entriesResId) {
+ setEntries(getContext().getResources().getTextArray(entriesResId));
+ }
+
+ /**
+ * The list of entries to be shown in the list in subsequent dialogs.
+ *
+ * @return The list as an array.
+ */
+ public CharSequence[] getEntries() {
+ return mEntries;
+ }
+
+ /**
+ * The array to find the value to save for a preference when an entry from
+ * entries is selected. If a user clicks on the second item in entries, the
+ * second item in this array will be saved to the preference.
+ *
+ * @param entryValues The array to be used as values to save for the preference.
+ */
+ public void setEntryValues(CharSequence[] entryValues) {
+ mEntryValues = entryValues;
+ }
+
+ /**
+ * @see #setEntryValues(CharSequence[])
+ * @param entryValuesResId The entry values array as a resource.
+ */
+ public void setEntryValues(@ArrayRes int entryValuesResId) {
+ setEntryValues(getContext().getResources().getTextArray(entryValuesResId));
+ }
+
+ /**
+ * Returns the array of values to be saved for the preference.
+ *
+ * @return The array of values.
+ */
+ public CharSequence[] getEntryValues() {
+ return mEntryValues;
+ }
+
+ /**
+ * Sets the value of the key. This should contain entries in
+ * {@link #getEntryValues()}.
+ *
+ * @param values The values to set for the key.
+ */
+ public void setValues(Set<String> values) {
+ mValues.clear();
+ mValues.addAll(values);
+
+ persistStringSet(values);
+ }
+
+ /**
+ * Retrieves the current value of the key.
+ */
+ public Set<String> getValues() {
+ return mValues;
+ }
+
+ /**
+ * Returns the index of the given value (in the entry values array).
+ *
+ * @param value The value whose index should be returned.
+ * @return The index of the value, or -1 if not found.
+ */
+ public int findIndexOfValue(String value) {
+ if (value != null && mEntryValues != null) {
+ for (int i = mEntryValues.length - 1; i >= 0; i--) {
+ if (mEntryValues[i].equals(value)) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ protected boolean[] getSelectedItems() {
+ final CharSequence[] entries = mEntryValues;
+ final int entryCount = entries.length;
+ final Set<String> values = mValues;
+ boolean[] result = new boolean[entryCount];
+
+ for (int i = 0; i < entryCount; i++) {
+ result[i] = values.contains(entries[i].toString());
+ }
+
+ return result;
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ final CharSequence[] defaultValues = a.getTextArray(index);
+ final Set<String> result = new HashSet<>();
+
+ for (final CharSequence defaultValue : defaultValues) {
+ result.add(defaultValue.toString());
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setValues(restoreValue ? getPersistedStringSet(mValues) : (Set<String>) defaultValue);
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ if (isPersistent()) {
+ // No need to save instance state
+ return superState;
+ }
+
+ final SavedState myState = new SavedState(superState);
+ myState.values = getValues();
+ return myState;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ if (state == null || !state.getClass().equals(SavedState.class)) {
+ // Didn't save state for us in onSaveInstanceState
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ SavedState myState = (SavedState) state;
+ super.onRestoreInstanceState(myState.getSuperState());
+ setValues(myState.values);
+ }
+
+ private static class SavedState extends BaseSavedState {
+ Set<String> values;
+
+ public SavedState(Parcel source) {
+ super(source);
+ final int size = source.readInt();
+ values = new HashSet<>();
+ String[] strings = new String[size];
+ source.readStringArray(strings);
+
+ Collections.addAll(values, strings);
+ }
+
+ public SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(values.size());
+ dest.writeStringArray(values.toArray(new String[values.size()]));
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR =
+ new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+}
diff --git a/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java
new file mode 100644
index 0000000..ec46aac
--- /dev/null
+++ b/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 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.v14.preference;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class MultiSelectListPreferenceDialogFragment extends PreferenceDialogFragment {
+
+ private Set<String> mNewValues = new HashSet<>();
+ private boolean mPreferenceChanged;
+
+ public static MultiSelectListPreferenceDialogFragment newInstance(String key) {
+ final MultiSelectListPreferenceDialogFragment fragment =
+ new MultiSelectListPreferenceDialogFragment();
+ final Bundle b = new Bundle(1);
+ b.putString(ARG_KEY, key);
+ fragment.setArguments(b);
+ return fragment;
+ }
+
+ private MultiSelectListPreference getListPreference() {
+ return (MultiSelectListPreference) getPreference();
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+ super.onPrepareDialogBuilder(builder);
+
+ final MultiSelectListPreference preference = getListPreference();
+
+ if (preference.getEntries() == null || preference.getEntryValues() == null) {
+ throw new IllegalStateException(
+ "MultiSelectListPreference requires an entries array and " +
+ "an entryValues array.");
+ }
+
+ boolean[] checkedItems = preference.getSelectedItems();
+ builder.setMultiChoiceItems(preference.getEntries(), checkedItems,
+ new DialogInterface.OnMultiChoiceClickListener() {
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ if (isChecked) {
+ mPreferenceChanged |= mNewValues.add(
+ preference.getEntryValues()[which].toString());
+ } else {
+ mPreferenceChanged |= mNewValues.remove(
+ preference.getEntryValues()[which].toString());
+ }
+ }
+ });
+ mNewValues.clear();
+ mNewValues.addAll(preference.getValues());
+ }
+
+ @Override
+ public void onDialogClosed(boolean positiveResult) {
+ final MultiSelectListPreference preference = getListPreference();
+ if (positiveResult && mPreferenceChanged) {
+ final Set<String> values = mNewValues;
+ if (preference.callChangeListener(values)) {
+ preference.setValues(values);
+ }
+ }
+ mPreferenceChanged = false;
+ }
+
+}
diff --git a/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java
new file mode 100644
index 0000000..b9027a4
--- /dev/null
+++ b/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015 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.v14.preference;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v7.preference.DialogPreference;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+public abstract class PreferenceDialogFragment extends DialogFragment implements
+ DialogInterface.OnClickListener {
+
+ protected static final String ARG_KEY = "key";
+
+ private DialogPreference mPreference;
+
+ /** Which button was clicked. */
+ private int mWhichButtonClicked;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final Fragment rawFragment = getTargetFragment();
+ if (!(rawFragment instanceof DialogPreference.TargetFragment)) {
+ throw new IllegalStateException("Target fragment must implement TargetFragment" +
+ " interface");
+ }
+
+ final DialogPreference.TargetFragment fragment =
+ (DialogPreference.TargetFragment) rawFragment;
+
+ final String key = getArguments().getString(ARG_KEY);
+ mPreference = (DialogPreference) fragment.findPreference(key);
+ }
+
+ @Override
+ public @NonNull
+ Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Context context = getActivity();
+ mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE;
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context)
+ .setTitle(mPreference.getDialogTitle())
+ .setIcon(mPreference.getDialogIcon())
+ .setPositiveButton(mPreference.getPositiveButtonText(), this)
+ .setNegativeButton(mPreference.getNegativeButtonText(), this);
+
+ View contentView = onCreateDialogView(context);
+ if (contentView != null) {
+ onBindDialogView(contentView);
+ builder.setView(contentView);
+ } else {
+ builder.setMessage(mPreference.getDialogMessage());
+ }
+
+ onPrepareDialogBuilder(builder);
+
+ // Create the dialog
+ final Dialog dialog = builder.create();
+ if (needInputMethod()) {
+ requestInputMethod(dialog);
+ }
+
+
+ return builder.create();
+ }
+
+ /**
+ * Get the preference that requested this dialog. Available after {@link #onCreate(Bundle)} has
+ * been called.
+ *
+ * @return The {@link DialogPreference} associated with this
+ * dialog.
+ */
+ public DialogPreference getPreference() {
+ return mPreference;
+ }
+
+ /**
+ * Prepares the dialog builder to be shown when the preference is clicked.
+ * Use this to set custom properties on the dialog.
+ * <p>
+ * Do not {@link AlertDialog.Builder#create()} or
+ * {@link AlertDialog.Builder#show()}.
+ */
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {}
+
+ /**
+ * Returns whether the preference needs to display a soft input method when the dialog
+ * is displayed. Default is false. Subclasses should override this method if they need
+ * the soft input method brought up automatically.
+ * @hide
+ */
+ protected boolean needInputMethod() {
+ return false;
+ }
+
+ /**
+ * Sets the required flags on the dialog window to enable input method window to show up.
+ */
+ private void requestInputMethod(Dialog dialog) {
+ Window window = dialog.getWindow();
+ window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+ }
+
+ /**
+ * Creates the content view for the dialog (if a custom content view is
+ * required). By default, it inflates the dialog layout resource if it is
+ * set.
+ *
+ * @return The content View for the dialog.
+ * @see DialogPreference#setLayoutResource(int)
+ */
+ protected View onCreateDialogView(Context context) {
+ final int resId = mPreference.getDialogLayoutResource();
+ if (resId == 0) {
+ return null;
+ }
+
+ LayoutInflater inflater = LayoutInflater.from(context);
+ return inflater.inflate(resId, null);
+ }
+
+ /**
+ * Binds views in the content View of the dialog to data.
+ * <p>
+ * Make sure to call through to the superclass implementation.
+ *
+ * @param view The content View of the dialog, if it is custom.
+ */
+ protected void onBindDialogView(View view) {
+ View dialogMessageView = view.findViewById(android.R.id.message);
+
+ if (dialogMessageView != null) {
+ final CharSequence message = mPreference.getDialogMessage();
+ int newVisibility = View.GONE;
+
+ if (!TextUtils.isEmpty(message)) {
+ if (dialogMessageView instanceof TextView) {
+ ((TextView) dialogMessageView).setText(message);
+ }
+
+ newVisibility = View.VISIBLE;
+ }
+
+ if (dialogMessageView.getVisibility() != newVisibility) {
+ dialogMessageView.setVisibility(newVisibility);
+ }
+ }
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mWhichButtonClicked = which;
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON_POSITIVE);
+ }
+
+ public abstract void onDialogClosed(boolean positiveResult);
+}
diff --git a/v14/preference/src/android/support/v14/preference/PreferenceFragment.java b/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
new file mode 100644
index 0000000..a51dab3
--- /dev/null
+++ b/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2015 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.v14.preference;
+
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.annotation.Nullable;
+import android.support.annotation.XmlRes;
+import android.support.v7.preference.DialogPreference;
+import android.support.v7.preference.EditTextPreference;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceGroupAdapter;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Shows a hierarchy of {@link Preference} objects as
+ * lists. These preferences will
+ * automatically save to {@link android.content.SharedPreferences} as the user interacts with
+ * them. To retrieve an instance of {@link android.content.SharedPreferences} that the
+ * preference hierarchy in this fragment will use, call
+ * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)}
+ * with a context in the same package as this fragment.
+ * <p>
+ * Furthermore, the preferences shown will follow the visual style of system
+ * preferences. It is easy to create a hierarchy of preferences (that can be
+ * shown on multiple screens) via XML. For these reasons, it is recommended to
+ * use this fragment (as a superclass) to deal with preferences in applications.
+ * <p>
+ * A {@link PreferenceScreen} object should be at the top of the preference
+ * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy
+ * denote a screen break--that is the preferences contained within subsequent
+ * {@link PreferenceScreen} should be shown on another screen. The preference
+ * framework handles showing these other screens from the preference hierarchy.
+ * <p>
+ * The preference hierarchy can be formed in multiple ways:
+ * <li> From an XML file specifying the hierarchy
+ * <li> From different {@link android.app.Activity Activities} that each specify its own
+ * preferences in an XML file via {@link android.app.Activity} meta-data
+ * <li> From an object hierarchy rooted with {@link PreferenceScreen}
+ * <p>
+ * To inflate from XML, use the {@link #addPreferencesFromResource(int)}. The
+ * root element should be a {@link PreferenceScreen}. Subsequent elements can point
+ * to actual {@link Preference} subclasses. As mentioned above, subsequent
+ * {@link PreferenceScreen} in the hierarchy will result in the screen break.
+ * <p>
+ * To specify an object hierarchy rooted with {@link PreferenceScreen}, use
+ * {@link #setPreferenceScreen(PreferenceScreen)}.
+ * <p>
+ * As a convenience, this fragment implements a click listener for any
+ * preference in the current hierarchy, see
+ * {@link #onPreferenceTreeClick(Preference)}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about using {@code PreferenceFragment},
+ * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>
+ * guide.</p>
+ * </div>
+ *
+ * <a name="SampleCode"></a>
+ * <h3>Sample Code</h3>
+ *
+ * <p>The following sample code shows a simple preference fragment that is
+ * populated from a resource. The resource it loads is:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/xml/preferences.xml preferences}
+ *
+ * <p>The fragment implementation itself simply populates the preferences
+ * when created. Note that the preferences framework takes care of loading
+ * the current values out of the app preferences and writing them when changed:</p>
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java
+ * fragment}
+ *
+ * @see Preference
+ * @see PreferenceScreen
+ */
+public abstract class PreferenceFragment extends Fragment implements
+ PreferenceManager.OnPreferenceTreeClickListener,
+ PreferenceManager.OnDisplayPreferenceDialogListener,
+ PreferenceManager.OnNavigateToScreenListener,
+ DialogPreference.TargetFragment {
+
+ /**
+ * Fragment argument used to specify the tag of the desired root
+ * {@link android.support.v7.preference.PreferenceScreen} object.
+ */
+ public static final String ARG_PREFERENCE_ROOT =
+ "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT";
+
+ private static final String PREFERENCES_TAG = "android:preferences";
+
+ private static final String DIALOG_FRAGMENT_TAG =
+ "android.support.v14.preference.PreferenceFragment.DIALOG";
+
+ private PreferenceManager mPreferenceManager;
+ private RecyclerView mList;
+ private boolean mHavePrefs;
+ private boolean mInitDone;
+
+ private Context mStyledContext;
+
+ private int mLayoutResId = R.layout.preference_list_fragment;
+
+ /**
+ * The starting request code given out to preference framework.
+ */
+ private static final int FIRST_REQUEST_CODE = 100;
+
+ private static final int MSG_BIND_PREFERENCES = 1;
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+
+ case MSG_BIND_PREFERENCES:
+ bindPreferences();
+ break;
+ }
+ }
+ };
+
+ final private Runnable mRequestFocus = new Runnable() {
+ public void run() {
+ mList.focusableViewAvailable(mList);
+ }
+ };
+
+ /**
+ * Interface that PreferenceFragment's containing activity should
+ * implement to be able to process preference items that wish to
+ * switch to a specified fragment.
+ */
+ public interface OnPreferenceStartFragmentCallback {
+ /**
+ * Called when the user has clicked on a Preference that has
+ * a fragment class name associated with it. The implementation
+ * should instantiate and switch to an instance of the given
+ * fragment.
+ * @param caller The fragment requesting navigation.
+ * @param pref The preference requesting the fragment.
+ * @return true if the fragment creation has been handled
+ */
+ boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref);
+ }
+
+ /**
+ * Interface that PreferenceFragment's containing activity should
+ * implement to be able to process preference items that wish to
+ * switch to a new screen of preferences.
+ */
+ public interface OnPreferenceStartScreenCallback {
+ /**
+ * Called when the user has clicked on a PreferenceScreen item in order to navigate to a new
+ * screen of preferences.
+ * @param caller The fragment requesting navigation.
+ * @param pref The preference screen to navigate to.
+ * @return true if the screen navigation has been handled
+ */
+ boolean onPreferenceStartScreen(PreferenceFragment caller, PreferenceScreen pref);
+ }
+
+ public interface OnPreferenceDisplayDialogCallback {
+
+ /**
+ *
+ * @param caller The fragment containing the preference requesting the dialog.
+ * @param pref The preference requesting the dialog.
+ * @return true if the dialog creation has been handled.
+ */
+ boolean onPreferenceDisplayDialog(PreferenceFragment caller, Preference pref);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final TypedValue tv = new TypedValue();
+ getActivity().getTheme().resolveAttribute(R.attr.preferenceTheme, tv, true);
+ final int theme = tv.resourceId;
+ if (theme <= 0) {
+ throw new IllegalStateException("Must specify preferenceTheme in theme");
+ }
+ mStyledContext = new ContextThemeWrapper(getActivity(), theme);
+
+ mPreferenceManager = new PreferenceManager(mStyledContext);
+ mPreferenceManager.setOnNavigateToScreenListener(this);
+ final Bundle args = getArguments();
+ final String rootKey;
+ if (args != null) {
+ rootKey = getArguments().getString(ARG_PREFERENCE_ROOT);
+ } else {
+ rootKey = null;
+ }
+ onCreatePreferences(savedInstanceState, rootKey);
+ }
+
+ /**
+ * Called during {@link #onCreate(Bundle)} to supply the preferences for this fragment.
+ * Subclasses are expected to call {@link #setPreferenceScreen(PreferenceScreen)} either
+ * directly or via helper methods such as {@link #addPreferencesFromResource(int)}.
+ *
+ * @param savedInstanceState If the fragment is being re-created from
+ * a previous saved state, this is the state.
+ * @param rootKey If non-null, this preference fragment should be rooted at the
+ * {@link android.support.v7.preference.PreferenceScreen} with this key.
+ */
+ public abstract void onCreatePreferences(Bundle savedInstanceState, String rootKey);
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ TypedArray a = mStyledContext.obtainStyledAttributes(null,
+ R.styleable.PreferenceFragmentCompat,
+ R.attr.preferenceFragmentStyle,
+ 0);
+
+ mLayoutResId = a.getResourceId(R.styleable.PreferenceFragmentCompat_layout,
+ mLayoutResId);
+
+ a.recycle();
+
+ final View view = inflater.inflate(mLayoutResId, container, false);
+
+ final View rawListContainer = view.findViewById(R.id.list_container);
+ if (!(rawListContainer instanceof ViewGroup)) {
+ throw new RuntimeException("Content has view with id attribute 'R.id.list_container' "
+ + "that is not a ViewGroup class");
+ }
+
+ final ViewGroup listContainer = (ViewGroup) rawListContainer;
+
+ final RecyclerView listView = onCreateRecyclerView(inflater, listContainer,
+ savedInstanceState);
+ if (listView == null) {
+ throw new RuntimeException("Could not create RecyclerView");
+ }
+
+ mList = listView;
+ listContainer.addView(mList);
+ mHandler.post(mRequestFocus);
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ if (mHavePrefs) {
+ bindPreferences();
+ }
+
+ mInitDone = true;
+
+ if (savedInstanceState != null) {
+ Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG);
+ if (container != null) {
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ preferenceScreen.restoreHierarchyState(container);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mPreferenceManager.setOnPreferenceTreeClickListener(this);
+ mPreferenceManager.setOnDisplayPreferenceDialogListener(this);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mPreferenceManager.setOnPreferenceTreeClickListener(null);
+ mPreferenceManager.setOnDisplayPreferenceDialogListener(null);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mList = null;
+ mHandler.removeCallbacks(mRequestFocus);
+ mHandler.removeMessages(MSG_BIND_PREFERENCES);
+ super.onDestroyView();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ Bundle container = new Bundle();
+ preferenceScreen.saveHierarchyState(container);
+ outState.putBundle(PREFERENCES_TAG, container);
+ }
+ }
+
+ /**
+ * Returns the {@link PreferenceManager} used by this fragment.
+ * @return The {@link PreferenceManager}.
+ */
+ public PreferenceManager getPreferenceManager() {
+ return mPreferenceManager;
+ }
+
+ /**
+ * Sets the root of the preference hierarchy that this fragment is showing.
+ *
+ * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
+ */
+ public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+ if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {
+ onUnbindPreferences();
+ mHavePrefs = true;
+ if (mInitDone) {
+ postBindPreferences();
+ }
+ }
+ }
+
+ /**
+ * Gets the root of the preference hierarchy that this fragment is showing.
+ *
+ * @return The {@link PreferenceScreen} that is the root of the preference
+ * hierarchy.
+ */
+ public PreferenceScreen getPreferenceScreen() {
+ return mPreferenceManager.getPreferenceScreen();
+ }
+
+ /**
+ * Inflates the given XML resource and adds the preference hierarchy to the current
+ * preference hierarchy.
+ *
+ * @param preferencesResId The XML resource ID to inflate.
+ */
+ public void addPreferencesFromResource(@XmlRes int preferencesResId) {
+ requirePreferenceManager();
+
+ setPreferenceScreen(mPreferenceManager.inflateFromResource(mStyledContext,
+ preferencesResId, getPreferenceScreen()));
+ }
+
+ /**
+ * Inflates the given XML resource and replaces the current preference hierarchy (if any) with
+ * the preference hierarchy rooted at {@code key}.
+ *
+ * @param preferencesResId The XML resource ID to inflate.
+ * @param key The preference key of the {@link android.support.v7.preference.PreferenceScreen}
+ * to use as the root of the preference hierarchy, or null to use the root
+ * {@link android.support.v7.preference.PreferenceScreen}.
+ */
+ public void setPreferencesFromResource(@XmlRes int preferencesResId, @Nullable String key) {
+ requirePreferenceManager();
+
+ final PreferenceScreen xmlRoot = mPreferenceManager.inflateFromResource(mStyledContext,
+ preferencesResId, null);
+
+ final Preference root;
+ if (key != null) {
+ root = xmlRoot.findPreference(key);
+ if (!(root instanceof PreferenceScreen)) {
+ throw new IllegalArgumentException("Preference object with key " + key
+ + " is not a PreferenceScreen");
+ }
+ } else {
+ root = xmlRoot;
+ }
+
+ setPreferenceScreen((PreferenceScreen) root);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean onPreferenceTreeClick(Preference preference) {
+ if (preference.getFragment() != null) {
+ boolean handled = false;
+ if (getTargetFragment() instanceof OnPreferenceStartFragmentCallback) {
+ handled = ((OnPreferenceStartFragmentCallback) getTargetFragment())
+ .onPreferenceStartFragment(this, preference);
+ }
+ if (!handled && getActivity() instanceof OnPreferenceStartFragmentCallback){
+ handled = ((OnPreferenceStartFragmentCallback) getActivity())
+ .onPreferenceStartFragment(this, preference);
+ }
+ return handled;
+ }
+ return false;
+ }
+
+ /**
+ * Called by
+ * {@link android.support.v7.preference.PreferenceScreen#onClick()} in order to navigate to a
+ * new screen of preferences. Calls
+ * {@link PreferenceFragment.OnPreferenceStartScreenCallback#onPreferenceStartScreen}
+ * if the target fragment or containing activity implements
+ * {@link PreferenceFragment.OnPreferenceStartScreenCallback}.
+ * @param preferenceScreen The {@link android.support.v7.preference.PreferenceScreen} to
+ * navigate to.
+ */
+ @Override
+ public void onNavigateToScreen(PreferenceScreen preferenceScreen) {
+ boolean handled = false;
+ if (getTargetFragment() instanceof OnPreferenceStartScreenCallback) {
+ handled = ((OnPreferenceStartScreenCallback) getTargetFragment())
+ .onPreferenceStartScreen(this, preferenceScreen);
+ }
+ if (!handled && getActivity() instanceof OnPreferenceStartScreenCallback) {
+ ((OnPreferenceStartScreenCallback) getActivity())
+ .onPreferenceStartScreen(this, preferenceScreen);
+ }
+ }
+
+ /**
+ * Finds a {@link Preference} based on its key.
+ *
+ * @param key The key of the preference to retrieve.
+ * @return The {@link Preference} with the key, or null.
+ * @see android.support.v7.preference.PreferenceGroup#findPreference(CharSequence)
+ */
+ public Preference findPreference(CharSequence key) {
+ if (mPreferenceManager == null) {
+ return null;
+ }
+ return mPreferenceManager.findPreference(key);
+ }
+
+ private void requirePreferenceManager() {
+ if (mPreferenceManager == null) {
+ throw new RuntimeException("This should be called after super.onCreate.");
+ }
+ }
+
+ private void postBindPreferences() {
+ if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
+ mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
+ }
+
+ private void bindPreferences() {
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ getListView().setAdapter(onCreateAdapter(preferenceScreen));
+ }
+ onBindPreferences();
+ }
+
+ /** @hide */
+ protected void onBindPreferences() {
+ }
+
+ /** @hide */
+ protected void onUnbindPreferences() {
+ }
+
+ public final RecyclerView getListView() {
+ return mList;
+ }
+
+ /**
+ * Creates the {@link android.support.v7.widget.RecyclerView} used to display the preferences.
+ * Subclasses may override this to return a customized
+ * {@link android.support.v7.widget.RecyclerView}.
+ * @param inflater The LayoutInflater object that can be used to inflate the
+ * {@link android.support.v7.widget.RecyclerView}.
+ * @param parent The parent {@link android.view.View} that the RecyclerView will be attached to.
+ * This method should not add the view itself, but this can be used to generate
+ * the LayoutParams of the view.
+ * @param savedInstanceState If non-null, this view is being re-constructed from a previous
+ * saved state as given here
+ * @return A new RecyclerView object to be placed into the view hierarchy
+ */
+ public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
+ Bundle savedInstanceState) {
+ RecyclerView recyclerView = (RecyclerView) inflater
+ .inflate(R.layout.preference_recyclerview, parent, false);
+
+ recyclerView.setLayoutManager(onCreateLayoutManager());
+
+ return recyclerView;
+ }
+
+ /**
+ * Called from {@link #onCreateRecyclerView} to create the
+ * {@link android.support.v7.widget.RecyclerView.LayoutManager} for the created
+ * {@link android.support.v7.widget.RecyclerView}.
+ * @return A new {@link android.support.v7.widget.RecyclerView.LayoutManager} instance.
+ */
+ public RecyclerView.LayoutManager onCreateLayoutManager() {
+ return new LinearLayoutManager(getActivity());
+ }
+
+ /**
+ * Creates the root adapter.
+ *
+ * @param preferenceScreen Preference screen object to create the adapter for.
+ * @return An adapter that contains the preferences contained in this {@link PreferenceScreen}.
+ */
+ protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
+ return new PreferenceGroupAdapter(preferenceScreen);
+ }
+
+ /**
+ * Called when a preference in the tree requests to display a dialog. Subclasses should
+ * override this method to display custom dialogs or to handle dialogs for custom preference
+ * classes.
+ *
+ * @param preference The Preference object requesting the dialog.
+ */
+ @Override
+ public void onDisplayPreferenceDialog(Preference preference) {
+
+ boolean handled = false;
+ if (getTargetFragment() instanceof OnPreferenceDisplayDialogCallback) {
+ handled = ((OnPreferenceDisplayDialogCallback) getTargetFragment())
+ .onPreferenceDisplayDialog(this, preference);
+ }
+ if (!handled && getActivity() instanceof OnPreferenceDisplayDialogCallback) {
+ handled = ((OnPreferenceDisplayDialogCallback) getActivity())
+ .onPreferenceDisplayDialog(this, preference);
+ }
+
+ if (handled) {
+ return;
+ }
+
+ // check if dialog is already showing
+ if (getFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
+ return;
+ }
+
+ final DialogFragment f;
+ if (preference instanceof EditTextPreference) {
+ f = EditTextPreferenceDialogFragment.newInstance(preference.getKey());
+ } else if (preference instanceof ListPreference) {
+ f = ListPreferenceDialogFragment.newInstance(preference.getKey());
+ } else if (preference instanceof MultiSelectListPreference) {
+ f = MultiSelectListPreferenceDialogFragment.newInstance(preference.getKey());
+ } else {
+ throw new IllegalArgumentException("Tried to display dialog for unknown " +
+ "preference type. Did you forget to override onDisplayPreferenceDialog()?");
+ }
+ f.setTargetFragment(this, 0);
+ f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
+ }
+
+}
diff --git a/v14/preference/src/android/support/v14/preference/SwitchPreference.java b/v14/preference/src/android/support/v14/preference/SwitchPreference.java
new file mode 100644
index 0000000..048bc6c
--- /dev/null
+++ b/v14/preference/src/android/support/v14/preference/SwitchPreference.java
@@ -0,0 +1,214 @@
+/*
+* Copyright (C) 2015 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.v14.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.support.v7.preference.TwoStatePreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Checkable;
+import android.widget.CompoundButton;
+import android.widget.Switch;
+
+/**
+ * A {@link android.support.v7.preference.Preference} that provides a two-state toggleable option.
+ * <p>
+ * This preference will store a boolean into the SharedPreferences.
+ *
+ * @attr ref android.R.styleable#SwitchPreference_summaryOff
+ * @attr ref android.R.styleable#SwitchPreference_summaryOn
+ * @attr ref android.R.styleable#SwitchPreference_switchTextOff
+ * @attr ref android.R.styleable#SwitchPreference_switchTextOn
+ * @attr ref android.R.styleable#SwitchPreference_disableDependentsState
+ */
+public class SwitchPreference extends TwoStatePreference {
+ private final Listener mListener = new Listener();
+
+ // Switch text for on and off states
+ private CharSequence mSwitchOn;
+ private CharSequence mSwitchOff;
+
+ private class Listener implements CompoundButton.OnCheckedChangeListener {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!callChangeListener(isChecked)) {
+ // Listener didn't like it, change it back.
+ // CompoundButton will make sure we don't recurse.
+ buttonView.setChecked(!isChecked);
+ return;
+ }
+
+ SwitchPreference.this.setChecked(isChecked);
+ }
+ }
+
+ /**
+ * Construct a new SwitchPreference with the given style options.
+ *
+ * @param context The Context that will style this preference
+ * @param attrs Style attributes that differ from the default
+ * @param defStyleAttr An attribute in the current theme that contains a
+ * reference to a style resource that supplies default values for
+ * the view. Can be 0 to not look for defaults.
+ * @param defStyleRes A resource identifier of a style resource that
+ * supplies default values for the view, used only if
+ * defStyleAttr is 0 or can not be found in the theme. Can be 0
+ * to not look for defaults.
+ */
+ public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.SwitchPreference, defStyleAttr, defStyleRes);
+
+ setSummaryOn(TypedArrayUtils.getString(a, R.styleable.SwitchPreference_summaryOn,
+ R.styleable.SwitchPreference_android_summaryOn));
+
+ setSummaryOff(TypedArrayUtils.getString(a, R.styleable.SwitchPreference_summaryOff,
+ R.styleable.SwitchPreference_android_summaryOff));
+
+ setSwitchTextOn(TypedArrayUtils.getString(a,
+ R.styleable.SwitchPreference_switchTextOn,
+ R.styleable.SwitchPreference_android_switchTextOn));
+
+ setSwitchTextOff(TypedArrayUtils.getString(a,
+ R.styleable.SwitchPreference_switchTextOff,
+ R.styleable.SwitchPreference_android_switchTextOff));
+
+ setDisableDependentsState(TypedArrayUtils.getBoolean(a,
+ R.styleable.SwitchPreference_disableDependentsState,
+ R.styleable.SwitchPreference_android_disableDependentsState, false));
+
+ a.recycle();
+ }
+
+ /**
+ * Construct a new SwitchPreference with the given style options.
+ *
+ * @param context The Context that will style this preference
+ * @param attrs Style attributes that differ from the default
+ * @param defStyleAttr An attribute in the current theme that contains a
+ * reference to a style resource that supplies default values for
+ * the view. Can be 0 to not look for defaults.
+ */
+ public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ /**
+ * Construct a new SwitchPreference with the given style options.
+ *
+ * @param context The Context that will style this preference
+ * @param attrs Style attributes that differ from the default
+ */
+ public SwitchPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.switchPreferenceStyle);
+ }
+
+ /**
+ * Construct a new SwitchPreference with default style options.
+ *
+ * @param context The Context that will style this preference
+ */
+ public SwitchPreference(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ View checkableView = holder.findViewById(R.id.switchWidget);
+ if (checkableView != null && checkableView instanceof Checkable) {
+ if (checkableView instanceof Switch) {
+ final Switch switchView = (Switch) checkableView;
+ switchView.setOnCheckedChangeListener(null);
+ }
+
+ ((Checkable) checkableView).setChecked(mChecked);
+
+ if (checkableView instanceof Switch) {
+ final Switch switchView = (Switch) checkableView;
+ switchView.setTextOn(mSwitchOn);
+ switchView.setTextOff(mSwitchOff);
+ switchView.setOnCheckedChangeListener(mListener);
+ }
+ }
+
+ syncSummaryView(holder);
+ }
+
+ /**
+ * Set the text displayed on the switch widget in the on state.
+ * This should be a very short string; one word if possible.
+ *
+ * @param onText Text to display in the on state
+ */
+ public void setSwitchTextOn(CharSequence onText) {
+ mSwitchOn = onText;
+ notifyChanged();
+ }
+
+ /**
+ * Set the text displayed on the switch widget in the off state.
+ * This should be a very short string; one word if possible.
+ *
+ * @param offText Text to display in the off state
+ */
+ public void setSwitchTextOff(CharSequence offText) {
+ mSwitchOff = offText;
+ notifyChanged();
+ }
+
+ /**
+ * Set the text displayed on the switch widget in the on state.
+ * This should be a very short string; one word if possible.
+ *
+ * @param resId The text as a string resource ID
+ */
+ public void setSwitchTextOn(int resId) {
+ setSwitchTextOn(getContext().getString(resId));
+ }
+
+ /**
+ * Set the text displayed on the switch widget in the off state.
+ * This should be a very short string; one word if possible.
+ *
+ * @param resId The text as a string resource ID
+ */
+ public void setSwitchTextOff(int resId) {
+ setSwitchTextOff(getContext().getString(resId));
+ }
+
+ /**
+ * @return The text that will be displayed on the switch widget in the on state
+ */
+ public CharSequence getSwitchTextOn() {
+ return mSwitchOn;
+ }
+
+ /**
+ * @return The text that will be displayed on the switch widget in the off state
+ */
+ public CharSequence getSwitchTextOff() {
+ return mSwitchOff;
+ }
+}
diff --git a/v17/leanback/api/current.txt b/v17/leanback/api/current.txt
index 336a422..0dd5831 100644
--- a/v17/leanback/api/current.txt
+++ b/v17/leanback/api/current.txt
@@ -504,6 +504,22 @@
}
+package android.support.v17.leanback.view {
+
+ public class ViewGroupOverlayHelper {
+ ctor public ViewGroupOverlayHelper();
+ method public static void addChildToOverlay(android.view.ViewGroup, android.view.View);
+ method public static void removeChildFromOverlay(android.view.ViewGroup, android.view.View);
+ method public static boolean supportsOverlay();
+ }
+
+ public static abstract interface ViewGroupOverlayHelper.Impl {
+ method public abstract void addChildToOverlay(android.view.ViewGroup, android.view.View);
+ method public abstract void removeChildFromOverlay(android.view.ViewGroup, android.view.View);
+ }
+
+}
+
package android.support.v17.leanback.widget {
public abstract class AbstractDetailsDescriptionPresenter extends android.support.v17.leanback.widget.Presenter {
diff --git a/v17/leanback/build.gradle b/v17/leanback/build.gradle
index b34e2a1..8dc79e8 100644
--- a/v17/leanback/build.gradle
+++ b/v17/leanback/build.gradle
@@ -27,6 +27,11 @@
androidTest.java.srcDir 'tests/java'
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
lintOptions {
// TODO: fix errors and reenable.
abortOnError false
diff --git a/v17/leanback/jbmr2/android/support/v17/leanback/view/ViewGroupOverlayHelperJbmr2.java b/v17/leanback/jbmr2/android/support/v17/leanback/view/ViewGroupOverlayHelperJbmr2.java
new file mode 100644
index 0000000..12dda9a
--- /dev/null
+++ b/v17/leanback/jbmr2/android/support/v17/leanback/view/ViewGroupOverlayHelperJbmr2.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 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.v17.leanback.view;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+public class ViewGroupOverlayHelperJbmr2 {
+
+ public static void addChildToOverlay(ViewGroup parent, View child) {
+ parent.getOverlay().add(child);
+ }
+
+ public static void removeChildFromOverlay(ViewGroup parent, View child) {
+ parent.getOverlay().remove(child);
+ }
+}
diff --git a/v17/leanback/res/values-af/strings.xml b/v17/leanback/res/values-af/strings.xml
index fa93257..c7109bb 100644
--- a/v17/leanback/res/values-af/strings.xml
+++ b/v17/leanback/res/values-af/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Praat om te soek"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Deursoek <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Praat om <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> te deursoek"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Speel"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Laat wag"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Vinnig vorentoe"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Spoel vorentoe %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Spoel terug"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Spoel terug %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Slaan volgende oor"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Slaan vorige oor"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Nog handelinge"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Ontkies laaik baie"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Kies laaik baie"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Ontkies laaik niks"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Kies laaik niks"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Herhaal niks"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Herhaal alles"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Herhaal een"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Aktiveer skommel"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Deaktiveer skommel"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Aktiveer hoë gehalte"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Deaktiveer hoë gehalte"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktiveer onderskrifte"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Deaktiveer onderskrifte"</string>
</resources>
diff --git a/v17/leanback/res/values-am/strings.xml b/v17/leanback/res/values-am/strings.xml
index 4b0f26f..d5bf0f5 100644
--- a/v17/leanback/res/values-am/strings.xml
+++ b/v17/leanback/res/values-am/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"ለመፈለግ ይናገሩ"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ፈልግ"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>ን ለመፈለግ ይናገሩ"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"አጫውት"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"ለአፍታ አቁም"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"በፍጥነት አሳልፍ"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"በ%1$dX ወደፊት አፍጥን"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"ወደኋላ አጠንጥን"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"በ%1$dX አጠንጥን"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"የሚቀጥለውን ዝለል"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"የቀደመውን ዝለል"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"ተጨማሪ እርምጃዎች"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"አውራጣት ወደ ላይን አትምረጥ"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"አውራ ጣት ወደላይን ምረጥ"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"አውራ ጣት ወደታችን አትምረጥ"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"አውራ ጣት ወደታችን ምረጥ"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"ምንም አትድገም"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"ሁሉንም ድገም"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"አንዱን ድገም"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"መበወዣን አንቃ"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"መበወዣን አሰናክል"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"ከፍተኛ ጥራትን አንቃ"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"ከፍተኛ ጥራትን አሰናክል"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ዝግ የምስል ስር ጽሑፍ አጻጻፍን አንቃ"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ዝግ የምስል ስር ጽሑፍ አጻጻፍን አሰናክል"</string>
</resources>
diff --git a/v17/leanback/res/values-ar/strings.xml b/v17/leanback/res/values-ar/strings.xml
index 6540a3e..31f4d1a 100644
--- a/v17/leanback/res/values-ar/strings.xml
+++ b/v17/leanback/res/values-ar/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"التحدث للبحث"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"بحث في <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"تحدّث للبحث في <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"تشغيل"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"إيقاف مؤقت"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"تقديم سريع"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"التقديم السريع %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"إرجاع"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"الترجيع %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"تخطي التالي"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"تخطي السابق"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"مزيد من الإجراءات"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"إلغاء تحديد زر \"أعجبني\""</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"تحديد زر \"أعجبني\""</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"إلغاء تحديد زر \"لم يعجبني\""</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"تحديد زر \"لم يعجبني\""</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"عدم التكرار"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"تكرار الكل"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"تكرار مقطع واحد"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"تمكين الترتيب العشوائي"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"تعطيل الترتيب العشوائي"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"تمكين الجودة العالية"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"تعطيل الجودة العالية"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"تمكين الترجمة المصاحبة"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"تعطيل الترجمة المصاحبة"</string>
</resources>
diff --git a/v17/leanback/res/values-bg/strings.xml b/v17/leanback/res/values-bg/strings.xml
index 9cd9b5c..de0b6f8 100644
--- a/v17/leanback/res/values-bg/strings.xml
+++ b/v17/leanback/res/values-bg/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Говорете, за да търсите"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Търсете в/ъв <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Говорете, за да търсите в/ъв <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Пускане"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Поставяне на пауза"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Превъртане напред"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Превъртане напред със скорост %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Превъртане назад"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Превъртане назад със скорост %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Напред към следващия елемент"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Назад към предишния елемент"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Още действия"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Премахване на избора от „Харесва ми“"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Избиране на „Харесва ми“"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Премахване на избора от „Не ми харесва“"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Избиране на „Не ми харесва“"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Без повтаряне"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Повтаряне на всички"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Повтаряне на един елемент"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Активиране на разбъркването"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Деактивиране на разбъркването"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Активиране на високото качество"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Деактивиране на високото качество"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Активиране на субтитрите"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Деактивиране на субтитрите"</string>
</resources>
diff --git a/v17/leanback/res/values-bn-rBD/strings.xml b/v17/leanback/res/values-bn-rBD/strings.xml
index 400553a..4f0526c 100644
--- a/v17/leanback/res/values-bn-rBD/strings.xml
+++ b/v17/leanback/res/values-bn-rBD/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"অনুসন্ধান করতে বলুন"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> অনুসন্ধান করুন"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> অনুসন্ধান করতে বলুন"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"চালান"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"বিরাম দিন"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"দ্রুত ফরওয়ার্ড"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"দ্রুত ফরওয়ার্ড %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"পেছনের দিকে যান"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"পেছনের দিকে যান %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"সরাসরি পরেরটিতে চলে যান"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"সরাসরি আগেরটিতে চলে যান"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"আরো অ্যাকশন"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"উপরের দিকে বুড়ো আঙ্গুল নির্দেশিত চিহ্ন নির্বাচন মুক্ত করুন"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"উপরের দিকে বুড়ো আঙ্গুল নির্দেশিত চিহ্ন নির্বাচিত করুন"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"নীচের দিকে বুড়ো আঙ্গুল নির্দেশিত চিহ্ন নির্বাচন মুক্ত করুন"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"নীচের দিকে বুড়ো আঙ্গুল নির্দেশিত চিহ্ন নির্বাচন করুন"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"একটিরও পুনরাবৃত্তি করবেন না"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"সবগুলির পুনরাবৃত্তি করুন"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"একটির পুনরাবৃত্তি করুন"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"শাফল করা সক্ষম করুন"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"শাফল করা অক্ষম করুন"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"উচ্চ গুণমান সক্ষম করুন"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"উচ্চ গুণমান অক্ষম করুন"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"সাবটাইটেল সক্ষম করুন"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"সাবটাইটেল অক্ষম করুন"</string>
</resources>
diff --git a/v17/leanback/res/values-ca/strings.xml b/v17/leanback/res/values-ca/strings.xml
index 9087b56..187f5af 100644
--- a/v17/leanback/res/values-ca/strings.xml
+++ b/v17/leanback/res/values-ca/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Parla per fer una cerca."</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Cerca a <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>."</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Parla per cercar a <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>."</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Reprodueix"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Posa en pausa"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Avança ràpidament"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Avança ràpidament %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Rebobina"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Rebobina %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Passa al següent"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Passa a l\'anterior"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Més accions"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Anul·la \"M\'agrada\""</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Selecciona \"M\'agrada\""</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Anul·la \"No m\'agrada\""</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Selecciona \"M\'agrada\""</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"No en repeteixis cap"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repeteix-ho tot"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repeteix-ne un"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Activa la reproducció aleatòria"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Desactiva la reproducció aleatòria"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Activa l\'alta qualitat"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Desactiva l\'alta qualitat"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activa els subtítols tancats"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desactiva els subtítols tancats"</string>
</resources>
diff --git a/v17/leanback/res/values-cs/strings.xml b/v17/leanback/res/values-cs/strings.xml
index 7c5b18c..1a60828 100644
--- a/v17/leanback/res/values-cs/strings.xml
+++ b/v17/leanback/res/values-cs/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Vyhledávání"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Vyhledávejte hlasem"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Hledat <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Vyhledávejte v kontextu <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> hlasem"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Vyhledávejte v kategorii „<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>“ hlasem"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$d×"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$d×"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Přehrát"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pozastavit"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Přetočit vpřed"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Přetočit vpřed %1$d×"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Přetočit zpět"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Přetočit zpět %1$d×"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Přeskočit na další"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Přeskočit na předchozí"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Další akce"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Zrušit výběr hodnocení palec nahoru"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Vybrat hodnocení palec nahoru"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Zrušit výběr hodnocení palec dolů"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Vybrat hodnocení palec dolů"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Neopakovat"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Opakovat vše"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Opakovat jednu položku"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Zapnout náhodné přehrávání"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Vypnout náhodné přehrávání"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Zapnout vysokou kvalitu"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Vypnout vysokou kvalitu"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Zapnout titulky"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Vypnout titulky"</string>
</resources>
diff --git a/v17/leanback/res/values-da/strings.xml b/v17/leanback/res/values-da/strings.xml
index 51a195a..e3e0f9f 100644
--- a/v17/leanback/res/values-da/strings.xml
+++ b/v17/leanback/res/values-da/strings.xml
@@ -17,9 +17,33 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="orb_search_action" msgid="5651268540267663887">"Søgehandling"</string>
+ <string name="orb_search_action" msgid="5651268540267663887">"Søg handling"</string>
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Søg"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Tal for at søge"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Søg efter <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Tal for at søge efter <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Afspil"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Sæt på pause"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Spol frem"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Spol frem %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Spol tilbage"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Spol tilbage %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Spring til næste"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Spring til forrige"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Flere handlinger"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Fravælg tommelfinger op"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Vælg tommelfinger op"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Fravælg tommelfinger ned"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Vælg tommelfinger ned"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Gentag ingen"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Gentag alle"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Gentag en"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Aktivér bland"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Deaktiver bland"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Aktivér høj aktivitet"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Deaktiver høj kvalitet"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktivér undertekster"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Deaktiver undertekster"</string>
</resources>
diff --git a/v17/leanback/res/values-de/strings.xml b/v17/leanback/res/values-de/strings.xml
index 1b353a0..d729f7c 100644
--- a/v17/leanback/res/values-de/strings.xml
+++ b/v17/leanback/res/values-de/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Suchen"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Zum Suchen sprechen"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"In <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> suchen"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Zum Suchen in <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> sprechen"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Zum Suchen in der Kategorie \"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>\" sprechen"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dx"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dx"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Wiedergabe"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pausieren"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Vorspulen"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Vorspulen %1$dx"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Zurückspulen"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Zurückspulen %1$dx"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Nächsten Titel überspringen"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Vorherigen Titel überspringen"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Weitere Aktionen"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"\"Mag ich\" deaktivieren"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"\"Mag ich\" aktivieren"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"\"Mag ich nicht\" deaktivieren"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"\"Mag ich nicht\" aktivieren"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Keinen Titel wiederholen"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Alle wiederholen"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Einen Titel wiederholen"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Zufallsmix aktivieren"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Zufallsmix deaktivieren"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Hohe Qualität aktivieren"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Hohe Qualität deaktivieren"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Untertitel aktivieren"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Untertitel deaktivieren"</string>
</resources>
diff --git a/v17/leanback/res/values-el/strings.xml b/v17/leanback/res/values-el/strings.xml
index fc8c159..9b93dcf 100644
--- a/v17/leanback/res/values-el/strings.xml
+++ b/v17/leanback/res/values-el/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Μιλήστε για να κάνετε αναζήτηση"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Αναζήτηση <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Μιλήστε για αναζήτηση <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Αναπαραγωγή"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Παύση"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Γρήγορη προώθηση"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Γρήγορη προώθηση %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Επαναφορά"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Επαναφορά %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Παράβλεψη επόμενου"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Παράβλεψη προηγούμενου"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Περισσότερες ενέργειες"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Κατάργηση επιλογής \"Μου αρέσουν\""</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Επιλογή \"Μου αρέσουν\""</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Κατάργηση επιλογής \"Δεν μου αρέσουν\""</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Επιλογή \"Δεν μου αρέσουν\""</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Καμία επανάληψη"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Επανάληψη όλων"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Επανάληψη ενός στοιχείου"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Ενεργοποίηση Τυχαίας αναπαραγωγής"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Απενεργοποίηση Τυχαίας αναπαραγωγής"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Ενεργοποίηση Υψηλής ποιότητας"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Απενεργοποίηση Υψηλής ποιότητας"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ενεργοποίηση υποτίτλων"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Απενεργοποίηση υποτίτλων"</string>
</resources>
diff --git a/v17/leanback/res/values-en-rAU/strings.xml b/v17/leanback/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..ed22ccd
--- /dev/null
+++ b/v17/leanback/res/values-en-rAU/strings.xml
@@ -0,0 +1,49 @@
+<?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="orb_search_action" msgid="5651268540267663887">"Search Action"</string>
+ <string name="lb_search_bar_hint" msgid="8325490927970116252">"Search"</string>
+ <string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Speak to search"</string>
+ <string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Search <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Speak to search <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Play"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pause"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Fast-Forward"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Fast Forward %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Rewind"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Rewind %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Skip Next"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Skip Previous"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"More Actions"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Deselect Thumb Up"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Select Thumb Up"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Deselect Thumb Down"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Select Thumb Down"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Repeat None"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repeat All"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repeat One"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Enable Shuffle"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Disable Shuffle"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Enable High Quality"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Disable High Quality"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Enable Closed Captioning"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Disable Closed Captioning"</string>
+</resources>
diff --git a/v17/leanback/res/values-en-rGB/strings.xml b/v17/leanback/res/values-en-rGB/strings.xml
index 666fa5c..ed22ccd 100644
--- a/v17/leanback/res/values-en-rGB/strings.xml
+++ b/v17/leanback/res/values-en-rGB/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Speak to search"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Search <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Speak to search <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Play"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pause"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Fast-Forward"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Fast Forward %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Rewind"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Rewind %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Skip Next"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Skip Previous"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"More Actions"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Deselect Thumb Up"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Select Thumb Up"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Deselect Thumb Down"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Select Thumb Down"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Repeat None"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repeat All"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repeat One"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Enable Shuffle"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Disable Shuffle"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Enable High Quality"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Disable High Quality"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Enable Closed Captioning"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Disable Closed Captioning"</string>
</resources>
diff --git a/v17/leanback/res/values-en-rIN/strings.xml b/v17/leanback/res/values-en-rIN/strings.xml
index 666fa5c..ed22ccd 100644
--- a/v17/leanback/res/values-en-rIN/strings.xml
+++ b/v17/leanback/res/values-en-rIN/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Speak to search"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Search <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Speak to search <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Play"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pause"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Fast-Forward"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Fast Forward %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Rewind"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Rewind %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Skip Next"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Skip Previous"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"More Actions"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Deselect Thumb Up"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Select Thumb Up"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Deselect Thumb Down"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Select Thumb Down"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Repeat None"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repeat All"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repeat One"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Enable Shuffle"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Disable Shuffle"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Enable High Quality"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Disable High Quality"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Enable Closed Captioning"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Disable Closed Captioning"</string>
</resources>
diff --git a/v17/leanback/res/values-es-rUS/strings.xml b/v17/leanback/res/values-es-rUS/strings.xml
index 896535a..ab05f83 100644
--- a/v17/leanback/res/values-es-rUS/strings.xml
+++ b/v17/leanback/res/values-es-rUS/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Búsqueda"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Habla para buscar"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Buscar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Habla para buscar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>."</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Habla para buscar en <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>."</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Reproducir"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pausar"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Avanzar"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Avanzar rápidamente %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Retroceder"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Rebobinar %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Ir al siguiente"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Ir al anterior"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Más acciones"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Desmarcar \"Me gusta\""</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Marcar \"Me gusta\""</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Desmarcar \"No me gusta\""</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Marcar \"No me gusta\""</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"No repetir"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repetir todo"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repetir uno"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Habilitar reproducción aleatoria"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Inhabilitar reproducción aleatoria"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Habilitar calidad alta"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Inhabilitar calidad alta"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Habilitar subtítulos"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Inhabilitar subtítulos"</string>
</resources>
diff --git a/v17/leanback/res/values-es/strings.xml b/v17/leanback/res/values-es/strings.xml
index 9990ae6..0cff1c9 100644
--- a/v17/leanback/res/values-es/strings.xml
+++ b/v17/leanback/res/values-es/strings.xml
@@ -19,7 +19,31 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="orb_search_action" msgid="5651268540267663887">"Buscar..."</string>
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Buscar"</string>
- <string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Buscar por voz"</string>
+ <string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Habla para buscar"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Buscar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Buscar por voz <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Habla para buscar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Reproducir"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pausar"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Avance rápido"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Avance rápido %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Rebobinar"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Rebobinar %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Saltar siguiente"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Saltar anterior"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Más acciones"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"No seleccionar pulgar hacia arriba"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Seleccionar pulgar hacia arriba"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"No seleccionar pulgar hacia abajo"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Seleccionar pulgar hacia abajo"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"No repetir"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repetir todo"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repetir uno"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Habilitar reproducción aleatoria"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Inhabilitar reproducción aleatoria"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Habilitar alta calidad"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Inhabilitar alta calidad"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Habilitar subtítulos"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Inhabilitar subtítulos"</string>
</resources>
diff --git a/v17/leanback/res/values-et-rEE/strings.xml b/v17/leanback/res/values-et-rEE/strings.xml
index a097b5d..32fff96 100644
--- a/v17/leanback/res/values-et-rEE/strings.xml
+++ b/v17/leanback/res/values-et-rEE/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Öelge otsimiseks"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Otsige teenusest <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Kõnelge teenusest <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> otsimiseks"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Esita"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Peata"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Keri edasi"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Edasikerimine %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Keri tagasi"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Tagasikerimine %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Liigu järgmise üksuse juurde"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Liigu eelmise üksuse juurde"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Veel toiminguid"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Tühista hinnang Meeldib"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Vali hinnang Meeldib"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Tühista hinnang Ei meeldi"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Vali hinnang Ei meeldi"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Ära korda midagi"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Korda kõike"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Korda ühte"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Luba juhuslikus järjekorras esitamine"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Keela juhuslikus järjekorras esitamine"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Luba kõrgkvaliteetne taasesitus"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Keela kõrgkvaliteetne taasesitus"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Luba subtiitrid"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Keela subtiitrid"</string>
</resources>
diff --git a/v17/leanback/res/values-eu-rES/strings.xml b/v17/leanback/res/values-eu-rES/strings.xml
index 2690a84..d9f9bf7 100644
--- a/v17/leanback/res/values-eu-rES/strings.xml
+++ b/v17/leanback/res/values-eu-rES/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Esan bilatu nahi duzuna"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Bilatu <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Esan bilatu nahi duzuna, bilaketa hemen egiteko: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Erreproduzitu"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pausatu"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Aurreratu"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Aurreratu %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Atzeratu"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Atzeratu %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Saltatu hurrengora"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Saltatu aurrekora"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Ekintza gehiago"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Desautatu \"erpurua gora\""</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Hautatu \"erpurua gora\""</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Desautatu \"erpurua behera\""</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Hautatu \"erpurua behera\""</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Ez errepikatu"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Errepikatu guztiak"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Errepikatu bat"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Gaitu ausazko erreprodukzioa"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Desgaitu ausazko erreprodukzioa"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Gaitu kalitate handiko erreprodukzioa"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Desgaitu kalitate handiko erreprodukzioa"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Gaitu azpitituluak"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desgaitu azpitituluak"</string>
</resources>
diff --git a/v17/leanback/res/values-fa/strings.xml b/v17/leanback/res/values-fa/strings.xml
index fa4bb0c..bb615fc 100644
--- a/v17/leanback/res/values-fa/strings.xml
+++ b/v17/leanback/res/values-fa/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"برای جستجو صحبت کنید"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"جستجوی <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"جستجو با گفتن <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"پخش"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"توقف موقت"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"جلو بردن سریع"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"بازارسال سریع %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"عقب بردن"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"عقب بردن %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"رد شدن از بعدی"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"رد شدن از قبلی"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"عملکردهای بیشتر"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"لغو انتخاب رأی موافق"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"انتخاب رأی موافق"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"لغو انتخاب رأی مخالف"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"انتخاب رأی مخالف"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"تکرار هیچکدام"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"تکرار همه"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"یکبار تکرار"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"فعال کردن پخش تصادفی"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"غیرفعال کردن پخش تصادفی"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"فعال کردن کیفیت بالا"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"غیرفعال کردن کیفیت بالا"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"فعال کردن زیرنویس"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"غیرفعال کردن زیرنویس"</string>
</resources>
diff --git a/v17/leanback/res/values-fi/strings.xml b/v17/leanback/res/values-fi/strings.xml
index 3193006..9d38d3c 100644
--- a/v17/leanback/res/values-fi/strings.xml
+++ b/v17/leanback/res/values-fi/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Tee haku puhumalla"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Haku: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Puhehaku: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Toista"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Keskeytä"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Kelaa eteenpäin"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Kelaa eteenpäin %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Kelaa taakse"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Kelaa taaksepäin %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Siirry seuraavaan"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Siirry edelliseen"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Lisää toimintoja"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Poista Tykkään-valinta"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Valitse Tykkään"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Poista En tykkää -valinta"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Valitse En tykkää"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Ei uudelleentoistoa"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Toista kaikki uudelleen"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Toista yksi uudelleen"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Ota satunnaistoisto käyttöön"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Poista satunnaistoisto käytöstä"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Ota korkea laatu käyttöön"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Poista korkea laatu käytöstä"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ota tekstitys käyttöön"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Poista tekstitys käytöstä"</string>
</resources>
diff --git a/v17/leanback/res/values-fr-rCA/strings.xml b/v17/leanback/res/values-fr-rCA/strings.xml
index 20595c3..bbd3eea 100644
--- a/v17/leanback/res/values-fr-rCA/strings.xml
+++ b/v17/leanback/res/values-fr-rCA/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Énoncez votre recherche"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Rechercher dans <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Énoncez votre recherche dans <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Lecture"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pause"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Avance rapide"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Avance rapide à %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Reculer"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Retour rapide à %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Passer à l\'élément suivant"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Passer à l\'élément précédent"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Autres actions"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Désélectionner la mention « J\'aime »"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Sélectionner la mention « J\'aime »"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Désélectionner la mention « Je n\'aime pas »"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Sélectionner la mention « Je n\'aime pas »"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Aucune répétition"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Tout lire en boucle"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Répéter un élément"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Activer la lecture aléatoire"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Désactiver la lecture aléatoire"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Activer la lecture haute qualité"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Désactiver la lecture haute qualité"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activer le sous-titrage"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Désactiver le sous-titrage"</string>
</resources>
diff --git a/v17/leanback/res/values-fr/strings.xml b/v17/leanback/res/values-fr/strings.xml
index 9a8d2c7..e9c051c 100644
--- a/v17/leanback/res/values-fr/strings.xml
+++ b/v17/leanback/res/values-fr/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Énoncer la recherche"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Rechercher \"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>\""</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Énoncer la recherche \"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>\""</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Lecture"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Interrompre"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Avance rapide"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Avance rapide de %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Retour arrière"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Retour arrière de %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Ignorer l\'élément suivant"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Ignorer l\'élément précédent"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Autres actions"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Désélectionner \"J\'aime\""</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Sélectionner \"J\'aime\""</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Désélectionner \"Je n\'aime pas\""</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Sélectionner \"Je n\'aime pas\""</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Ne rien lire en boucle"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Tout lire en boucle"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Lire en boucle un élément"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Désactiver la lecture en mode aléatoire"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Désactiver la lecture en mode aléatoire"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Activer la haute qualité"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Désactiver la haute qualité"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activer les sous-titres"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Désactiver les sous-titres"</string>
</resources>
diff --git a/v17/leanback/res/values-gl-rES/strings.xml b/v17/leanback/res/values-gl-rES/strings.xml
index b85dcd1..717b994 100644
--- a/v17/leanback/res/values-gl-rES/strings.xml
+++ b/v17/leanback/res/values-gl-rES/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Fala para efectuar a busca"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Busca <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Fala para buscar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Reproducir"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pausar"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Avance rápido"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Avance rápido %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Rebobinar"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Rebobinado %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Saltar seguinte"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Saltar anterior"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Máis accións"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Anular \"Gústame\""</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Seleccionar polgar cara arriba"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Anular \"Non me gusta\""</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Seleccionar polgar cara abaixo"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Non repetir"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repetir todo"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repetir un"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Activar reprodución aleatoria"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Desactivar reprodución aleatoria"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Activar alta calidade"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Desactivar alta calidade"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activar subtítulos"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desactivar subtítulos"</string>
</resources>
diff --git a/v17/leanback/res/values-gu-rIN/strings.xml b/v17/leanback/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000..2e4f30f
--- /dev/null
+++ b/v17/leanback/res/values-gu-rIN/strings.xml
@@ -0,0 +1,49 @@
+<?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="orb_search_action" msgid="5651268540267663887">"શોધ ક્રિયા"</string>
+ <string name="lb_search_bar_hint" msgid="8325490927970116252">"શોધો"</string>
+ <string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"શોધવા માટે બોલો"</string>
+ <string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> શોધો"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ને શોધવા માટે બોલો"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"ચલાવો"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"થોભો"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"ઝડપી ફોરવર્ડ"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"ફાસ્ટ ફોરવર્ડ કરો %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"રીવાઇન્ડ કરો"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX ને રિવાઇન્ડ કરો"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"આગલા પર જાઓ"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"પહેલાનાને છોડો"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"વધુ ક્રિયાઓ"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"એકદમ સરસ નાપસંદ કરો"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"એકદમ સરસ પસંદ કરો"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"સારું નથી નાપસંદ કરો"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"સારું નથી પસંદ કરો"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"કોઈનું પુનરાવર્તન નહીં"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"બધાનું પુનરાવર્તન કરો"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"એક પુનરાવર્તિત કરો"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"શફલ કરોને સક્ષમ કરો"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"શફલ કરોને અક્ષમ કરો"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"ઉચ્ચ ગુણવત્તા સક્ષમ કરો"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"ઉચ્ચ ગુણવત્તા અક્ષમ કરો"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ઉપશીર્ષક સક્ષમ કરો"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"વિગતવાર ઉપશીર્ષકોને અક્ષમ કરો"</string>
+</resources>
diff --git a/v17/leanback/res/values-hi/strings.xml b/v17/leanback/res/values-hi/strings.xml
index 0d3e72d..a926396 100644
--- a/v17/leanback/res/values-hi/strings.xml
+++ b/v17/leanback/res/values-hi/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"खोजने के लिए बोलें"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> खोजें"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> खोजने के लिए बोलें"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"चलाएं"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"रोकें"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"फ़ास्ट फ़ॉरवर्ड"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"फ़ास्ट फ़ॉरवर्ड %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"रिवाइंड करें"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"रिवाइंड %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"अगले पर जाएं"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"पिछले पर जाएं"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"अधिक विकल्प"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"पसंदीदा को ना चुनें"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"पसंदीदा चुनें"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"नापसंद को ना चुनें"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"नापसंद चुनें"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"कुछ भी न दोहराएं"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"सभी को दोहराएं"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"एक दोहराएं"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"फेर-बदल सक्षम करें"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"फेर-बदल अक्षम करें"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"उच्च गुणवत्ता सक्षम करें"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"उच्च गुणवत्ता अक्षम करें"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"उपशीर्षक सक्षम करें"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"उपशीर्षक अक्षम करें"</string>
</resources>
diff --git a/v17/leanback/res/values-hr/strings.xml b/v17/leanback/res/values-hr/strings.xml
index 89d8053..166369f 100644
--- a/v17/leanback/res/values-hr/strings.xml
+++ b/v17/leanback/res/values-hr/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Izgovorite upit za pretraživanje"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Tražite <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Izgovorite upit za pretraživanje <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Reproduciraj"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pauziraj"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Brzo naprijed"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Brzo unaprijed %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Unatrag"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Unatrag %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Preskoči na sljedeće"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Preskoči na prethodno"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Više radnji"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Poništi odabir palca gore"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Odaberi palac gore"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Poništi odabir palca dolje"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Odaberi palac dolje"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Bez ponavljanja"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Ponovi sve"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Ponovi jedno"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Omogući nasumičnu reprodukciju"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Onemogući nasumičnu reprodukciju"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Omogući visoku kvalitetu"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Onemogući visoku kvalitetu"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Omogući titlove"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Onemogući titlove"</string>
</resources>
diff --git a/v17/leanback/res/values-hu/strings.xml b/v17/leanback/res/values-hu/strings.xml
index e6eaacb..427f1cd 100644
--- a/v17/leanback/res/values-hu/strings.xml
+++ b/v17/leanback/res/values-hu/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Keresés"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Beszéljen a keresés indításához"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Keresés itt: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Mondjon valamit, hogy itt keressen: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Mondj valamit a kereséshez: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Lejátszás"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Szünet"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Gyors előretekerés"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Előretekerés %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Visszatekerés"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Visszatekerés %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Ugrás a következőre"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Ugrás az előzőre"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"További műveletek"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"„Tetszik” értékelés visszavonása"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"„Tetszik” értékelés kiválasztása"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"„Nem tetszik” értékelés visszavonása"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"„Nem tetszik” értékelés kiválasztása"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Nincs ismétlés"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Összes ismétlése"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Egy ismétlése"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Véletlenszerű lejátszás engedélyezése"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Véletlenszerű lejátszás letiltása"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Jó minőségű lejátszás engedélyezése"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Jó minőségű lejátszás letiltása"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Feliratok engedélyezése"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Feliratok letiltása"</string>
</resources>
diff --git a/v17/leanback/res/values-hy-rAM/strings.xml b/v17/leanback/res/values-hy-rAM/strings.xml
index de8561f..7e8112e 100644
--- a/v17/leanback/res/values-hy-rAM/strings.xml
+++ b/v17/leanback/res/values-hy-rAM/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Խոսեք՝ որոնելու համար"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Որոնեք <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Խոսեք՝ <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> որոնելու համար"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Նվագարկել"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Դադարեցնել"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Արագ առաջ անցնել"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Առագ առաջանցում %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Հետ փաթաթել"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Հետանցում %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Անցնել հաջորդին"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Անցնել նախորդին"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Այլ գործողություններ"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Ապանշել Հավանելու կոճակը"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Նշել Հավանելու կոճակը"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Ապանշել Չհավանելու կոճակը"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Նշել Չհավանելու կոճակը"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Չկրկնել"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Կրկնել բոլորը"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Կրկնել մեկը"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Միացնել խառը նվագարկումը"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Անջատել խառը նվագարկումը"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Միացնել բարձր որակը"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Անջատել բարձր որակը"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Միացնել խորագրերը"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Անջատել խորագրերը"</string>
</resources>
diff --git a/v17/leanback/res/values-in/strings.xml b/v17/leanback/res/values-in/strings.xml
index 9be0a01..2dca7d3 100644
--- a/v17/leanback/res/values-in/strings.xml
+++ b/v17/leanback/res/values-in/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Ucapkan untuk menelusuri"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Telusuri <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Ucapkan untuk menelusuri <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Putar"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Jeda"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Maju Cepat"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Maju %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Putar Ulang"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Mundur %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Lewati ke Berikutnya"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Lewati ke Sebelumnya"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Tindakan Lainnya"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Batal Pilih Yang Disukai"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Pilih Yang Disukai"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Batal Pilih Yang Tidak Disukai"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Pilih Yang Tidak Disukai"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Jangan Ulangi"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Ulangi Semua"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Ulangi Satu"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Aktifkan Acak"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Nonaktifkan Acak"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Aktifkan Kualitas Tinggi"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Nonaktifkan Kualitas Tinggi"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktifkan Pembuatan Teks"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Nonaktifkan Pembuatan Teks"</string>
</resources>
diff --git a/v17/leanback/res/values-is-rIS/strings.xml b/v17/leanback/res/values-is-rIS/strings.xml
index 29ccdc1..c84a4c6 100644
--- a/v17/leanback/res/values-is-rIS/strings.xml
+++ b/v17/leanback/res/values-is-rIS/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Talaðu til að leita"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Leita í <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Talaðu til að leita í <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Spila"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Hlé"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Spóla áfram"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Spóla áfram %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Spóla til baka"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Spóla til baka %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Fara í næsta"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Fara í fyrra"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Fleiri aðgerðir"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Hætta við þumal upp"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Gefa þumal upp"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Hætta við þumal niður"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Gefa þumal niður"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Endurtaka ekkert"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Endurtaka allt"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Endurtaka eitt"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Kveikja á stokkun"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Slökkva á stokkun"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Kveikja á miklum gæðum"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Slökkva á miklum gæðum"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Kveikja á skjátextum"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Slökkva á skjátextum"</string>
</resources>
diff --git a/v17/leanback/res/values-it/strings.xml b/v17/leanback/res/values-it/strings.xml
index fa11e9d..1b58e0c 100644
--- a/v17/leanback/res/values-it/strings.xml
+++ b/v17/leanback/res/values-it/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Parla per cercare"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Cerca in <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Parla per cercare in <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Riproduci"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Metti in pausa"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Avanza velocemente"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Avanti veloce: %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Riavvolgi"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Indietro: %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Salta successivo"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Salta precedente"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Altre azioni"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Deseleziona Mi piace"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Seleziona Mi piace"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Deseleziona pollice abbassato"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Seleziona pollice abbassato"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Non ripetere nessuno"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Ripeti tutti"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Ripeti uno"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Attiva riproduzione casuale"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Disattiva riproduzione casuale"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Attiva alta qualità"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Disattiva alta qualità"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Attiva sottotitoli"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Disattiva sottotitoli"</string>
</resources>
diff --git a/v17/leanback/res/values-iw/strings.xml b/v17/leanback/res/values-iw/strings.xml
index dacb052..f102498 100644
--- a/v17/leanback/res/values-iw/strings.xml
+++ b/v17/leanback/res/values-iw/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"דבר כדי לחפש"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"חפש את <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"דבר כדי לחפש את <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"הפעל"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"השהה"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"הרץ קדימה"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"העברה קדימה של %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"הרץ אחורה"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"העברה לאחור של %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"דלג אל הפריט הבא"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"דלג אל הפריט הקודם"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"עוד פעולות"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"בטל בחירה באגודל כלפי מעלה"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"בחר באגודל כלפי מעלה"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"בטל בחירה באגודל כלפי מטה"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"בחר באגודל כלפי מטה"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"אל תחזור על כלום"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"חזור על הכל"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"חזור על פריט אחד"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"הפעל ערבוב"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"השבת ערבוב"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"הפעל איכות גבוהה"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"השבת איכות גבוהה"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"הפעל כתוביות"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"השבת כתוביות"</string>
</resources>
diff --git a/v17/leanback/res/values-ja/strings.xml b/v17/leanback/res/values-ja/strings.xml
index 62b08b5..802631c 100644
--- a/v17/leanback/res/values-ja/strings.xml
+++ b/v17/leanback/res/values-ja/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"音声検索"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>を検索"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>を音声検索"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"再生"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"一時停止"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"早送り"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"早送り%1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"巻き戻し"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"巻き戻し%1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"次の曲にスキップ"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"前の曲にスキップ"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"その他の操作"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"グッドの選択を解除"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"グッドを選択"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"イマイチの選択を解除"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"イマイチを選択"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"繰り返しなし"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"全曲を繰り返し"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"1曲を繰り返し"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"シャッフルを有効にする"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"シャッフルを無効にする"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"高品質を有効にする"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"高品質を無効にする"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"字幕を有効にする"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"字幕を無効にする"</string>
</resources>
diff --git a/v17/leanback/res/values-ka-rGE/strings.xml b/v17/leanback/res/values-ka-rGE/strings.xml
index ab9492c..70aeada 100644
--- a/v17/leanback/res/values-ka-rGE/strings.xml
+++ b/v17/leanback/res/values-ka-rGE/strings.xml
@@ -22,4 +22,32 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"თქვით საძიებო ფრაზა"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>-ის ძიება"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"თქვით <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>-ის საძიებლად"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"დაკვრა"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"პაუზა"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"წინ გადახვევა"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for lb_playback_controls_fast_forward_multiplier (1058753672110224526) -->
+ <skip />
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"უკან გადახვევა"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for lb_playback_controls_rewind_multiplier (1640629531440849942) -->
+ <skip />
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"შემდეგის გამოტოვება"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"წინას გამოტოვება"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"დამატებითი ქმედებები"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"მაღალი შეფასების არჩევის გაუქმება"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"მაღალი შეფასების არჩევა"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"დაბალი შეფასების არჩევის გაუქმება"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"დაბალი შეფასების არჩევა"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"არცერთის გამეორება"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"ყველას გამეორება"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ერთის გამეორება"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"არეულად დაკვრის ჩართვა"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"არეულად დაკვრის გამორთვა"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"მაღალი ხარისხის ჩართვა"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"მაღალი ხარისხის გამორთვა"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"დახურული წარწერების ჩართვა"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"დახურული წარწერების გაუქმება"</string>
</resources>
diff --git a/v17/leanback/res/values-kk-rKZ/strings.xml b/v17/leanback/res/values-kk-rKZ/strings.xml
index 160a8e7..9ed6ce2 100644
--- a/v17/leanback/res/values-kk-rKZ/strings.xml
+++ b/v17/leanback/res/values-kk-rKZ/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Іздеу үшін сөйлеу"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> іздеу"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> іздеу үшін сөйлеңіз"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Ойнату"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Кідірту"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Алға айналдыру"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX алға айналдыру"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Кері айналдыру"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX кері айналдыру"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Келесіге өту"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Алдыңғыға өту"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Қосымша әрекеттер"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Саусақты жоғары қаратудан таңдауды алу"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Саусақты жоғары қаратуды таңдау"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Саусақты төмен қаратудан таңдауды алу"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Саусақты төмен қаратуды таңдау"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Ешқайсысын қайталамау"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Барлығын қайталау"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Біреуін қайталау"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Кездейсоқ ойнатуды қосу"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Кездейсоқ ойнатуды өшіру"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Жоғары сапаны қосу"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Жоғары сапаны өшіру"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Жасырын титрлерді қосу"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Жасырын титрлерді өшіру"</string>
</resources>
diff --git a/v17/leanback/res/values-km-rKH/strings.xml b/v17/leanback/res/values-km-rKH/strings.xml
index 92245b7..7874af2 100644
--- a/v17/leanback/res/values-km-rKH/strings.xml
+++ b/v17/leanback/res/values-km-rKH/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"និយាយដើម្បីស្វែងរក"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"ស្វែងរក <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"និយាយដើម្បីស្វែងរក <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"ចាក់"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"ផ្អាក"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"បញ្ជូនបន្តរហ័ស"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"ខាទៅមុខ %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"ខាថយក្រោយ"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"ខាថយក្រោយ %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"រំលងបន្ទាប់"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"រំលងមុន"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"សកម្មភាពច្រើនទៀត"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"មិនជ្រើសមេដៃឡើងវិញ"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"ជ្រើសមេដៃឡើងលើ"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"មិនជ្រើសមេដៃចុះក្រោម"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"ជ្រើសមេដៃចុះក្រោម"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"មិនធ្វើឡើងវិញ"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"ធ្វើម្ដងទៀតទាំងអស់"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ធ្វើឡើងវិញម្ដង"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"បើកការច្របល់"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"បិទការច្របល់"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"បើកគុណភាពខ្ពស់"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"បិទគុណភាពខ្ពស់"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"បើកការដាក់ចំណងដែលបានបិទ"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"បិទការដាក់ចំណងដែលបានបិទ"</string>
</resources>
diff --git a/v17/leanback/res/values-kn-rIN/strings.xml b/v17/leanback/res/values-kn-rIN/strings.xml
index 6ca527f..196b154 100644
--- a/v17/leanback/res/values-kn-rIN/strings.xml
+++ b/v17/leanback/res/values-kn-rIN/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"ಹುಡುಕಲು ಮಾತನಾಡಿ"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ಹುಡುಕಿ"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ಮಾತನಾಡಿ ಹುಡುಕಾಟ ನಡೆಸಿ"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"ಪ್ಲೇ ಮಾಡು"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"ವಿರಾಮಗೊಳಿಸು"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"ಫಾಸ್ಟ್ ಫಾರ್ವರ್ಡ್"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"ಫಾಸ್ಟ್ ಫಾರ್ವರ್ಡ್ %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"ರೀವೈಂಡ್"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"ರಿವೈಂಡ್ %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"ಮುಂದೆ ಸ್ಕಿಪ್ ಮಾಡಿ"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"ಹಿಂದೆ ಸ್ಕಿಪ್ ಮಾಡಿ"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"ಹೆಚ್ಚು ಕ್ರಿಯೆಗಳು"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"ಥಂಬ್ ಅಪ್ ಆಯ್ಕೆರದ್ದುಮಾಡಿ"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"ಥಂಬ್ ಅಪ್ ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"ಥಂಬ್ ಡೌನ್ ಆಯ್ಕೆರದ್ದುಮಾಡಿ"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"ಥಂಬ್ ಡೌನ್ ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"ಯಾವುದನ್ನೂ ಪುನರಾವರ್ತಿಸಬೇಡಿ"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"ಎಲ್ಲವನ್ನು ಪುನರಾವರ್ತಿಸಿ"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ಒಂದನ್ನು ಪುನರಾವರ್ತಿಸಿ"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"ಜೋಡಿಸುವುದನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"ಜೋಡಿಸುವುದನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"ಹೆಚ್ಚು ಗುಣಮಟ್ಟವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"ಹೆಚ್ಚು ಗುಣಮಟ್ಟವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
</resources>
diff --git a/v17/leanback/res/values-ko/strings.xml b/v17/leanback/res/values-ko/strings.xml
index af0130d..c244dbf 100644
--- a/v17/leanback/res/values-ko/strings.xml
+++ b/v17/leanback/res/values-ko/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"음성 검색"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> 검색"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> 음성 검색"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$d배속"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$d배속"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"재생"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"일시중지"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"빨리 감기"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$d배속 빨리 감기"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"되감기"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$d배속 되감기"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"다음으로 건너뛰기"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"이전으로 건너뛰기"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"추가 작업"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"추천 선택 해제"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"추천 선택"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"비추천 선택 해제"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"비추천 선택"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"반복 안함"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"전체 반복"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"한 항목 반복"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"셔플 사용 설정"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"셔플 사용 중지"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"고화질 사용 설정"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"고화질 사용 중지"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"자막 사용 설정"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"자막 사용 중지"</string>
</resources>
diff --git a/v17/leanback/res/values-ky-rKG/strings.xml b/v17/leanback/res/values-ky-rKG/strings.xml
index 64a2e72..4ddb284 100644
--- a/v17/leanback/res/values-ky-rKG/strings.xml
+++ b/v17/leanback/res/values-ky-rKG/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Издөө үчүн сүйлөңүз"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> издөө"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> издөө үчүн сүйлөңүз"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Ойнотуу"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Тындыруу"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Алдыга түрүү"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Алдыга түрүү %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Артка түрүү"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Артка түрүү %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Кийинкини өткөрүп жиберүү"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Мурункуну өткөрүп жиберүү"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Дагы көнүгүүлөр"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Жактырууну тандоодон чыгаруу"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Жактырууну тандоо"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Жактырбоону тандоодон чыгаруу"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Жактырбоону тандоо"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Эч бирин кайталабоо"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Баарын кайталоо"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Бирөөнү кайталоо"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Аралаштырууну иштетүү"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Аралаштырууну өчүрүү"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Жогорку сапатты иштетүү"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Жогорку сапатты өчүрүү"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Жабык субтитрлерди иштетүү"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Жабык субтитрлерди өчүрүү"</string>
</resources>
diff --git a/v17/leanback/res/values-lo-rLA/strings.xml b/v17/leanback/res/values-lo-rLA/strings.xml
index 107f989..35f519b 100644
--- a/v17/leanback/res/values-lo-rLA/strings.xml
+++ b/v17/leanback/res/values-lo-rLA/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"ເວົ້າເພື່ອຊອກຫາ"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"ຊອກຫາ <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"ເວົ້າເພື່ອຊອກຫາ <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"ຫຼິ້ນ"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"ຢຸດຊົ່ວຄາວ"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"ເລື່ອນໄປໜ້າ"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"ໄປໜ້າແບບໄວ %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"ຣີວາຍກັບ"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"ກັບຄືນ %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"ຂ້າມໄປຕໍ່"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"ຂ້າມໄປກ່ອນໜ້າ"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"ຄຳສັ່ງເພີ່ມເຕີມ"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"ຢຸດເລືອກຍົກໂປ້ແລ້ວ"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"ເລືອກຍົກໂປ້ແລ້ວ"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"ຢຸດຊີ້ໂປ້ລົງແລ້ວ"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"ເລືອກຊີ້ໂປ້ລົງແລ້ວ"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"ບໍ່ຫຼິ້ນຊ້ຳ"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"ຫຼິ້ນຊ້ຳທັງໝົດ"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ຫຼິ້ນຊ້ຳ"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"ເປີດນຳໃຊ້ການສະຫຼັບ"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"ປິດນຳໃຊ້ການສະຫຼັບ"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"ເປີດນຳໃຊ້ການຫຼິ້ນດ້ວຍຄຸນນະພາບສູງ"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"ປິດນຳໃຊ້ການຫຼິ້ນດ້ວຍຄຸນນະພາບສູງ"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ເປີດນຳໃຊ້ຄຳບັນຍາຍແບບປິດ"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ປິດນຳໃຊ້ຄຳບັນຍາຍແບບປິດ"</string>
</resources>
diff --git a/v17/leanback/res/values-lt/strings.xml b/v17/leanback/res/values-lt/strings.xml
index f765d04..6ca2bab 100644
--- a/v17/leanback/res/values-lt/strings.xml
+++ b/v17/leanback/res/values-lt/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Pasakykite, kad ieškotumėte"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Ieškoti „<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>“"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Kalbėkite, kad ieškotumėte „<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>“"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$d k."</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$d k."</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Leisti"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pristabdyti"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Sukti pirmyn"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Sukti pirmyn %1$d k. greičiau"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Sukti atgal"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Sukti atgal %1$d k. greičiau"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Praleisti kitą"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Praleisti ankstesnį"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Daugiau veiksmų"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Panaikinti parinkties „Patinka“ pasirinkimą"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Pasirinkti parinktį „Patinka“"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Panaikinti parinkties „Nepatinka“ pasirinkimą"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Pasirinkti parinktį „Nepatinka“"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Nekartoti nieko"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Kartoti viską"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Kartoti vieną"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Įgalinti maišymą"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Išjungti maišymą"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Įgalinti aukštą kokybę"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Išjungti aukštą kokybę"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Įgalinti subtitrus"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Išjungti subtitrus"</string>
</resources>
diff --git a/v17/leanback/res/values-lv/strings.xml b/v17/leanback/res/values-lv/strings.xml
index 677ae6b..7d3bc2b 100644
--- a/v17/leanback/res/values-lv/strings.xml
+++ b/v17/leanback/res/values-lv/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Meklēt"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Runāt, lai meklētu"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Meklējiet <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Runājiet, lai meklētu <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Runājiet, lai meklētu: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Atskaņot"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pauzēt"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Pārtīt uz priekšu"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Pārtīt uz priekšu %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Attīt atpakaļ"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Attīt atpakaļ %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Izlaist nākamo"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Izlaist iepriekšējo"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Citas darbības"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Atcelt “Patīk” atlasi"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Atlasīt “Patīk”"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Atcelt “Nepatīk” atlasi"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Atlasīt “Nepatīk”"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Neatkārtot nevienu"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Atkārtot visu"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Atkārtot vienu"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Iespējot atskaņošanu jauktā secībā"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Atspējot atskaņošanu jauktā secībā"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Iespējot augstas kvalitātes vienumu atskaņošanu"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Atspējot augstas kvalitātes vienumu atskaņošanu"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Iespējot slēgtos parakstus"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Atspējot slēgtos parakstus"</string>
</resources>
diff --git a/v17/leanback/res/values-mk-rMK/strings.xml b/v17/leanback/res/values-mk-rMK/strings.xml
index 8ab8384..75666e0 100644
--- a/v17/leanback/res/values-mk-rMK/strings.xml
+++ b/v17/leanback/res/values-mk-rMK/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Зборувајте за да пребарувате"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Пребарувај <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Кажете за да се пребарува <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Пушти"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Пауза"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Брзо премотај напред"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Премотај напред %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Премотај назад"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Премотај назад %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Прескокни на следна"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Прескокни на претходна"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Повеќе дејства"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Откажи палец нагоре"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Избери палец нагоре"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Откажи палец надолу"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Избери палец надолу"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Не повторувај ниту една"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Повтори ги сите"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Повтори една"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Овозможи мешање"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Оневозможи мешање"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Овозможи висок квалитет"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Оневозможи висок квалитет"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Овозможи затворено објаснување"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Оневозможи затворено објаснување"</string>
</resources>
diff --git a/v17/leanback/res/values-ml-rIN/strings.xml b/v17/leanback/res/values-ml-rIN/strings.xml
index e31770d..b900f09 100644
--- a/v17/leanback/res/values-ml-rIN/strings.xml
+++ b/v17/leanback/res/values-ml-rIN/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"ശബ്ദം ഉപയോഗിച്ച് തിരയുക"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> തിരയുക"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> തിരയുന്നതിന് സംസാരിക്കുക"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"പ്ലേ ചെയ്യുക"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"താൽക്കാലികമായി നിർത്തുക"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"ഫാസ്റ്റ് ഫോർവേഡ് ചെയ്യുക"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX വേഗത്തിൽ ഫോർവേഡുചെയ്യുക"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"റിവൈൻഡുചെയ്യുക"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX റിവൈൻഡുചെയ്യുക"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"അടുത്തതിലേക്ക് പോകുക"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"മുമ്പത്തേതിലേക്ക് പോകുക"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"കൂടുതൽ പ്രവർത്തനങ്ങൾ"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"തമ്പ് അപ്പ് തിരഞ്ഞെടുത്തത് മാറ്റുക"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"തമ്പ് അപ്പ് തിരഞ്ഞെടുക്കുക"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"തമ്പ് ഡൗൺ തിരഞ്ഞെടുത്തത് മാറ്റുക"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"തമ്പ് ഡൗൺ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"ഒന്നും ആവർത്തിക്കരുത്"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"എല്ലാം ആവർത്തിക്കുക"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ഒന്ന് ആവർത്തിക്കുക"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"ഷഫിൾ ചെയ്യുന്നത് പ്രവർത്തനക്ഷമമാക്കുക"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"ഷഫിൾ ചെയ്യുന്നത് പ്രവർത്തനരഹിതമാക്കുക"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"ഉയർന്ന നിലവാരം പ്രവർത്തനക്ഷമമാക്കുക"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"ഉയർന്ന നിലവാരം പ്രവർത്തനരഹിതമാക്കുക"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"അടച്ച അടിക്കുറിപ്പ് നൽകൽ പ്രവർത്തനക്ഷമമാക്കുക"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"അടച്ച അടിക്കുറിപ്പ് നൽകൽ പ്രവർത്തനരഹിതമാക്കുക"</string>
</resources>
diff --git a/v17/leanback/res/values-mn-rMN/strings.xml b/v17/leanback/res/values-mn-rMN/strings.xml
index a58dfe9..e4a8fcd 100644
--- a/v17/leanback/res/values-mn-rMN/strings.xml
+++ b/v17/leanback/res/values-mn-rMN/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Ярьж хайх"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> Хайх"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> хайхын тулд ярина уу"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Тоглуулах"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Түр зогсоох"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Хурдан урагшлуулах"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Түргэн Урагш Гүйлгэх %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Буцааж хураах"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Хойш Гүйлгэх %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Дараагийнхийг алгасах"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Өмнөхийг алгасах"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Өөр үйлдлүүд"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Дээш эрхий хурууг цуцлах"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Дээш эрхий хурууг сонгох"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Доош эрхий хурууг цуцлах"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Доош эрхий хурууг сонгох"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Алийг нь ч давтахгүй"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Бүгдийг давтах"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Нэгийг давтах"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Холихыг идэвхжүүлэх"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Холихыг идэвхгүйжүүлэх"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Өндөр чанарыг идэвхжүүлэх"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Өндөр чанарыг идэвхгүйжүүлэх"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Текст тайлбарыг идэвхжүүлэх"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Текст тайлбарыг идэвхгүйжүүлэх"</string>
</resources>
diff --git a/v17/leanback/res/values-mr-rIN/strings.xml b/v17/leanback/res/values-mr-rIN/strings.xml
index 296b21c..11748ec 100644
--- a/v17/leanback/res/values-mr-rIN/strings.xml
+++ b/v17/leanback/res/values-mr-rIN/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"शोधण्यासाठी बोला"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> शोधा"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> शोधण्यासाठी बोला"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"प्ले करा"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"विराम द्या"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"फास्ट फॉरवर्ड करा"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"फास्ट फॉरवर्ड %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"रिवाईँड करा"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"रीवाईंड %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"पुढील वगळा"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"मागील वगळा"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"अधिक क्रिया"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"वर अंगठा निवड रद्द करा"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"वर अंगठा निवडा"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"खाली अंगठा निवड रद्द करा"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"खाली अंगठा निवडा"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"काहीही पुनरावृत्ती करू नका"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"सर्व पुनरावृत्ती करा"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"एक पुनरावृत्ती करा"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"शफल करा सक्षम करा"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"शफल करा अक्षम करा"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"उच्च गुणवत्ता सक्षम करा"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"उच्च गुणवत्ता अक्षम करा"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"उपशीर्षके सक्षम करा"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"उपशीर्षके अक्षम करा"</string>
</resources>
diff --git a/v17/leanback/res/values-ms-rMY/strings.xml b/v17/leanback/res/values-ms-rMY/strings.xml
index d915409..c073e43 100644
--- a/v17/leanback/res/values-ms-rMY/strings.xml
+++ b/v17/leanback/res/values-ms-rMY/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Tutur untuk membuat carian"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Cari <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Sebut untuk mencari <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Main"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Jeda"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Mara Laju"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Lajukan %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Gulung semula"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Gulung semula %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Langkau Seterusnya"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Langkau Sebelumnya"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Lagi Tindakan"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Nyahpilih Bagus"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Pilih Bagus"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Nyahpilih Tidak Bagus"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Pilih Tidak Bagus"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Jangan Ulang"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Ulang Semua"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Ulang Satu"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Dayakan Rombak"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Lumpuhkan Rombak"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Dayakan Kualiti Tinggi"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Lumpuhkan Kualiti Tinggi"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Dayakan Kapsyen Tertutup"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Lumpuhkan Kapsyen Tertutup"</string>
</resources>
diff --git a/v17/leanback/res/values-my-rMM/strings.xml b/v17/leanback/res/values-my-rMM/strings.xml
index 76e70f2..2efaf7f 100644
--- a/v17/leanback/res/values-my-rMM/strings.xml
+++ b/v17/leanback/res/values-my-rMM/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"ရှာဖွေရန် ပြောပါ"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>ကို ရှာရန်"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ကို ရှာရန် ပြောပါ"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"ဖွင့်ရန်"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"ခဏရပ်ရန်"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"ရှေ့သို့ သွားရန်"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"ရှေ့သို့ ရစ်ရန် %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"ပြန်ရစ်ရန်"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"နောက်သို့ ရစ်ရန် %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"နောက်တစ်ပုဒ်သို့ ကျော်ရန်"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"ယခင်တစ်ပုဒ်သို့ သွားရန်"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"နောက်ထပ် လုပ်ဆောင်ချက်များ"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"နှစ်ခြိုက်သော သင်္ကေတအား မရွေးရန်"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"နှစ်ခြိုက်သော သင်္ကေတအား ရွေးရန်"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"မနှစ်ခြိုက်သော သင်္ကေတအား မရွေးရန်"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"မနှစ်ခြိုက်သော သင်္ကေတအား ရွေးရန်"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"ထပ်တလဲလဲမဖွင့်ရန်"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"အားလုံး ထပ်တလဲလဲဖွင့်ရန်"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"တစ်ခုအား ထပ်တလဲလဲဖွင့်ရန်"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"ရောသမမွှေခြင်း ပြုရန်"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"ရောသမမေွှခြင်း မပြုရန်"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"အရည်အသွေးကောင်းအား ဖွင့်ရန်"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"အရည်အသွေးကောင်းအား ပိတ်ထားရန်"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"စာတမ်းထိုး ဖွင့်ရန်"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"စာတမ်းထိုးအား ပိတ်ထားရန်"</string>
</resources>
diff --git a/v17/leanback/res/values-nb/strings.xml b/v17/leanback/res/values-nb/strings.xml
index c1fe682..f5ab2e1 100644
--- a/v17/leanback/res/values-nb/strings.xml
+++ b/v17/leanback/res/values-nb/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Snakk for å søke"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Søk i <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Snakk for å søke i <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Spill av"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Sett på pause"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Fremoverspoling"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Fremoverspoling %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Tilbakespoling"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Tilbakespoling %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Hopp til neste"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Hopp til forrige"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Flere handlinger"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Fjern valg av tommel opp"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Velg tommel opp"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Fjern valg av tommel ned"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Velg tommel ned"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Ikke gjenta noen"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Gjenta alle"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Gjenta én"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Aktivér avspilling i tilfeldig rekkefølge"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Deaktiver avspilling i tilfeldig rekkefølge"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Aktivér høy kvalitet"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Deaktiver høy kvalitet"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktivér teksting"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Deaktiver teksting"</string>
</resources>
diff --git a/v17/leanback/res/values-ne-rNP/strings.xml b/v17/leanback/res/values-ne-rNP/strings.xml
index 81ce461..c399985 100644
--- a/v17/leanback/res/values-ne-rNP/strings.xml
+++ b/v17/leanback/res/values-ne-rNP/strings.xml
@@ -22,4 +22,30 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"खोजी गर्न बोल्नुहोस्"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> खोज्नुहोस्"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> खोजी गर्न बोल्नुहोस्"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"प्ले गर्नुहोस्"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"रोक्नुहोस्"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"फास्ट फर्वार्ड"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for lb_playback_controls_fast_forward_multiplier (1058753672110224526) -->
+ <skip />
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"दोहोर्याउनुहोस्"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"पुन: वाइन्ड गर्नुहोस् %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"अर्को छोड्नुहोस्"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"अघिल्लो छोड्नुहोस्"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"थप कार्यहरू"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"औंठा माथि चयन नगर्नुहोस्"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"औंठा माथि चयन गर्नुहोस्"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"औंठा तल चयन नगर्नुहोस्"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"औंठा तल चयन गर्नुहोस्"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"कुनै पनि नदोहोर्याउनुहोस्"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"सबै दोहोर्याउनुहोस्"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"एउटा दोहोर्याउनुहोस्"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"सफ्फल सक्षम"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"सफ्फल असक्षम"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"उच्च गुणस्तर सक्षम"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"उच्च गुणस्तर असक्षम"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"बन्द क्याप्सनहरु सक्षम"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"बन्द क्याप्सनहरु असक्षम"</string>
</resources>
diff --git a/v17/leanback/res/values-nl/strings.xml b/v17/leanback/res/values-nl/strings.xml
index 5c0ba2e..fe73141 100644
--- a/v17/leanback/res/values-nl/strings.xml
+++ b/v17/leanback/res/values-nl/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Spreek om te zoeken"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> zoeken"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Spreek om <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> te zoeken"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Afspelen"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Onderbreken"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Vooruitspoelen"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Vooruitspoelen %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Terugspoelen"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Terugspoelen %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Naar volgende"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Naar vorige"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Meer acties"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Selectie van \'Leuk\' ongedaan maken"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"\'Leuk\' selecteren"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Selectie van \'Niet leuk\' ongedaan maken"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"\'Niet leuk\' selecteren"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Niet herhalen"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Alles herhalen"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Eén herhalen"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Shuffle inschakelen"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Shuffle uitschakelen"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Hoge kwaliteit inschakelen"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Hoge kwaliteit uitschakelen"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ondertiteling inschakelen"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Ondertiteling uitschakelen"</string>
</resources>
diff --git a/v17/leanback/res/values-pa-rIN/strings.xml b/v17/leanback/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000..f9c7c4b
--- /dev/null
+++ b/v17/leanback/res/values-pa-rIN/strings.xml
@@ -0,0 +1,49 @@
+<?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="orb_search_action" msgid="5651268540267663887">"ਖੋਜ ਕਿਰਿਆ"</string>
+ <string name="lb_search_bar_hint" msgid="8325490927970116252">"ਖੋਜੋ"</string>
+ <string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"ਖੋਜਣ ਲਈ ਬੋਲੋ"</string>
+ <string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ਖੋਜੋ"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ਖੋਜਣ ਲਈ ਬੋਲੋ"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"ਪਲੇ ਕਰੋ"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"ਰੋਕੋ"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"ਅੱਗੇ ਭੇਜੋ"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX ਨੂੰ ਅੱਗੇ ਭੇਜੋ"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"ਰੀਵਾਈਂਡ"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX ਨੂੰ ਰੀਵਾਈਂਡ ਕਰੋ"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"ਅਗਲਾ ਨੂੰ ਛੱਡੋ"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"ਪਿਛਲਾ ਨੂੰ ਛੱਡੋ"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"ਹੋਰ ਕਿਰਿਆਵਾਂ"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"ਥੰਬ ਅਪ ਨੂੰ ਅਚੋਣਵਾਂ ਕਰੋ"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"ਥੰਬ ਅਪ ਨੂੰ ਚੁਣੋ"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"ਥੰਬ ਡਾਊਨ ਨੂੰ ਅਚੋਣਵਾਂ ਕਰੋ"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"ਥੰਬ ਡਾਊਨ ਨੂੰ ਚੁਣੋ"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"ਕੋਈ ਵੀ ਨਾ ਦੁਹਰਾਓ"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"ਸਾਰਿਆਂ ਨੂੰ ਦੁਹਰਾਓ"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ਇੱਕ ਦੁਹਰਾਓ"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"ਸ਼ਫਲ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"ਸ਼ਫਲ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"ਉੱਚ ਗੁਣਵੱਤਾ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"ਉੱਚ ਗੁਣਵੱਤਾ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ਬੰਦ ਕੈਪਸ਼ਨਿੰਗ ਸਮਰੱਥ ਬਣਾਓ"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ਬੰਦ ਕੈਪਸ਼ਨਿੰਗ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
+</resources>
diff --git a/v17/leanback/res/values-pl/strings.xml b/v17/leanback/res/values-pl/strings.xml
index 9942bc7..f6280a3 100644
--- a/v17/leanback/res/values-pl/strings.xml
+++ b/v17/leanback/res/values-pl/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Szukaj"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Powiedz, aby wyszukać"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Szukaj <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Powiedz, by wyszukać <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Powiedz, by wyszukać w aplikacji <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Odtwórz"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Wstrzymaj"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Przewiń do przodu"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Przewiń do przodu %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Przewiń do tyłu"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Przewiń do tyłu %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Pomiń następny"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Pomiń poprzedni"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Więcej czynności"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Odznacz Lubię"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Zaznacz Lubię"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Odznacz Nie lubię"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Zaznacz Nie lubię"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Nie powtarzaj"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Powtórz wszystkie"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Powtórz jeden"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Włącz odtwarzanie losowe"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Wyłącz odtwarzanie losowe"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Włącz wysoką jakość"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Wyłącz wysoką jakość"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Włącz napisy"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Wyłącz napisy"</string>
</resources>
diff --git a/v17/leanback/res/values-pt-rPT/strings.xml b/v17/leanback/res/values-pt-rPT/strings.xml
index 0f15262..f3bf4aa 100644
--- a/v17/leanback/res/values-pt-rPT/strings.xml
+++ b/v17/leanback/res/values-pt-rPT/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Fale para pesquisar"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Pesquisar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Fale para pesquisar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Reproduzir"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Interromper"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Avançar"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Avançar %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Recuar"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Recuar %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Avançar para o seguinte"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Avançar para o anterior"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Mais ações"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Desselecionar Gosto"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Selecionar Gosto"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Desselecionar Não gosto"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Selecionar Não gosto"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Não repetir"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repetir tudo"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repetir um"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Ativar reprodução aleatória"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Desativar reprodução aleatória"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Ativar alta qualidade"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Desativar alta qualidade"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ativar legendas"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desativar legendas"</string>
</resources>
diff --git a/v17/leanback/res/values-pt/strings.xml b/v17/leanback/res/values-pt/strings.xml
index 0f15262..13d01a5 100644
--- a/v17/leanback/res/values-pt/strings.xml
+++ b/v17/leanback/res/values-pt/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Fale para pesquisar"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Pesquisar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Fale para pesquisar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Reproduzir"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pausar"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Avançar"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Avançar %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Retroceder"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Retroceder %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Pular próxima"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Pular anterior"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Mais ações"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Desmarcar gostei"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Marcar gostei"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Desmarcar não gostei"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Marcar não gostei"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Não repetir"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repetir tudo"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repetir uma"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Ativar reprodução aleatória"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Desativar reprodução aleatória"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Ativar alta qualidade"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Desativar alta qualidade"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ativar closed captioning"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desativar closed captioning"</string>
</resources>
diff --git a/v17/leanback/res/values-ro/strings.xml b/v17/leanback/res/values-ro/strings.xml
index fd354372..cb6aa4a 100644
--- a/v17/leanback/res/values-ro/strings.xml
+++ b/v17/leanback/res/values-ro/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Căutați"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Rostiți pentru a căuta"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Căutați <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Vorbiți pentru a căuta <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Vorbiți pentru a căuta în <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Redă"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Întrerupe"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Derulează rapid înainte"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Derulați rapid înainte cu %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Derulează"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Derulați înapoi cu %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Ignoră articolul următor"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Ignoră articolul anterior"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Mai multe acţiuni"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Deselectează „Îmi place”"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Selectează „Îmi place”"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Deselectează „Nu-mi place”"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Selectează „Nu-mi place”"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Nu repetă"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Repetă toate"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Repetă unul"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Activează redarea în mod aleatoriu"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Dezactivează redarea în mod aleatoriu"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Activează calitatea înaltă"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Dezactivează calitatea înaltă"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activează subtitrările"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Dezactivează subtitrările"</string>
</resources>
diff --git a/v17/leanback/res/values-ru/strings.xml b/v17/leanback/res/values-ru/strings.xml
index a06ebbc..fb03f9d 100644
--- a/v17/leanback/res/values-ru/strings.xml
+++ b/v17/leanback/res/values-ru/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Поиск"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Произнесите запрос"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Поиск здесь: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Произнесите запрос для поиска здесь: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Произнесите запрос, чтобы найти <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Воспроизвести."</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Приостановить."</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Перемотка вперед."</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Перемотка вперед %1$dX."</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Перемотать назад."</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Перемотка назад %1$dX."</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Перейти к следующему элементу."</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Перейти к предыдущему элементу."</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Другие действия."</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Убрать отметку Нравится."</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Поставить отметку Нравится."</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Убрать отметку Не нравится."</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Поставить отметку Не нравится."</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Не повторять."</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Повторять все."</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Повторять один элемент."</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Включить перемешивание."</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Отключить перемешивание."</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Включить высокое качество."</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Отключить высокое качество."</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Включить субтитры."</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Отключить субтитры."</string>
</resources>
diff --git a/v17/leanback/res/values-si-rLK/strings.xml b/v17/leanback/res/values-si-rLK/strings.xml
index 77742b5..e5c0cf4 100644
--- a/v17/leanback/res/values-si-rLK/strings.xml
+++ b/v17/leanback/res/values-si-rLK/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"සෙවීමට කථා කරන්න"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> සොයන්න"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> සොයන්න කථා කරන්න"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"ධාවනය කරන්න"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"විරාමය"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"වේගයෙන් ඉදිරියට යන"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX වේගයෙන් ඉදිරියට යවන්න"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"නැවත ඔතන්න"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX ආපස්සට යවන්න"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"ඊළඟ එක මග අරින්න"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"කළින් එක මග අරින්න"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"තව ක්රියාකාරකම්"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"මහපටැඟිල්ල ඉහළට තිබීම තේරීම නොකරන්න"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"මහපටැඟිල්ල ඉහළට තිබීම තේරීම කරන්න"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"මහපටැඟිල්ල පහළට තිබීම තේරීම නොකරන්න"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"මහපටැඟිල්ල පහළට තිබීම තේරීම කරන්න"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"නැවත කරන්න කිසිවක් නැත"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"සියල්ල නැවත කරන්න"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"එකක් නැවත කරන්න"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"ඇනීම සබල කරන්න"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"ඇනීම අබල කරන්න"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"උපරිම ගුණත්වය සබල කරන ලදි"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"උපරිම ගුණත්වය අබල කරන ලදි"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"වැසුණු ශිර්ෂ කිරීම සබල කරන ලදි"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"වැසුණු ශිර්ෂ කිරීම අබල කරන ලදි"</string>
</resources>
diff --git a/v17/leanback/res/values-sk/strings.xml b/v17/leanback/res/values-sk/strings.xml
index 8af51d8..74a9044 100644
--- a/v17/leanback/res/values-sk/strings.xml
+++ b/v17/leanback/res/values-sk/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Hľadať"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Hovorením spustíte vyhľadávanie"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Vyhľadať výraz <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Vyslovením výrazu <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> spustíte jeho vyhľad."</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Hovorte na vyhľadávanie v kontexte <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Prehrať"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pozastaviť"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Pretočiť dopredu"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Pretočiť dopredu %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Pretočiť späť"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Pretočiť späť %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Prejsť na ďalšiu položku"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Prejsť na predchádzajúcu položku"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Viac akcií"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Zrušiť Páči sa mi"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Vybrať Páči sa mi"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Zrušiť Nepáči sa mi"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Vybrať Nepáči sa mi"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Neopakovať"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Opakovať všetko"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Opakovať jednu položku"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Zapnúť náhodné prehrávanie"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Vypnúť náhodné prehrávanie"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Povoliť médiá vo vysokej kvalite"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Zakázať médiá vo vysokej kvalite"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Zapnúť skryté titulky"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Vypnúť skryté titulky"</string>
</resources>
diff --git a/v17/leanback/res/values-sl/strings.xml b/v17/leanback/res/values-sl/strings.xml
index d367572..1af639b 100644
--- a/v17/leanback/res/values-sl/strings.xml
+++ b/v17/leanback/res/values-sl/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Izgovorite, če želite iskati"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Iskanje: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Govorite, če želite iskati: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$d-kratno"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$d-kratno"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Predvajaj"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Zaustavi"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Previj naprej"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Hitro previjanje naprej – %1$d-kratno"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Previj nazaj"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Previjanje nazaj – %1$d-kratno"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Preskoči naslednje"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Preskoči prejšnje"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Več dejanj"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Prekliči izbor palca gor"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Izberi palec gor"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Prekliči izbor palca dol"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Izberi palec dol"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Ne ponovi"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Ponovi vse"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Ponovi eno"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Omogoči naključno predvajanje"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Onemogoči naključno predvajanje"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Omogoči visoko kakovost"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Onemogoči visoko kakovost"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Omogoči podnapise"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Onemogoči podnapise"</string>
</resources>
diff --git a/v17/leanback/res/values-sq-rAL/strings.xml b/v17/leanback/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000..28c313f
--- /dev/null
+++ b/v17/leanback/res/values-sq-rAL/strings.xml
@@ -0,0 +1,49 @@
+<?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="orb_search_action" msgid="5651268540267663887">"Veprim i kërkimit"</string>
+ <string name="lb_search_bar_hint" msgid="8325490927970116252">"Kërko"</string>
+ <string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Fol për të kërkuar"</string>
+ <string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Kërko për <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Fol për të kërkuar <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Luaj"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pauzë"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Përparo me shpejtësi"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Përparo me shpejtësi %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Kthe në fillim"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Kthe në fillim %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Kapërce për te tjetra"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Kapërce të mëparshmin"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Veprime të tjera"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Hiq nga përzgjedhja \"Gishti lart\""</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Përzgjidh \"Gishtin sipër\""</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Hiq nga përzgjedhja \"Gishti poshtë\""</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Përzgjidh \"Gishtin poshtë\""</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Mos përsërit asnjë"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Përsërit të gjitha"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Përsërit një"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Aktivizo përzierjen"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Çaktivizo përzierjen"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Aktivizo \"Cilësinë e lartë\""</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Çaktivizo \"Cilësinë e lartë\""</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktivizo titrat"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Çaktivizo titrat me sekuencë kohore"</string>
+</resources>
diff --git a/v17/leanback/res/values-sr/strings.xml b/v17/leanback/res/values-sr/strings.xml
index 771067c..bb5c32d 100644
--- a/v17/leanback/res/values-sr/strings.xml
+++ b/v17/leanback/res/values-sr/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Говорите да бисте претраживали"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Претражите <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Изговорите да бисте претражили <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Пусти"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Паузирај"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Премотај унапред"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Премотај унапред %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Премотај уназад"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Премотај уназад %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Прескочи следећу"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Прескочи претходну"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Још радњи"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Опозови избор палца нагоре"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Изабери палац нагоре"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Опозови избор палца надоле"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Изабери палац надоле"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Не понављај ниједну"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Понови све"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Понови једну"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Омогући насумичну репродукцију"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Онемогући насумичну репродукцију"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Омогући висок квалитет"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Онемогући висок квалитет"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Омогући титлове"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Онемогући титлове"</string>
</resources>
diff --git a/v17/leanback/res/values-sv/strings.xml b/v17/leanback/res/values-sv/strings.xml
index 8b64837..1a8e757 100644
--- a/v17/leanback/res/values-sv/strings.xml
+++ b/v17/leanback/res/values-sv/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Säg det du söker efter"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Sök i <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Tala för att söka i <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Spela upp"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Pausa"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Snabbspola framåt"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Spola framåt %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Spola tillbaka"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Spola tillbaka %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Hoppa till nästa"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Hoppa till föregående"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Fler åtgärder"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Avmarkera tummen upp"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Markera tummen upp"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Avmarkera tummen ned"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Markera tummen ned"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Upprepa inga"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Upprepa alla"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Upprepa en"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Blanda spår"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Blanda inte spår"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Aktivera hög kvalitet"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Inaktivera hög kvalitet"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktivera textning"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Inaktivera textning"</string>
</resources>
diff --git a/v17/leanback/res/values-sw/strings.xml b/v17/leanback/res/values-sw/strings.xml
index 23d2641..17c7480 100644
--- a/v17/leanback/res/values-sw/strings.xml
+++ b/v17/leanback/res/values-sw/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Tamka ili utafute"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Tafuta <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Tamka ili utafute <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Google Play"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Sitisha"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Peleka mbele Haraka"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Peleka Mbele %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Rudisha nyuma"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Peleka nyuma %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Ruka Inayofuata"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Ruka Iliyotangulia"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Vitendo zaidi"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Ondoa Uteuzi wa Bomba"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Teua Bomba"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Ondoa Uteuzi wa Si Bomba"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Teua Si Bomba"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Usirudie Yoyote"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Rudia zote"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Rudia Moja"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Washa Kuchanganya"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Zima Kuchanganya"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Washa Ubora wa Juu"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Zima Ubora wa Juu"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Washa manukuu"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Zima manukuu"</string>
</resources>
diff --git a/v17/leanback/res/values-ta-rIN/strings.xml b/v17/leanback/res/values-ta-rIN/strings.xml
index 9533839..9472522 100644
--- a/v17/leanback/res/values-ta-rIN/strings.xml
+++ b/v17/leanback/res/values-ta-rIN/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"தேட, பேசவும்"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ஐத் தேடுக"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> ஐத் தேட, பேசவும்"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"இயக்கு"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"இடைநிறுத்து"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"வேகமாக முன் நகர்த்து"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX வேகத்தில் முன்செல்"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"வேகமாக பின் நகர்த்து"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX வேகத்தில் பின்செல்"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"அடுத்ததைத் தவிர்"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"முந்தையதைத் தவிர்"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"மேலும் செயல்கள்"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"தரமேற்றத்தைத் திரும்பப் பெறு"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"தரமேற்றத்தைத் தேர்ந்தெடு"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"தரமிறக்கத்தைத் திரும்பப் பெறு"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"தரமிறக்கத்தைத் தேர்ந்தெடு"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"எதையும் மீண்டும் இயக்காதே"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"அனைத்தையும் மீண்டும் இயக்கு"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ஒன்றை மட்டும் மீண்டும் இயக்கு"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"கலைத்து இயக்கு"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"கலைக்காமல் இயக்கு"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"உயர் தரத்தை இயக்கு"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"உயர் தரத்தை முடக்கு"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"விரிவான வசனங்களை இயக்கு"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"விரிவான வசனங்களை முடக்கு"</string>
</resources>
diff --git a/v17/leanback/res/values-te-rIN/strings.xml b/v17/leanback/res/values-te-rIN/strings.xml
index 2715f97..f71e8cb 100644
--- a/v17/leanback/res/values-te-rIN/strings.xml
+++ b/v17/leanback/res/values-te-rIN/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"శోధించడానికి చదివి వినిపించండి"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>ని శోధించండి"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>ని శోధించడానికి చదివి వినిపించండి"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"ప్లే చేయి"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"పాజ్ చేయి"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"వేగంగా ఫార్వార్డ్ చేయి"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX ఫాస్ట్ ఫార్వార్డ్ చేయి"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"రివైండ్ చేయి"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX రివైండ్ చేయి"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"తదుపరి దానికి దాటవేయి"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"మునుపటి దానికి దాటవేయి"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"మరిన్ని చర్యలు"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"విజయ సంకేతం ఎంపికను తీసివేయి"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"విజయ సంకేతాన్ని ఎంచుకోండి"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"ఓటమి సంకేతం ఎంపికను తీసివేయి"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"ఓటమి సంకేతాన్ని ఎంచుకోండి"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"ఏదీ పునరావృతం చేయవద్దు"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"అన్నీ పునరావృతం చేయి"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ఒకదాన్ని పునరావృతం చేయి"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"షఫుల్ను ప్రారంభించు"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"షఫుల్ను నిలిపివేయి"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"అధిక నాణ్యతను ప్రారంభించు"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"అధిక నాణ్యతను నిలిపివేయి"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"సంవృత శీర్షికలను ప్రారంభించు"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"సంవృత శీర్షికలను నిలిపివేయి"</string>
</resources>
diff --git a/v17/leanback/res/values-th/strings.xml b/v17/leanback/res/values-th/strings.xml
index 09922aa..581bac0 100644
--- a/v17/leanback/res/values-th/strings.xml
+++ b/v17/leanback/res/values-th/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"พูดเพื่อค้นหา"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"ค้นหา <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"พูดเพื่อค้นหา <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"เล่น"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"หยุดชั่วคราว"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"กรอไปข้างหน้า"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"กรอไปข้างหน้า %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"กรอกลับ"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"กรอกลับ %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"ข้ามไปรายการถัดไป"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"ข้ามไปรายการก่อนหน้า"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"การทำงานเพิ่มเติม"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"ยกเลิกการเลือกว่าชอบ"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"เลือกว่าชอบ"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"ยกเลิกการเลือกว่าไม่ชอบ"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"เลือกว่าไม่ชอบ"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"ไม่เล่นซ้ำ"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"เล่นซ้ำทั้งหมด"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"เล่นซ้ำรายการเดียว"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"เปิดใช้การสุ่มเพลง"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"ปิดใช้การสุ่มเพลง"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"เปิดใช้คุณภาพสูง"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"ปิดใช้คุณภาพสูง"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"เปิดใช้คำบรรยาย"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ปิดใช้คำบรรยาย"</string>
</resources>
diff --git a/v17/leanback/res/values-tl/strings.xml b/v17/leanback/res/values-tl/strings.xml
index 43eaad2..c4e15ec 100644
--- a/v17/leanback/res/values-tl/strings.xml
+++ b/v17/leanback/res/values-tl/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Magsalita upang maghanap"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Hanapin ang <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Magsalita upang hanapin ang <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"I-play"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"I-pause"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"I-fast Forward"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"I-fast Forward %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"I-rewind"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"I-rewind %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Laktawan ang Susunod"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Laktawan ang Nakaraan"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Higit Pang Mga Pagkilos"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Alisin sa Pagkakapili ang Thumb Up"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Piliin ang Thumb Up"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Alisin sa Pagkakapili ang Thumb Down"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Piliin ang Thumb Down"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Walang Uulitin"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Ulitin Lahat"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Ulitin ang Isa"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"I-enable ang Shuffle"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"I-disable ang Shuffle"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"I-enable ang Mataas na Kalidad"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"I-disable ang Mataas na Kalidad"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"I-enable ang Paglalagay ng Subtitle"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"I-disable ang Paglalagay ng Subtitle"</string>
</resources>
diff --git a/v17/leanback/res/values-tr/strings.xml b/v17/leanback/res/values-tr/strings.xml
index cfa5167..4671058 100644
--- a/v17/leanback/res/values-tr/strings.xml
+++ b/v17/leanback/res/values-tr/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Arama yapmak için konuşun"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Ara: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Aramak için konuşun: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Oynat"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Duraklat"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"İleri Sar"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX İleri Sar"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Geri Sar"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX Geri Sar"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Sonrakine Atla"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Öncekine Atla"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Diğer İşlemler"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Beğenme Seçimini Kaldır"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Beğenmeyi Seç"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Beğenmeme Seçimini Kaldır"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Beğenmemeyi Seç"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Hiçbirini Tekrarlama"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Tümünü Tekrarla"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Birini Tekrarla"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Karıştırmayı Etkinleştir"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Karıştırmayı Devre Dışı Bırak"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Yüksek Kalitede Oynatmayı Etkinleştir"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Yüksek Kalitede Oynatmayı Devre Dışı Bırak"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Altyazıları Etkinleştir"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Altyazıları Devre Dışı Bırak"</string>
</resources>
diff --git a/v17/leanback/res/values-uk/strings.xml b/v17/leanback/res/values-uk/strings.xml
index c67bc8b..79b2782 100644
--- a/v17/leanback/res/values-uk/strings.xml
+++ b/v17/leanback/res/values-uk/strings.xml
@@ -21,5 +21,29 @@
<string name="lb_search_bar_hint" msgid="8325490927970116252">"Пошук"</string>
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Продиктуйте пошуковий запит"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Шукати: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
- <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Продиктуйте, щоб шукати: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Продиктуйте запит для пошуку: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Відтворити"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Призупинити"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Перемотати вперед"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Перемотати вперед %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Перемотати назад"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Перемотати назад %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Пропустити наступний елемент"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Пропустити попередній елемент"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Інші дії"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Скасувати оцінку \"Подобається\""</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Вибрати оцінку \"Подобається\""</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Скасувати оцінку \"Не подобається\""</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Вибрати оцінку \"Не подобається\""</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Не повторювати"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Повторити все"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Повторити один елемент"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Увімкнути перемішування"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Вимкнути перемішування"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Увімкнути високу якість"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Вимкнути високу якість"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Увімкнути субтитри"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Вимкнути субтитри"</string>
</resources>
diff --git a/v17/leanback/res/values-ur-rPK/strings.xml b/v17/leanback/res/values-ur-rPK/strings.xml
index bcc9fde..b670251 100644
--- a/v17/leanback/res/values-ur-rPK/strings.xml
+++ b/v17/leanback/res/values-ur-rPK/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"تلاش کرنے کیلئے بولیں"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> تلاش کریں"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g> تلاش کرنے کیلئے بولیں"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"چلائیں"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"موقوف کریں"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"تیزی سے فارورڈ کریں"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"تیزی سے فارورڈ کریں %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"ریوائینڈ کریں"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"ریوائنڈ کریں %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"اگلے پر جائیں"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"پچھلے پر جائیں"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"مزید کارروائیاں"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"اوپر کی طرف والے انگوٹھے کے نشان کو غیر منتخب کریں"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"اوپر کی طرف والے انگوٹھے کے نشان کو منتخب کریں"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"نیچے کی طرف والے انگوٹھے کے نشان کو غیر منتخب کریں"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"نیچے کی طرف والے انگوٹھے کے نشان کو منتخب کریں"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"کسی کو نہ دہرائیں"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"سبھی کو دہرائیں"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ایک کو دہرائیں"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"شفل کو فعال کریں"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"شفل کو غیر فعال کریں"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"اعلی معیار کو فعال کریں"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"اعلی معیار کو غیر فعال کریں"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"سب ٹائٹلز کو فعال کریں"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"سب ٹائٹلز کو غیر فعال کریں"</string>
</resources>
diff --git a/v17/leanback/res/values-uz-rUZ/strings.xml b/v17/leanback/res/values-uz-rUZ/strings.xml
index 95ae803..235d88f 100644
--- a/v17/leanback/res/values-uz-rUZ/strings.xml
+++ b/v17/leanback/res/values-uz-rUZ/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Qidirish uchun gapiring"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Qidirish: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Qidirish uchun ayting: <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Ijro qilish"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"To‘xtatib turish"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Oldinga o‘tkazish"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX tezlikda oldinga o‘tkazish"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Orqaga qaytarish"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX tezlikda orqaga qaytarish"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Keyingisiga o‘tish"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Avvalgisiga qaytish"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Boshqa amallar"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Ijobiy baho tanlovini bekor qilish"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Ijobiy bahoni tanlash"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Salbiy baho tanlovini bekor qilish"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Salbiy bahoni tanlash"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Takrorlamaslik"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Barchasini takrorlash"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Bir marta takrorlash"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Aralashtirish funksiyasini yoqish"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Aralashtirish funksiyasini o‘chirish"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Yuqori sifatni yoqish"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Yuqori sifatni o‘chirib qo‘yish"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Taglavhalarni yoqish"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Taglavhalarni o‘chirib qo‘yish"</string>
</resources>
diff --git a/v17/leanback/res/values-vi/strings.xml b/v17/leanback/res/values-vi/strings.xml
index 2da6873..201d137 100644
--- a/v17/leanback/res/values-vi/strings.xml
+++ b/v17/leanback/res/values-vi/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Nói để tìm kiếm"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Tìm kiếm <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Nói để tìm kiếm <xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Phát"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Tạm dừng"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Tua nhanh"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Tua đi %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Tua lại"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Tua lại %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Chuyển đến mục tiếp theo"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Chuyển về mục trước"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Tác vụ khác"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Bỏ chọn thích"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Chọn thích"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Bỏ chọn không thích"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Chọn không thích"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Không lặp lại"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Lặp lại tất cả"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Lặp lại một mục"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Bật phát ngẫu nhiên"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Tắt phát ngẫu nhiên"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Bật chế độ chất lượng cao"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Tắt chế độ chất lượng cao"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Bật phụ đề"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Tắt phụ đề"</string>
</resources>
diff --git a/v17/leanback/res/values-zh-rCN/strings.xml b/v17/leanback/res/values-zh-rCN/strings.xml
index 7f91918..276e7bb 100644
--- a/v17/leanback/res/values-zh-rCN/strings.xml
+++ b/v17/leanback/res/values-zh-rCN/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"说话即可开始搜索"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"搜索<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"说话即可在<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>中搜索"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$d 倍速"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$d 倍速"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"播放"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"暂停"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"快进"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$d 倍速快进"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"快退"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$d 倍速快退"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"跳至下一个"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"跳至上一个"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"更多操作"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"取消选择顶操作"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"选择顶操作"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"取消选择踩操作"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"选择踩操作"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"不重复播放"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"重复播放全部"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"重复播放一项"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"开启随机播放"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"关闭随机播放"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"开启高画质模式"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"关闭高画质模式"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"开启字幕"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"关闭字幕"</string>
</resources>
diff --git a/v17/leanback/res/values-zh-rHK/strings.xml b/v17/leanback/res/values-zh-rHK/strings.xml
index 6e32bf5..5e87989 100644
--- a/v17/leanback/res/values-zh-rHK/strings.xml
+++ b/v17/leanback/res/values-zh-rHK/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"使用語音搜尋"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"搜尋「<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>」"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"使用語音搜尋「<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>」"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"播放"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"暫停"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"向前快轉"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"快轉 %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"向後倒轉"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"倒帶 %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"移至下一個媒體項目"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"移至上一個媒體項目"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"更多動作"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"取消選取喜歡"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"選取喜歡"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"取消選取不喜歡"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"選取不喜歡"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"不重複播放"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"重複播放所有媒體項目"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"重複播放一個媒體項目"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"啟用隨機播放"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"停用隨機播放"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"啟用高畫質"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"停用高畫質"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"啟用字幕"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"停用字幕"</string>
</resources>
diff --git a/v17/leanback/res/values-zh-rTW/strings.xml b/v17/leanback/res/values-zh-rTW/strings.xml
index 6e32bf5..67efc40 100644
--- a/v17/leanback/res/values-zh-rTW/strings.xml
+++ b/v17/leanback/res/values-zh-rTW/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"使用語音搜尋"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"搜尋「<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>」"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"使用語音搜尋「<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>」"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"播放"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"暫停"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"向前快轉"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"快轉 %1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"倒轉"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"倒轉 %1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"跳至下一個項目"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"跳至上一個項目"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"更多動作"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"取消選取喜歡"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"選取喜歡"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"取消選取不喜歡"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"選取不喜歡"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"不重複播放"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"重複播放所有項目"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"重複播放單一項目"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"啟用隨機播放"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"停用隨機播放"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"啟用高品質播放"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"停用高品質播放"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"啟用字幕"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"停用字幕"</string>
</resources>
diff --git a/v17/leanback/res/values-zu/strings.xml b/v17/leanback/res/values-zu/strings.xml
index 4168b19..f17455d 100644
--- a/v17/leanback/res/values-zu/strings.xml
+++ b/v17/leanback/res/values-zu/strings.xml
@@ -22,4 +22,28 @@
<string name="lb_search_bar_hint_speech" msgid="5511270823320183816">"Khuluma ukuze useshe"</string>
<string name="lb_search_bar_hint_with_title" msgid="1627103380996590035">"Sesha i-<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
<string name="lb_search_bar_hint_with_title_speech" msgid="2712734639766312034">"Khuluma ukuze useshe i-<xliff:g id="SEARCH_CONTEXT">%1$s</xliff:g>"</string>
+ <string name="lb_control_display_fast_forward_multiplier" msgid="4541442045214207774">"%1$dX"</string>
+ <string name="lb_control_display_rewind_multiplier" msgid="3097220783222910245">"%1$dX"</string>
+ <string name="lb_playback_controls_play" msgid="731953341987346903">"Dlala"</string>
+ <string name="lb_playback_controls_pause" msgid="6189521112079849518">"Misa isikhashana"</string>
+ <string name="lb_playback_controls_fast_forward" msgid="8569951318244687220">"Iya phambili ngokushesha"</string>
+ <string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"Mikisa phambili ngokushesha i-%1$dX"</string>
+ <string name="lb_playback_controls_rewind" msgid="2227196334132350684">"Buyisela emuva"</string>
+ <string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"Mikisa emuva i-%1$dX"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"Yeqa okulandelayo"</string>
+ <string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"Yeqa kwangaphambilini"</string>
+ <string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"Izenzo eziningi"</string>
+ <string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"Susa ukukhetha isithupha saphezulu"</string>
+ <string name="lb_playback_controls_thumb_up_outline" msgid="1577637924003500946">"Khetha isithupha saphezulu"</string>
+ <string name="lb_playback_controls_thumb_down" msgid="4498041193172964797">"Susa ukukhetha isithupha saphansi"</string>
+ <string name="lb_playback_controls_thumb_down_outline" msgid="2936020280629424365">"Khetha isithupha saphansi"</string>
+ <string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"Ungaphindi lutho"</string>
+ <string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"Phinda konke"</string>
+ <string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"Phida okukodwa"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"Nika amandla ukushova"</string>
+ <string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"Khubaza ukushova"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"Nika amandla ikhwalithi ephezulu"</string>
+ <string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"Khubaza ikhwalithi ephezulu"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Nika amandla imibhalo engezansi"</string>
+ <string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Khubaza imihbalo engezansi"</string>
</resources>
diff --git a/v17/leanback/res/values/attrs.xml b/v17/leanback/res/values/attrs.xml
index 1b77694..656e38e 100644
--- a/v17/leanback/res/values/attrs.xml
+++ b/v17/leanback/res/values/attrs.xml
@@ -431,5 +431,27 @@
</declare-styleable>
+ <attr name="cardGravity">
+ <!-- Push child views to the left of the container. -->
+ <flag name="left" value="0x03" />
+ <!-- Push child views to the right of the container. -->
+ <flag name="right" value="0x05" />
+ <!-- Push child views to the beginning of the container. -->
+ <flag name="start" value="0x00800003" />
+ <!-- Push child views to the end of the container. -->
+ <flag name="end" value="0x00800005" />
+ </attr>
+
+ <declare-styleable name="StackedLayout">
+ <!-- Defines the width of child views in this layout -->
+ <attr name="cardWidth" format="dimension" />
+ <!-- Defines the distance to shift child views away from the edge when another child
+ is added -->
+ <attr name="stackShift" format="dimension" />
+ <!-- Defines the amount to increment the elevation of each added child -->
+ <attr name="elevationIncrement" format="dimension" />
+ <!-- Defines which edge child views are laid out on -->
+ <attr name="cardGravity" />
+ </declare-styleable>
</resources>
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BackgroundManager.java b/v17/leanback/src/android/support/v17/leanback/app/BackgroundManager.java
index 4eec366..1b10741 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BackgroundManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BackgroundManager.java
@@ -15,6 +15,7 @@
import java.lang.ref.WeakReference;
+import android.support.annotation.ColorInt;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
@@ -964,7 +965,7 @@
* Sets the background to the given color. The timing for when this becomes
* visible in the app is undefined and may take place after a small delay.
*/
- public void setColor(int color) {
+ public void setColor(@ColorInt int color) {
if (DEBUG) Log.v(TAG, "setColor " + Integer.toHexString(color));
mBackgroundColor = color;
@@ -1116,6 +1117,7 @@
/**
* Returns the current background color.
*/
+ @ColorInt
public final int getColor() {
return mBackgroundColor;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
index 4860018..5f8cd51 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
@@ -13,6 +13,7 @@
*/
package android.support.v17.leanback.app;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.support.v17.leanback.transition.LeanbackTransitionHelper;
import android.support.v17.leanback.transition.TransitionHelper;
@@ -276,7 +277,7 @@
*
* @param color The color to use as the brand color of the fragment.
*/
- public void setBrandColor(int color) {
+ public void setBrandColor(@ColorInt int color) {
mBrandColor = color;
mBrandColorSet = true;
@@ -289,6 +290,7 @@
* Returns the brand color for the browse fragment.
* The default is transparent.
*/
+ @ColorInt
public int getBrandColor() {
return mBrandColor;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
index bfa83e8..a98e1ea 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
@@ -15,6 +15,7 @@
*/
package android.support.v17.leanback.app;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.support.v17.leanback.transition.LeanbackTransitionHelper;
import android.support.v17.leanback.transition.TransitionHelper;
@@ -278,7 +279,7 @@
*
* @param color The color to use as the brand color of the fragment.
*/
- public void setBrandColor(int color) {
+ public void setBrandColor(@ColorInt int color) {
mBrandColor = color;
mBrandColorSet = true;
@@ -291,6 +292,7 @@
* Returns the brand color for the browse fragment.
* The default is transparent.
*/
+ @ColorInt
public int getBrandColor() {
return mBrandColor;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
index d02ef97..6b6cc2e 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
@@ -13,6 +13,7 @@
*/
package android.support.v17.leanback.app;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.BrowseFrameLayout;
import android.support.v17.leanback.widget.OnChildLaidOutListener;
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
index 73d299c..0770761 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
@@ -15,6 +15,7 @@
*/
package android.support.v17.leanback.app;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.BrowseFrameLayout;
import android.support.v17.leanback.widget.OnChildLaidOutListener;
diff --git a/v17/leanback/src/android/support/v17/leanback/view/StackedLayout.java b/v17/leanback/src/android/support/v17/leanback/view/StackedLayout.java
new file mode 100644
index 0000000..56c4bad
--- /dev/null
+++ b/v17/leanback/src/android/support/v17/leanback/view/StackedLayout.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2015 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.v17.leanback.view;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.support.v17.leanback.R;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.view.ViewCompat;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A ViewGroup which arranges its children in an overlapping stack with the most
+ * recently added view displayed at the top. Adding and removing views is animated.
+ *
+ * @attr ref R.styleable#StackedLayout_cardWidth
+ * @attr ref R.styleable#StackedLayout_stackShift
+ * @attr ref R.styleable#StackedLayout_elevationIncrement
+ * @attr ref R.styleable#StackedLayout_cardGravity
+ *
+ * @hide
+ */
+public class StackedLayout extends ViewGroup {
+
+ private int mCardWidth;
+ private int mStackShift;
+ private float mElevationIncrement;
+ private int mCardGravity;
+
+ private int mAddedViews = 0;
+ private int mRemovedViews = 0;
+ private List<View> mQueuedRemovedViews;
+ private Animator mCurrentAnimator;
+
+ private OnHierarchyChangeListener mHierarchyChangeListener;
+ private final OnHierarchyChangeListener mHierarchyChangeListenerInternal =
+ new OnHierarchyChangeInternalListener();
+
+ public StackedLayout(Context context) {
+ this(context, null);
+ }
+
+ public StackedLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public StackedLayout(Context context, AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.StackedLayout, defStyleAttr, 0);
+ mCardWidth = Math.round(a.getDimension(R.styleable.StackedLayout_cardWidth, 0));
+ mStackShift = Math.round(a.getDimension(R.styleable.StackedLayout_stackShift, 0));
+ mElevationIncrement = a.getDimension(R.styleable.StackedLayout_elevationIncrement, 0);
+ mCardGravity = a.getInt(R.styleable.StackedLayout_cardGravity, GravityCompat.END);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ super.setOnHierarchyChangeListener(mHierarchyChangeListenerInternal);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ super.setOnHierarchyChangeListener(null);
+ }
+
+ @Override
+ public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) {
+ mHierarchyChangeListener = listener;
+ }
+
+ @Override
+ protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+ final int childCount = getChildCount();
+ if (childCount == 0) {
+ return false;
+ }
+ final View lastChild = getChildAt(childCount - 1);
+ return lastChild.requestFocus(direction, previouslyFocusedRect);
+ }
+
+ @Override
+ public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+ // We only want to be able to focus the [child views of] the last child
+ if (getChildCount() == 0) {
+ return;
+ }
+
+ final View lastChild = getChildAt(getChildCount() - 1);
+ lastChild.addFocusables(views, direction, focusableMode);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+ final int width;
+ final int height;
+
+ switch (widthMode) {
+ case MeasureSpec.EXACTLY:
+ case MeasureSpec.AT_MOST:
+ width = widthSize;
+ break;
+ case MeasureSpec.UNSPECIFIED:
+ default:
+ width = ViewCompat.getMinimumWidth(this);
+ break;
+ }
+
+ switch (heightMode) {
+ case MeasureSpec.EXACTLY:
+ case MeasureSpec.AT_MOST:
+ height = heightSize;
+ break;
+ case MeasureSpec.UNSPECIFIED:
+ default:
+ height = ViewCompat.getMinimumHeight(this);
+ break;
+ }
+
+ setMeasuredDimension(width, height);
+
+ final int childWidthMeasureSpec =
+ MeasureSpec.makeMeasureSpec(mCardWidth, MeasureSpec.EXACTLY);
+ final int childHeightMeasureSpec =
+ MeasureSpec.makeMeasureSpec(height - getPaddingTop() - getPaddingBottom(),
+ MeasureSpec.AT_MOST);
+
+ measureChildren(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams;
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return new LayoutParams(p);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final boolean rightEdge =
+ (GravityCompat.getAbsoluteGravity(mCardGravity, ViewCompat.getLayoutDirection(this))
+ & Gravity.RIGHT) == Gravity.RIGHT;
+
+ layoutInternal(l, t, r, b, rightEdge);
+ if (mAddedViews != 0 || mRemovedViews != 0) {
+ if (mCurrentAnimator != null) {
+ mCurrentAnimator.cancel();
+ mCurrentAnimator = null;
+ }
+
+ final int initialPositions[] = getChildLeftPositions();
+
+ mAddedViews = 0;
+ mRemovedViews = 0;
+ layoutInternal(l, t, r, b, rightEdge);
+
+ final int finalPositions[] = getChildLeftPositions();
+
+
+ final int childCount = getChildCount();
+ final List<Animator> animators = new ArrayList<>(childCount);
+
+ for (int childIndex = 0; childIndex < childCount; childIndex++) {
+ final View child = getChildAt(childIndex);
+ // Want: initialPos = finalPos + translationX
+ // Thus: initialPos - finalPos = translationX
+ // Plus any current translation in case we interrupted an animation in progress
+
+ final int newTranslationX = initialPositions[childIndex]
+ - finalPositions[childIndex] + Math.round(child.getTranslationX());
+
+ child.setTranslationX(newTranslationX);
+
+ if (newTranslationX != 0) {
+ // Animate to zero
+ animators.add(ObjectAnimator.ofFloat(child, "translationX", 0));
+ }
+ }
+
+ if (mQueuedRemovedViews != null) {
+ for (final View child : mQueuedRemovedViews) {
+ // Want: initialPos = finalPos + translationX
+ // Thus: initialPos - finalPos = translationX
+ // Plus any current translation in case we interrupted an animation in progress
+
+ final int newTranslationX;
+
+ if (rightEdge) {
+ newTranslationX = child.getLeft() - getRight()
+ + Math.round(child.getTranslationX());
+ // Move the child to the new position and set the translation
+ child.offsetLeftAndRight(getRight() - child.getLeft());
+ } else {
+ newTranslationX = child.getLeft() - getLeft() + child.getWidth()
+ + Math.round(child.getTranslationX());
+ // Move the child to the new position and set the translation
+ child.offsetLeftAndRight(getLeft() - child.getWidth() - child.getLeft());
+ }
+
+ child.setTranslationX(newTranslationX);
+
+ // Animate to zero
+ final Animator animator = ObjectAnimator.ofFloat(child, "translationX", 0);
+ animator.addListener(new RemovalAnimationListener(child));
+ animators.add(animator);
+ }
+ mQueuedRemovedViews = null;
+ }
+
+ final AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.playTogether(animators);
+ mCurrentAnimator = animatorSet;
+ mCurrentAnimator.start();
+ }
+
+ }
+
+ private int[] getChildLeftPositions() {
+ final int childCount = getChildCount();
+ final int positions[] = new int[childCount];
+ for (int childIndex = 0; childIndex < childCount; childIndex++) {
+ positions[childIndex] = getChildAt(childIndex).getLeft();
+ }
+ return positions;
+ }
+
+ private void layoutInternal(int l, int t, int r, int b, boolean rightEdge) {
+ final int parentLeft = getPaddingLeft();
+ final int parentRight = r - l - getPaddingRight();
+
+ final int parentTop = getPaddingTop();
+ final int parentBottom = b - t - getPaddingBottom();
+
+ final float baseElevation = ViewCompat.getElevation(this);
+
+ final int childCount = getChildCount();
+ for (int childIndex = 0; childIndex < childCount; childIndex++) {
+ final View child = getChildAt(childIndex);
+ if (child.getVisibility() != GONE) {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ final int width = Math.round(mCardWidth);
+ final int height = child.getMeasuredHeight();
+
+ final int childLeft;
+ if (childIndex >= childCount - mAddedViews) {
+ // This is a freshly added view, start it off the edge of the container.
+ if (rightEdge) {
+ childLeft = parentRight;
+ } else {
+ childLeft = parentLeft - width;
+ }
+ } else {
+ // This is an existing view, just place it normally. If there are added/removed
+ // views, then place it as if those views have not yet been added/removed.
+ if (rightEdge) {
+ childLeft = parentRight - width - lp.rightMargin -
+ (childCount - childIndex - (1 + mAddedViews - mRemovedViews))
+ * mStackShift;
+ } else {
+ childLeft = parentLeft + lp.leftMargin +
+ (childCount - childIndex - (1 + mAddedViews - mRemovedViews))
+ * mStackShift;
+ }
+ }
+ final int childTop = parentTop + lp.topMargin;
+
+ child.layout(childLeft, childTop, childLeft + width, childTop + height);
+
+ ViewCompat.setElevation(child,
+ baseElevation + (childIndex + 1) * mElevationIncrement);
+ }
+ }
+ }
+
+ public class LayoutParams extends MarginLayoutParams {
+
+ public LayoutParams(Context c, AttributeSet attrs) {
+ super(c, attrs);
+ }
+
+ public LayoutParams(int width, int height) {
+ super(width, height);
+ }
+
+ public LayoutParams(MarginLayoutParams source) {
+ super(source);
+ }
+
+ public LayoutParams(ViewGroup.LayoutParams source) {
+ super(source);
+ }
+ }
+
+ private class OnHierarchyChangeInternalListener implements OnHierarchyChangeListener {
+
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount - 1; i++) {
+ final View oldChild = getChildAt(i);
+ oldChild.clearFocus();
+ }
+ mAddedViews++;
+ if (mHierarchyChangeListener != null) {
+ mHierarchyChangeListener.onChildViewAdded(parent, child);
+ }
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, final View child) {
+ if (mHierarchyChangeListener != null) {
+ mHierarchyChangeListener.onChildViewRemoved(parent, child);
+ }
+ mRemovedViews++;
+ if (ViewGroupOverlayHelper.supportsOverlay()) {
+ ViewGroupOverlayHelper.addChildToOverlay(StackedLayout.this, child);
+ if (mQueuedRemovedViews == null) {
+ mQueuedRemovedViews = new ArrayList<>(1);
+ }
+ mQueuedRemovedViews.add(child);
+ }
+ }
+ }
+
+ private class RemovalAnimationListener implements Animator.AnimatorListener {
+ private final View mView;
+
+ public RemovalAnimationListener(View view) {
+ mView = view;
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {}
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ ViewGroupOverlayHelper.removeChildFromOverlay(StackedLayout.this, mView);
+ animation.removeListener(this);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ // Re-add the view to the queued list so that the next animation continues
+ // animating it away
+ if (mQueuedRemovedViews == null) {
+ mQueuedRemovedViews = new ArrayList<>(1);
+ }
+ mQueuedRemovedViews.add(mView);
+ animation.removeListener(this);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {}
+
+ @Override
+ public String toString() {
+ return getClass().getName() + " [" + mView.toString() + "]";
+ }
+ }
+
+}
diff --git a/v17/leanback/src/android/support/v17/leanback/view/ViewGroupOverlayHelper.java b/v17/leanback/src/android/support/v17/leanback/view/ViewGroupOverlayHelper.java
new file mode 100644
index 0000000..18e3534
--- /dev/null
+++ b/v17/leanback/src/android/support/v17/leanback/view/ViewGroupOverlayHelper.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 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.v17.leanback.view;
+
+import android.os.Build;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class ViewGroupOverlayHelper {
+
+ public interface Impl {
+ void addChildToOverlay(ViewGroup parent, View child);
+ void removeChildFromOverlay(ViewGroup parent, View child);
+ }
+
+ private static class ImplStub implements Impl {
+
+ @Override
+ public void addChildToOverlay(ViewGroup parent, View child) {}
+
+ @Override
+ public void removeChildFromOverlay(ViewGroup parent, View child) {}
+ }
+
+ private static class ImplJbmr2 implements Impl {
+
+ @Override
+ public void addChildToOverlay(ViewGroup parent, View child) {
+ ViewGroupOverlayHelperJbmr2.addChildToOverlay(parent, child);
+ }
+
+ @Override
+ public void removeChildFromOverlay(ViewGroup parent, View child) {
+ ViewGroupOverlayHelperJbmr2.removeChildFromOverlay(parent, child);
+ }
+ }
+
+ private static Impl sInstance;
+
+ private static Impl getInstance() {
+ if (sInstance == null) {
+ if (Build.VERSION.SDK_INT >= 18) {
+ sInstance = new ImplJbmr2();
+ } else {
+ sInstance = new ImplStub();
+ }
+ }
+ return sInstance;
+ }
+
+ public static boolean supportsOverlay() {
+ return Build.VERSION.SDK_INT >= 18;
+ }
+
+ public static void addChildToOverlay(ViewGroup parent, View child) {
+ getInstance().addChildToOverlay(parent, child);
+ }
+
+ public static void removeChildFromOverlay(ViewGroup parent, View child) {
+ getInstance().removeChildFromOverlay(parent, child);
+ }
+}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRowPresenter.java
index be9a263..34c2004 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRowPresenter.java
@@ -21,6 +21,7 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
@@ -326,7 +327,7 @@
/**
* Sets the background color. If not set, a default from the theme will be used.
*/
- public void setBackgroundColor(int color) {
+ public void setBackgroundColor(@ColorInt int color) {
mBackgroundColor = color;
mBackgroundColorSet = true;
}
@@ -335,6 +336,7 @@
* Returns the background color. If no background color was set, transparent
* is returned.
*/
+ @ColorInt
public int getBackgroundColor() {
return mBackgroundColor;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java
index 48e491b..15943b4 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java
@@ -529,6 +529,8 @@
Context context = iconView.getContext();
icon = action.getIcon();
if (icon != null) {
+ // setImageDrawable resets the drawable's level unless we set the view level first.
+ iconView.setImageLevel(icon.getLevel());
iconView.setImageDrawable(icon);
iconView.setVisibility(View.VISIBLE);
} else {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ImageCardView.java b/v17/leanback/src/android/support/v17/leanback/widget/ImageCardView.java
index 4e556cb..78b7785 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ImageCardView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ImageCardView.java
@@ -16,6 +16,7 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -174,8 +175,8 @@
/**
* Sets the info area background color.
- */
- public void setInfoAreaBackgroundColor(int color) {
+ */
+ public void setInfoAreaBackgroundColor(@ColorInt int color) {
if (mInfoArea != null) {
mInfoArea.setBackgroundColor(color);
if (mBadgeImage != null) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java
index 72352f9..f1db00b 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java
@@ -20,6 +20,7 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -227,7 +228,7 @@
return mMoreActionsEnabled;
}
- public void setProgressColor(ViewHolder vh, int color) {
+ public void setProgressColor(ViewHolder vh, @ColorInt int color) {
Drawable drawable = new ClipDrawable(new ColorDrawable(color),
Gravity.LEFT, ClipDrawable.HORIZONTAL);
((LayerDrawable) vh.mProgressBar.getProgressDrawable())
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
index f6ceacb..b43fdb7 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
@@ -14,6 +14,7 @@
package android.support.v17.leanback.widget;
import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.ControlBarPresenter.OnControlClickedListener;
import android.support.v17.leanback.widget.ControlBarPresenter.OnControlSelectedListener;
@@ -231,7 +232,7 @@
/**
* Sets the background color. If not set, a default from the theme will be used.
*/
- public void setBackgroundColor(int color) {
+ public void setBackgroundColor(@ColorInt int color) {
mBackgroundColor = color;
mBackgroundColorSet = true;
}
@@ -240,6 +241,7 @@
* Returns the background color. If no background color was set, transparent
* is returned.
*/
+ @ColorInt
public int getBackgroundColor() {
return mBackgroundColor;
}
@@ -248,7 +250,7 @@
* Sets the primary color for the progress bar. If not set, a default from
* the theme will be used.
*/
- public void setProgressColor(int color) {
+ public void setProgressColor(@ColorInt int color) {
mProgressColor = color;
mProgressColorSet = true;
}
@@ -257,6 +259,7 @@
* Returns the primary color for the progress bar. If no color was set, transparent
* is returned.
*/
+ @ColorInt
public int getProgressColor() {
return mProgressColor;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/RowContainerView.java b/v17/leanback/src/android/support/v17/leanback/widget/RowContainerView.java
index 4de58ea..a8ea24c 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/RowContainerView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/RowContainerView.java
@@ -17,6 +17,7 @@
import android.graphics.Canvas;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -77,7 +78,7 @@
invalidate();
}
- public void setForegroundColor(int color) {
+ public void setForegroundColor(@ColorInt int color) {
if (mForeground instanceof ColorDrawable) {
((ColorDrawable) mForeground.mutate()).setColor(color);
invalidate();
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java b/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java
index 46293ea..a060ec0 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java
@@ -25,6 +25,7 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -63,7 +64,7 @@
*
* @param color The main search orb color.
*/
- public Colors(int color) {
+ public Colors(@ColorInt int color) {
this(color, color);
}
@@ -74,7 +75,7 @@
* @param color The main search orb color.
* @param brightColor A brighter version of the search orb used for animation.
*/
- public Colors(int color, int brightColor) {
+ public Colors(@ColorInt int color, @ColorInt int brightColor) {
this(color, brightColor, Color.TRANSPARENT);
}
@@ -85,7 +86,7 @@
* @param brightColor A brighter version of the search orb used for animation.
* @param iconColor A color used to tint the search orb icon.
*/
- public Colors(int color, int brightColor, int iconColor) {
+ public Colors(@ColorInt int color, @ColorInt int brightColor, @ColorInt int iconColor) {
this.color = color;
this.brightColor = brightColor == color ? getBrightColor(color) : brightColor;
this.iconColor = iconColor;
@@ -94,16 +95,19 @@
/**
* The main color of the search orb.
*/
+ @ColorInt
public int color;
/**
* A brighter version of the search orb used for animation.
*/
+ @ColorInt
public int brightColor;
/**
* A color used to tint the search orb icon.
*/
+ @ColorInt
public int iconColor;
/**
@@ -294,7 +298,7 @@
* @deprecated Use {@link #setOrbColors(Colors)} instead.
*/
@Deprecated
- public void setOrbColor(int color, int brightColor) {
+ public void setOrbColor(@ColorInt int color, @ColorInt int brightColor) {
setOrbColors(new Colors(color, brightColor, Color.TRANSPARENT));
}
@@ -302,6 +306,7 @@
* Returns the orb color
* @return the RGBA color
*/
+ @ColorInt
public int getOrbColor() {
return mColors.color;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ShadowOverlayContainer.java b/v17/leanback/src/android/support/v17/leanback/widget/ShadowOverlayContainer.java
index 2244f5e..ad82fd2 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ShadowOverlayContainer.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ShadowOverlayContainer.java
@@ -14,6 +14,7 @@
package android.support.v17.leanback.widget;
import android.content.Context;
+import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -216,7 +217,7 @@
/**
* Set color (with alpha) of the overlay.
*/
- public void setOverlayColor(int overlayColor) {
+ public void setOverlayColor(@ColorInt int overlayColor) {
if (mColorDimOverlay != null) {
mColorDimOverlay.setBackgroundColor(overlayColor);
}
diff --git a/v17/preference-leanback/Android.mk b/v17/preference-leanback/Android.mk
new file mode 100644
index 0000000..05a7a54
--- /dev/null
+++ b/v17/preference-leanback/Android.mk
@@ -0,0 +1,64 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# Build the resources using the current SDK version.
+# We do this here because the final static library must be compiled with an older
+# SDK version than the resources. The resources library and the R class that it
+# contains will not be linked into the final static library.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v17-preference-leanback-res
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, dummy)
+LOCAL_RESOURCE_DIR := \
+ frameworks/support/v7/appcompat/res \
+ frameworks/support/v7/recyclerview/res \
+ frameworks/support/v7/preference/res \
+ frameworks/support/v14/preference/res \
+ frameworks/support/v17/leanback/res \
+ $(LOCAL_PATH)/res
+LOCAL_AAPT_FLAGS := \
+ --auto-add-overlay
+LOCAL_JAR_EXCLUDE_FILES := none
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Here is the final static library that apps can link against.
+# The R class is automatically excluded from the generated library.
+# Applications that use this library must specify LOCAL_RESOURCE_DIR
+# in their makefiles to include the resources in their package.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v17-preference-leanback
+LOCAL_SDK_VERSION := 17
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+# LOCAL_STATIC_JAVA_LIBRARIES :=
+LOCAL_JAVA_LIBRARIES := \
+ android-support-v4 \
+ android-support-v7-appcompat \
+ android-support-v7-recyclerview \
+ android-support-v7-preference \
+ android-support-v14-preference \
+ android-support-v17-leanback \
+ android-support-annotations \
+ android-support-v17-preference-leanback-res
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# API Check
+# ---------------------------------------------
+support_module := $(LOCAL_MODULE)
+support_module_api_dir := $(LOCAL_PATH)/api
+support_module_src_files := $(LOCAL_SRC_FILES)
+support_module_java_libraries := $(LOCAL_JAVA_LIBRARIES)
+support_module_java_packages := android.support.v17.preference
+include $(SUPPORT_API_CHECK)
diff --git a/v17/preference-leanback/AndroidManifest.xml b/v17/preference-leanback/AndroidManifest.xml
new file mode 100644
index 0000000..e2cfe35
--- /dev/null
+++ b/v17/preference-leanback/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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="android.support.v17.preference"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="17" />
+ <application />
+</manifest>
diff --git a/v17/preference-leanback/api/current.txt b/v17/preference-leanback/api/current.txt
new file mode 100644
index 0000000..b31306c
--- /dev/null
+++ b/v17/preference-leanback/api/current.txt
@@ -0,0 +1,68 @@
+package android.support.v17.preference {
+
+ public abstract class BaseLeanbackPreferenceFragment extends android.support.v14.preference.PreferenceFragment {
+ ctor public BaseLeanbackPreferenceFragment();
+ }
+
+ public class LeanbackListPreferenceDialogFragment extends android.support.v17.preference.LeanbackPreferenceDialogFragment {
+ ctor public LeanbackListPreferenceDialogFragment();
+ method public static android.support.v17.preference.LeanbackListPreferenceDialogFragment newInstanceMulti(java.lang.String);
+ method public static android.support.v17.preference.LeanbackListPreferenceDialogFragment newInstanceSingle(java.lang.String);
+ method public android.support.v7.widget.RecyclerView.Adapter onCreateAdapter();
+ }
+
+ public class LeanbackListPreferenceDialogFragment.AdapterMulti extends android.support.v7.widget.RecyclerView.Adapter implements android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
+ ctor public LeanbackListPreferenceDialogFragment.AdapterMulti(java.lang.CharSequence[], java.lang.CharSequence[], java.util.Set<java.lang.String>);
+ method public int getItemCount();
+ method public void onBindViewHolder(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder, int);
+ method public android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+ method public void onItemClick(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder);
+ }
+
+ public class LeanbackListPreferenceDialogFragment.AdapterSingle extends android.support.v7.widget.RecyclerView.Adapter implements android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
+ ctor public LeanbackListPreferenceDialogFragment.AdapterSingle(java.lang.CharSequence[], java.lang.CharSequence[], java.lang.CharSequence);
+ method public int getItemCount();
+ method public void onBindViewHolder(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder, int);
+ method public android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+ method public void onItemClick(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder);
+ }
+
+ public static class LeanbackListPreferenceDialogFragment.ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder implements android.view.View.OnClickListener {
+ ctor public LeanbackListPreferenceDialogFragment.ViewHolder(android.view.View, android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener);
+ method public android.view.ViewGroup getContainer();
+ method public android.widget.TextView getTitleView();
+ method public android.widget.Checkable getWidgetView();
+ method public void onClick(android.view.View);
+ }
+
+ public static abstract interface LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
+ method public abstract void onItemClick(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder);
+ }
+
+ public class LeanbackPreferenceDialogFragment extends android.app.Fragment {
+ ctor public LeanbackPreferenceDialogFragment();
+ method public android.support.v7.preference.DialogPreference getPreference();
+ method public android.support.v14.preference.PreferenceFragment getPreferenceFragment();
+ method public android.support.v17.preference.LeanbackSettingsFragment getSettingsFragment();
+ field public static final java.lang.String ARG_KEY = "key";
+ }
+
+ public static abstract interface LeanbackPreferenceDialogFragment.TargetFragment {
+ method public abstract android.support.v14.preference.PreferenceFragment getPreferenceFragment();
+ method public abstract android.support.v17.preference.LeanbackSettingsFragment getSettingsFragment();
+ }
+
+ public abstract class LeanbackPreferenceFragment extends android.support.v17.preference.BaseLeanbackPreferenceFragment {
+ ctor public LeanbackPreferenceFragment();
+ }
+
+ public abstract class LeanbackSettingsFragment extends android.app.Fragment {
+ ctor public LeanbackSettingsFragment();
+ method public boolean onPreferenceDisplayDialog(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
+ method public abstract void onPreferenceStartInitialScreen();
+ method public void startImmersiveFragment(android.app.Fragment, java.lang.String);
+ method public void startPreferenceFragment(android.app.Fragment, java.lang.String);
+ }
+
+}
+
diff --git a/v17/preference-leanback/api/removed.txt b/v17/preference-leanback/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/v17/preference-leanback/api/removed.txt
diff --git a/v17/preference-leanback/build.gradle b/v17/preference-leanback/build.gradle
new file mode 100644
index 0000000..e8195da
--- /dev/null
+++ b/v17/preference-leanback/build.gradle
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 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
+ */
+
+
+
+apply plugin: 'android-library'
+
+archivesBaseName = 'preference-leanback-v17'
+
+dependencies {
+ compile project(':support-v4')
+ compile project(':support-appcompat-v7')
+ compile project(':support-recyclerview-v7')
+ compile project(':support-preference-v7')
+ compile project(':support-preference-v14')
+ compile project(':support-leanback-v17')
+}
+
+android {
+ compileSdkVersion 'current'
+
+ sourceSets {
+ main.manifest.srcFile 'AndroidManifest.xml'
+ main.java.srcDir 'src'
+ main.res.srcDir 'res'
+ main.assets.srcDir 'assets'
+ main.resources.srcDir 'src'
+
+ // this moves src/instrumentTest to tests so all folders follow:
+ // tests/java, tests/res, tests/assets, ...
+ // This is a *reset* so it replaces the default paths
+ androidTest.setRoot('tests')
+ androidTest.java.srcDir 'tests/src'
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
+ lintOptions {
+ // TODO: fix errors and reenable.
+ abortOnError false
+ }
+}
diff --git a/v17/preference-leanback/res/layout/leanback_list_preference_fragment.xml b/v17/preference-leanback/res/layout/leanback_list_preference_fragment.xml
new file mode 100644
index 0000000..ba8254b
--- /dev/null
+++ b/v17/preference-leanback/res/layout/leanback_list_preference_fragment.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/main_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/lb_preference_decor_list_background"
+ android:orientation="vertical"
+ >
+
+ <TextView android:id="@+id/decor_title"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/lb_preference_decor_title_text_height"
+ android:background="?attr/defaultBrandColor"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="center_vertical"
+ android:paddingTop="@dimen/lb_preference_decor_title_padding_top"
+ android:paddingStart="@dimen/lb_preference_decor_title_padding_start"
+ android:paddingEnd="@dimen/lb_preference_decor_title_padding_end"
+ android:singleLine="true"
+ android:textSize="@dimen/lb_preference_decor_title_text_size"
+ android:textColor="?android:attr/textColorPrimary"
+ />
+
+ <TextView
+ android:id="@android:id/message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="14dp"
+ android:paddingBottom="14dp"
+ android:paddingStart="24dp"
+ android:paddingEnd="56dp"
+ android:visibility="gone" />
+
+ <android.support.v17.leanback.widget.VerticalGridView android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
diff --git a/v17/preference-leanback/res/layout/leanback_list_preference_item_multi.xml b/v17/preference-leanback/res/layout/leanback_list_preference_item_multi.xml
new file mode 100644
index 0000000..3b1345c
--- /dev/null
+++ b/v17/preference-leanback/res/layout/leanback_list_preference_item_multi.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:background="?android:attr/selectableItemBackground"
+ android:clickable="true"
+ android:focusable="true"
+ android:descendantFocusability="blocksDescendants"
+ android:orientation="horizontal">
+ <CheckBox
+ android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center_vertical" />
+</LinearLayout>
diff --git a/v17/preference-leanback/res/layout/leanback_list_preference_item_single.xml b/v17/preference-leanback/res/layout/leanback_list_preference_item_single.xml
new file mode 100644
index 0000000..eaf42a4
--- /dev/null
+++ b/v17/preference-leanback/res/layout/leanback_list_preference_item_single.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:background="?android:attr/selectableItemBackground"
+ android:clickable="true"
+ android:focusable="true"
+ android:descendantFocusability="blocksDescendants"
+ android:orientation="horizontal">
+ <RadioButton
+ android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center_vertical" />
+</LinearLayout>
diff --git a/v17/preference-leanback/res/layout/leanback_preference_fragment.xml b/v17/preference-leanback/res/layout/leanback_preference_fragment.xml
new file mode 100644
index 0000000..3279a42
--- /dev/null
+++ b/v17/preference-leanback/res/layout/leanback_preference_fragment.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/main_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/lb_preference_decor_list_background"
+ android:orientation="vertical"
+ >
+
+ <TextView android:id="@+id/decor_title"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/lb_preference_decor_title_text_height"
+ android:background="?attr/defaultBrandColor"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="center_vertical"
+ android:paddingTop="@dimen/lb_preference_decor_title_padding_top"
+ android:paddingStart="@dimen/lb_preference_decor_title_padding_start"
+ android:paddingEnd="@dimen/lb_preference_decor_title_padding_end"
+ android:singleLine="true"
+ android:textSize="@dimen/lb_preference_decor_title_text_size"
+ android:textColor="?android:attr/textColorPrimary"
+ />
+
+</LinearLayout>
diff --git a/v17/preference-leanback/res/layout/leanback_preferences_list.xml b/v17/preference-leanback/res/layout/leanback_preferences_list.xml
new file mode 100644
index 0000000..15ecebc
--- /dev/null
+++ b/v17/preference-leanback/res/layout/leanback_preferences_list.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<android.support.v17.leanback.widget.VerticalGridView
+ android:id="@+id/list"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
diff --git a/v17/preference-leanback/res/layout/leanback_settings_fragment.xml b/v17/preference-leanback/res/layout/leanback_settings_fragment.xml
new file mode 100644
index 0000000..5cf3e51
--- /dev/null
+++ b/v17/preference-leanback/res/layout/leanback_settings_fragment.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<android.support.v17.preference.LeanbackSettingsRootView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/settings_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
diff --git a/v17/preference-leanback/res/layout/leanback_settings_fragment_stack.xml b/v17/preference-leanback/res/layout/leanback_settings_fragment_stack.xml
new file mode 100644
index 0000000..568c41e
--- /dev/null
+++ b/v17/preference-leanback/res/layout/leanback_settings_fragment_stack.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<android.support.v17.leanback.view.StackedLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/settings_preference_stack"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:cardWidth="@dimen/lb_settings_card_width"
+ app:stackShift="@dimen/lb_settings_card_shift"
+ app:elevationIncrement="@dimen/lb_settings_card_elevation"
+ />
diff --git a/v17/preference-leanback/res/values/colors.xml b/v17/preference-leanback/res/values/colors.xml
new file mode 100644
index 0000000..de6c888
--- /dev/null
+++ b/v17/preference-leanback/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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>
+ <color name="lb_preference_decor_list_background">#263238</color>
+</resources>
diff --git a/v17/preference-leanback/res/values/dimens.xml b/v17/preference-leanback/res/values/dimens.xml
new file mode 100644
index 0000000..c3e519f
--- /dev/null
+++ b/v17/preference-leanback/res/values/dimens.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<resources>
+ <dimen name="lb_preference_decor_title_text_height">64dp</dimen>
+ <dimen name="lb_preference_decor_title_padding_top">27dp</dimen>
+ <dimen name="lb_preference_decor_title_padding_start">24dp</dimen>
+ <dimen name="lb_preference_decor_title_padding_end">56dp</dimen>
+ <dimen name="lb_preference_decor_title_text_size">20sp</dimen>
+
+ <dimen name="lb_settings_card_width">360dp</dimen>
+ <dimen name="lb_settings_card_shift">72dp</dimen>
+ <dimen name="lb_settings_card_elevation">12dp</dimen>
+</resources>
diff --git a/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java b/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java
new file mode 100644
index 0000000..40d9607
--- /dev/null
+++ b/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 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.v17.preference;
+
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+/**
+ * This fragment provides a preference fragment with leanback-style behavior, suitable for
+ * embedding into broader UI elements.
+ */
+public abstract class BaseLeanbackPreferenceFragment extends PreferenceFragment {
+
+ @Override
+ public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
+ Bundle savedInstanceState) {
+ VerticalGridView verticalGridView = (VerticalGridView) inflater
+ .inflate(R.layout.leanback_preferences_list, parent, false);
+ verticalGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
+ verticalGridView.setFocusScrollStrategy(VerticalGridView.FOCUS_SCROLL_ALIGNED);
+ return verticalGridView;
+ }
+}
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java
new file mode 100644
index 0000000..17887e0
--- /dev/null
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2015 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.v17.preference;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v14.preference.MultiSelectListPreference;
+import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v7.preference.DialogPreference;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.widget.RecyclerView;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Checkable;
+import android.widget.TextView;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class LeanbackListPreferenceDialogFragment extends LeanbackPreferenceDialogFragment {
+
+ public static LeanbackListPreferenceDialogFragment newInstanceSingle(String key) {
+ final Bundle args = new Bundle(5);
+ args.putString(ARG_KEY, key);
+
+ final LeanbackListPreferenceDialogFragment
+ fragment = new LeanbackListPreferenceDialogFragment();
+ fragment.setArguments(args);
+
+ return fragment;
+ }
+
+ public static LeanbackListPreferenceDialogFragment newInstanceMulti(String key) {
+ final Bundle args = new Bundle(5);
+ args.putString(ARG_KEY, key);
+
+ final LeanbackListPreferenceDialogFragment
+ fragment = new LeanbackListPreferenceDialogFragment();
+ fragment.setArguments(args);
+
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final DialogPreference preference = getPreference();
+ if (!(preference instanceof ListPreference) &&
+ !(preference instanceof MultiSelectListPreference)) {
+ throw new IllegalArgumentException("Preference must be a ListPreference or " +
+ "MultiSelectListPreference");
+ }
+ }
+
+ @Override
+ public @Nullable View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.leanback_list_preference_fragment, container,
+ false);
+ final VerticalGridView verticalGridView =
+ (VerticalGridView) view.findViewById(android.R.id.list);
+
+ verticalGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
+ verticalGridView.setFocusScrollStrategy(VerticalGridView.FOCUS_SCROLL_ALIGNED);
+ verticalGridView.setAdapter(onCreateAdapter());
+
+ final DialogPreference preference = getPreference();
+ final CharSequence title = preference.getDialogTitle();
+ if (!TextUtils.isEmpty(title)) {
+ final TextView titleView = (TextView) view.findViewById(R.id.decor_title);
+ titleView.setText(title);
+ }
+
+ final CharSequence message = preference.getDialogMessage();
+ if (!TextUtils.isEmpty(message)) {
+ final TextView messageView = (TextView) view.findViewById(android.R.id.message);
+ messageView.setVisibility(View.VISIBLE);
+ messageView.setText(message);
+ }
+
+ return view;
+ }
+
+ public RecyclerView.Adapter onCreateAdapter() {
+ final DialogPreference preference = getPreference();
+ if (preference instanceof MultiSelectListPreference) {
+ final MultiSelectListPreference pref = (MultiSelectListPreference) preference;
+ final CharSequence[] entries = pref.getEntries();
+ final CharSequence[] entryValues = pref.getEntryValues();
+ final Set<String> initialSelections = pref.getValues();
+ return new AdapterMulti(entries, entryValues, initialSelections);
+ } else if (preference instanceof ListPreference) {
+ final ListPreference pref = (ListPreference) preference;
+ final CharSequence[] entries = pref.getEntries();
+ final CharSequence[] entryValues = pref.getEntryValues();
+ final String initialSelection = pref.getValue();
+ return new AdapterSingle(entries, entryValues, initialSelection);
+ } else {
+ throw new IllegalStateException("Unknown preference type");
+ }
+ }
+
+ public class AdapterSingle extends RecyclerView.Adapter<ViewHolder>
+ implements ViewHolder.OnItemClickListener {
+
+ private final CharSequence[] mEntries;
+ private final CharSequence[] mEntryValues;
+ private CharSequence mSelectedValue;
+
+ public AdapterSingle(CharSequence[] entries, CharSequence[] entryValues,
+ CharSequence selectedValue) {
+ mEntries = entries;
+ mEntryValues = entryValues;
+ mSelectedValue = selectedValue;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+ final View view = inflater.inflate(R.layout.leanback_list_preference_item_single,
+ parent, false);
+ return new ViewHolder(view, this);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ holder.getWidgetView().setChecked(mEntryValues[position].equals(mSelectedValue));
+ holder.getTitleView().setText(mEntries[position]);
+ }
+
+ @Override
+ public int getItemCount() {
+ return mEntries.length;
+ }
+
+ @Override
+ public void onItemClick(ViewHolder viewHolder) {
+ final int index = viewHolder.getAdapterPosition();
+ final CharSequence entry = mEntryValues[index];
+ mSelectedValue = entry;
+ ((ListPreference) getPreference()).setValue(entry.toString());
+ getFragmentManager().popBackStack();
+ notifyDataSetChanged();
+ }
+ }
+
+ public class AdapterMulti extends RecyclerView.Adapter<ViewHolder>
+ implements ViewHolder.OnItemClickListener {
+
+ private final CharSequence[] mEntries;
+ private final CharSequence[] mEntryValues;
+ private final Set<String> mSelections;
+
+ public AdapterMulti(CharSequence[] entries, CharSequence[] entryValues,
+ Set<String> initialSelections) {
+ mEntries = entries;
+ mEntryValues = entryValues;
+ mSelections = new HashSet<>(initialSelections);
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+ final View view = inflater.inflate(R.layout.leanback_list_preference_item_multi, parent,
+ false);
+ return new ViewHolder(view, this);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ holder.getWidgetView().setChecked(
+ mSelections.contains(mEntryValues[position].toString()));
+ holder.getTitleView().setText(mEntries[position]);
+ }
+
+ @Override
+ public int getItemCount() {
+ return mEntries.length;
+ }
+
+ @Override
+ public void onItemClick(ViewHolder viewHolder) {
+ final int index = viewHolder.getAdapterPosition();
+ final String entry = mEntryValues[index].toString();
+ if (mSelections.contains(entry)) {
+ mSelections.remove(entry);
+ } else {
+ mSelections.add(entry);
+ }
+ ((MultiSelectListPreference) getPreference()).setValues(mSelections);
+ notifyDataSetChanged();
+ }
+ }
+
+ public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
+
+ public interface OnItemClickListener {
+ void onItemClick(ViewHolder viewHolder);
+ }
+
+ private final Checkable mWidgetView;
+ private final TextView mTitleView;
+ private final ViewGroup mContainer;
+ private final OnItemClickListener mListener;
+
+ public ViewHolder(@NonNull View view, @NonNull OnItemClickListener listener) {
+ super(view);
+ mWidgetView = (Checkable) view.findViewById(R.id.button);
+ mContainer = (ViewGroup) view.findViewById(R.id.container);
+ mTitleView = (TextView) view.findViewById(android.R.id.title);
+ mContainer.setOnClickListener(this);
+ mListener = listener;
+ }
+
+ public Checkable getWidgetView() {
+ return mWidgetView;
+ }
+
+ public TextView getTitleView() {
+ return mTitleView;
+ }
+
+ public ViewGroup getContainer() {
+ return mContainer;
+ }
+
+ @Override
+ public void onClick(View v) {
+ mListener.onItemClick(this);
+ }
+ }
+}
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceDialogFragment.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceDialogFragment.java
new file mode 100644
index 0000000..e92ce81
--- /dev/null
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceDialogFragment.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 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.v17.preference;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.v14.preference.MultiSelectListPreference;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.DialogPreference;
+import android.support.v7.preference.ListPreference;
+
+public class LeanbackPreferenceDialogFragment extends Fragment {
+
+ public interface TargetFragment extends DialogPreference.TargetFragment {
+
+ PreferenceFragment getPreferenceFragment();
+
+ LeanbackSettingsFragment getSettingsFragment();
+ }
+
+ public static final String ARG_KEY = "key";
+
+ private DialogPreference mPreference;
+
+ private PreferenceFragment mPreferenceFragment;
+
+ private LeanbackSettingsFragment mSettingsFragment;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final Fragment rawFragment = getParentFragment();
+ if (!(rawFragment instanceof TargetFragment)) {
+ throw new IllegalStateException("Target fragment must implement TargetFragment" +
+ " interface");
+ }
+
+ final TargetFragment fragment = (TargetFragment) rawFragment;
+
+ final String key = getArguments().getString(LeanbackListPreferenceDialogFragment.ARG_KEY);
+ mPreference = (DialogPreference) fragment.findPreference(key);
+ mPreferenceFragment = fragment.getPreferenceFragment();
+ mSettingsFragment = fragment.getSettingsFragment();
+ }
+
+ public DialogPreference getPreference() {
+ return mPreference;
+ }
+
+ public PreferenceFragment getPreferenceFragment() {
+ return mPreferenceFragment;
+ }
+
+ public LeanbackSettingsFragment getSettingsFragment() {
+ return mSettingsFragment;
+ }
+}
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceFragment.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceFragment.java
new file mode 100644
index 0000000..73ce174
--- /dev/null
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceFragment.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 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.v17.preference;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * This fragment provides a fully decorated leanback-style preference fragment, including a
+ * list background and header.
+ */
+public abstract class LeanbackPreferenceFragment extends BaseLeanbackPreferenceFragment {
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.leanback_preference_fragment, container, false);
+ final ViewGroup innerContainer = (ViewGroup) view.findViewById(R.id.main_frame);
+ final View innerView = super.onCreateView(inflater, innerContainer, savedInstanceState);
+ if (innerView != null) {
+ innerContainer.addView(innerView);
+ }
+ return view;
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ final TextView decorTitle = (TextView) view.findViewById(R.id.decor_title);
+ decorTitle.setText(getPreferenceScreen().getTitle());
+ }
+}
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java
new file mode 100644
index 0000000..38ef3d9
--- /dev/null
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2015 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.v17.preference;
+
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v14.preference.MultiSelectListPreference;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public abstract class LeanbackSettingsFragment extends Fragment
+ implements PreferenceFragment.OnPreferenceStartFragmentCallback,
+ PreferenceFragment.OnPreferenceStartScreenCallback,
+ PreferenceFragment.OnPreferenceDisplayDialogCallback {
+
+ private static final String SETTINGS_FRAGMENT_INNER_TAG =
+ "android.support.v17.preference.LeanbackSettingsFragment.INNER_FRAGMENT";
+
+ private boolean mInitialScreen;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final View v = inflater.inflate(R.layout.leanback_settings_fragment, container, false);
+
+ // Trap back button presses
+ ((LeanbackSettingsRootView) v).setOnBackKeyListener(new RootViewOnKeyListener());
+
+ return v;
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ if (savedInstanceState == null) {
+ final Fragment f = new LeanbackSettingsFragmentInner();
+ getChildFragmentManager().beginTransaction()
+ .add(R.id.settings_fragment_container, f, SETTINGS_FRAGMENT_INNER_TAG)
+ .commit();
+ getChildFragmentManager().executePendingTransactions();
+ mInitialScreen = true;
+ onPreferenceStartInitialScreen();
+ mInitialScreen = false;
+ }
+ }
+
+ @Override
+ public boolean onPreferenceDisplayDialog(PreferenceFragment caller, Preference pref) {
+ final Fragment f;
+ if (pref instanceof ListPreference) {
+ final ListPreference listPreference = (ListPreference) pref;
+ f = LeanbackListPreferenceDialogFragment.newInstanceSingle(listPreference.getKey());
+ getInnerFragment().startDialogFragment(f, caller, null);
+ } else if (pref instanceof MultiSelectListPreference) {
+ MultiSelectListPreference listPreference = (MultiSelectListPreference) pref;
+ f = LeanbackListPreferenceDialogFragment.newInstanceMulti(listPreference.getKey());
+ getInnerFragment().startDialogFragment(f, caller, null);
+ }
+ // TODO
+// else if (pref instanceof EditTextPreference) {
+//
+// }
+ else {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Called to instantiate the initial {@link android.support.v14.preference.PreferenceFragment}
+ * to be shown in this fragment. Implementations are expected to call
+ * {@link #startPreferenceFragment(android.app.Fragment, java.lang.String)}.
+ */
+ public abstract void onPreferenceStartInitialScreen();
+
+ /**
+ * Displays a preference fragment to the user. This method can also be used to display
+ * list-style fragments on top of the stack of preference fragments.
+ *
+ * @param fragment Fragment instance to be added.
+ * @param tag Fragment tag
+ */
+ public void startPreferenceFragment(@NonNull Fragment fragment, @Nullable String tag) {
+ getInnerFragment().startStackedFragment(fragment, tag, !mInitialScreen);
+ }
+
+ /**
+ * Displays a fragment to the user, temporarily replacing the contents of this fragment.
+ *
+ * @param fragment Fragment instance to be added.
+ * @param tag Fragment tag
+ */
+ public void startImmersiveFragment(@NonNull Fragment fragment, @Nullable String tag) {
+ getChildFragmentManager().beginTransaction()
+ .replace(R.id.settings_fragment_container, fragment, tag)
+ .addToBackStack(null)
+ .commit();
+ }
+
+ private LeanbackSettingsFragmentInner getInnerFragment() {
+ return (LeanbackSettingsFragmentInner)
+ getChildFragmentManager().findFragmentByTag(SETTINGS_FRAGMENT_INNER_TAG);
+ }
+
+ private boolean handleBackPress() {
+ final LeanbackSettingsFragmentInner inner = getInnerFragment();
+ boolean handled = false;
+ if (inner != null && inner.isVisible()) {
+ handled = inner.handleBackPress();
+ }
+ return handled || getChildFragmentManager().popBackStackImmediate();
+ }
+
+ /**
+ * @hide
+ */
+ public static class LeanbackSettingsFragmentInner extends Fragment
+ implements LeanbackPreferenceDialogFragment.TargetFragment {
+
+ private static final String SAVESTATE_TARGET_PREF_FRAG =
+ "android.support.v17.preference.LeanbackSettingsFragment.TARGET_PREF_FRAG";
+
+ private static final String TARGET_FRAGMENT_TAG =
+ "android.support.v17.preference.LeanbackSettingsFragment.TARGET";
+
+ // Preference fragment which last launched a dialog
+ private PreferenceFragment mTargetPreferenceFragment;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState != null &&
+ savedInstanceState.containsKey(SAVESTATE_TARGET_PREF_FRAG)) {
+ mTargetPreferenceFragment = (PreferenceFragment) getChildFragmentManager()
+ .getFragment(savedInstanceState, SAVESTATE_TARGET_PREF_FRAG);
+ }
+ }
+
+ @Override
+ public @Nullable View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.leanback_settings_fragment_stack,
+ container, false);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ if (mTargetPreferenceFragment != null) {
+ getChildFragmentManager().putFragment(outState, SAVESTATE_TARGET_PREF_FRAG,
+ mTargetPreferenceFragment);
+ }
+ }
+
+ public void startDialogFragment(@NonNull Fragment dialogFragment,
+ @NonNull PreferenceFragment requestingFragment, @Nullable String tag) {
+ mTargetPreferenceFragment = requestingFragment;
+ startFragment(dialogFragment, tag, true);
+ }
+
+ public void startStackedFragment(@NonNull Fragment fragment, @Nullable String tag,
+ boolean addToBackstack) {
+ fragment.setTargetFragment(findTarget(), 0);
+ startFragment(fragment, tag, addToBackstack);
+ }
+
+ private void startFragment(@NonNull Fragment fragment, @Nullable String tag,
+ boolean addToBackstack) {
+ final FragmentTransaction transaction = getChildFragmentManager().beginTransaction()
+ .add(R.id.settings_preference_stack, fragment, tag);
+ if (addToBackstack) {
+ transaction.addToBackStack(null);
+ }
+ transaction.commit();
+ }
+
+ private Fragment findTarget() {
+ Fragment target =
+ getChildFragmentManager().findFragmentByTag(TARGET_FRAGMENT_TAG);
+ if (target == null) {
+ target = new Target();
+ getChildFragmentManager().beginTransaction()
+ .add(target, TARGET_FRAGMENT_TAG)
+ .commit();
+ getChildFragmentManager().executePendingTransactions();
+ }
+ return target;
+ }
+
+ public boolean handleBackPress() {
+ return getChildFragmentManager().popBackStackImmediate();
+ }
+
+ public Preference findPreference(CharSequence key) {
+ return mTargetPreferenceFragment.findPreference(key);
+ }
+
+ public PreferenceFragment getPreferenceFragment() {
+ return mTargetPreferenceFragment;
+ }
+
+ @Override
+ public LeanbackSettingsFragment getSettingsFragment() {
+ return (LeanbackSettingsFragment) getParentFragment();
+ }
+
+ // This looks terrible, and it is. We need this because the target fragment needs to be
+ // in the same FragmentManager as the fragment targeting it.
+ /**
+ * @hide
+ */
+ public static class Target extends Fragment
+ implements PreferenceFragment.OnPreferenceStartFragmentCallback,
+ PreferenceFragment.OnPreferenceStartScreenCallback,
+ PreferenceFragment.OnPreferenceDisplayDialogCallback {
+
+ private LeanbackSettingsFragment getOuterParent() {
+ return (LeanbackSettingsFragment) getParentFragment().getParentFragment();
+ }
+
+ @Override
+ public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
+ return getOuterParent().onPreferenceStartFragment(caller, pref);
+ }
+
+ @Override
+ public boolean onPreferenceStartScreen(PreferenceFragment caller,
+ PreferenceScreen pref) {
+ return getOuterParent().onPreferenceStartScreen(caller, pref);
+ }
+
+ @Override
+ public boolean onPreferenceDisplayDialog(PreferenceFragment caller, Preference pref) {
+ return getOuterParent().onPreferenceDisplayDialog(caller, pref);
+ }
+ }
+ }
+
+ private class RootViewOnKeyListener implements View.OnKeyListener {
+
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ return handleBackPress();
+ } else {
+ return false;
+ }
+ }
+ }
+}
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsRootView.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsRootView.java
new file mode 100644
index 0000000..6114f13
--- /dev/null
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsRootView.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 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.v17.preference;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.widget.FrameLayout;
+
+/**
+ * @hide
+ */
+public class LeanbackSettingsRootView extends FrameLayout {
+
+ private OnKeyListener mOnBackKeyListener;
+
+ public LeanbackSettingsRootView(Context context) {
+ super(context);
+ }
+
+ public LeanbackSettingsRootView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LeanbackSettingsRootView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public void setOnBackKeyListener(OnKeyListener backKeyListener) {
+ mOnBackKeyListener = backKeyListener;
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
+ boolean handled = false;
+ if (event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_BACK
+ && mOnBackKeyListener != null) {
+ handled = mOnBackKeyListener.onKey(this, event.getKeyCode(), event);
+ }
+ return handled || super.dispatchKeyEvent(event);
+ }
+}
diff --git a/v4/Android.mk b/v4/Android.mk
index 6e1187a..2050725 100644
--- a/v4/Android.mk
+++ b/v4/Android.mk
@@ -184,6 +184,16 @@
# -----------------------------------------------------------------------
+# A helper sub-library that makes direct use of V23 APIs.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v4-api23
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, api23)
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-api22
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# -----------------------------------------------------------------------
+
# Here is the final static library that apps can link against.
include $(CLEAR_VARS)
LOCAL_MODULE := android-support-v4
@@ -191,8 +201,7 @@
LOCAL_AIDL_INCLUDES := frameworks/support/v4/java
LOCAL_SRC_FILES := $(call all-java-files-under, java) \
$(call all-Iaidl-files-under, java)
-LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4-api22
-
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4-api23
include $(BUILD_STATIC_JAVA_LIBRARY)
# API Check
diff --git a/v4/AndroidManifest.xml b/v4/AndroidManifest.xml
index 08dbb61..a21d926 100644
--- a/v4/AndroidManifest.xml
+++ b/v4/AndroidManifest.xml
@@ -15,5 +15,6 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.v4">
+ <uses-sdk android:minSdkVersion="4"/>
<application />
</manifest>
diff --git a/v4/api/current.txt b/v4/api/current.txt
index 41e3610..2bc5d17 100644
--- a/v4/api/current.txt
+++ b/v4/api/current.txt
@@ -87,6 +87,7 @@
ctor public ActivityCompat();
method public static void finishAffinity(android.app.Activity);
method public static void finishAfterTransition(android.app.Activity);
+ method public android.net.Uri getReferrer(android.app.Activity);
method public static boolean invalidateOptionsMenu(android.app.Activity);
method public static void postponeEnterTransition(android.app.Activity);
method public static void setEnterSharedElementCallback(android.app.Activity, android.support.v4.app.SharedElementCallback);
@@ -142,9 +143,11 @@
method public boolean getAllowReturnTransitionOverlap();
method public final android.os.Bundle getArguments();
method public final android.support.v4.app.FragmentManager getChildFragmentManager();
+ method public android.content.Context getContext();
method public java.lang.Object getEnterTransition();
method public java.lang.Object getExitTransition();
method public final android.support.v4.app.FragmentManager getFragmentManager();
+ method public final java.lang.Object getHost();
method public final int getId();
method public android.support.v4.app.LoaderManager getLoaderManager();
method public final android.support.v4.app.Fragment getParentFragment();
@@ -174,7 +177,8 @@
method public final boolean isVisible();
method public void onActivityCreated(android.os.Bundle);
method public void onActivityResult(int, int, android.content.Intent);
- method public void onAttach(android.app.Activity);
+ method public void onAttach(android.content.Context);
+ method public deprecated void onAttach(android.app.Activity);
method public void onConfigurationChanged(android.content.res.Configuration);
method public boolean onContextItemSelected(android.view.MenuItem);
method public void onCreate(android.os.Bundle);
@@ -187,7 +191,8 @@
method public void onDestroyView();
method public void onDetach();
method public void onHiddenChanged(boolean);
- method public void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle);
+ method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
+ method public deprecated void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle);
method public void onLowMemory();
method public boolean onOptionsItemSelected(android.view.MenuItem);
method public void onOptionsMenuClosed(android.view.Menu);
@@ -250,6 +255,65 @@
method public void supportStartPostponedEnterTransition();
}
+ public abstract class FragmentContainer {
+ ctor public FragmentContainer();
+ method public abstract android.view.View findViewById(int);
+ method public abstract boolean hasView();
+ }
+
+ public class FragmentController {
+ method public void attachHost(android.support.v4.app.Fragment);
+ method public static final android.support.v4.app.FragmentController createController(android.support.v4.app.FragmentHostCallbacks<?>);
+ method public void dispatchActivityCreated();
+ method public void dispatchConfigurationChanged(android.content.res.Configuration);
+ method public boolean dispatchContextItemSelected(android.view.MenuItem);
+ method public void dispatchCreate();
+ method public boolean dispatchCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+ method public void dispatchDestroy();
+ method public void dispatchDestroyView();
+ method public void dispatchLowMemory();
+ method public boolean dispatchOptionsItemSelected(android.view.MenuItem);
+ method public void dispatchOptionsMenuClosed(android.view.Menu);
+ method public void dispatchPause();
+ method public boolean dispatchPrepareOptionsMenu(android.view.Menu);
+ method public void dispatchReallyStop();
+ method public void dispatchResume();
+ method public void dispatchStart();
+ method public void dispatchStop();
+ method public void doLoaderDestroy();
+ method public void doLoaderRetain();
+ method public void doLoaderStart();
+ method public void doLoaderStop(boolean);
+ method public void dumpLoaders(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public boolean execPendingActions();
+ method public java.util.List<android.support.v4.app.Fragment> getActiveFragments(java.util.List<android.support.v4.app.Fragment>);
+ method public int getActiveFragmentsCount();
+ method public android.support.v4.app.FragmentManager getSupportFragmentManager();
+ method public android.support.v4.app.LoaderManager getSupportLoaderManager();
+ method public void noteStateNotSaved();
+ method public android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+ method public void reportLoaderStart();
+ method public void restoreAllState(android.os.Parcelable, java.util.ArrayList<android.support.v4.app.Fragment>);
+ method public void restoreLoaderNonConfig(android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager>);
+ method public android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager> retainLoaderNonConfig();
+ method public java.util.ArrayList<android.support.v4.app.Fragment> retainNonConfig();
+ method public android.os.Parcelable saveAllState();
+ }
+
+ public class FragmentHostCallbacks extends android.support.v4.app.FragmentContainer {
+ ctor public FragmentHostCallbacks(android.content.Context, android.os.Handler, int);
+ method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public android.view.View findViewById(int);
+ method public E getHost();
+ method public android.view.LayoutInflater getLayoutInflater();
+ method public int getWindowAnimations();
+ method public boolean hasView();
+ method public boolean hasWindowAnimations();
+ method public boolean shouldSaveFragmentState(android.support.v4.app.Fragment);
+ method public void startActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int);
+ method public void supportInvalidateOptionsMenu();
+ }
+
public abstract class FragmentManager {
ctor public FragmentManager();
method public abstract void addOnBackStackChangedListener(android.support.v4.app.FragmentManager.OnBackStackChangedListener);
@@ -463,11 +527,11 @@
public static class NotificationCompat.Action extends android.support.v4.app.NotificationCompatBase.Action {
ctor public NotificationCompat.Action(int, java.lang.CharSequence, android.app.PendingIntent);
- method protected android.app.PendingIntent getActionIntent();
+ method public android.app.PendingIntent getActionIntent();
method public android.os.Bundle getExtras();
- method protected int getIcon();
+ method public int getIcon();
method public android.support.v4.app.RemoteInput[] getRemoteInputs();
- method protected java.lang.CharSequence getTitle();
+ method public java.lang.CharSequence getTitle();
field public android.app.PendingIntent actionIntent;
field public int icon;
field public java.lang.CharSequence title;
@@ -671,16 +735,17 @@
field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
}
- class NotificationCompatBase {
+ public class NotificationCompatBase {
+ ctor public NotificationCompatBase();
}
public static abstract class NotificationCompatBase.Action {
ctor public NotificationCompatBase.Action();
- method protected abstract android.app.PendingIntent getActionIntent();
- method protected abstract android.os.Bundle getExtras();
- method protected abstract int getIcon();
- method protected abstract android.support.v4.app.RemoteInputCompatBase.RemoteInput[] getRemoteInputs();
- method protected abstract java.lang.CharSequence getTitle();
+ method public abstract android.app.PendingIntent getActionIntent();
+ method public abstract android.os.Bundle getExtras();
+ method public abstract int getIcon();
+ method public abstract android.support.v4.app.RemoteInputCompatBase.RemoteInput[] getRemoteInputs();
+ method public abstract java.lang.CharSequence getTitle();
}
public static abstract class NotificationCompatBase.UnreadConversation {
@@ -849,16 +914,23 @@
public abstract class AsyncTaskLoader extends android.support.v4.content.Loader {
ctor public AsyncTaskLoader(android.content.Context);
- method public boolean cancelLoad();
+ method public void cancelLoadInBackground();
+ method public boolean isLoadInBackgroundCanceled();
method public abstract D loadInBackground();
method public void onCanceled(D);
method protected D onLoadInBackground();
method public void setUpdateThrottle(long);
}
+ public class ContentResolverCompat {
+ method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.support.v4.os.CancellationSignal);
+ }
+
public class ContextCompat {
ctor public ContextCompat();
method public final java.io.File getCodeCacheDir(android.content.Context);
+ method public static final int getColor(android.content.Context, int);
+ method public static final android.content.res.ColorStateList getColorStateList(android.content.Context, int);
method public static final android.graphics.drawable.Drawable getDrawable(android.content.Context, int);
method public static java.io.File[] getExternalCacheDirs(android.content.Context);
method public static java.io.File[] getExternalFilesDirs(android.content.Context, java.lang.String);
@@ -913,8 +985,10 @@
public class Loader {
ctor public Loader(android.content.Context);
method public void abandon();
+ method public boolean cancelLoad();
method public void commitContentChanged();
method public java.lang.String dataToString(D);
+ method public void deliverCancellation();
method public void deliverResult(D);
method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
method public void forceLoad();
@@ -924,24 +998,31 @@
method public boolean isReset();
method public boolean isStarted();
method protected void onAbandon();
+ method protected boolean onCancelLoad();
method public void onContentChanged();
method protected void onForceLoad();
method protected void onReset();
method protected void onStartLoading();
method protected void onStopLoading();
method public void registerListener(int, android.support.v4.content.Loader.OnLoadCompleteListener<D>);
+ method public void registerOnLoadCanceledListener(android.support.v4.content.Loader.OnLoadCanceledListener<D>);
method public void reset();
method public void rollbackContentChanged();
method public final void startLoading();
method public void stopLoading();
method public boolean takeContentChanged();
method public void unregisterListener(android.support.v4.content.Loader.OnLoadCompleteListener<D>);
+ method public void unregisterOnLoadCanceledListener(android.support.v4.content.Loader.OnLoadCanceledListener<D>);
}
public final class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
ctor public Loader.ForceLoadContentObserver();
}
+ public static abstract interface Loader.OnLoadCanceledListener {
+ method public abstract void onLoadCanceled(android.support.v4.content.Loader<D>);
+ }
+
public static abstract interface Loader.OnLoadCompleteListener {
method public abstract void onLoadComplete(android.support.v4.content.Loader<D>, D);
}
@@ -954,6 +1035,15 @@
method public void unregisterReceiver(android.content.BroadcastReceiver);
}
+ public class SharedPreferencesCompat {
+ ctor public SharedPreferencesCompat();
+ }
+
+ public static class SharedPreferencesCompat.EditorCompat {
+ method public void apply(android.content.SharedPreferences.Editor);
+ method public static android.support.v4.content.SharedPreferencesCompat.EditorCompat getInstance();
+ }
+
public abstract class WakefulBroadcastReceiver extends android.content.BroadcastReceiver {
ctor public WakefulBroadcastReceiver();
method public static boolean completeWakefulIntent(android.content.Intent);
@@ -1068,6 +1158,37 @@
}
+package android.support.v4.hardware.fingerprint {
+
+ public class FingerprintManagerCompat {
+ method public void authenticate(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject, android.support.v4.os.CancellationSignal, android.support.v4.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, int);
+ method public static android.support.v4.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
+ method public boolean hasEnrolledFingerprints();
+ method public boolean isHardwareDetected();
+ }
+
+ public static abstract class FingerprintManagerCompat.AuthenticationCallback {
+ ctor public FingerprintManagerCompat.AuthenticationCallback();
+ method public void onAuthenticationError(int, java.lang.CharSequence);
+ method public void onAuthenticationFailed();
+ method public void onAuthenticationHelp(int, java.lang.CharSequence);
+ method public void onAuthenticationSucceeded(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult);
+ }
+
+ public static final class FingerprintManagerCompat.AuthenticationResult {
+ ctor public FingerprintManagerCompat.AuthenticationResult(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject);
+ method public android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject getCryptoObject();
+ }
+
+ public static class FingerprintManagerCompat.CryptoObject {
+ ctor public FingerprintManagerCompat.CryptoObject(java.security.Signature);
+ ctor public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
+ method public javax.crypto.Cipher getCipher();
+ method public java.security.Signature getSignature();
+ }
+
+}
+
package android.support.v4.media {
public final class MediaDescriptionCompat implements android.os.Parcelable {
@@ -1529,12 +1650,30 @@
method public static android.os.AsyncTask<Params, Progress, Result> executeParallel(android.os.AsyncTask<Params, Progress, Result>, Params...);
}
+ public final class CancellationSignal {
+ ctor public CancellationSignal();
+ method public void cancel();
+ method public java.lang.Object getCancellationSignalObject();
+ method public boolean isCanceled();
+ method public void setOnCancelListener(android.support.v4.os.CancellationSignal.OnCancelListener);
+ method public void throwIfCanceled();
+ }
+
+ public static abstract interface CancellationSignal.OnCancelListener {
+ method public abstract void onCancel();
+ }
+
public class EnvironmentCompat {
ctor public EnvironmentCompat();
method public static java.lang.String getStorageState(java.io.File);
field public static final java.lang.String MEDIA_UNKNOWN = "unknown";
}
+ public class OperationCanceledException extends java.lang.RuntimeException {
+ ctor public OperationCanceledException();
+ ctor public OperationCanceledException(java.lang.String);
+ }
+
public class ParcelableCompat {
ctor public ParcelableCompat();
method public static android.os.Parcelable.Creator<T> newCreator(android.support.v4.os.ParcelableCompatCreatorCallbacks<T>);
@@ -1636,8 +1775,7 @@
public class ICUCompat {
ctor public ICUCompat();
- method public static java.lang.String addLikelySubtags(java.lang.String);
- method public static java.lang.String getScript(java.lang.String);
+ method public static java.lang.String maximizeAndGetScript(java.util.Locale);
}
public abstract interface TextDirectionHeuristicCompat {
@@ -1961,6 +2099,8 @@
method public static android.view.MenuItem setActionProvider(android.view.MenuItem, android.support.v4.view.ActionProvider);
method public static android.view.MenuItem setActionView(android.view.MenuItem, android.view.View);
method public static android.view.MenuItem setActionView(android.view.MenuItem, int);
+ method public static android.view.MenuItem setIconTintList(android.view.MenuItem, android.content.res.ColorStateList);
+ method public static android.view.MenuItem setIconTintMode(android.view.MenuItem, android.graphics.PorterDuff.Mode);
method public static android.view.MenuItem setOnActionExpandListener(android.view.MenuItem, android.support.v4.view.MenuItemCompat.OnActionExpandListener);
method public static void setShowAsAction(android.view.MenuItem, int);
field public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
@@ -2904,8 +3044,10 @@
method public void invalidateVirtualView(int);
method protected abstract boolean onPerformActionForVirtualView(int, int, android.os.Bundle);
method protected abstract void onPopulateEventForVirtualView(int, android.view.accessibility.AccessibilityEvent);
+ method public void onPopulateNodeForHost(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
method protected abstract void onPopulateNodeForVirtualView(int, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
method public boolean sendEventForVirtualView(int, int);
+ field public static final int HOST_ID = -1; // 0xffffffff
field public static final int INVALID_ID = -2147483648; // 0x80000000
}
@@ -2945,6 +3087,10 @@
}
public class PopupWindowCompat {
+ method public static boolean getOverlapAnchor(android.widget.PopupWindow);
+ method public static int getWindowLayoutType(android.widget.PopupWindow);
+ method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
+ method public static void setWindowLayoutType(android.widget.PopupWindow, int);
method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
}
diff --git a/v4/api20/android/support/v4/app/NotificationCompatApi20.java b/v4/api20/android/support/v4/app/NotificationCompatApi20.java
index 047d01a..fcd7576 100644
--- a/v4/api20/android/support/v4/app/NotificationCompatApi20.java
+++ b/v4/api20/android/support/v4/app/NotificationCompatApi20.java
@@ -91,6 +91,7 @@
return b;
}
+ @Override
public Notification build() {
b.setExtras(mExtras);
return b.build();
diff --git a/v4/api21/android/support/v4/app/FragmentTransitionCompat21.java b/v4/api21/android/support/v4/app/FragmentTransitionCompat21.java
index ef41045..e11e858 100644
--- a/v4/api21/android/support/v4/app/FragmentTransitionCompat21.java
+++ b/v4/api21/android/support/v4/app/FragmentTransitionCompat21.java
@@ -283,7 +283,6 @@
public boolean onPreDraw() {
sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
if (enterTransition != null) {
- enterTransition.removeTarget(nonExistentView);
removeTargets(enterTransition, enteringViews);
}
if (exitTransition != null) {
diff --git a/v4/api21/android/support/v4/app/NotificationCompatApi21.java b/v4/api21/android/support/v4/app/NotificationCompatApi21.java
index a16b2a2..dbce1db 100644
--- a/v4/api21/android/support/v4/app/NotificationCompatApi21.java
+++ b/v4/api21/android/support/v4/app/NotificationCompatApi21.java
@@ -115,6 +115,7 @@
return b;
}
+ @Override
public Notification build() {
return b.build();
}
diff --git a/v4/api21/android/support/v4/widget/PopupWindowCompatApi21.java b/v4/api21/android/support/v4/widget/PopupWindowCompatApi21.java
new file mode 100644
index 0000000..3440f3c
--- /dev/null
+++ b/v4/api21/android/support/v4/widget/PopupWindowCompatApi21.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 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.v4.widget;
+
+import android.util.Log;
+import android.widget.PopupWindow;
+
+import java.lang.reflect.Field;
+
+class PopupWindowCompatApi21 {
+
+ private static final String TAG = "PopupWindowCompatApi21";
+
+ private static Field sOverlapAnchorField;
+
+ static {
+ try {
+ sOverlapAnchorField = PopupWindow.class.getDeclaredField("mOverlapAnchor");
+ sOverlapAnchorField.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ Log.i(TAG, "Could not fetch mOverlapAnchor field from PopupWindow", e);
+ }
+ }
+
+ static void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
+ if (sOverlapAnchorField != null) {
+ try {
+ sOverlapAnchorField.set(popupWindow, overlapAnchor);
+ } catch (IllegalAccessException e) {
+ Log.i(TAG, "Could not set overlap anchor field in PopupWindow", e);
+ }
+ }
+ }
+
+ static boolean getOverlapAnchor(PopupWindow popupWindow) {
+ if (sOverlapAnchorField != null) {
+ try {
+ return (Boolean) sOverlapAnchorField.get(popupWindow);
+ } catch (IllegalAccessException e) {
+ Log.i(TAG, "Could not get overlap anchor field in PopupWindow", e);
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/v4/api22/android/support/v4/app/ActivityCompat22.java b/v4/api22/android/support/v4/app/ActivityCompat22.java
new file mode 100644
index 0000000..3946f1d
--- /dev/null
+++ b/v4/api22/android/support/v4/app/ActivityCompat22.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 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.v4.app;
+
+import android.app.Activity;
+import android.net.Uri;
+
+class ActivityCompat22 {
+ public static Uri getReferrer(Activity activity) {
+ return activity.getReferrer();
+ }
+}
diff --git a/v4/api23/android/support/v4/content/ContextCompatApi23.java b/v4/api23/android/support/v4/content/ContextCompatApi23.java
new file mode 100644
index 0000000..64f1c15
--- /dev/null
+++ b/v4/api23/android/support/v4/content/ContextCompatApi23.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package android.support.v4.content;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.drawable.Drawable;
+
+import java.io.File;
+
+class ContextCompatApi23 {
+ public static ColorStateList getColorStateList(Context context, int id) {
+ return context.getColorStateList(id);
+ }
+
+ public static int getColor(Context context, int id) {
+ return context.getColor(id);
+ }
+}
diff --git a/v4/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java b/v4/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java
new file mode 100644
index 0000000..2f22fbd
--- /dev/null
+++ b/v4/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2015 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.v4.hardware.fingerprint;
+
+import android.content.Context;
+import android.hardware.fingerprint.FingerprintManager;
+
+import java.security.Signature;
+
+import javax.crypto.Cipher;
+
+/**
+ * Actual FingerprintManagerCompat implementation for API level 23 and later.
+ */
+public final class FingerprintManagerCompatApi23 {
+
+ private static FingerprintManager getFingerprintManager(Context ctx) {
+ return ctx.getSystemService(FingerprintManager.class);
+ }
+
+ public static boolean hasEnrolledFingerprints(Context context) {
+ return getFingerprintManager(context).hasEnrolledFingerprints();
+ }
+
+ public static boolean isHardwareDetected(Context context) {
+ return getFingerprintManager(context).isHardwareDetected();
+ }
+
+ public static void authenticate(Context context, CryptoObject crypto, Object cancel,
+ AuthenticationCallback callback, int flags) {
+ getFingerprintManager(context).authenticate(wrapCryptoObject(crypto),
+ (android.os.CancellationSignal) cancel,
+ wrapCallback(callback), flags);
+ }
+
+ private static FingerprintManager.CryptoObject wrapCryptoObject(CryptoObject cryptoObject) {
+ if (cryptoObject.getCipher() != null) {
+ return new FingerprintManager.CryptoObject(cryptoObject.getCipher());
+ } else {
+ return new FingerprintManager.CryptoObject(cryptoObject.getSignature());
+ }
+ }
+
+ private static CryptoObject unwrapCryptoObject(FingerprintManager.CryptoObject cryptoObject) {
+ if (cryptoObject.getCipher() != null) {
+ return new CryptoObject(cryptoObject.getCipher());
+ } else {
+ return new CryptoObject(cryptoObject.getSignature());
+ }
+ }
+
+ private static FingerprintManager.AuthenticationCallback wrapCallback(
+ final AuthenticationCallback callback) {
+ return new FingerprintManager.AuthenticationCallback() {
+ @Override
+ public void onAuthenticationError(int errMsgId, CharSequence errString) {
+ callback.onAuthenticationError(errMsgId, errString);
+ }
+
+ @Override
+ public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
+ callback.onAuthenticationHelp(helpMsgId, helpString);
+ }
+
+ @Override
+ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
+ callback.onAuthenticationSucceeded(new AuthenticationResultInternal(
+ unwrapCryptoObject(result.getCryptoObject())));
+ }
+
+ @Override
+ public void onAuthenticationFailed() {
+ callback.onAuthenticationFailed();
+ }
+ };
+ }
+
+ public static class CryptoObject {
+
+ private final Signature mSignature;
+ private final Cipher mCipher;
+
+ public CryptoObject(Signature signature) {
+ mSignature = signature;
+ mCipher = null;
+ }
+
+ public CryptoObject(Cipher cipher) {
+ mCipher = cipher;
+ mSignature = null;
+ }
+
+ public Signature getSignature() { return mSignature; }
+ public Cipher getCipher() { return mCipher; }
+ }
+
+ public static final class AuthenticationResultInternal {
+ private CryptoObject mCryptoObject;
+
+ public AuthenticationResultInternal(CryptoObject crypto) {
+ mCryptoObject = crypto;
+ }
+
+ public CryptoObject getCryptoObject() { return mCryptoObject; }
+ }
+
+ public static abstract class AuthenticationCallback {
+
+ public void onAuthenticationError(int errMsgId, CharSequence errString) { }
+ public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { }
+ public void onAuthenticationSucceeded(AuthenticationResultInternal result) { }
+ public void onAuthenticationFailed() { }
+ }
+}
diff --git a/v4/api23/android/support/v4/text/ICUCompatApi23.java b/v4/api23/android/support/v4/text/ICUCompatApi23.java
new file mode 100644
index 0000000..f013522
--- /dev/null
+++ b/v4/api23/android/support/v4/text/ICUCompatApi23.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 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.v4.text;
+
+import android.util.Log;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Locale;
+
+public class ICUCompatApi23 {
+
+ private static final String TAG = "ICUCompatIcs";
+
+ private static Method sAddLikelySubtagsMethod;
+
+ static {
+ try {
+ // This class should always exist on API-23 since it's CTS tested.
+ final Class<?> clazz = Class.forName("libcore.icu.ICU");
+ sAddLikelySubtagsMethod = clazz.getMethod("addLikelySubtags",
+ new Class[]{ Locale.class });
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+
+ public static String maximizeAndGetScript(Locale locale) {
+ try {
+ final Object[] args = new Object[] { locale };
+ return ((Locale) sAddLikelySubtagsMethod.invoke(null, args)).getScript();
+ } catch (InvocationTargetException e) {
+ Log.w(TAG, e);
+ } catch (IllegalAccessException e) {
+ Log.w(TAG, e);
+ }
+
+ return locale.getScript();
+ }
+}
diff --git a/v4/api23/android/support/v4/view/MenuItemCompatApi23.java b/v4/api23/android/support/v4/view/MenuItemCompatApi23.java
new file mode 100644
index 0000000..4cdeae0
--- /dev/null
+++ b/v4/api23/android/support/v4/view/MenuItemCompatApi23.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 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.v4.view;
+
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
+import android.view.MenuItem;
+
+class MenuItemCompatApi23 {
+ public static MenuItem setIconTintList(MenuItem item, ColorStateList tint) {
+ return item.setIconTintList(tint);
+ }
+
+ public static MenuItem setIconTintMode(MenuItem item, PorterDuff.Mode tintMode) {
+ return item.setIconTintMode(tintMode);
+ }
+}
diff --git a/v4/api23/android/support/v4/widget/PopupWindowCompatApi23.java b/v4/api23/android/support/v4/widget/PopupWindowCompatApi23.java
new file mode 100644
index 0000000..96bf8d9
--- /dev/null
+++ b/v4/api23/android/support/v4/widget/PopupWindowCompatApi23.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 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.v4.widget;
+
+import android.widget.PopupWindow;
+
+class PopupWindowCompatApi23 {
+
+ static void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
+ popupWindow.setOverlapAnchor(overlapAnchor);
+ }
+
+ static boolean getOverlapAnchor(PopupWindow popupWindow) {
+ return popupWindow.getOverlapAnchor();
+ }
+
+ static void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+ popupWindow.setWindowLayoutType(layoutType);
+ }
+
+ static int getWindowLayoutType(PopupWindow popupWindow) {
+ return popupWindow.getWindowLayoutType();
+ }
+
+}
diff --git a/v4/build.gradle b/v4/build.gradle
index e64c5ad..939b0c8 100644
--- a/v4/build.gradle
+++ b/v4/build.gradle
@@ -30,6 +30,7 @@
def api20SS = createApiSourceset('api20', 'api20', '20', kitkatSS)
def api21SS = createApiSourceset('api21', 'api21', '21', api20SS)
def api22SS = createApiSourceset('api22', 'api22', 'current', api21SS)
+def api23SS = createApiSourceset('api23', 'api23', 'current', api22SS)
def createApiSourceset(String name, String folder, String apiLevel, SourceSet previousSource) {
diff --git a/v4/donut/android/support/v4/app/NotificationCompatBase.java b/v4/donut/android/support/v4/app/NotificationCompatBase.java
index fdc1da0..777a57f 100644
--- a/v4/donut/android/support/v4/app/NotificationCompatBase.java
+++ b/v4/donut/android/support/v4/app/NotificationCompatBase.java
@@ -19,14 +19,17 @@
import android.app.PendingIntent;
import android.os.Bundle;
-class NotificationCompatBase {
+/**
+ * @hide
+ */
+public class NotificationCompatBase {
public static abstract class Action {
- protected abstract int getIcon();
- protected abstract CharSequence getTitle();
- protected abstract PendingIntent getActionIntent();
- protected abstract Bundle getExtras();
- protected abstract RemoteInputCompatBase.RemoteInput[] getRemoteInputs();
+ public abstract int getIcon();
+ public abstract CharSequence getTitle();
+ public abstract PendingIntent getActionIntent();
+ public abstract Bundle getExtras();
+ public abstract RemoteInputCompatBase.RemoteInput[] getRemoteInputs();
public interface Factory {
Action build(int icon, CharSequence title, PendingIntent actionIntent,
diff --git a/v4/donut/android/support/v4/graphics/drawable/DrawableWrapperDonut.java b/v4/donut/android/support/v4/graphics/drawable/DrawableWrapperDonut.java
index ce8e777..e1cbbe0 100644
--- a/v4/donut/android/support/v4/graphics/drawable/DrawableWrapperDonut.java
+++ b/v4/donut/android/support/v4/graphics/drawable/DrawableWrapperDonut.java
@@ -37,7 +37,8 @@
private ColorStateList mTintList;
private PorterDuff.Mode mTintMode = DEFAULT_MODE;
- private int mCurrentColor = Integer.MIN_VALUE;
+ private boolean mValidCurrentColor;
+ private int mCurrentColor;
Drawable mDrawable;
@@ -205,11 +206,15 @@
private boolean updateTint(int[] state) {
if (mTintList != null && mTintMode != null) {
final int color = mTintList.getColorForState(state, mTintList.getDefaultColor());
- if (color != mCurrentColor) {
+ if (!mValidCurrentColor || color != mCurrentColor) {
setColorFilter(color, mTintMode);
mCurrentColor = color;
+ mValidCurrentColor = true;
return true;
}
+ } else {
+ mValidCurrentColor = false;
+ clearColorFilter();
}
return false;
}
diff --git a/v4/gingerbread/android/support/v4/content/EditorCompatGingerbread.java b/v4/gingerbread/android/support/v4/content/EditorCompatGingerbread.java
new file mode 100644
index 0000000..394964d
--- /dev/null
+++ b/v4/gingerbread/android/support/v4/content/EditorCompatGingerbread.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 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.v4.content;
+
+import android.content.SharedPreferences;
+import android.support.annotation.NonNull;
+
+class EditorCompatGingerbread {
+ public static void apply(@NonNull SharedPreferences.Editor editor) {
+ try {
+ editor.apply();
+ } catch (AbstractMethodError unused) {
+ // The app injected its own pre-Gingerbread
+ // SharedPreferences.Editor implementation without
+ // an apply method.
+ editor.commit();
+ }
+ }
+}
diff --git a/v4/gingerbread/android/support/v4/widget/PopupWindowCompatGingerbread.java b/v4/gingerbread/android/support/v4/widget/PopupWindowCompatGingerbread.java
new file mode 100644
index 0000000..b87db30
--- /dev/null
+++ b/v4/gingerbread/android/support/v4/widget/PopupWindowCompatGingerbread.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 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.v4.widget;
+
+import android.widget.PopupWindow;
+
+import java.lang.reflect.Method;
+
+/**
+ * Implementation of PopupWindow compatibility that can call Gingerbread APIs.
+ */
+class PopupWindowCompatGingerbread {
+
+ private static Method sSetWindowLayoutTypeMethod;
+ private static boolean sSetWindowLayoutTypeMethodAttempted;
+ private static Method sGetWindowLayoutTypeMethod;
+ private static boolean sGetWindowLayoutTypeMethodAttempted;
+
+ static void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+ if (!sSetWindowLayoutTypeMethodAttempted) {
+ try {
+ sSetWindowLayoutTypeMethod = PopupWindow.class.getDeclaredMethod(
+ "setWindowLayoutType", int.class);
+ sSetWindowLayoutTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ // Reflection method fetch failed. Oh well.
+ }
+ sSetWindowLayoutTypeMethodAttempted = true;
+ }
+
+ if (sSetWindowLayoutTypeMethod != null) {
+ try {
+ sSetWindowLayoutTypeMethod.invoke(popupWindow, layoutType);
+ } catch (Exception e) {
+ // Reflection call failed. Oh well.
+ }
+ }
+ }
+
+ static int getWindowLayoutType(PopupWindow popupWindow) {
+ if (!sGetWindowLayoutTypeMethodAttempted) {
+ try {
+ sGetWindowLayoutTypeMethod = PopupWindow.class.getDeclaredMethod(
+ "getWindowLayoutType");
+ sGetWindowLayoutTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ // Reflection method fetch failed. Oh well.
+ }
+ sGetWindowLayoutTypeMethodAttempted = true;
+ }
+
+ if (sGetWindowLayoutTypeMethod != null) {
+ try {
+ return (Integer) sGetWindowLayoutTypeMethod.invoke(popupWindow);
+ } catch (Exception e) {
+ // Reflection call failed. Oh well.
+ }
+ }
+ return 0;
+ }
+
+}
diff --git a/v4/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java b/v4/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
index 4de2e21..f1b2d82 100644
--- a/v4/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
+++ b/v4/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
@@ -22,7 +22,10 @@
* Interface implemented by notification compat builders that support
* an accessor for {@link Notification.Builder}. {@link Notification.Builder}
* was introduced in HoneyComb.
+ *
+ * @hide
*/
-interface NotificationBuilderWithBuilderAccessor {
+public interface NotificationBuilderWithBuilderAccessor {
public Notification.Builder getBuilder();
+ public Notification build();
}
diff --git a/v4/ics/android/support/v4/app/NotificationCompatIceCreamSandwich.java b/v4/ics/android/support/v4/app/NotificationCompatIceCreamSandwich.java
index 97912d9..0842451 100644
--- a/v4/ics/android/support/v4/app/NotificationCompatIceCreamSandwich.java
+++ b/v4/ics/android/support/v4/app/NotificationCompatIceCreamSandwich.java
@@ -23,34 +23,47 @@
import android.widget.RemoteViews;
class NotificationCompatIceCreamSandwich {
- static Notification add(Context context, Notification n,
- CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
- RemoteViews tickerView, int number,
- PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon,
- int progressMax, int progress, boolean progressIndeterminate) {
- Notification.Builder b = new Notification.Builder(context)
- .setWhen(n.when)
- .setSmallIcon(n.icon, n.iconLevel)
- .setContent(n.contentView)
- .setTicker(n.tickerText, tickerView)
- .setSound(n.sound, n.audioStreamType)
- .setVibrate(n.vibrate)
- .setLights(n.ledARGB, n.ledOnMS, n.ledOffMS)
- .setOngoing((n.flags & Notification.FLAG_ONGOING_EVENT) != 0)
- .setOnlyAlertOnce((n.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)
- .setAutoCancel((n.flags & Notification.FLAG_AUTO_CANCEL) != 0)
- .setDefaults(n.defaults)
- .setContentTitle(contentTitle)
- .setContentText(contentText)
- .setContentInfo(contentInfo)
- .setContentIntent(contentIntent)
- .setDeleteIntent(n.deleteIntent)
- .setFullScreenIntent(fullScreenIntent,
- (n.flags & Notification.FLAG_HIGH_PRIORITY) != 0)
- .setLargeIcon(largeIcon)
- .setNumber(number)
- .setProgress(progressMax, progress, progressIndeterminate);
- return b.getNotification();
+ public static class Builder implements NotificationBuilderWithBuilderAccessor {
+
+ private Notification.Builder b;
+
+ public Builder(Context context, Notification n, CharSequence contentTitle,
+ CharSequence contentText, CharSequence contentInfo, RemoteViews tickerView,
+ int number, PendingIntent contentIntent, PendingIntent fullScreenIntent,
+ Bitmap largeIcon, int progressMax, int progress, boolean progressIndeterminate) {
+ b = new Notification.Builder(context)
+ .setWhen(n.when)
+ .setSmallIcon(n.icon, n.iconLevel)
+ .setContent(n.contentView)
+ .setTicker(n.tickerText, tickerView)
+ .setSound(n.sound, n.audioStreamType)
+ .setVibrate(n.vibrate)
+ .setLights(n.ledARGB, n.ledOnMS, n.ledOffMS)
+ .setOngoing((n.flags & Notification.FLAG_ONGOING_EVENT) != 0)
+ .setOnlyAlertOnce((n.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)
+ .setAutoCancel((n.flags & Notification.FLAG_AUTO_CANCEL) != 0)
+ .setDefaults(n.defaults)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .setContentInfo(contentInfo)
+ .setContentIntent(contentIntent)
+ .setDeleteIntent(n.deleteIntent)
+ .setFullScreenIntent(fullScreenIntent,
+ (n.flags & Notification.FLAG_HIGH_PRIORITY) != 0)
+ .setLargeIcon(largeIcon)
+ .setNumber(number)
+ .setProgress(progressMax, progress, progressIndeterminate);
+ }
+
+ @Override
+ public Notification.Builder getBuilder() {
+ return b;
+ }
+
+ @Override
+ public Notification build() {
+ return b.getNotification();
+ }
}
}
diff --git a/v4/ics/android/support/v4/text/ICUCompatIcs.java b/v4/ics/android/support/v4/text/ICUCompatIcs.java
index 7dc5d3c..dfb9e7e 100644
--- a/v4/ics/android/support/v4/text/ICUCompatIcs.java
+++ b/v4/ics/android/support/v4/text/ICUCompatIcs.java
@@ -20,6 +20,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.Locale;
class ICUCompatIcs {
@@ -38,15 +39,27 @@
new Class[]{ String.class });
}
} catch (Exception e) {
+ sGetScriptMethod = null;
+ sAddLikelySubtagsMethod = null;
+
// Nothing we can do here, we just log the exception
Log.w(TAG, e);
}
}
- public static String getScript(String locale) {
+ public static String maximizeAndGetScript(Locale locale) {
+ final String localeWithSubtags = addLikelySubtags(locale);
+ if (localeWithSubtags != null) {
+ return getScript(localeWithSubtags);
+ }
+
+ return null;
+ }
+
+ private static String getScript(String localeStr) {
try {
if (sGetScriptMethod != null) {
- final Object[] args = new Object[] { locale };
+ final Object[] args = new Object[] { localeStr };
return (String) sGetScriptMethod.invoke(null, args);
}
} catch (IllegalAccessException e) {
@@ -60,10 +73,11 @@
return null;
}
- public static String addLikelySubtags(String locale) {
+ private static String addLikelySubtags(Locale locale) {
+ final String localeStr = locale.toString();
try {
if (sAddLikelySubtagsMethod != null) {
- final Object[] args = new Object[] { locale };
+ final Object[] args = new Object[] { localeStr };
return (String) sAddLikelySubtagsMethod.invoke(null, args);
}
} catch (IllegalAccessException e) {
@@ -74,6 +88,7 @@
// Nothing we can do here, we just log the exception
Log.w(TAG, e);
}
- return locale;
+
+ return localeStr;
}
}
diff --git a/v4/java/android/support/v4/app/ActivityCompat.java b/v4/java/android/support/v4/app/ActivityCompat.java
index 8d8bf04..5b4f84e 100644
--- a/v4/java/android/support/v4/app/ActivityCompat.java
+++ b/v4/java/android/support/v4/app/ActivityCompat.java
@@ -21,6 +21,7 @@
import android.content.Intent;
import android.graphics.Matrix;
import android.graphics.RectF;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
@@ -163,6 +164,27 @@
}
/**
+ * Backwards compatible implementation of {@link android.app.Activity#getReferrer()
+ * Activity.getReferrer}. Uses the platform's implementation if available, otherwise
+ * only falls back to digging any explicitly specified referrer from the activity's intent.
+ */
+ public Uri getReferrer(Activity activity) {
+ if (Build.VERSION.SDK_INT >= 22) {
+ return ActivityCompat22.getReferrer(activity);
+ }
+ Intent intent = activity.getIntent();
+ Uri referrer = intent.getParcelableExtra("android.intent.extra.REFERRER");
+ if (referrer != null) {
+ return referrer;
+ }
+ String referrerName = intent.getStringExtra("android.intent.extra.REFERRER_NAME");
+ if (referrerName != null) {
+ return Uri.parse(referrerName);
+ }
+ return null;
+ }
+
+ /**
* When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
* android.view.View, String)} was used to start an Activity, <var>callback</var>
* will be called to handle shared elements on the <i>launched</i> Activity. This requires
diff --git a/v4/java/android/support/v4/app/BackStackRecord.java b/v4/java/android/support/v4/app/BackStackRecord.java
index 25f3ebf..103d04f 100644
--- a/v4/java/android/support/v4/app/BackStackRecord.java
+++ b/v4/java/android/support/v4/app/BackStackRecord.java
@@ -16,12 +16,10 @@
package android.support.v4.app;
-import android.graphics.Rect;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.util.LogWriter;
-import android.support.v4.util.Pair;
import android.support.v4.util.ArrayMap;
import android.text.TextUtils;
import android.util.Log;
@@ -33,7 +31,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collection;
final class BackStackState implements Parcelable {
final int[] mOps;
@@ -48,7 +45,7 @@
final ArrayList<String> mSharedElementSourceNames;
final ArrayList<String> mSharedElementTargetNames;
- public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
+ public BackStackState(BackStackRecord bse) {
int numRemoved = 0;
BackStackRecord.Op op = bse.mHead;
while (op != null) {
@@ -371,14 +368,14 @@
public CharSequence getBreadCrumbTitle() {
if (mBreadCrumbTitleRes != 0) {
- return mManager.mActivity.getText(mBreadCrumbTitleRes);
+ return mManager.mHost.getContext().getText(mBreadCrumbTitleRes);
}
return mBreadCrumbTitleText;
}
public CharSequence getBreadCrumbShortTitle() {
if (mBreadCrumbShortTitleRes != 0) {
- return mManager.mActivity.getText(mBreadCrumbShortTitleRes);
+ return mManager.mHost.getContext().getText(mBreadCrumbShortTitleRes);
}
return mBreadCrumbShortTitleText;
}
@@ -1023,7 +1020,7 @@
// Adding a non-existent target view makes sure that the transitions don't target
// any views by default. They'll only target the views we tell add. If we don't
// add any, then no views will be targeted.
- state.nonExistentView = new View(mManager.mActivity);
+ state.nonExistentView = new View(mManager.mHost.getContext());
boolean anyTransitionStarted = false;
// Go over all leaving fragments.
@@ -1392,7 +1389,7 @@
private static void setNameOverride(ArrayMap<String, String> overrides,
String source, String target) {
- if (source != null && target != null && !source.equals(target)) {
+ if (source != null && target != null) {
for (int index = 0; index < overrides.size(); index++) {
if (source.equals(overrides.valueAt(index))) {
overrides.setValueAt(index, target);
diff --git a/v4/java/android/support/v4/app/DialogFragment.java b/v4/java/android/support/v4/app/DialogFragment.java
index 343c145..fa7ad7b 100644
--- a/v4/java/android/support/v4/app/DialogFragment.java
+++ b/v4/java/android/support/v4/app/DialogFragment.java
@@ -306,23 +306,30 @@
}
mDialog = onCreateDialog(savedInstanceState);
- switch (mStyle) {
- case STYLE_NO_INPUT:
- mDialog.getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
- WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
- // fall through...
- case STYLE_NO_FRAME:
- case STYLE_NO_TITLE:
- mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
- }
+
if (mDialog != null) {
+ setupDialog(mDialog, mStyle);
+
return (LayoutInflater) mDialog.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
- return (LayoutInflater) mActivity.getSystemService(
+ return (LayoutInflater) mHost.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
+
+ /** @hide */
+ public void setupDialog(Dialog dialog, int style) {
+ switch (style) {
+ case STYLE_NO_INPUT:
+ dialog.getWindow().addFlags(
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
+ WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+ // fall through...
+ case STYLE_NO_FRAME:
+ case STYLE_NO_TITLE:
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ }
+ }
/**
* Override to build your own custom Dialog container. This is typically
diff --git a/v4/java/android/support/v4/app/Fragment.java b/v4/java/android/support/v4/app/Fragment.java
index eb6ab0d..1913cae 100644
--- a/v4/java/android/support/v4/app/Fragment.java
+++ b/v4/java/android/support/v4/app/Fragment.java
@@ -22,8 +22,6 @@
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -89,20 +87,21 @@
mArguments = in.readBundle();
mSavedFragmentState = in.readBundle();
}
-
- public Fragment instantiate(FragmentActivity activity, Fragment parent) {
+
+ public Fragment instantiate(FragmentHostCallbacks host, Fragment parent) {
if (mInstance != null) {
return mInstance;
}
-
+
+ final Context context = host.getContext();
if (mArguments != null) {
- mArguments.setClassLoader(activity.getClassLoader());
+ mArguments.setClassLoader(context.getClassLoader());
}
-
- mInstance = Fragment.instantiate(activity, mClassName, mArguments);
-
+
+ mInstance = Fragment.instantiate(context, mClassName, mArguments);
+
if (mSavedFragmentState != null) {
- mSavedFragmentState.setClassLoader(activity.getClassLoader());
+ mSavedFragmentState.setClassLoader(context.getClassLoader());
mInstance.mSavedFragmentState = mSavedFragmentState;
}
mInstance.setIndex(mIndex, parent);
@@ -113,14 +112,14 @@
mInstance.mTag = mTag;
mInstance.mRetainInstance = mRetainInstance;
mInstance.mDetached = mDetached;
- mInstance.mFragmentManager = activity.mFragments;
+ mInstance.mFragmentManager = host.mFragmentManager;
if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
"Instantiated fragment " + mInstance);
return mInstance;
}
-
+
public int describeContents() {
return 0;
}
@@ -228,17 +227,17 @@
// True if this fragment has been restored from previously saved state.
boolean mRestored;
-
+
// Number of active back stack entries this fragment is in.
int mBackStackNesting;
-
+
// The fragment manager we are associated with. Set as soon as the
// fragment is used in a transaction; cleared after it has been removed
// from all transactions.
FragmentManagerImpl mFragmentManager;
- // Activity this fragment is attached to.
- FragmentActivity mActivity;
+ // Host this fragment is attached to.
+ FragmentHostCallbacks mHost;
// Private fragment manager for child fragments inside of this one.
FragmentManagerImpl mChildFragmentManager;
@@ -348,10 +347,12 @@
public static final Parcelable.Creator<SavedState> CREATOR
= new Parcelable.Creator<SavedState>() {
+ @Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in, null);
}
+ @Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
@@ -606,22 +607,39 @@
}
/**
- * Return the Activity this fragment is currently associated with.
+ * Return the {@link Context} this fragment is currently associated with.
+ */
+ public Context getContext() {
+ return mHost == null ? null : mHost.getContext();
+ }
+
+ /**
+ * Return the {@link FragmentActivity} this fragment is currently associated with.
+ * May return {@code null} if the fragment is associated with a {@link Context}
+ * instead.
*/
final public FragmentActivity getActivity() {
- return mActivity;
+ return mHost == null ? null : (FragmentActivity) mHost.getActivity();
}
-
+
+ /**
+ * Return the host object of this fragment. May return {@code null} if the fragment
+ * isn't currently being hosted.
+ */
+ final public Object getHost() {
+ return mHost == null ? null : mHost.getHost();
+ }
+
/**
* Return <code>getActivity().getResources()</code>.
*/
final public Resources getResources() {
- if (mActivity == null) {
+ if (mHost == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
- return mActivity.getResources();
+ return mHost.getContext().getResources();
}
-
+
/**
* Return a localized, styled CharSequence from the application's package's
* default string table.
@@ -701,7 +719,7 @@
* Return true if the fragment is currently added to its activity.
*/
final public boolean isAdded() {
- return mActivity != null && mAdded;
+ return mHost != null && mAdded;
}
/**
@@ -812,14 +830,14 @@
* Report that this fragment would like to participate in populating
* the options menu by receiving a call to {@link #onCreateOptionsMenu}
* and related methods.
- *
+ *
* @param hasMenu If true, the fragment has menu items to contribute.
*/
public void setHasOptionsMenu(boolean hasMenu) {
if (mHasMenu != hasMenu) {
mHasMenu = hasMenu;
if (isAdded() && !isHidden()) {
- mActivity.supportInvalidateOptionsMenu();
+ mHost.supportInvalidateOptionsMenu();
}
}
}
@@ -837,7 +855,7 @@
if (mMenuVisible != menuVisible) {
mMenuVisible = menuVisible;
if (mHasMenu && isAdded() && !isHidden()) {
- mActivity.supportInvalidateOptionsMenu();
+ mHost.supportInvalidateOptionsMenu();
}
}
}
@@ -878,42 +896,42 @@
if (mLoaderManager != null) {
return mLoaderManager;
}
- if (mActivity == null) {
+ if (mHost == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
mCheckedForLoaderManager = true;
- mLoaderManager = mActivity.getLoaderManager(mWho, mLoadersStarted, true);
+ mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, true);
return mLoaderManager;
}
-
+
/**
* Call {@link Activity#startActivity(Intent)} on the fragment's
* containing Activity.
*/
public void startActivity(Intent intent) {
- if (mActivity == null) {
+ if (mHost == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
- mActivity.startActivityFromFragment(this, intent, -1);
+ mHost.startActivityFromFragment(this /*fragment*/, intent, -1);
}
-
+
/**
* Call {@link Activity#startActivityForResult(Intent, int)} on the fragment's
* containing Activity.
*/
public void startActivityForResult(Intent intent, int requestCode) {
- if (mActivity == null) {
+ if (mHost == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
- mActivity.startActivityFromFragment(this, intent, requestCode);
+ mHost.startActivityFromFragment(this /*fragment*/, intent, requestCode);
}
-
+
/**
* Receive the result from a previous call to
* {@link #startActivityForResult(Intent, int)}. This follows the
* related Activity API as described there in
* {@link Activity#onActivityResult(int, int, Intent)}.
- *
+ *
* @param requestCode The integer request code originally supplied to
* startActivityForResult(), allowing you to identify who this
* result came from.
@@ -924,19 +942,19 @@
*/
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
-
+
/**
* @hide Hack so that DialogFragment can make its Dialog before creating
* its views, and the view construction can use the dialog's context for
* inflation. Maybe this should become a public API. Note sure.
*/
public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
- LayoutInflater result = mActivity.getLayoutInflater().cloneInContext(mActivity);
+ LayoutInflater result = mHost.getLayoutInflater();
getChildFragmentManager(); // Init if needed; use raw implementation below.
LayoutInflaterCompat.setFactory(result, mChildFragmentManager.getLayoutInflaterFactory());
return result;
}
-
+
/**
* Called when a fragment is being created as part of a view layout
* inflation, typically from setting the content view of an activity. This
@@ -973,31 +991,61 @@
* {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java
* create}
*
- * @param activity The Activity that is inflating this fragment.
+ * @param context The Activity that is inflating this fragment.
* @param attrs The attributes at the tag where the fragment is
* being created.
* @param savedInstanceState If the fragment is being re-created from
* a previous saved state, this is the state.
*/
+ public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
+ mCalled = true;
+ final Activity hostActivity = mHost == null ? null : mHost.getActivity();
+ if (hostActivity != null) {
+ mCalled = false;
+ onInflate(hostActivity, attrs, savedInstanceState);
+ }
+ }
+
+ /**
+ * Called when a fragment is being created as part of a view layout
+ * inflation, typically from setting the content view of an activity.
+ * <p>Deprecated. See {@link #onInflate(Context, AttributeSet, Bundle)}.
+ */
+ @Deprecated
public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
mCalled = true;
}
/**
- * Called when a fragment is first attached to its activity.
+ * Called when a fragment is first attached to its context.
* {@link #onCreate(Bundle)} will be called after this.
*/
+ public void onAttach(Context context) {
+ mCalled = true;
+ final Activity hostActivity = mHost == null ? null : mHost.getActivity();
+ if (hostActivity != null) {
+ mCalled = false;
+ onAttach(hostActivity);
+ }
+ }
+
+ /**
+ * Called when a fragment is first attached to its activity.
+ * {@link #onCreate(Bundle)} will be called after this.
+ * <p>Deprecated. See {@link #onAttach(Context)}.
+ */
+ @Deprecated
public void onAttach(Activity activity) {
mCalled = true;
}
-
+
/**
* Called when a fragment loads an animation.
*/
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
return null;
}
-
+
/**
* Called to do initial creation of a fragment. This is called after
* {@link #onAttach(Activity)} and before
@@ -1104,19 +1152,19 @@
*/
public void onStart() {
mCalled = true;
-
+
if (!mLoadersStarted) {
mLoadersStarted = true;
if (!mCheckedForLoaderManager) {
mCheckedForLoaderManager = true;
- mLoaderManager = mActivity.getLoaderManager(mWho, mLoadersStarted, false);
+ mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
}
if (mLoaderManager != null) {
mLoaderManager.doStart();
}
}
}
-
+
/**
* Called when the fragment is visible to the user and actively running.
* This is generally
@@ -1198,7 +1246,7 @@
// + " mLoaderManager=" + mLoaderManager);
if (!mCheckedForLoaderManager) {
mCheckedForLoaderManager = true;
- mLoaderManager = mActivity.getLoaderManager(mWho, mLoadersStarted, false);
+ mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
}
if (mLoaderManager != null) {
mLoaderManager.doDestroy();
@@ -1223,7 +1271,7 @@
mBackStackNesting = 0;
mFragmentManager = null;
mChildFragmentManager = null;
- mActivity = null;
+ mHost = null;
mFragmentId = 0;
mContainerId = 0;
mTag = null;
@@ -1335,6 +1383,7 @@
* It is not safe to hold onto the context menu after this method returns.
* {@inheritDoc}
*/
+ @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
getActivity().onCreateContextMenu(menu, v, menuInfo);
}
@@ -1678,9 +1727,9 @@
writer.print(prefix); writer.print("mFragmentManager=");
writer.println(mFragmentManager);
}
- if (mActivity != null) {
- writer.print(prefix); writer.print("mActivity=");
- writer.println(mActivity);
+ if (mHost != null) {
+ writer.print(prefix); writer.print("mHost=");
+ writer.println(mHost);
}
if (mParentFragment != null) {
writer.print(prefix); writer.print("mParentFragment=");
@@ -1741,7 +1790,7 @@
void instantiateChildFragmentManager() {
mChildFragmentManager = new FragmentManagerImpl();
- mChildFragmentManager.attachActivity(mActivity, new FragmentContainer() {
+ mChildFragmentManager.attachController(mHost, new FragmentContainer() {
@Override
@Nullable
public View findViewById(int id) {
@@ -1974,10 +2023,10 @@
mLoadersStarted = false;
if (!mCheckedForLoaderManager) {
mCheckedForLoaderManager = true;
- mLoaderManager = mActivity.getLoaderManager(mWho, mLoadersStarted, false);
+ mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
}
if (mLoaderManager != null) {
- if (!mActivity.mRetaining) {
+ if (!mRetaining) {
mLoaderManager.doStop();
} else {
mLoaderManager.doRetain();
diff --git a/v4/java/android/support/v4/app/FragmentActivity.java b/v4/java/android/support/v4/app/FragmentActivity.java
index 566ffed..2bf3189 100644
--- a/v4/java/android/support/v4/app/FragmentActivity.java
+++ b/v4/java/android/support/v4/app/FragmentActivity.java
@@ -31,6 +31,7 @@
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -40,6 +41,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
/**
* Base class for activities that want to use the support-based
@@ -75,9 +77,9 @@
*/
public class FragmentActivity extends Activity {
private static final String TAG = "FragmentActivity";
-
+
static final String FRAGMENTS_TAG = "android:support:fragments";
-
+
// This is the SDK API version of Honeycomb (3.0).
private static final int HONEYCOMB = 11;
@@ -103,21 +105,8 @@
}
};
- final FragmentManagerImpl mFragments = new FragmentManagerImpl();
- final FragmentContainer mContainer = new FragmentContainer() {
- @Override
- @Nullable
- public View findViewById(int id) {
- return FragmentActivity.this.findViewById(id);
- }
+ final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
- @Override
- public boolean hasView() {
- Window window = FragmentActivity.this.getWindow();
- return (window != null && window.peekDecorView() != null);
- }
- };
-
boolean mCreated;
boolean mResumed;
boolean mStopped;
@@ -126,23 +115,16 @@
boolean mOptionsMenuInvalidated;
- boolean mCheckedForLoaderManager;
- boolean mLoadersStarted;
- SimpleArrayMap<String, LoaderManagerImpl> mAllLoaderManagers;
- LoaderManagerImpl mLoaderManager;
-
static final class NonConfigurationInstances {
- Object activity;
Object custom;
- SimpleArrayMap<String, Object> children;
ArrayList<Fragment> fragments;
- SimpleArrayMap<String, LoaderManagerImpl> loaders;
+ SimpleArrayMap<String, LoaderManager> loaders;
}
-
+
// ------------------------------------------------------------------------
// HOOKS INTO ACTIVITY
// ------------------------------------------------------------------------
-
+
/**
* Dispatch incoming result to the correct fragment.
*/
@@ -152,12 +134,15 @@
int index = requestCode>>16;
if (index != 0) {
index--;
- if (mFragments.mActive == null || index < 0 || index >= mFragments.mActive.size()) {
+ final int activeFragmentsCount = mFragments.getActiveFragmentsCount();
+ if (activeFragmentsCount == 0 || index < 0 || index >= activeFragmentsCount) {
Log.w(TAG, "Activity result fragment index out of range: 0x"
+ Integer.toHexString(requestCode));
return;
}
- Fragment frag = mFragments.mActive.get(index);
+ final List<Fragment> activeFragments =
+ mFragments.getActiveFragments(new ArrayList<Fragment>(activeFragmentsCount));
+ Fragment frag = activeFragments.get(index);
if (frag == null) {
Log.w(TAG, "Activity result no fragment exists for index: 0x"
+ Integer.toHexString(requestCode));
@@ -166,7 +151,7 @@
}
return;
}
-
+
super.onActivityResult(requestCode, resultCode, data);
}
@@ -175,7 +160,7 @@
* as appropriate.
*/
public void onBackPressed() {
- if (!mFragments.popBackStackImmediate()) {
+ if (!mFragments.getSupportFragmentManager().popBackStackImmediate()) {
supportFinishAfterTransition();
}
}
@@ -246,20 +231,21 @@
/**
* Perform initialization of all fragments and loaders.
*/
+ @SuppressWarnings("deprecation")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
- mFragments.attachActivity(this, mContainer, null);
+ mFragments.attachHost(null /*parent*/);
// Old versions of the platform didn't do this!
if (getLayoutInflater().getFactory() == null) {
getLayoutInflater().setFactory(this);
}
-
+
super.onCreate(savedInstanceState);
-
- NonConfigurationInstances nc = (NonConfigurationInstances)
- getLastNonConfigurationInstance();
+
+ NonConfigurationInstances nc =
+ (NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
- mAllLoaderManagers = nc.loaders;
+ mFragments.restoreLoaderNonConfig(nc.loaders);
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
@@ -286,7 +272,7 @@
}
return super.onCreatePanelMenu(featureId, menu);
}
-
+
/**
* Add support for inflating the <fragment> tag.
*/
@@ -314,9 +300,7 @@
doReallyStop(false);
mFragments.dispatchDestroy();
- if (mLoaderManager != null) {
- mLoaderManager.doDestroy();
- }
+ mFragments.doLoaderDestroy();
}
/**
@@ -486,35 +470,16 @@
Object custom = onRetainCustomNonConfigurationInstance();
ArrayList<Fragment> fragments = mFragments.retainNonConfig();
- boolean retainLoaders = false;
- if (mAllLoaderManagers != null) {
- // prune out any loader managers that were already stopped and so
- // have nothing useful to retain.
- final int N = mAllLoaderManagers.size();
- LoaderManagerImpl loaders[] = new LoaderManagerImpl[N];
- for (int i=N-1; i>=0; i--) {
- loaders[i] = mAllLoaderManagers.valueAt(i);
- }
- for (int i=0; i<N; i++) {
- LoaderManagerImpl lm = loaders[i];
- if (lm.mRetaining) {
- retainLoaders = true;
- } else {
- lm.doDestroy();
- mAllLoaderManagers.remove(lm.mWho);
- }
- }
- }
- if (fragments == null && !retainLoaders && custom == null) {
+ SimpleArrayMap<String, LoaderManager> loaders = mFragments.retainLoaderNonConfig();
+
+ if (fragments == null && loaders == null && custom == null) {
return null;
}
-
+
NonConfigurationInstances nci = new NonConfigurationInstances();
- nci.activity = null;
nci.custom = custom;
- nci.children = null;
nci.fragments = fragments;
- nci.loaders = mAllLoaderManagers;
+ nci.loaders = loaders;
return nci;
}
@@ -549,35 +514,13 @@
mFragments.noteStateNotSaved();
mFragments.execPendingActions();
-
- if (!mLoadersStarted) {
- mLoadersStarted = true;
- if (mLoaderManager != null) {
- mLoaderManager.doStart();
- } else if (!mCheckedForLoaderManager) {
- mLoaderManager = getLoaderManager("(root)", mLoadersStarted, false);
- // the returned loader manager may be a new one, so we have to start it
- if ((mLoaderManager != null) && (!mLoaderManager.mStarted)) {
- mLoaderManager.doStart();
- }
- }
- mCheckedForLoaderManager = true;
- }
+
+ mFragments.doLoaderStart();
+
// NOTE: HC onStart goes here.
-
+
mFragments.dispatchStart();
- if (mAllLoaderManagers != null) {
- final int N = mAllLoaderManagers.size();
- LoaderManagerImpl loaders[] = new LoaderManagerImpl[N];
- for (int i=N-1; i>=0; i--) {
- loaders[i] = mAllLoaderManagers.valueAt(i);
- }
- for (int i=0; i<N; i++) {
- LoaderManagerImpl lm = loaders[i];
- lm.finishRetain();
- lm.doReportStart();
- }
- }
+ mFragments.reportLoaderStart();
}
/**
@@ -589,14 +532,14 @@
mStopped = true;
mHandler.sendEmptyMessage(MSG_REALLY_STOPPED);
-
+
mFragments.dispatchStop();
}
// ------------------------------------------------------------------------
// NEW METHODS
// ------------------------------------------------------------------------
-
+
/**
* Use this instead of {@link #onRetainNonConfigurationInstance()}.
* Retrieve later with {@link #getLastCustomNonConfigurationInstance()}.
@@ -609,6 +552,7 @@
* Return the value previously returned from
* {@link #onRetainCustomNonConfigurationInstance()}.
*/
+ @SuppressWarnings("deprecation")
public Object getLastCustomNonConfigurationInstance() {
NonConfigurationInstances nc = (NonConfigurationInstances)
getLastNonConfigurationInstance();
@@ -659,15 +603,8 @@
writer.print(mResumed); writer.print(" mStopped=");
writer.print(mStopped); writer.print(" mReallyStopped=");
writer.println(mReallyStopped);
- writer.print(innerPrefix); writer.print("mLoadersStarted=");
- writer.println(mLoadersStarted);
- if (mLoaderManager != null) {
- writer.print(prefix); writer.print("Loader Manager ");
- writer.print(Integer.toHexString(System.identityHashCode(mLoaderManager)));
- writer.println(":");
- mLoaderManager.dump(prefix + " ", fd, writer, args);
- }
- mFragments.dump(prefix, fd, writer, args);
+ mFragments.dumpLoaders(innerPrefix, fd, writer, args);
+ mFragments.getSupportFragmentManager().dump(prefix, fd, writer, args);
writer.print(prefix); writer.println("View Hierarchy:");
dumpViewHierarchy(prefix + " ", writer, getWindow().getDecorView());
}
@@ -776,16 +713,7 @@
* tell us what we need to know.
*/
void onReallyStop() {
- if (mLoadersStarted) {
- mLoadersStarted = false;
- if (mLoaderManager != null) {
- if (!mRetaining) {
- mLoaderManager.doStop();
- } else {
- mLoaderManager.doRetain();
- }
- }
- }
+ mFragments.doLoaderStop(mRetaining);
mFragments.dispatchReallyStop();
}
@@ -793,19 +721,24 @@
// ------------------------------------------------------------------------
// FRAGMENT SUPPORT
// ------------------------------------------------------------------------
-
+
/**
* Called when a fragment is attached to the activity.
*/
+ @SuppressWarnings("unused")
public void onAttachFragment(Fragment fragment) {
}
-
+
/**
* Return the FragmentManager for interacting with fragments associated
* with this activity.
*/
public FragmentManager getSupportFragmentManager() {
- return mFragments;
+ return mFragments.getSupportFragmentManager();
+ }
+
+ public LoaderManager getSupportLoaderManager() {
+ return mFragments.getSupportLoaderManager();
}
/**
@@ -823,7 +756,7 @@
/**
* Called by Fragment.startActivityForResult() to implement its behavior.
*/
- public void startActivityFromFragment(Fragment fragment, Intent intent,
+ public void startActivityFromFragment(Fragment fragment, Intent intent,
int requestCode) {
if (requestCode == -1) {
super.startActivityForResult(intent, -1);
@@ -834,47 +767,63 @@
}
super.startActivityForResult(intent, ((fragment.mIndex+1)<<16) + (requestCode&0xffff));
}
-
- void invalidateSupportFragment(String who) {
- //Log.v(TAG, "invalidateSupportFragment: who=" + who);
- if (mAllLoaderManagers != null) {
- LoaderManagerImpl lm = mAllLoaderManagers.get(who);
- if (lm != null && !lm.mRetaining) {
- lm.doDestroy();
- mAllLoaderManagers.remove(who);
- }
+
+ class HostCallbacks extends FragmentHostCallbacks<FragmentActivity> {
+ public HostCallbacks() {
+ super(FragmentActivity.this /*fragmentActivity*/);
}
- }
-
- // ------------------------------------------------------------------------
- // LOADER SUPPORT
- // ------------------------------------------------------------------------
-
- /**
- * Return the LoaderManager for this fragment, creating it if needed.
- */
- public LoaderManager getSupportLoaderManager() {
- if (mLoaderManager != null) {
- return mLoaderManager;
+
+ @Override
+ public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+ FragmentActivity.this.dump(prefix, fd, writer, args);
}
- mCheckedForLoaderManager = true;
- mLoaderManager = getLoaderManager("(root)", mLoadersStarted, true);
- return mLoaderManager;
- }
-
- LoaderManagerImpl getLoaderManager(String who, boolean started, boolean create) {
- if (mAllLoaderManagers == null) {
- mAllLoaderManagers = new SimpleArrayMap<String, LoaderManagerImpl>();
+
+ @Override
+ public boolean shouldSaveFragmentState(Fragment fragment) {
+ return !isFinishing();
}
- LoaderManagerImpl lm = mAllLoaderManagers.get(who);
- if (lm == null) {
- if (create) {
- lm = new LoaderManagerImpl(who, this, started);
- mAllLoaderManagers.put(who, lm);
- }
- } else {
- lm.updateActivity(this);
+
+ @Override
+ public LayoutInflater getLayoutInflater() {
+ return FragmentActivity.this.getLayoutInflater().cloneInContext(FragmentActivity.this);
}
- return lm;
+
+ @Override
+ public FragmentActivity getHost() {
+ return FragmentActivity.this;
+ }
+
+ @Override
+ public void supportInvalidateOptionsMenu() {
+ FragmentActivity.this.supportInvalidateOptionsMenu();
+ }
+
+ @Override
+ public void startActivityFromFragment(Fragment fragment, Intent intent, int requestCode) {
+ FragmentActivity.this.startActivityFromFragment(fragment, intent, requestCode);
+ }
+
+ @Override
+ public boolean hasWindowAnimations() {
+ return getWindow() != null;
+ }
+
+ @Override
+ public int getWindowAnimations() {
+ final Window w = getWindow();
+ return (w == null) ? 0 : w.getAttributes().windowAnimations;
+ }
+
+ @Nullable
+ @Override
+ public View findViewById(int id) {
+ return FragmentActivity.this.findViewById(id);
+ }
+
+ @Override
+ public boolean hasView() {
+ final Window w = getWindow();
+ return (w != null && w.peekDecorView() != null);
+ }
}
}
diff --git a/v4/java/android/support/v4/app/FragmentContainer.java b/v4/java/android/support/v4/app/FragmentContainer.java
new file mode 100644
index 0000000..74cd7cc
--- /dev/null
+++ b/v4/java/android/support/v4/app/FragmentContainer.java
@@ -0,0 +1,23 @@
+package android.support.v4.app;
+
+import android.support.annotation.IdRes;
+import android.support.annotation.Nullable;
+import android.view.View;
+
+
+/**
+ * Callbacks to a {@link Fragment}'s container.
+ */
+public abstract class FragmentContainer {
+ /**
+ * Return the view with the given resource ID. May return {@code null} if the
+ * view is not a child of this container.
+ */
+ @Nullable
+ public abstract View findViewById(@IdRes int id);
+
+ /**
+ * Return {@code true} if the container holds any view.
+ */
+ public abstract boolean hasView();
+}
diff --git a/v4/java/android/support/v4/app/FragmentController.java b/v4/java/android/support/v4/app/FragmentController.java
new file mode 100644
index 0000000..2651aff
--- /dev/null
+++ b/v4/java/android/support/v4/app/FragmentController.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2015 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.v4.app;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.Parcelable;
+import android.support.v4.util.SimpleArrayMap;
+import android.util.AttributeSet;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provides integration points with a {@link FragmentManager}. For example, a fragment
+ * host, such as {@link FragmentActivity}, uses the {@link FragmentController} to control
+ * the {@link Fragment} lifecycle.
+ */
+public class FragmentController {
+ private final FragmentHostCallbacks<?> mHost;
+
+ /**
+ * Returns a {@link FragmentController}.
+ */
+ public static final FragmentController createController(FragmentHostCallbacks<?> callbacks) {
+ return new FragmentController(callbacks);
+ }
+
+ private FragmentController(FragmentHostCallbacks<?> callbacks) {
+ mHost = callbacks;
+ }
+
+ public FragmentManager getSupportFragmentManager() {
+ return mHost.getFragmentManagerImpl();
+ }
+
+ public LoaderManager getSupportLoaderManager() {
+ return mHost.getLoaderManagerImpl();
+ }
+
+ /** Returns the number of active fragments. */
+ public int getActiveFragmentsCount() {
+ final List<Fragment> actives = mHost.mFragmentManager.mActive;
+ return actives == null ? 0 : actives.size();
+ }
+
+ /** Returns the list of active fragments. */
+ public List<Fragment> getActiveFragments(List<Fragment> actives) {
+ if (mHost.mFragmentManager.mActive == null) {
+ return null;
+ }
+ if (actives == null) {
+ actives = new ArrayList<Fragment>(getActiveFragmentsCount());
+ }
+ actives.addAll(mHost.mFragmentManager.mActive);
+ return actives;
+ }
+
+ /** Attaches the host to the FragmentManager. */
+ public void attachHost(Fragment parent) {
+ mHost.mFragmentManager.attachController(
+ mHost, mHost /*container*/, parent);
+ }
+
+ public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
+ return mHost.mFragmentManager.onCreateView(parent, name, context, attrs);
+ }
+
+ /**
+ * Marks the fragment state as unsaved. This allows for "state loss" detection.
+ */
+ public void noteStateNotSaved() {
+ mHost.mFragmentManager.noteStateNotSaved();
+ }
+
+ /**
+ * Saves the state for all Fragments.
+ */
+ public Parcelable saveAllState() {
+ return mHost.mFragmentManager.saveAllState();
+ }
+
+ /**
+ * Restores the saved state for all Fragments. The given Fragment list are Fragment
+ * instances retained across configuration changes.
+ *
+ * @see #retainNonConfig()
+ */
+ public void restoreAllState(Parcelable state, ArrayList<Fragment> nonConfigList) {
+ mHost.mFragmentManager.restoreAllState(state, nonConfigList);
+ }
+
+ /**
+ * Returns a list of Fragments that have opted to retain their instance across
+ * configuration changes.
+ */
+ public ArrayList<Fragment> retainNonConfig() {
+ return mHost.mFragmentManager.retainNonConfig();
+ }
+
+ public void dispatchCreate() {
+ mHost.mFragmentManager.dispatchCreate();
+ }
+
+ public void dispatchActivityCreated() {
+ mHost.mFragmentManager.dispatchActivityCreated();
+ }
+
+ public void dispatchStart() {
+ mHost.mFragmentManager.dispatchStart();
+ }
+
+ public void dispatchResume() {
+ mHost.mFragmentManager.dispatchResume();
+ }
+
+ public void dispatchPause() {
+ mHost.mFragmentManager.dispatchPause();
+ }
+
+ public void dispatchStop() {
+ mHost.mFragmentManager.dispatchStop();
+ }
+
+ public void dispatchReallyStop() {
+ mHost.mFragmentManager.dispatchReallyStop();
+ }
+
+ public void dispatchDestroyView() {
+ mHost.mFragmentManager.dispatchDestroyView();
+ }
+
+ public void dispatchDestroy() {
+ mHost.mFragmentManager.dispatchDestroy();
+ }
+
+ public void dispatchConfigurationChanged(Configuration newConfig) {
+ mHost.mFragmentManager.dispatchConfigurationChanged(newConfig);
+ }
+
+ public void dispatchLowMemory() {
+ mHost.mFragmentManager.dispatchLowMemory();
+ }
+
+ public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ return mHost.mFragmentManager.dispatchCreateOptionsMenu(menu, inflater);
+ }
+
+ public boolean dispatchPrepareOptionsMenu(Menu menu) {
+ return mHost.mFragmentManager.dispatchPrepareOptionsMenu(menu);
+ }
+
+ public boolean dispatchOptionsItemSelected(MenuItem item) {
+ return mHost.mFragmentManager.dispatchOptionsItemSelected(item);
+ }
+
+ public boolean dispatchContextItemSelected(MenuItem item) {
+ return mHost.mFragmentManager.dispatchContextItemSelected(item);
+ }
+
+ public void dispatchOptionsMenuClosed(Menu menu) {
+ mHost.mFragmentManager.dispatchOptionsMenuClosed(menu);
+ }
+
+ public boolean execPendingActions() {
+ return mHost.mFragmentManager.execPendingActions();
+ }
+
+ /**
+ * Starts the loaders.
+ */
+ public void doLoaderStart() {
+ mHost.doLoaderStart();
+ }
+
+ /**
+ * Stops the loaders, optionally retaining their state. This is useful for keeping the
+ * loader state across configuration changes.
+ *
+ * @param retain When {@code true}, the loaders aren't stopped, but, their instances
+ * are retained in a started state
+ */
+ public void doLoaderStop(boolean retain) {
+ mHost.doLoaderStop(retain);
+ }
+
+ /**
+ * Retains the state of each of the loaders.
+ */
+ public void doLoaderRetain() {
+ mHost.doLoaderRetain();
+ }
+
+ /**
+ * Destroys all inactive loaders and optionally destroys all active loaders. Active loaders
+ * will not be destroyed if their state is retained.
+ */
+ public void doLoaderDestroy() {
+ mHost.doLoaderDestroy();
+ }
+
+ /**
+ * Reports all loaders as started.
+ */
+ public void reportLoaderStart() {
+ mHost.reportLoaderStart();
+ }
+
+ /**
+ * Returns a list of LoaderManagers that have opted to retain their instance across
+ * configuration changes.
+ */
+ public SimpleArrayMap<String, LoaderManager> retainLoaderNonConfig() {
+ return mHost.retainLoaderNonConfig();
+ }
+
+ /**
+ * Restores the saved state for all LoaderManagers. The given LoaderManager list are
+ * LoaderManager instances retained across configuration changes.
+ *
+ * @see #retainLoaderNonConfig()
+ */
+ public void restoreLoaderNonConfig(SimpleArrayMap<String, LoaderManager> loaderManagers) {
+ mHost.restoreLoaderNonConfig(loaderManagers);
+ }
+
+ public void dumpLoaders(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+ mHost.dumpLoaders(prefix, fd, writer, args);
+ }
+}
diff --git a/v4/java/android/support/v4/app/FragmentHostCallbacks.java b/v4/java/android/support/v4/app/FragmentHostCallbacks.java
new file mode 100644
index 0000000..d304f3a
--- /dev/null
+++ b/v4/java/android/support/v4/app/FragmentHostCallbacks.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2015 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.v4.app;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.Nullable;
+import android.support.v4.util.SimpleArrayMap;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Provides integration points with the host that is managing the {@link Fragment} lifecycle.
+ */
+public class FragmentHostCallbacks<E> extends FragmentContainer {
+ private final Activity mActivity;
+ final Context mContext;
+ private final Handler mHandler;
+ final int mWindowAnimations;
+ final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
+ private SimpleArrayMap<String, LoaderManager> mAllLoaderManagers;
+ private LoaderManagerImpl mLoaderManager;
+ private boolean mCheckedForLoaderManager;
+ private boolean mLoadersStarted;
+
+ public FragmentHostCallbacks(Context context, Handler handler, int windowAnimations) {
+ this(null /*activity*/, context, handler, windowAnimations);
+ }
+
+ FragmentHostCallbacks(FragmentActivity activity) {
+ this(activity, activity /*context*/, activity.mHandler, 0 /*windowAnimations*/);
+ }
+
+ FragmentHostCallbacks(Activity activity, Context context, Handler handler,
+ int windowAnimations) {
+ mActivity = activity;
+ mContext = context;
+ mHandler = handler;
+ mWindowAnimations = windowAnimations;
+ }
+
+ /**
+ * Print internal state into the given stream.
+ *
+ * @param prefix Desired prefix to prepend at each line of output.
+ * @param fd The raw file descriptor that the dump is being sent to.
+ * @param writer The PrintWriter to which you should dump your state. This will be closed
+ * for you after you return.
+ * @param args additional arguments to the dump request.
+ */
+ public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+ }
+
+ /**
+ * Return {@code true} if the fragment's state needs to be saved.
+ */
+ public boolean shouldSaveFragmentState(Fragment fragment) {
+ return true;
+ }
+
+ /**
+ * Return a {@link LayoutInflater}.
+ * See {@link Activity#getLayoutInflater()}.
+ */
+ public LayoutInflater getLayoutInflater() {
+ return (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ /**
+ * Return the object that's currently hosting the fragment. If a {@link Fragment}
+ * is hosted by a {@link FragmentActivity}, the object returned here should be
+ * the same object returned from {@link Fragment#getActivity()}.
+ */
+ @Nullable
+ public E getHost() {
+ return null;
+ }
+
+ /**
+ * Invalidates the activity's options menu.
+ * See {@link FragmentActivity#supportInvalidateOptionsMenu()}
+ */
+ public void supportInvalidateOptionsMenu() {
+ }
+
+ /**
+ * Starts a new {@link Activity} from the given fragment.
+ * See {@link FragmentActivity#startActivityForResult(Intent, int)}.
+ */
+ public void startActivityFromFragment(Fragment fragment, Intent intent, int requestCode) {
+ if (requestCode != -1) {
+ throw new IllegalStateException(
+ "Starting activity with a requestCode requires a FragmentActivity host");
+ }
+ mContext.startActivity(intent);
+ }
+
+ /**
+ * Return {@code true} if there are window animations.
+ */
+ public boolean hasWindowAnimations() {
+ return true;
+ }
+
+ /**
+ * Return the window animations.
+ */
+ public int getWindowAnimations() {
+ return mWindowAnimations;
+ }
+
+ @Nullable
+ @Override
+ public View findViewById(int id) {
+ return null;
+ }
+
+ @Override
+ public boolean hasView() {
+ return true;
+ }
+
+ Activity getActivity() {
+ return mActivity;
+ }
+
+ Context getContext() {
+ return mContext;
+ }
+
+ Handler getHandler() {
+ return mHandler;
+ }
+
+ FragmentManagerImpl getFragmentManagerImpl() {
+ return mFragmentManager;
+ }
+
+ LoaderManagerImpl getLoaderManagerImpl() {
+ if (mLoaderManager != null) {
+ return mLoaderManager;
+ }
+ mCheckedForLoaderManager = true;
+ mLoaderManager = getLoaderManager("(root)", mLoadersStarted, true /*create*/);
+ return mLoaderManager;
+ }
+
+ void inactivateFragment(String who) {
+ //Log.v(TAG, "invalidateSupportFragment: who=" + who);
+ if (mAllLoaderManagers != null) {
+ LoaderManagerImpl lm = (LoaderManagerImpl) mAllLoaderManagers.get(who);
+ if (lm != null && !lm.mRetaining) {
+ lm.doDestroy();
+ mAllLoaderManagers.remove(who);
+ }
+ }
+ }
+
+ void onFragmentInflate(Fragment fragment, AttributeSet attrs, Bundle savedInstanceState) {
+ fragment.onInflate(mContext, attrs, savedInstanceState);
+ }
+
+ void onFragmentAttach(Fragment fragment) {
+ fragment.onAttach(mContext);
+ }
+
+ void doLoaderStart() {
+ if (mLoadersStarted) {
+ return;
+ }
+ mLoadersStarted = true;
+
+ if (mLoaderManager != null) {
+ mLoaderManager.doStart();
+ } else if (!mCheckedForLoaderManager) {
+ mLoaderManager = getLoaderManager("(root)", mLoadersStarted, false);
+ // the returned loader manager may be a new one, so we have to start it
+ if ((mLoaderManager != null) && (!mLoaderManager.mStarted)) {
+ mLoaderManager.doStart();
+ }
+ }
+ mCheckedForLoaderManager = true;
+ }
+
+ // retain -- whether to stop the loader or retain it
+ void doLoaderStop(boolean retain) {
+ if (mLoaderManager == null) {
+ return;
+ }
+
+ if (!mLoadersStarted) {
+ return;
+ }
+ mLoadersStarted = false;
+
+ if (retain) {
+ mLoaderManager.doRetain();
+ } else {
+ mLoaderManager.doStop();
+ }
+ }
+
+ void doLoaderRetain() {
+ if (mLoaderManager == null) {
+ return;
+ }
+ mLoaderManager.doRetain();
+ }
+
+ void doLoaderDestroy() {
+ if (mLoaderManager == null) {
+ return;
+ }
+ mLoaderManager.doDestroy();
+ }
+
+ void reportLoaderStart() {
+ if (mAllLoaderManagers != null) {
+ final int N = mAllLoaderManagers.size();
+ LoaderManagerImpl loaders[] = new LoaderManagerImpl[N];
+ for (int i=N-1; i>=0; i--) {
+ loaders[i] = (LoaderManagerImpl) mAllLoaderManagers.valueAt(i);
+ }
+ for (int i=0; i<N; i++) {
+ LoaderManagerImpl lm = loaders[i];
+ lm.finishRetain();
+ lm.doReportStart();
+ }
+ }
+ }
+
+ LoaderManagerImpl getLoaderManager(String who, boolean started, boolean create) {
+ if (mAllLoaderManagers == null) {
+ mAllLoaderManagers = new SimpleArrayMap<String, LoaderManager>();
+ }
+ LoaderManagerImpl lm = (LoaderManagerImpl) mAllLoaderManagers.get(who);
+ if (lm == null) {
+ if (create) {
+ lm = new LoaderManagerImpl(who, this, started);
+ mAllLoaderManagers.put(who, lm);
+ }
+ } else {
+ lm.updateHostController(this);
+ }
+ return lm;
+ }
+
+ SimpleArrayMap<String, LoaderManager> retainLoaderNonConfig() {
+ boolean retainLoaders = false;
+ if (mAllLoaderManagers != null) {
+ // prune out any loader managers that were already stopped and so
+ // have nothing useful to retain.
+ final int N = mAllLoaderManagers.size();
+ LoaderManagerImpl loaders[] = new LoaderManagerImpl[N];
+ for (int i=N-1; i>=0; i--) {
+ loaders[i] = (LoaderManagerImpl) mAllLoaderManagers.valueAt(i);
+ }
+ for (int i=0; i<N; i++) {
+ LoaderManagerImpl lm = loaders[i];
+ if (lm.mRetaining) {
+ retainLoaders = true;
+ } else {
+ lm.doDestroy();
+ mAllLoaderManagers.remove(lm.mWho);
+ }
+ }
+ }
+
+ if (retainLoaders) {
+ return mAllLoaderManagers;
+ }
+ return null;
+ }
+
+ void restoreLoaderNonConfig(SimpleArrayMap<String, LoaderManager> loaderManagers) {
+ mAllLoaderManagers = loaderManagers;
+ }
+
+ void dumpLoaders(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+ writer.print(prefix); writer.print("mLoadersStarted=");
+ writer.println(mLoadersStarted);
+ if (mLoaderManager != null) {
+ writer.print(prefix); writer.print("Loader Manager ");
+ writer.print(Integer.toHexString(System.identityHashCode(mLoaderManager)));
+ writer.println(":");
+ mLoaderManager.dump(prefix + " ", fd, writer, args);
+ }
+ }
+}
diff --git a/v4/java/android/support/v4/app/FragmentManager.java b/v4/java/android/support/v4/app/FragmentManager.java
index 6d41d45..5739057 100644
--- a/v4/java/android/support/v4/app/FragmentManager.java
+++ b/v4/java/android/support/v4/app/FragmentManager.java
@@ -26,7 +26,6 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IdRes;
-import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.util.DebugUtils;
import android.support.v4.util.LogWriter;
@@ -399,15 +398,6 @@
}
/**
- * Callbacks from FragmentManagerImpl to its container.
- */
-interface FragmentContainer {
- @Nullable
- public View findViewById(@IdRes int id);
- public boolean hasView();
-}
-
-/**
* Container for fragments associated with an activity.
*/
final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
@@ -438,7 +428,8 @@
ArrayList<OnBackStackChangedListener> mBackStackChangeListeners;
int mCurState = Fragment.INITIALIZING;
- FragmentActivity mActivity;
+ FragmentHostCallbacks mHost;
+ FragmentController mController;
FragmentContainer mContainer;
Fragment mParent;
@@ -464,9 +455,9 @@
Log.e(TAG, "Activity state:");
LogWriter logw = new LogWriter(TAG);
PrintWriter pw = new PrintWriter(logw);
- if (mActivity != null) {
+ if (mHost != null) {
try {
- mActivity.dump(" ", null, pw, new String[] { });
+ mHost.dump(" ", null, pw, new String[] { });
} catch (Exception e) {
Log.e(TAG, "Failed dumping state", e);
}
@@ -494,7 +485,7 @@
public void popBackStack() {
enqueueAction(new Runnable() {
@Override public void run() {
- popBackStackState(mActivity.mHandler, null, -1, 0);
+ popBackStackState(mHost.getHandler(), null, -1, 0);
}
}, false);
}
@@ -503,14 +494,14 @@
public boolean popBackStackImmediate() {
checkStateLoss();
executePendingTransactions();
- return popBackStackState(mActivity.mHandler, null, -1, 0);
+ return popBackStackState(mHost.getHandler(), null, -1, 0);
}
@Override
public void popBackStack(final String name, final int flags) {
enqueueAction(new Runnable() {
@Override public void run() {
- popBackStackState(mActivity.mHandler, name, -1, flags);
+ popBackStackState(mHost.getHandler(), name, -1, flags);
}
}, false);
}
@@ -519,7 +510,7 @@
public boolean popBackStackImmediate(String name, int flags) {
checkStateLoss();
executePendingTransactions();
- return popBackStackState(mActivity.mHandler, name, -1, flags);
+ return popBackStackState(mHost.getHandler(), name, -1, flags);
}
@Override
@@ -529,7 +520,7 @@
}
enqueueAction(new Runnable() {
@Override public void run() {
- popBackStackState(mActivity.mHandler, null, id, flags);
+ popBackStackState(mHost.getHandler(), null, id, flags);
}
}, false);
}
@@ -541,7 +532,7 @@
if (id < 0) {
throw new IllegalArgumentException("Bad id: " + id);
}
- return popBackStackState(mActivity.mHandler, null, id, flags);
+ return popBackStackState(mHost.getHandler(), null, id, flags);
}
@Override
@@ -628,7 +619,7 @@
if (mParent != null) {
DebugUtils.buildShortClassTag(mParent, sb);
} else {
- DebugUtils.buildShortClassTag(mActivity, sb);
+ DebugUtils.buildShortClassTag(mHost, sb);
}
sb.append("}}");
return sb.toString();
@@ -725,7 +716,7 @@
}
writer.print(prefix); writer.println("FragmentManager misc state:");
- writer.print(prefix); writer.print(" mActivity="); writer.println(mActivity);
+ writer.print(prefix); writer.print(" mHost="); writer.println(mHost);
writer.print(prefix); writer.print(" mContainer="); writer.println(mContainer);
if (mParent != null) {
writer.print(prefix); writer.print(" mParent="); writer.println(mParent);
@@ -785,7 +776,7 @@
}
if (fragment.mNextAnim != 0) {
- Animation anim = AnimationUtils.loadAnimation(mActivity, fragment.mNextAnim);
+ Animation anim = AnimationUtils.loadAnimation(mHost.getContext(), fragment.mNextAnim);
if (anim != null) {
return anim;
}
@@ -802,21 +793,21 @@
switch (styleIndex) {
case ANIM_STYLE_OPEN_ENTER:
- return makeOpenCloseAnimation(mActivity, 1.125f, 1.0f, 0, 1);
+ return makeOpenCloseAnimation(mHost.getContext(), 1.125f, 1.0f, 0, 1);
case ANIM_STYLE_OPEN_EXIT:
- return makeOpenCloseAnimation(mActivity, 1.0f, .975f, 1, 0);
+ return makeOpenCloseAnimation(mHost.getContext(), 1.0f, .975f, 1, 0);
case ANIM_STYLE_CLOSE_ENTER:
- return makeOpenCloseAnimation(mActivity, .975f, 1.0f, 0, 1);
+ return makeOpenCloseAnimation(mHost.getContext(), .975f, 1.0f, 0, 1);
case ANIM_STYLE_CLOSE_EXIT:
- return makeOpenCloseAnimation(mActivity, 1.0f, 1.075f, 1, 0);
+ return makeOpenCloseAnimation(mHost.getContext(), 1.0f, 1.075f, 1, 0);
case ANIM_STYLE_FADE_ENTER:
- return makeFadeAnimation(mActivity, 0, 1);
+ return makeFadeAnimation(mHost.getContext(), 0, 1);
case ANIM_STYLE_FADE_EXIT:
- return makeFadeAnimation(mActivity, 1, 0);
+ return makeFadeAnimation(mHost.getContext(), 1, 0);
}
- if (transitionStyle == 0 && mActivity.getWindow() != null) {
- transitionStyle = mActivity.getWindow().getAttributes().windowAnimations;
+ if (transitionStyle == 0 && mHost.hasWindowAnimations()) {
+ transitionStyle = mHost.getWindowAnimations();
}
if (transitionStyle == 0) {
return null;
@@ -881,7 +872,7 @@
case Fragment.INITIALIZING:
if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
if (f.mSavedFragmentState != null) {
- f.mSavedFragmentState.setClassLoader(mActivity.getClassLoader());
+ f.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader());
f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
FragmentManagerImpl.VIEW_STATE_TAG);
f.mTarget = getFragment(f.mSavedFragmentState,
@@ -899,18 +890,18 @@
}
}
}
- f.mActivity = mActivity;
+ f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
- ? mParent.mChildFragmentManager : mActivity.mFragments;
+ ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
f.mCalled = false;
- f.onAttach(mActivity);
+ mHost.onFragmentAttach(f);
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onAttach()");
}
if (f.mParentFragment == null) {
- mActivity.onAttachFragment(f);
+ mHost.onFragmentAttach(f);
}
if (!f.mRetaining) {
@@ -1021,7 +1012,7 @@
if (f.mView != null) {
// Need to save the current view state if not
// done already.
- if (!mActivity.isFinishing() && f.mSavedViewState == null) {
+ if (mHost.shouldSaveFragmentState(f) && f.mSavedViewState == null) {
saveFragmentViewState(f);
}
}
@@ -1098,7 +1089,7 @@
if (!f.mRetaining) {
makeInactive(f);
} else {
- f.mActivity = null;
+ f.mHost = null;
f.mParentFragment = null;
f.mFragmentManager = null;
f.mChildFragmentManager = null;
@@ -1121,8 +1112,8 @@
}
void moveToState(int newState, int transit, int transitStyle, boolean always) {
- if (mActivity == null && newState != Fragment.INITIALIZING) {
- throw new IllegalStateException("No activity");
+ if (mHost == null && newState != Fragment.INITIALIZING) {
+ throw new IllegalStateException("No host");
}
if (!always && mCurState == newState) {
@@ -1146,8 +1137,8 @@
startPendingDeferredFragments();
}
- if (mNeedMenuInvalidate && mActivity != null && mCurState == Fragment.RESUMED) {
- mActivity.supportInvalidateOptionsMenu();
+ if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
+ mHost.supportInvalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
}
@@ -1194,7 +1185,7 @@
mAvailIndices = new ArrayList<Integer>();
}
mAvailIndices.add(f.mIndex);
- mActivity.invalidateSupportFragment(f.mWho);
+ mHost.inactivateFragment(f.mWho);
f.initState();
}
@@ -1395,7 +1386,7 @@
checkStateLoss();
}
synchronized (this) {
- if (mDestroyed || mActivity == null) {
+ if (mDestroyed || mHost == null) {
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
@@ -1403,8 +1394,8 @@
}
mPendingActions.add(action);
if (mPendingActions.size() == 1) {
- mActivity.mHandler.removeCallbacks(mExecCommit);
- mActivity.mHandler.post(mExecCommit);
+ mHost.getHandler().removeCallbacks(mExecCommit);
+ mHost.getHandler().post(mExecCommit);
}
}
}
@@ -1473,7 +1464,7 @@
throw new IllegalStateException("Recursive entry to executePendingTransactions");
}
- if (Looper.myLooper() != mActivity.mHandler.getLooper()) {
+ if (Looper.myLooper() != mHost.getHandler().getLooper()) {
throw new IllegalStateException("Must be called from main thread of process");
}
@@ -1493,7 +1484,7 @@
}
mPendingActions.toArray(mTmpActions);
mPendingActions.clear();
- mActivity.mHandler.removeCallbacks(mExecCommit);
+ mHost.getHandler().removeCallbacks(mExecCommit);
}
mExecutingActions = true;
@@ -1537,6 +1528,7 @@
reportBackStackChanged();
}
+ @SuppressWarnings("unused")
boolean popBackStackState(Handler handler, String name, int id, int flags) {
if (mBackStack == null) {
return false;
@@ -1780,7 +1772,7 @@
if (N > 0) {
backStack = new BackStackState[N];
for (int i=0; i<N; i++) {
- backStack[i] = new BackStackState(this, mBackStack.get(i));
+ backStack[i] = new BackStackState(mBackStack.get(i));
if (DEBUG) Log.v(TAG, "saveAllState: adding back stack #" + i
+ ": " + mBackStack.get(i));
}
@@ -1815,7 +1807,7 @@
f.mAdded = false;
f.mTarget = null;
if (fs.mSavedFragmentState != null) {
- fs.mSavedFragmentState.setClassLoader(mActivity.getClassLoader());
+ fs.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader());
f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray(
FragmentManagerImpl.VIEW_STATE_TAG);
f.mSavedFragmentState = fs.mSavedFragmentState;
@@ -1832,7 +1824,7 @@
for (int i=0; i<fms.mActive.length; i++) {
FragmentState fs = fms.mActive[i];
if (fs != null) {
- Fragment f = fs.instantiate(mActivity, mParent);
+ Fragment f = fs.instantiate(mHost, mParent);
if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f);
mActive.add(f);
// Now that the fragment is instantiated (or came from being
@@ -1906,11 +1898,11 @@
mBackStack = null;
}
}
-
- public void attachActivity(FragmentActivity activity,
+
+ public void attachController(FragmentHostCallbacks host,
FragmentContainer container, Fragment parent) {
- if (mActivity != null) throw new IllegalStateException("Already attached");
- mActivity = activity;
+ if (mHost != null) throw new IllegalStateException("Already attached");
+ mHost = host;
mContainer = container;
mParent = parent;
}
@@ -1964,7 +1956,7 @@
mDestroyed = true;
execPendingActions();
moveToState(Fragment.INITIALIZING, false);
- mActivity = null;
+ mHost = null;
mContainer = null;
mParent = null;
}
@@ -2132,7 +2124,7 @@
String tag = a.getString(FragmentTag.Fragment_tag);
a.recycle();
- if (!Fragment.isSupportFragmentClass(mActivity, fname)) {
+ if (!Fragment.isSupportFragmentClass(mHost.getContext(), fname)) {
// Invalid support lib fragment; let the device's framework handle it.
// This will allow android.app.Fragments to do the right thing.
return null;
@@ -2166,7 +2158,7 @@
fragment.mTag = tag;
fragment.mInLayout = true;
fragment.mFragmentManager = this;
- fragment.onInflate(mActivity, attrs, fragment.mSavedFragmentState);
+ mHost.onFragmentInflate(fragment, attrs, fragment.mSavedFragmentState);
addFragment(fragment, true);
} else if (fragment.mInLayout) {
@@ -2184,7 +2176,7 @@
// from last saved state), then give it the attributes to
// initialize itself.
if (!fragment.mRetaining) {
- fragment.onInflate(mActivity, attrs, fragment.mSavedFragmentState);
+ mHost.onFragmentInflate(fragment, attrs, fragment.mSavedFragmentState);
}
}
diff --git a/v4/java/android/support/v4/app/LoaderManager.java b/v4/java/android/support/v4/app/LoaderManager.java
index 57c0a30..e67cc4b 100644
--- a/v4/java/android/support/v4/app/LoaderManager.java
+++ b/v4/java/android/support/v4/app/LoaderManager.java
@@ -184,6 +184,9 @@
public boolean hasRunningLoaders() { return false; }
}
+/**
+ * @hide
+ */
class LoaderManagerImpl extends LoaderManager {
static final String TAG = "LoaderManager";
static boolean DEBUG = false;
@@ -201,14 +204,15 @@
final String mWho;
- FragmentActivity mActivity;
boolean mStarted;
boolean mRetaining;
boolean mRetainingStarted;
boolean mCreatingLoader;
+ private FragmentHostCallbacks mHost;
- final class LoaderInfo implements Loader.OnLoadCompleteListener<Object> {
+ final class LoaderInfo implements Loader.OnLoadCompleteListener<Object>,
+ Loader.OnLoadCanceledListener<Object> {
final int mId;
final Bundle mArgs;
LoaderManager.LoaderCallbacks<Object> mCallbacks;
@@ -216,8 +220,11 @@
boolean mHaveData;
boolean mDeliveredData;
Object mData;
+ @SuppressWarnings("hiding")
boolean mStarted;
+ @SuppressWarnings("hiding")
boolean mRetaining;
+ @SuppressWarnings("hiding")
boolean mRetainingStarted;
boolean mReportNextStart;
boolean mDestroyed;
@@ -260,6 +267,7 @@
}
if (!mListenerRegistered) {
mLoader.registerListener(mId, this);
+ mLoader.registerOnLoadCanceledListener(this);
mListenerRegistered = true;
}
mLoader.startLoading();
@@ -318,11 +326,21 @@
// Let the loader know we're done with it
mListenerRegistered = false;
mLoader.unregisterListener(this);
+ mLoader.unregisterOnLoadCanceledListener(this);
mLoader.stopLoading();
}
}
}
-
+
+ void cancel() {
+ if (DEBUG) Log.v(TAG, " Canceling: " + this);
+ if (mStarted && mLoader != null && mListenerRegistered) {
+ if (!mLoader.cancelLoad()) {
+ onLoadCanceled(mLoader);
+ }
+ }
+ }
+
void destroy() {
if (DEBUG) Log.v(TAG, " Destroying: " + this);
mDestroyed = true;
@@ -331,15 +349,15 @@
if (mCallbacks != null && mLoader != null && mHaveData && needReset) {
if (DEBUG) Log.v(TAG, " Reseting: " + this);
String lastBecause = null;
- if (mActivity != null) {
- lastBecause = mActivity.mFragments.mNoTransactionsBecause;
- mActivity.mFragments.mNoTransactionsBecause = "onLoaderReset";
+ if (mHost != null) {
+ lastBecause = mHost.mFragmentManager.mNoTransactionsBecause;
+ mHost.mFragmentManager.mNoTransactionsBecause = "onLoaderReset";
}
try {
mCallbacks.onLoaderReset(mLoader);
} finally {
- if (mActivity != null) {
- mActivity.mFragments.mNoTransactionsBecause = lastBecause;
+ if (mHost != null) {
+ mHost.mFragmentManager.mNoTransactionsBecause = lastBecause;
}
}
}
@@ -350,6 +368,7 @@
if (mListenerRegistered) {
mListenerRegistered = false;
mLoader.unregisterListener(this);
+ mLoader.unregisterOnLoadCanceledListener(this);
}
mLoader.reset();
}
@@ -357,8 +376,38 @@
mPendingLoader.destroy();
}
}
-
- @Override public void onLoadComplete(Loader<Object> loader, Object data) {
+
+ @Override
+ public void onLoadCanceled(Loader<Object> loader) {
+ if (DEBUG) Log.v(TAG, "onLoadCanceled: " + this);
+
+ if (mDestroyed) {
+ if (DEBUG) Log.v(TAG, " Ignoring load canceled -- destroyed");
+ return;
+ }
+
+ if (mLoaders.get(mId) != this) {
+ // This cancellation message is not coming from the current active loader.
+ // We don't care about it.
+ if (DEBUG) Log.v(TAG, " Ignoring load canceled -- not active");
+ return;
+ }
+
+ LoaderInfo pending = mPendingLoader;
+ if (pending != null) {
+ // There is a new request pending and we were just
+ // waiting for the old one to cancel or complete before starting
+ // it. So now it is time, switch over to the new loader.
+ if (DEBUG) Log.v(TAG, " Switching to pending loader: " + pending);
+ mPendingLoader = null;
+ mLoaders.put(mId, null);
+ destroy();
+ installLoader(pending);
+ }
+ }
+
+ @Override
+ public void onLoadComplete(Loader<Object> loader, Object data) {
if (DEBUG) Log.v(TAG, "onLoadComplete: " + this);
if (mDestroyed) {
@@ -409,25 +458,25 @@
mInactiveLoaders.remove(mId);
}
- if (mActivity != null && !hasRunningLoaders()) {
- mActivity.mFragments.startPendingDeferredFragments();
+ if (mHost != null && !hasRunningLoaders()) {
+ mHost.mFragmentManager.startPendingDeferredFragments();
}
}
void callOnLoadFinished(Loader<Object> loader, Object data) {
if (mCallbacks != null) {
String lastBecause = null;
- if (mActivity != null) {
- lastBecause = mActivity.mFragments.mNoTransactionsBecause;
- mActivity.mFragments.mNoTransactionsBecause = "onLoadFinished";
+ if (mHost != null) {
+ lastBecause = mHost.mFragmentManager.mNoTransactionsBecause;
+ mHost.mFragmentManager.mNoTransactionsBecause = "onLoadFinished";
}
try {
if (DEBUG) Log.v(TAG, " onLoadFinished in " + loader + ": "
+ loader.dataToString(data));
mCallbacks.onLoadFinished(loader, data);
} finally {
- if (mActivity != null) {
- mActivity.mFragments.mNoTransactionsBecause = lastBecause;
+ if (mHost != null) {
+ mHost.mFragmentManager.mNoTransactionsBecause = lastBecause;
}
}
mDeliveredData = true;
@@ -474,21 +523,21 @@
}
}
- LoaderManagerImpl(String who, FragmentActivity activity, boolean started) {
+ LoaderManagerImpl(String who, FragmentHostCallbacks host, boolean started) {
mWho = who;
- mActivity = activity;
+ mHost = host;
mStarted = started;
}
- void updateActivity(FragmentActivity activity) {
- mActivity = activity;
+ void updateHostController(FragmentHostCallbacks host) {
+ mHost = host;
}
private LoaderInfo createLoader(int id, Bundle args,
LoaderManager.LoaderCallbacks<Object> callback) {
- LoaderInfo info = new LoaderInfo(id, args, (LoaderManager.LoaderCallbacks<Object>)callback);
+ LoaderInfo info = new LoaderInfo(id, args, callback);
Loader<Object> loader = callback.onCreateLoader(id, args);
- info.mLoader = (Loader<Object>)loader;
+ info.mLoader = loader;
return info;
}
@@ -533,7 +582,7 @@
* @param id A unique (to this LoaderManager instance) identifier under
* which to manage the new Loader.
* @param args Optional arguments that will be propagated to
- * {@link LoaderCallbacks#onCreateLoader(int, Bundle) LoaderCallbacks.onCreateLoader()}.
+ * {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader(int, Bundle) LoaderCallbacks.onCreateLoader()}.
* @param callback Interface implementing management of this Loader. Required.
* Its onCreateLoader() method will be called while inside of the function to
* instantiate the Loader object.
@@ -583,7 +632,7 @@
* @param id A unique (to this LoaderManager instance) identifier under
* which to manage the new Loader.
* @param args Optional arguments that will be propagated to
- * {@link LoaderCallbacks#onCreateLoader(int, Bundle) LoaderCallbacks.onCreateLoader()}.
+ * {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader(int, Bundle) LoaderCallbacks.onCreateLoader()}.
* @param callback Interface implementing management of this Loader. Required.
* Its onCreateLoader() method will be called while inside of the function to
* instantiate the Loader object.
@@ -622,7 +671,9 @@
} else {
// Now we have three active loaders... we'll queue
// up this request to be processed once one of the other loaders
- // finishes.
+ // finishes or is canceled.
+ if (DEBUG) Log.v(TAG, " Current loader is running; attempting to cancel");
+ info.cancel();
if (info.mPendingLoader != null) {
if (DEBUG) Log.v(TAG, " Removing pending loader: " + info.mPendingLoader);
info.mPendingLoader.destroy();
@@ -672,8 +723,8 @@
mInactiveLoaders.removeAt(idx);
info.destroy();
}
- if (mActivity != null && !hasRunningLoaders()) {
- mActivity.mFragments.startPendingDeferredFragments();
+ if (mHost != null && !hasRunningLoaders()) {
+ mHost.mFragmentManager.startPendingDeferredFragments();
}
}
@@ -791,7 +842,7 @@
sb.append("LoaderManager{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(" in ");
- DebugUtils.buildShortClassTag(mActivity, sb);
+ DebugUtils.buildShortClassTag(mHost, sb);
sb.append("}}");
return sb.toString();
}
diff --git a/v4/java/android/support/v4/app/NotificationCompat.java b/v4/java/android/support/v4/app/NotificationCompat.java
index e007bcd..b206e95 100644
--- a/v4/java/android/support/v4/app/NotificationCompat.java
+++ b/v4/java/android/support/v4/app/NotificationCompat.java
@@ -26,6 +26,7 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
+import android.support.annotation.ColorInt;
import android.support.v4.view.GravityCompat;
import android.view.Gravity;
import android.widget.RemoteViews;
@@ -342,6 +343,7 @@
* telling the system not to decorate this notification with any special color but instead use
* default colors when presenting this notification.
*/
+ @ColorInt
public static final int COLOR_DEFAULT = Color.TRANSPARENT;
/**
@@ -442,7 +444,7 @@
private static final NotificationCompatImpl IMPL;
interface NotificationCompatImpl {
- public Notification build(Builder b);
+ public Notification build(Builder b, BuilderExtender extender);
public Bundle getExtras(Notification n);
public int getActionCount(Notification n);
public Action getAction(Notification n, int actionIndex);
@@ -459,9 +461,20 @@
RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory);
}
+ /**
+ * Interface for appcompat to extend v4 builder with media style.
+ *
+ * @hide
+ */
+ protected static class BuilderExtender {
+ public Notification build(Builder b, NotificationBuilderWithBuilderAccessor builder) {
+ return builder.build();
+ }
+ }
+
static class NotificationCompatImplBase implements NotificationCompatImpl {
@Override
- public Notification build(Builder b) {
+ public Notification build(Builder b, BuilderExtender extender) {
Notification result = b.mNotification;
result.setLatestEventInfo(b.mContext, b.mContentTitle,
b.mContentText, b.mContentIntent);
@@ -538,7 +551,7 @@
static class NotificationCompatImplGingerbread extends NotificationCompatImplBase {
@Override
- public Notification build(Builder b) {
+ public Notification build(Builder b, BuilderExtender extender) {
Notification result = b.mNotification;
result.setLatestEventInfo(b.mContext, b.mContentTitle,
b.mContentText, b.mContentIntent);
@@ -554,7 +567,7 @@
static class NotificationCompatImplHoneycomb extends NotificationCompatImplBase {
@Override
- public Notification build(Builder b) {
+ public Notification build(Builder b, BuilderExtender extender) {
return NotificationCompatHoneycomb.add(b.mContext, b.mNotification,
b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView,
b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon);
@@ -563,17 +576,19 @@
static class NotificationCompatImplIceCreamSandwich extends NotificationCompatImplBase {
@Override
- public Notification build(Builder b) {
- return NotificationCompatIceCreamSandwich.add(b.mContext, b.mNotification,
- b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView,
- b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
+ public Notification build(Builder b, BuilderExtender extender) {
+ NotificationCompatIceCreamSandwich.Builder builder =
+ new NotificationCompatIceCreamSandwich.Builder(
+ b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
+ b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
b.mProgressMax, b.mProgress, b.mProgressIndeterminate);
+ return extender.build(b, builder);
}
}
static class NotificationCompatImplJellybean extends NotificationCompatImplBase {
@Override
- public Notification build(Builder b) {
+ public Notification build(Builder b, BuilderExtender extender) {
NotificationCompatJellybean.Builder builder = new NotificationCompatJellybean.Builder(
b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
@@ -582,7 +597,7 @@
b.mGroupKey, b.mGroupSummary, b.mSortKey);
addActionsToBuilder(builder, b.mActions);
addStyleToBuilderJellybean(builder, b.mStyle);
- return builder.build();
+ return extender.build(b, builder);
}
@Override
@@ -637,7 +652,7 @@
static class NotificationCompatImplKitKat extends NotificationCompatImplJellybean {
@Override
- public Notification build(Builder b) {
+ public Notification build(Builder b, BuilderExtender extender) {
NotificationCompatKitKat.Builder builder = new NotificationCompatKitKat.Builder(
b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
@@ -646,7 +661,7 @@
b.mPeople, b.mExtras, b.mGroupKey, b.mGroupSummary, b.mSortKey);
addActionsToBuilder(builder, b.mActions);
addStyleToBuilderJellybean(builder, b.mStyle);
- return builder.build();
+ return extender.build(b, builder);
}
@Override
@@ -688,7 +703,7 @@
static class NotificationCompatImplApi20 extends NotificationCompatImplKitKat {
@Override
- public Notification build(Builder b) {
+ public Notification build(Builder b, BuilderExtender extender) {
NotificationCompatApi20.Builder builder = new NotificationCompatApi20.Builder(
b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
@@ -697,7 +712,7 @@
b.mGroupKey, b.mGroupSummary, b.mSortKey);
addActionsToBuilder(builder, b.mActions);
addStyleToBuilderJellybean(builder, b.mStyle);
- return builder.build();
+ return extender.build(b, builder);
}
@Override
@@ -742,7 +757,7 @@
static class NotificationCompatImplApi21 extends NotificationCompatImplApi20 {
@Override
- public Notification build(Builder b) {
+ public Notification build(Builder b, BuilderExtender extender) {
NotificationCompatApi21.Builder builder = new NotificationCompatApi21.Builder(
b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
@@ -752,7 +767,7 @@
b.mGroupKey, b.mGroupSummary, b.mSortKey);
addActionsToBuilder(builder, b.mActions);
addStyleToBuilderJellybean(builder, b.mStyle);
- return builder.build();
+ return extender.build(b, builder);
}
@Override
@@ -860,28 +875,41 @@
*/
private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024;
- Context mContext;
+ // All these variables are declared public/hidden so they can be accessed by a builder
+ // extender.
- CharSequence mContentTitle;
- CharSequence mContentText;
+ /** @hide */
+ public Context mContext;
+
+ /** @hide */
+ public CharSequence mContentTitle;
+ /** @hide */
+ public CharSequence mContentText;
PendingIntent mContentIntent;
PendingIntent mFullScreenIntent;
RemoteViews mTickerView;
- Bitmap mLargeIcon;
- CharSequence mContentInfo;
- int mNumber;
+ /** @hide */
+ public Bitmap mLargeIcon;
+ /** @hide */
+ public CharSequence mContentInfo;
+ /** @hide */
+ public int mNumber;
int mPriority;
boolean mShowWhen = true;
- boolean mUseChronometer;
- Style mStyle;
- CharSequence mSubText;
+ /** @hide */
+ public boolean mUseChronometer;
+ /** @hide */
+ public Style mStyle;
+ /** @hide */
+ public CharSequence mSubText;
int mProgressMax;
int mProgress;
boolean mProgressIndeterminate;
String mGroupKey;
boolean mGroupSummary;
String mSortKey;
- ArrayList<Action> mActions = new ArrayList<Action>();
+ /** @hide */
+ public ArrayList<Action> mActions = new ArrayList<Action>();
boolean mLocalOnly = false;
String mCategory;
Bundle mExtras;
@@ -889,7 +917,8 @@
int mVisibility = VISIBILITY_PRIVATE;
Notification mPublicVersion;
- Notification mNotification = new Notification();
+ /** @hide */
+ public Notification mNotification = new Notification();
public ArrayList<String> mPeople;
/**
@@ -1171,7 +1200,7 @@
* rate. The rate is specified in terms of the number of milliseconds to be on
* and then the number of milliseconds to be off.
*/
- public Builder setLights(int argb, int onMs, int offMs) {
+ public Builder setLights(@ColorInt int argb, int onMs, int offMs) {
mNotification.ledARGB = argb;
mNotification.ledOnMS = onMs;
mNotification.ledOffMS = offMs;
@@ -1477,7 +1506,7 @@
*
* @return The same Builder.
*/
- public Builder setColor(int argb) {
+ public Builder setColor(@ColorInt int argb) {
mColor = argb;
return this;
}
@@ -1521,7 +1550,7 @@
*/
@Deprecated
public Notification getNotification() {
- return IMPL.build(this);
+ return build();
}
/**
@@ -1529,7 +1558,14 @@
* object.
*/
public Notification build() {
- return IMPL.build(this);
+ return IMPL.build(this, getExtender());
+ }
+
+ /**
+ * @hide
+ */
+ protected BuilderExtender getExtender() {
+ return new BuilderExtender();
}
protected static CharSequence limitCharSequenceLength(CharSequence cs) {
@@ -1801,17 +1837,17 @@
}
@Override
- protected int getIcon() {
+ public int getIcon() {
return icon;
}
@Override
- protected CharSequence getTitle() {
+ public CharSequence getTitle() {
return title;
}
@Override
- protected PendingIntent getActionIntent() {
+ public PendingIntent getActionIntent() {
return actionIntent;
}
@@ -2978,7 +3014,7 @@
* automotive setting. This method can be used to override the color provided in the
* notification in such a situation.
*/
- public CarExtender setColor(int color) {
+ public CarExtender setColor(@ColorInt int color) {
mColor = color;
return this;
}
@@ -2988,6 +3024,7 @@
*
* @see setColor
*/
+ @ColorInt
public int getColor() {
return mColor;
}
diff --git a/v4/java/android/support/v4/app/SharedElementCallback.java b/v4/java/android/support/v4/app/SharedElementCallback.java
index 7c0de86..8beb29d 100644
--- a/v4/java/android/support/v4/app/SharedElementCallback.java
+++ b/v4/java/android/support/v4/app/SharedElementCallback.java
@@ -48,9 +48,23 @@
private static final String BUNDLE_SNAPSHOT_IMAGE_MATRIX = "sharedElement:snapshot:imageMatrix";
/**
- * Called immediately after the start state is set for the shared element.
- * The shared element will start at the size and position of the shared element
- * in the launching Activity or Fragment.
+ * In Activity Transitions, onSharedElementStart is called immediately before
+ * capturing the start of the shared element state on enter and reenter transitions and
+ * immediately before capturing the end of the shared element state for exit and return
+ * transitions.
+ * <p>
+ * In Fragment Transitions, onSharedElementStart is called immediately before capturing the
+ * start state of all shared element transitions.
+ * <p>
+ * This call can be used to adjust the transition start state by modifying the shared
+ * element Views. Note that no layout step will be executed between onSharedElementStart
+ * and the transition state capture.
+ * <p>
+ * For Activity Transitions, any changes made in {@link #onSharedElementEnd(List, List, List)}
+ * that are not updated during layout should be corrected in onSharedElementStart for exit and
+ * return transitions. For example, rotation or scale will not be affected by layout and
+ * if changed in {@link #onSharedElementEnd(List, List, List)}, it will also have to be reset
+ * in onSharedElementStart again to correct the end state.
*
* @param sharedElementNames The names of the shared elements that were accepted into
* the View hierarchy.
@@ -65,17 +79,23 @@
List<View> sharedElements, List<View> sharedElementSnapshots) {}
/**
- * Called after the end state is set for the shared element, but before the end state
- * is captured by the shared element transition.
+ * In Activity Transitions, onSharedElementEnd is called immediately before
+ * capturing the end of the shared element state on enter and reenter transitions and
+ * immediately before capturing the start of the shared element state for exit and return
+ * transitions.
* <p>
- * Any customization done in
- * {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)}
- * may need to be modified to the final state of the shared element if it is not
- * automatically corrected by layout. For example, rotation or scale will not
- * be affected by layout and if changed in {@link #onSharedElementStart(java.util.List,
- * java.util.List, java.util.List)}, it will also have to be set here again to correct
- * the end state.
- * </p>
+ * In Fragment Transitions, onSharedElementEnd is called immediately before capturing the
+ * end state of all shared element transitions.
+ * <p>
+ * This call can be used to adjust the transition end state by modifying the shared
+ * element Views. Note that no layout step will be executed between onSharedElementEnd
+ * and the transition state capture.
+ * <p>
+ * Any changes made in {@link #onSharedElementStart(List, List, List)} that are not updated
+ * during layout should be corrected in onSharedElementEnd. For example, rotation or scale
+ * will not be affected by layout and if changed in
+ * {@link #onSharedElementStart(List, List, List)}, it will also have to be reset in
+ * onSharedElementEnd again to correct the end state.
*
* @param sharedElementNames The names of the shared elements that were accepted into
* the View hierarchy.
diff --git a/v4/java/android/support/v4/content/AsyncTaskLoader.java b/v4/java/android/support/v4/content/AsyncTaskLoader.java
index 22fe3a2..17d7416 100644
--- a/v4/java/android/support/v4/content/AsyncTaskLoader.java
+++ b/v4/java/android/support/v4/content/AsyncTaskLoader.java
@@ -19,12 +19,14 @@
import android.content.Context;
import android.os.Handler;
import android.os.SystemClock;
+import android.support.v4.os.OperationCanceledException;
import android.support.v4.util.TimeUtils;
import android.util.Log;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
/**
* Static library support version of the framework's {@link android.content.AsyncTaskLoader}.
@@ -38,19 +40,33 @@
static final boolean DEBUG = false;
final class LoadTask extends ModernAsyncTask<Void, Void, D> implements Runnable {
+ private final CountDownLatch mDone = new CountDownLatch(1);
- D result;
+ // Set to true to indicate that the task has been posted to a handler for
+ // execution at a later time. Used to throttle updates.
boolean waiting;
- private CountDownLatch done = new CountDownLatch(1);
-
/* Runs on a worker thread */
@Override
protected D doInBackground(Void... params) {
if (DEBUG) Log.v(TAG, this + " >>> doInBackground");
- result = AsyncTaskLoader.this.onLoadInBackground();
- if (DEBUG) Log.v(TAG, this + " <<< doInBackground");
- return result;
+ try {
+ D data = AsyncTaskLoader.this.onLoadInBackground();
+ if (DEBUG) Log.v(TAG, this + " <<< doInBackground");
+ return data;
+ } catch (OperationCanceledException ex) {
+ if (!isCancelled()) {
+ // onLoadInBackground threw a canceled exception spuriously.
+ // This is problematic because it means that the LoaderManager did not
+ // cancel the Loader itself and still expects to receive a result.
+ // Additionally, the Loader's own state will not have been updated to
+ // reflect the fact that the task was being canceled.
+ // So we treat this case as an unhandled exception.
+ throw ex;
+ }
+ if (DEBUG) Log.v(TAG, this + " <<< doInBackground (was canceled)", ex);
+ return null;
+ }
}
/* Runs on the UI thread */
@@ -60,27 +76,41 @@
try {
AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
} finally {
- done.countDown();
+ mDone.countDown();
}
}
+ /* Runs on the UI thread */
@Override
- protected void onCancelled() {
+ protected void onCancelled(D data) {
if (DEBUG) Log.v(TAG, this + " onCancelled");
try {
- AsyncTaskLoader.this.dispatchOnCancelled(this, result);
+ AsyncTaskLoader.this.dispatchOnCancelled(this, data);
} finally {
- done.countDown();
+ mDone.countDown();
}
}
+ /* Runs on the UI thread, when the waiting task is posted to a handler.
+ * This method is only executed when task execution was deferred (waiting was true). */
@Override
public void run() {
waiting = false;
AsyncTaskLoader.this.executePendingTask();
}
+
+ /* Used for testing purposes to wait for the task to complete. */
+ public void waitForLoader() {
+ try {
+ mDone.await();
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
}
+ private final Executor mExecutor;
+
volatile LoadTask mTask;
volatile LoadTask mCancellingTask;
@@ -89,12 +119,17 @@
Handler mHandler;
public AsyncTaskLoader(Context context) {
+ this(context, ModernAsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ private AsyncTaskLoader(Context context, Executor executor) {
super(context);
+ mExecutor = executor;
}
/**
* Set amount to throttle updates by. This is the minimum time from
- * when the last {@link #onLoadInBackground()} call has completed until
+ * when the last {@link #loadInBackground()} call has completed until
* a new load is scheduled.
*
* @param delayMS Amount of delay, in milliseconds.
@@ -115,24 +150,9 @@
executePendingTask();
}
- /**
- * Attempt to cancel the current load task. See {@link android.os.AsyncTask#cancel(boolean)}
- * for more info. Must be called on the main thread of the process.
- *
- * <p>Cancelling is not an immediate operation, since the load is performed
- * in a background thread. If there is currently a load in progress, this
- * method requests that the load be cancelled, and notes this is the case;
- * once the background thread has completed its work its remaining state
- * will be cleared. If another load request comes in during this time,
- * it will be held until the cancelled load is complete.
- *
- * @return Returns <tt>false</tt> if the task could not be cancelled,
- * typically because it has already completed normally, or
- * because {@link #startLoading()} hasn't been called; returns
- * <tt>true</tt> otherwise.
- */
- public boolean cancelLoad() {
- if (DEBUG) Log.v(TAG, "cancelLoad: mTask=" + mTask);
+ @Override
+ protected boolean onCancelLoad() {
+ if (DEBUG) Log.v(TAG, "onCancelLoad: mTask=" + mTask);
if (mTask != null) {
if (mCancellingTask != null) {
// There was a pending task already waiting for a previous
@@ -158,6 +178,7 @@
if (DEBUG) Log.v(TAG, "cancelLoad: cancelled=" + cancelled);
if (cancelled) {
mCancellingTask = mTask;
+ cancelLoadInBackground();
}
mTask = null;
return cancelled;
@@ -168,7 +189,10 @@
/**
* Called if the task was canceled before it was completed. Gives the class a chance
- * to properly dispose of the result.
+ * to clean up post-cancellation and to properly dispose of the result.
+ *
+ * @param data The value that was returned by {@link #loadInBackground}, or null
+ * if the task threw {@link OperationCanceledException}.
*/
public void onCanceled(D data) {
}
@@ -192,7 +216,7 @@
}
}
if (DEBUG) Log.v(TAG, "Executing: " + mTask);
- mTask.executeOnExecutor(ModernAsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+ mTask.executeOnExecutor(mExecutor, (Void[]) null);
}
}
@@ -203,6 +227,8 @@
rollbackContentChanged();
mLastLoadCompleteTime = SystemClock.uptimeMillis();
mCancellingTask = null;
+ if (DEBUG) Log.v(TAG, "Delivering cancellation");
+ deliverCancellation();
executePendingTask();
}
}
@@ -226,23 +252,76 @@
}
/**
+ * Called on a worker thread to perform the actual load and to return
+ * the result of the load operation.
+ *
+ * Implementations should not deliver the result directly, but should return them
+ * from this method, which will eventually end up calling {@link #deliverResult} on
+ * the UI thread. If implementations need to process the results on the UI thread
+ * they may override {@link #deliverResult} and do so there.
+ *
+ * To support cancellation, this method should periodically check the value of
+ * {@link #isLoadInBackgroundCanceled} and terminate when it returns true.
+ * Subclasses may also override {@link #cancelLoadInBackground} to interrupt the load
+ * directly instead of polling {@link #isLoadInBackgroundCanceled}.
+ *
+ * When the load is canceled, this method may either return normally or throw
+ * {@link OperationCanceledException}. In either case, the {@link Loader} will
+ * call {@link #onCanceled} to perform post-cancellation cleanup and to dispose of the
+ * result object, if any.
+ *
+ * @return The result of the load operation.
+ *
+ * @throws OperationCanceledException if the load is canceled during execution.
+ *
+ * @see #isLoadInBackgroundCanceled
+ * @see #cancelLoadInBackground
+ * @see #onCanceled
*/
public abstract D loadInBackground();
/**
- * Called on a worker thread to perform the actual load. Implementations should not deliver the
- * result directly, but should return them from this method, which will eventually end up
- * calling {@link #deliverResult} on the UI thread. If implementations need to process
- * the results on the UI thread they may override {@link #deliverResult} and do so
- * there.
+ * Calls {@link #loadInBackground()}.
*
- * @return Implementations must return the result of their load operation.
+ * This method is reserved for use by the loader framework.
+ * Subclasses should override {@link #loadInBackground} instead of this method.
+ *
+ * @return The result of the load operation.
+ *
+ * @throws OperationCanceledException if the load is canceled during execution.
+ *
+ * @see #loadInBackground
*/
protected D onLoadInBackground() {
return loadInBackground();
}
/**
+ * Called on the main thread to abort a load in progress.
+ *
+ * Override this method to abort the current invocation of {@link #loadInBackground}
+ * that is running in the background on a worker thread.
+ *
+ * This method should do nothing if {@link #loadInBackground} has not started
+ * running or if it has already finished.
+ *
+ * @see #loadInBackground
+ */
+ public void cancelLoadInBackground() {
+ }
+
+ /**
+ * Returns true if the current invocation of {@link #loadInBackground} is being canceled.
+ *
+ * @return True if the current invocation of {@link #loadInBackground} is being canceled.
+ *
+ * @see #loadInBackground
+ */
+ public boolean isLoadInBackgroundCanceled() {
+ return mCancellingTask != null;
+ }
+
+ /**
* Locks the current thread until the loader completes the current load
* operation. Returns immediately if there is no load operation running.
* Should not be called from the UI thread: calling it from the UI
@@ -255,11 +334,7 @@
public void waitForLoader() {
LoadTask task = mTask;
if (task != null) {
- try {
- task.done.await();
- } catch (InterruptedException e) {
- // Ignore
- }
+ task.waitForLoader();
}
}
diff --git a/v4/java/android/support/v4/content/ContentResolverCompat.java b/v4/java/android/support/v4/content/ContentResolverCompat.java
new file mode 100644
index 0000000..3b5f01c
--- /dev/null
+++ b/v4/java/android/support/v4/content/ContentResolverCompat.java
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+package android.support.v4.content;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.support.v4.os.CancellationSignal;
+import android.support.v4.os.OperationCanceledException;
+
+/**
+ * Helper for accessing features in {@link android.content.ContentResolver}
+ * introduced after API level 4 in a backwards compatible fashion.
+ */
+public class ContentResolverCompat {
+ interface ContentResolverCompatImpl {
+ Cursor query(ContentResolver resolver,
+ Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder, CancellationSignal cancellationSignal);
+ }
+
+ static class ContentResolverCompatImplBase implements ContentResolverCompatImpl {
+ @Override
+ public Cursor query(ContentResolver resolver, Uri uri, String[] projection,
+ String selection, String[] selectionArgs, String sortOrder,
+ CancellationSignal cancellationSignal) {
+ // Note that the cancellation signal cannot cancel the query in progress
+ // prior to Jellybean so we cancel it preemptively here if needed.
+ if (cancellationSignal != null) {
+ cancellationSignal.throwIfCanceled();
+ }
+ return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
+ }
+ }
+
+ static class ContentResolverCompatImplJB extends ContentResolverCompatImplBase {
+ @Override
+ public Cursor query(ContentResolver resolver, Uri uri, String[] projection,
+ String selection, String[] selectionArgs, String sortOrder,
+ CancellationSignal cancellationSignal) {
+ return ContentResolverCompatJellybean.query(resolver,
+ uri, projection, selection, selectionArgs, sortOrder,
+ cancellationSignal != null ?
+ cancellationSignal.getCancellationSignalObject() : null);
+ }
+ }
+
+ private static final ContentResolverCompatImpl IMPL;
+ static {
+ final int version = Build.VERSION.SDK_INT;
+ if (version >= 16) {
+ IMPL = new ContentResolverCompatImplJB();
+ } else {
+ IMPL = new ContentResolverCompatImplBase();
+ }
+ }
+
+ private ContentResolverCompat() {
+ /* Hide constructor */
+ }
+
+ /**
+ * Query the given URI, returning a {@link Cursor} over the result set
+ * with optional support for cancellation.
+ * <p>
+ * For best performance, the caller should follow these guidelines:
+ * <ul>
+ * <li>Provide an explicit projection, to prevent
+ * reading data from storage that aren't going to be used.</li>
+ * <li>Use question mark parameter markers such as 'phone=?' instead of
+ * explicit values in the {@code selection} parameter, so that queries
+ * that differ only by those values will be recognized as the same
+ * for caching purposes.</li>
+ * </ul>
+ * </p>
+ *
+ * @param uri The URI, using the content:// scheme, for the content to
+ * retrieve.
+ * @param projection A list of which columns to return. Passing null will
+ * return all columns, which is inefficient.
+ * @param selection A filter declaring which rows to return, formatted as an
+ * SQL WHERE clause (excluding the WHERE itself). Passing null will
+ * return all rows for the given URI.
+ * @param selectionArgs You may include ?s in selection, which will be
+ * replaced by the values from selectionArgs, in the order that they
+ * appear in the selection. The values will be bound as Strings.
+ * @param sortOrder How to order the rows, formatted as an SQL ORDER BY
+ * clause (excluding the ORDER BY itself). Passing null will use the
+ * default sort order, which may be unordered.
+ * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+ * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+ * when the query is executed.
+ * @return A Cursor object, which is positioned before the first entry, or null
+ * @see Cursor
+ */
+ public static Cursor query(ContentResolver resolver,
+ Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder, CancellationSignal cancellationSignal) {
+ return IMPL.query(resolver, uri, projection, selection, selectionArgs,
+ sortOrder, cancellationSignal);
+ }
+}
diff --git a/v4/java/android/support/v4/content/ContextCompat.java b/v4/java/android/support/v4/content/ContextCompat.java
index 5c632dd..ebd5fcf 100644
--- a/v4/java/android/support/v4/content/ContextCompat.java
+++ b/v4/java/android/support/v4/content/ContextCompat.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
@@ -323,6 +324,51 @@
}
/**
+ * Returns a color state list associated with a particular resource ID.
+ * <p>
+ * Starting in {@link android.os.Build.VERSION_CODES#MNC}, the returned
+ * color state list will be styled for the specified Context's theme.
+ *
+ * @param id The desired resource identifier, as generated by the aapt
+ * tool. This integer encodes the package, type, and resource
+ * entry. The value 0 is an invalid identifier.
+ * @return A color state list, or {@code null} if the resource could not be
+ * resolved.
+ * @throws android.content.res.Resources.NotFoundException if the given ID
+ * does not exist.
+ */
+ public static final ColorStateList getColorStateList(Context context, int id) {
+ final int version = Build.VERSION.SDK_INT;
+ if (version >= 23) {
+ return ContextCompatApi23.getColorStateList(context, id);
+ } else {
+ return context.getResources().getColorStateList(id);
+ }
+ }
+
+ /**
+ * Returns a color associated with a particular resource ID
+ * <p>
+ * Starting in {@link android.os.Build.VERSION_CODES#MNC}, the returned
+ * color will be styled for the specified Context's theme.
+ *
+ * @param id The desired resource identifier, as generated by the aapt
+ * tool. This integer encodes the package, type, and resource
+ * entry. The value 0 is an invalid identifier.
+ * @return A single color value in the form 0xAARRGGBB.
+ * @throws android.content.res.Resources.NotFoundException if the given ID
+ * does not exist.
+ */
+ public static final int getColor(Context context, int id) {
+ final int version = Build.VERSION.SDK_INT;
+ if (version >= 23) {
+ return ContextCompatApi23.getColor(context, id);
+ } else {
+ return context.getResources().getColor(id);
+ }
+ }
+
+ /**
* Returns the absolute path to the directory on the filesystem similar to
* {@link Context#getFilesDir()}. The difference is that files placed under this
* directory will be excluded from automatic backup to remote storage on
diff --git a/v4/java/android/support/v4/content/CursorLoader.java b/v4/java/android/support/v4/content/CursorLoader.java
index 980e7d9..503bb9c 100644
--- a/v4/java/android/support/v4/content/CursorLoader.java
+++ b/v4/java/android/support/v4/content/CursorLoader.java
@@ -16,10 +16,12 @@
package android.support.v4.content;
+import android.content.ContentResolver;
import android.content.Context;
-import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
+import android.support.v4.os.CancellationSignal;
+import android.support.v4.os.OperationCanceledException;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -42,18 +44,48 @@
String mSortOrder;
Cursor mCursor;
+ CancellationSignal mCancellationSignal;
/* Runs on a worker thread */
@Override
public Cursor loadInBackground() {
- Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection,
- mSelectionArgs, mSortOrder);
- if (cursor != null) {
- // Ensure the cursor window is filled
- cursor.getCount();
- cursor.registerContentObserver(mObserver);
+ synchronized (this) {
+ if (isLoadInBackgroundCanceled()) {
+ throw new OperationCanceledException();
+ }
+ mCancellationSignal = new CancellationSignal();
}
- return cursor;
+ try {
+ Cursor cursor = ContentResolverCompat.query(getContext().getContentResolver(),
+ mUri, mProjection, mSelection, mSelectionArgs, mSortOrder,
+ mCancellationSignal);
+ if (cursor != null) {
+ try {
+ // Ensure the cursor window is filled.
+ cursor.getCount();
+ cursor.registerContentObserver(mObserver);
+ } catch (RuntimeException ex) {
+ cursor.close();
+ throw ex;
+ }
+ }
+ return cursor;
+ } finally {
+ synchronized (this) {
+ mCancellationSignal = null;
+ }
+ }
+ }
+
+ @Override
+ public void cancelLoadInBackground() {
+ super.cancelLoadInBackground();
+
+ synchronized (this) {
+ if (mCancellationSignal != null) {
+ mCancellationSignal.cancel();
+ }
+ }
}
/* Runs on the UI thread */
@@ -90,7 +122,7 @@
/**
* Creates a fully-specified CursorLoader. See
- * {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
+ * {@link ContentResolver#query(Uri, String[], String, String[], String)
* ContentResolver.query()} for documentation on the meaning of the
* parameters. These will be passed as-is to that call.
*/
diff --git a/v4/java/android/support/v4/content/Loader.java b/v4/java/android/support/v4/content/Loader.java
index bd01b0a..cf6cc99 100644
--- a/v4/java/android/support/v4/content/Loader.java
+++ b/v4/java/android/support/v4/content/Loader.java
@@ -34,6 +34,7 @@
public class Loader<D> {
int mId;
OnLoadCompleteListener<D> mListener;
+ OnLoadCanceledListener<D> mOnLoadCanceledListener;
Context mContext;
boolean mStarted = false;
boolean mAbandoned = false;
@@ -45,8 +46,8 @@
* An implementation of a ContentObserver that takes care of connecting
* it to the Loader to have the loader re-load its data when the observer
* is told it has changed. You do not normally need to use this yourself;
- * it is used for you by {@link android.support.v4.content.CursorLoader}
- * to take care of executing an update when the cursor's backing data changes.
+ * it is used for you by {@link CursorLoader} to take care of executing
+ * an update when the cursor's backing data changes.
*/
public final class ForceLoadContentObserver extends ContentObserver {
public ForceLoadContentObserver() {
@@ -83,8 +84,29 @@
}
/**
- * Stores away the application context associated with context. Since Loaders can be used
- * across multiple activities it's dangerous to store the context directly.
+ * Interface that is implemented to discover when a Loader has been canceled
+ * before it finished loading its data. You do not normally need to implement
+ * this yourself; it is used in the implementation of {@link android.support.v4.app.LoaderManager}
+ * to find out when a Loader it is managing has been canceled so that it
+ * can schedule the next Loader. This interface should only be used if a
+ * Loader is not being used in conjunction with LoaderManager.
+ */
+ public interface OnLoadCanceledListener<D> {
+ /**
+ * Called on the thread that created the Loader when the load is canceled.
+ *
+ * @param loader the loader that canceled the load
+ */
+ public void onLoadCanceled(Loader<D> loader);
+ }
+
+ /**
+ * Stores away the application context associated with context.
+ * Since Loaders can be used across multiple activities it's dangerous to
+ * store the context directly; always use {@link #getContext()} to retrieve
+ * the Loader's Context, don't use the constructor argument directly.
+ * The Context returned by {@link #getContext} is safe to use across
+ * Activity instances.
*
* @param context used to retrieve the application context.
*/
@@ -106,6 +128,18 @@
}
/**
+ * Informs the registered {@link OnLoadCanceledListener} that the load has been canceled.
+ * Should only be called by subclasses.
+ *
+ * Must be called from the process's main thread.
+ */
+ public void deliverCancellation() {
+ if (mOnLoadCanceledListener != null) {
+ mOnLoadCanceledListener.onLoadCanceled(this);
+ }
+ }
+
+ /**
* @return an application context retrieved from the Context passed to the constructor.
*/
public Context getContext() {
@@ -150,6 +184,40 @@
}
/**
+ * Registers a listener that will receive callbacks when a load is canceled.
+ * The callback will be called on the process's main thread so it's safe to
+ * pass the results to widgets.
+ *
+ * Must be called from the process's main thread.
+ *
+ * @param listener The listener to register.
+ */
+ public void registerOnLoadCanceledListener(OnLoadCanceledListener<D> listener) {
+ if (mOnLoadCanceledListener != null) {
+ throw new IllegalStateException("There is already a listener registered");
+ }
+ mOnLoadCanceledListener = listener;
+ }
+
+ /**
+ * Unregisters a listener that was previously added with
+ * {@link #registerOnLoadCanceledListener}.
+ *
+ * Must be called from the process's main thread.
+ *
+ * @param listener The listener to unregister.
+ */
+ public void unregisterOnLoadCanceledListener(OnLoadCanceledListener<D> listener) {
+ if (mOnLoadCanceledListener == null) {
+ throw new IllegalStateException("No listener register");
+ }
+ if (mOnLoadCanceledListener != listener) {
+ throw new IllegalArgumentException("Attempting to unregister the wrong listener");
+ }
+ mOnLoadCanceledListener = null;
+ }
+
+ /**
* Return whether this load has been started. That is, its {@link #startLoading()}
* has been called and no calls to {@link #stopLoading()} or
* {@link #reset()} have yet been made.
@@ -177,6 +245,12 @@
}
/**
+ * This function will normally be called for you automatically by
+ * {@link android.support.v4.app.LoaderManager} when the associated fragment/activity
+ * is being started. When using a Loader with {@link android.support.v4.app.LoaderManager},
+ * you <em>must not</em> call this method yourself, or you will conflict
+ * with its management of the Loader.
+ *
* Starts an asynchronous load of the Loader's data. When the result
* is ready the callbacks will be called on the process's main thread.
* If a previous load has been completed and is still valid
@@ -207,6 +281,43 @@
}
/**
+ * Attempt to cancel the current load task.
+ * Must be called on the main thread of the process.
+ *
+ * <p>Cancellation is not an immediate operation, since the load is performed
+ * in a background thread. If there is currently a load in progress, this
+ * method requests that the load be canceled, and notes this is the case;
+ * once the background thread has completed its work its remaining state
+ * will be cleared. If another load request comes in during this time,
+ * it will be held until the canceled load is complete.
+ *
+ * @return Returns <tt>false</tt> if the task could not be canceled,
+ * typically because it has already completed normally, or
+ * because {@link #startLoading()} hasn't been called; returns
+ * <tt>true</tt> otherwise. When <tt>true</tt> is returned, the task
+ * is still running and the {@link OnLoadCanceledListener} will be called
+ * when the task completes.
+ */
+ public boolean cancelLoad() {
+ return onCancelLoad();
+ }
+
+ /**
+ * Subclasses must implement this to take care of requests to {@link #cancelLoad()}.
+ * This will always be called from the process's main thread.
+ *
+ * @return Returns <tt>false</tt> if the task could not be canceled,
+ * typically because it has already completed normally, or
+ * because {@link #startLoading()} hasn't been called; returns
+ * <tt>true</tt> otherwise. When <tt>true</tt> is returned, the task
+ * is still running and the {@link OnLoadCanceledListener} will be called
+ * when the task completes.
+ */
+ protected boolean onCancelLoad() {
+ return false;
+ }
+
+ /**
* Force an asynchronous load. Unlike {@link #startLoading()} this will ignore a previously
* loaded data set and load a new one. This simply calls through to the
* implementation's {@link #onForceLoad()}. You generally should only call this
@@ -226,7 +337,13 @@
}
/**
- * Stops delivery of updates until the next time {@link #startLoading()} is called.
+ * This function will normally be called for you automatically by
+ * {@link android.support.v4.app.LoaderManager} when the associated fragment/activity
+ * is being stopped. When using a Loader with {@link android.support.v4.app.LoaderManager},
+ * you <em>must not</em> call this method yourself, or you will conflict
+ * with its management of the Loader.
+ *
+ * <p>Stops delivery of updates until the next time {@link #startLoading()} is called.
* Implementations should <em>not</em> invalidate their data at this point --
* clients are still free to use the last data the loader reported. They will,
* however, typically stop reporting new data if the data changes; they can
@@ -254,6 +371,12 @@
}
/**
+ * This function will normally be called for you automatically by
+ * {@link android.support.v4.app.LoaderManager} when restarting a Loader. When using
+ * a Loader with {@link android.support.v4.app.LoaderManager},
+ * you <em>must not</em> call this method yourself, or you will conflict
+ * with its management of the Loader.
+ *
* Tell the Loader that it is being abandoned. This is called prior
* to {@link #reset} to have it retain its current data but not report
* any new data.
@@ -272,10 +395,16 @@
* {@link #onReset()} happens. You can retrieve the current abandoned
* state with {@link #isAbandoned}.
*/
- protected void onAbandon() {
+ protected void onAbandon() {
}
/**
+ * This function will normally be called for you automatically by
+ * {@link android.support.v4.app.LoaderManager} when destroying a Loader. When using
+ * a Loader with {@link android.support.v4.app.LoaderManager},
+ * you <em>must not</em> call this method yourself, or you will conflict
+ * with its management of the Loader.
+ *
* Resets the state of the Loader. The Loader should at this point free
* all of its resources, since it may never be called again; however, its
* {@link #startLoading()} may later be called at which point it must be
diff --git a/v4/java/android/support/v4/content/ModernAsyncTask.java b/v4/java/android/support/v4/content/ModernAsyncTask.java
index 43b17f4..503f1a2 100644
--- a/v4/java/android/support/v4/content/ModernAsyncTask.java
+++ b/v4/java/android/support/v4/content/ModernAsyncTask.java
@@ -134,13 +134,13 @@
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
- throw new RuntimeException("An error occured while executing doInBackground()",
- e.getCause());
+ throw new RuntimeException(
+ "An error occurred while executing doInBackground()", e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
} catch (Throwable t) {
- throw new RuntimeException("An error occured while executing "
- + "doInBackground()", t);
+ throw new RuntimeException(
+ "An error occurred while executing doInBackground()", t);
}
}
};
diff --git a/v4/java/android/support/v4/content/SharedPreferencesCompat.java b/v4/java/android/support/v4/content/SharedPreferencesCompat.java
new file mode 100644
index 0000000..dca99a8
--- /dev/null
+++ b/v4/java/android/support/v4/content/SharedPreferencesCompat.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 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.v4.content;
+
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.support.annotation.NonNull;
+
+public class SharedPreferencesCompat {
+
+ public static class EditorCompat {
+
+ private static EditorCompat sInstance;
+
+ private interface Helper {
+ void apply(@NonNull SharedPreferences.Editor editor);
+ }
+
+ private static class EditorHelperBaseImpl implements Helper {
+
+ @Override
+ public void apply(@NonNull SharedPreferences.Editor editor) {
+ editor.commit();
+ }
+ }
+
+ private static class EditorHelperApi9Impl implements Helper {
+
+ @Override
+ public void apply(@NonNull SharedPreferences.Editor editor) {
+ EditorCompatGingerbread.apply(editor);
+ }
+ }
+
+ private final Helper mHelper;
+
+ private EditorCompat() {
+ if (Build.VERSION.SDK_INT >= 9) {
+ mHelper = new EditorHelperApi9Impl();
+ } else {
+ mHelper = new EditorHelperBaseImpl();
+ }
+ }
+
+ public static EditorCompat getInstance() {
+ if (sInstance == null) {
+ sInstance = new EditorCompat();
+ }
+ return sInstance;
+ }
+
+ public void apply(@NonNull SharedPreferences.Editor editor) {
+ mHelper.apply(editor);
+ }
+ }
+
+}
diff --git a/v4/java/android/support/v4/content/res/TypedArrayUtils.java b/v4/java/android/support/v4/content/res/TypedArrayUtils.java
new file mode 100644
index 0000000..79e4ac8
--- /dev/null
+++ b/v4/java/android/support/v4/content/res/TypedArrayUtils.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 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.v4.content.res;
+
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.AnyRes;
+import android.support.annotation.StyleableRes;
+
+/**
+ * Compat methods for accessing TypedArray values.
+ *
+ * @hide
+ */
+public class TypedArrayUtils {
+ public static boolean getBoolean(TypedArray a, @StyleableRes int index,
+ @StyleableRes int fallbackIndex, boolean defaultValue) {
+ boolean val = a.getBoolean(fallbackIndex, defaultValue);
+ return a.getBoolean(index, val);
+ }
+
+ public static Drawable getDrawable(TypedArray a, @StyleableRes int index,
+ @StyleableRes int fallbackIndex) {
+ Drawable val = a.getDrawable(index);
+ if (val == null) {
+ val = a.getDrawable(fallbackIndex);
+ }
+ return val;
+ }
+
+ public static int getInt(TypedArray a, @StyleableRes int index,
+ @StyleableRes int fallbackIndex, int defaultValue) {
+ int val = a.getInt(fallbackIndex, defaultValue);
+ return a.getInt(index, val);
+ }
+
+ public static @AnyRes int getResourceId(TypedArray a, @StyleableRes int index,
+ @StyleableRes int fallbackIndex, @AnyRes int defaultValue) {
+ int val = a.getResourceId(fallbackIndex, defaultValue);
+ return a.getResourceId(index, val);
+ }
+
+ public static String getString(TypedArray a, @StyleableRes int index,
+ @StyleableRes int fallbackIndex) {
+ String val = a.getString(index);
+ if (val == null) {
+ val = a.getString(fallbackIndex);
+ }
+ return val;
+ }
+
+ public static CharSequence[] getTextArray(TypedArray a, @StyleableRes int index,
+ @StyleableRes int fallbackIndex) {
+ CharSequence[] val = a.getTextArray(index);
+ if (val == null) {
+ val = a.getTextArray(fallbackIndex);
+ }
+ return val;
+ }
+}
diff --git a/v4/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java b/v4/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
new file mode 100644
index 0000000..47a5916
--- /dev/null
+++ b/v4/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 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.v4.hardware.fingerprint;
+
+import android.content.Context;
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.os.CancellationSignal;
+
+import java.security.Signature;
+
+import javax.crypto.Cipher;
+
+/**
+ * A class that coordinates access to the fingerprint hardware.
+ * <p>
+ * On platforms before MNC, this class behaves as there would be no fingerprint hardware available.
+ */
+public class FingerprintManagerCompat {
+
+ private Context mContext;
+
+ /** Get a {@link FingerprintManagerCompat} instance for a provided context. */
+ public static FingerprintManagerCompat from(Context context) {
+ return new FingerprintManagerCompat(context);
+ }
+
+ private FingerprintManagerCompat(Context context) {
+ mContext = context;
+ }
+
+ static final FingerprintManagerCompatImpl IMPL;
+ static {
+ final int version = Build.VERSION.SDK_INT;
+ // STOPSHIP: Remove "MNC" check once the API's are final for MNC
+ if (version >= 23 || "MNC".equals(Build.VERSION.CODENAME)) {
+ IMPL = new Api23FingerprintManagerCompatImpl();
+ } else {
+ IMPL = new LegacyFingerprintManagerCompatImpl();
+ }
+ }
+
+ /**
+ * Determine if there is at least one fingerprint enrolled.
+ *
+ * @return true if at least one fingerprint is enrolled, false otherwise
+ */
+ public boolean hasEnrolledFingerprints() {
+ return IMPL.hasEnrolledFingerprints(mContext);
+ }
+
+ /**
+ * Determine if fingerprint hardware is present and functional.
+ *
+ * @return true if hardware is present and functional, false otherwise.
+ */
+ public boolean isHardwareDetected() {
+ return IMPL.isHardwareDetected(mContext);
+ }
+
+ /**
+ * Request authentication of a crypto object. This call warms up the fingerprint hardware
+ * and starts scanning for a fingerprint. It terminates when
+ * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
+ * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at
+ * which point the object is no longer valid. The operation can be canceled by using the
+ * provided cancel object.
+ *
+ * @param crypto object associated with the call or null if none required.
+ * @param cancel an object that can be used to cancel authentication
+ * @param callback an object to receive authentication events
+ * @param flags optional flags; should be 0
+ */
+ public void authenticate(@Nullable CryptoObject crypto,
+ @Nullable CancellationSignal cancel, @NonNull AuthenticationCallback callback,
+ int flags) {
+ IMPL.authenticate(mContext, crypto, cancel, callback, flags);
+ }
+
+ /**
+ * A wrapper class for the crypto objects supported by FingerprintManager. Currently the
+ * framework supports {@link Signature} and {@link Cipher} objects.
+ */
+ public static class CryptoObject {
+
+ private final Signature mSignature;
+ private final Cipher mCipher;
+
+ public CryptoObject(Signature signature) {
+ mSignature = signature;
+ mCipher = null;
+ }
+
+ public CryptoObject(Cipher cipher) {
+ mCipher = cipher;
+ mSignature = null;
+ }
+
+ /**
+ * Get {@link Signature} object.
+ * @return {@link Signature} object or null if this doesn't contain one.
+ */
+ public Signature getSignature() { return mSignature; }
+
+ /**
+ * Get {@link Cipher} object.
+ * @return {@link Cipher} object or null if this doesn't contain one.
+ */
+ public Cipher getCipher() { return mCipher; }
+ }
+
+ /**
+ * Container for callback data from {@link FingerprintManagerCompat#authenticate(CryptoObject,
+ * CancellationSignal, AuthenticationCallback, int)}.
+ */
+ public static final class AuthenticationResult {
+ private CryptoObject mCryptoObject;
+
+ public AuthenticationResult(CryptoObject crypto) {
+ mCryptoObject = crypto;
+ }
+
+ /**
+ * Obtain the crypto object associated with this transaction
+ * @return crypto object provided to {@link FingerprintManagerCompat#authenticate(
+ * CryptoObject, CancellationSignal, AuthenticationCallback, int)}.
+ */
+ public CryptoObject getCryptoObject() { return mCryptoObject; }
+ }
+
+ /**
+ * Callback structure provided to {@link FingerprintManagerCompat#authenticate(CryptoObject,
+ * CancellationSignal, AuthenticationCallback, int)}. Users of {@link
+ * FingerprintManagerCompat#authenticate(CryptoObject, CancellationSignal,
+ * AuthenticationCallback, int) } must provide an implementation of this for listening to
+ * fingerprint events.
+ */
+ public static abstract class AuthenticationCallback {
+ /**
+ * Called when an unrecoverable error has been encountered and the operation is complete.
+ * No further callbacks will be made on this object.
+ * @param errMsgId An integer identifying the error message
+ * @param errString A human-readable error string that can be shown in UI
+ */
+ public void onAuthenticationError(int errMsgId, CharSequence errString) { }
+
+ /**
+ * Called when a recoverable error has been encountered during authentication. The help
+ * string is provided to give the user guidance for what went wrong, such as
+ * "Sensor dirty, please clean it."
+ * @param helpMsgId An integer identifying the error message
+ * @param helpString A human-readable string that can be shown in UI
+ */
+ public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { }
+
+ /**
+ * Called when a fingerprint is recognized.
+ * @param result An object containing authentication-related data
+ */
+ public void onAuthenticationSucceeded(AuthenticationResult result) { }
+
+ /**
+ * Called when a fingerprint is valid but not recognized.
+ */
+ public void onAuthenticationFailed() { }
+ }
+
+ private interface FingerprintManagerCompatImpl {
+ boolean hasEnrolledFingerprints(Context context);
+ boolean isHardwareDetected(Context context);
+ void authenticate(Context context, CryptoObject crypto, CancellationSignal cancel,
+ AuthenticationCallback callback, int flags);
+ }
+
+ private static class LegacyFingerprintManagerCompatImpl
+ implements FingerprintManagerCompatImpl {
+
+ public LegacyFingerprintManagerCompatImpl() {
+ }
+
+ @Override
+ public boolean hasEnrolledFingerprints(Context context) {
+ return false;
+ }
+
+ @Override
+ public boolean isHardwareDetected(Context context) {
+ return false;
+ }
+
+ @Override
+ public void authenticate(Context context, CryptoObject crypto, CancellationSignal cancel,
+ AuthenticationCallback callback, int flags) {
+ // TODO: Figure out behavior when there is no fingerprint hardware available
+ }
+ }
+
+ private static class Api23FingerprintManagerCompatImpl implements FingerprintManagerCompatImpl {
+
+ public Api23FingerprintManagerCompatImpl() {
+ }
+
+ @Override
+ public boolean hasEnrolledFingerprints(Context context) {
+ return FingerprintManagerCompatApi23.hasEnrolledFingerprints(context);
+ }
+
+ @Override
+ public boolean isHardwareDetected(Context context) {
+ return FingerprintManagerCompatApi23.isHardwareDetected(context);
+ }
+
+ @Override
+ public void authenticate(Context context, CryptoObject crypto, CancellationSignal cancel,
+ AuthenticationCallback callback, int flags) {
+ FingerprintManagerCompatApi23.authenticate(context, wrapCryptoObject(crypto),
+ cancel != null ? cancel.getCancellationSignalObject() : null,
+ wrapCallback(callback), flags);
+ }
+
+ private static FingerprintManagerCompatApi23.CryptoObject wrapCryptoObject(
+ CryptoObject cryptoObject) {
+ if (cryptoObject.getCipher() != null) {
+ return new FingerprintManagerCompatApi23.CryptoObject(cryptoObject.getCipher());
+ } else {
+ return new FingerprintManagerCompatApi23.CryptoObject(cryptoObject.getSignature());
+ }
+ }
+
+ private static CryptoObject unwrapCryptoObject(
+ FingerprintManagerCompatApi23.CryptoObject cryptoObject) {
+ if (cryptoObject.getCipher() != null) {
+ return new CryptoObject(cryptoObject.getCipher());
+ } else {
+ return new CryptoObject(cryptoObject.getSignature());
+ }
+ }
+
+ private static FingerprintManagerCompatApi23.AuthenticationCallback wrapCallback(
+ final AuthenticationCallback callback) {
+ return new FingerprintManagerCompatApi23.AuthenticationCallback() {
+ @Override
+ public void onAuthenticationError(int errMsgId, CharSequence errString) {
+ callback.onAuthenticationError(errMsgId, errString);
+ }
+
+ @Override
+ public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
+ callback.onAuthenticationHelp(helpMsgId, helpString);
+ }
+
+ @Override
+ public void onAuthenticationSucceeded(
+ FingerprintManagerCompatApi23.AuthenticationResultInternal result) {
+ callback.onAuthenticationSucceeded(new AuthenticationResult(
+ unwrapCryptoObject(result.getCryptoObject())));
+ }
+
+ @Override
+ public void onAuthenticationFailed() {
+ callback.onAuthenticationFailed();
+ }
+ };
+ }
+ }
+}
diff --git a/v4/java/android/support/v4/internal/view/SupportMenuItem.java b/v4/java/android/support/v4/internal/view/SupportMenuItem.java
index 0a1bccb..e739ec8 100644
--- a/v4/java/android/support/v4/internal/view/SupportMenuItem.java
+++ b/v4/java/android/support/v4/internal/view/SupportMenuItem.java
@@ -16,6 +16,8 @@
package android.support.v4.internal.view;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.support.v4.view.ActionProvider;
import android.support.v4.view.MenuItemCompat;
import android.view.MenuItem;
@@ -201,4 +203,26 @@
* @return This menu item instance for call chaining
*/
public SupportMenuItem setSupportOnActionExpandListener(MenuItemCompat.OnActionExpandListener listener);
+
+ /**
+ * Applies a tint to the icon drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link android.view.MenuItem#setIcon(android.graphics.drawable.Drawable)}
+ * will automatically mutate the drawable and apply the specified tint and tint mode.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ * @return This menu item instance for call chaining
+ */
+ public MenuItem setIconTintList(ColorStateList tint);
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setIconTintList(ColorStateList)} to the icon drawable. The default mode is {@link
+ * PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ * @return This menu item instance for call chaining
+ */
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode);
}
\ No newline at end of file
diff --git a/v4/java/android/support/v4/media/session/MediaSessionCompat.java b/v4/java/android/support/v4/media/session/MediaSessionCompat.java
index fafb8e7..e6e2824 100644
--- a/v4/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/v4/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -1786,10 +1786,10 @@
mCallback.onCommand(cmd.command, cmd.extras, cmd.stub);
break;
case MSG_ADJUST_VOLUME:
- adjustVolume((Integer) msg.obj, 0);
+ adjustVolume((int) msg.obj, 0);
break;
case MSG_SET_VOLUME:
- setVolumeTo((Integer) msg.obj, 0);
+ setVolumeTo((int) msg.obj, 0);
break;
}
}
diff --git a/v4/java/android/support/v4/os/CancellationSignal.java b/v4/java/android/support/v4/os/CancellationSignal.java
new file mode 100644
index 0000000..41bdfe6
--- /dev/null
+++ b/v4/java/android/support/v4/os/CancellationSignal.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2012 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.v4.os;
+
+import android.os.Build;
+
+/**
+ * Static library support version of the framework's {@link android.os.CancellationSignal}.
+ * Used to write apps that run on platforms prior to Android 4.1. See the framework SDK
+ * documentation for a class overview.
+ */
+public final class CancellationSignal {
+ private boolean mIsCanceled;
+ private OnCancelListener mOnCancelListener;
+ private Object mCancellationSignalObj;
+ private boolean mCancelInProgress;
+
+ /**
+ * Creates a cancellation signal, initially not canceled.
+ */
+ public CancellationSignal() {
+ }
+
+ /**
+ * Returns true if the operation has been canceled.
+ *
+ * @return True if the operation has been canceled.
+ */
+ public boolean isCanceled() {
+ synchronized (this) {
+ return mIsCanceled;
+ }
+ }
+
+ /**
+ * Throws {@link OperationCanceledException} if the operation has been canceled.
+ *
+ * @throws OperationCanceledException if the operation has been canceled.
+ */
+ public void throwIfCanceled() {
+ if (isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+
+ /**
+ * Cancels the operation and signals the cancellation listener.
+ * If the operation has not yet started, then it will be canceled as soon as it does.
+ */
+ public void cancel() {
+ final OnCancelListener listener;
+ final Object obj;
+ synchronized (this) {
+ if (mIsCanceled) {
+ return;
+ }
+ mIsCanceled = true;
+ mCancelInProgress = true;
+ listener = mOnCancelListener;
+ obj = mCancellationSignalObj;
+ }
+
+ try {
+ if (listener != null) {
+ listener.onCancel();
+ }
+ if (obj != null) {
+ CancellationSignalCompatJellybean.cancel(obj);
+ }
+ } finally {
+ synchronized (this) {
+ mCancelInProgress = false;
+ notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Sets the cancellation listener to be called when canceled.
+ *
+ * This method is intended to be used by the recipient of a cancellation signal
+ * such as a database or a content provider to handle cancellation requests
+ * while performing a long-running operation. This method is not intended to be
+ * used by applications themselves.
+ *
+ * If {@link CancellationSignal#cancel} has already been called, then the provided
+ * listener is invoked immediately.
+ *
+ * This method is guaranteed that the listener will not be called after it
+ * has been removed.
+ *
+ * @param listener The cancellation listener, or null to remove the current listener.
+ */
+ public void setOnCancelListener(OnCancelListener listener) {
+ synchronized (this) {
+ waitForCancelFinishedLocked();
+
+ if (mOnCancelListener == listener) {
+ return;
+ }
+ mOnCancelListener = listener;
+ if (!mIsCanceled || listener == null) {
+ return;
+ }
+ }
+ listener.onCancel();
+ }
+
+ /**
+ * Gets the framework {@link android.os.CancellationSignal} associated with this object.
+ * <p>
+ * Framework support for cancellation signals was added in
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} so this method will always
+ * return null on older versions of the platform.
+ * </p>
+ *
+ * @return A framework cancellation signal object, or null on platform versions
+ * prior to Jellybean.
+ */
+ public Object getCancellationSignalObject() {
+ if (Build.VERSION.SDK_INT < 16) {
+ return null;
+ }
+ synchronized (this) {
+ if (mCancellationSignalObj == null) {
+ mCancellationSignalObj = CancellationSignalCompatJellybean.create();
+ if (mIsCanceled) {
+ CancellationSignalCompatJellybean.cancel(mCancellationSignalObj);
+ }
+ }
+ return mCancellationSignalObj;
+ }
+ }
+
+ private void waitForCancelFinishedLocked() {
+ while (mCancelInProgress) {
+ try {
+ wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ }
+
+ /**
+ * Listens for cancellation.
+ */
+ public interface OnCancelListener {
+ /**
+ * Called when {@link CancellationSignal#cancel} is invoked.
+ */
+ void onCancel();
+ }
+}
diff --git a/v4/java/android/support/v4/os/OperationCanceledException.java b/v4/java/android/support/v4/os/OperationCanceledException.java
new file mode 100644
index 0000000..9b28030
--- /dev/null
+++ b/v4/java/android/support/v4/os/OperationCanceledException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+package android.support.v4.os;
+
+
+/**
+ * An exception type that is thrown when an operation in progress is canceled.
+ */
+public class OperationCanceledException extends RuntimeException {
+ public OperationCanceledException() {
+ this(null);
+ }
+
+ public OperationCanceledException(String message) {
+ super(message != null ? message : "The operation has been canceled.");
+ }
+}
diff --git a/v4/java/android/support/v4/text/ICUCompat.java b/v4/java/android/support/v4/text/ICUCompat.java
index 6df35ff..43ada52 100644
--- a/v4/java/android/support/v4/text/ICUCompat.java
+++ b/v4/java/android/support/v4/text/ICUCompat.java
@@ -18,34 +18,32 @@
import android.os.Build;
+import java.util.Locale;
+
public class ICUCompat {
interface ICUCompatImpl {
- public String getScript(String locale);
- public String addLikelySubtags(String locale);
+ public String maximizeAndGetScript(Locale locale);
}
static class ICUCompatImplBase implements ICUCompatImpl {
@Override
- public String getScript(String locale) {
+ public String maximizeAndGetScript(Locale locale) {
return null;
}
-
- @Override
- public String addLikelySubtags(String locale) {
- return locale;
- }
}
static class ICUCompatImplIcs implements ICUCompatImpl {
@Override
- public String getScript(String locale) {
- return ICUCompatIcs.getScript(locale);
+ public String maximizeAndGetScript(Locale locale) {
+ return ICUCompatIcs.maximizeAndGetScript(locale);
}
+ }
+ static class ICUCompatImplLollipop implements ICUCompatImpl {
@Override
- public String addLikelySubtags(String locale) {
- return ICUCompatIcs.addLikelySubtags(locale);
+ public String maximizeAndGetScript(Locale locale) {
+ return ICUCompatApi23.maximizeAndGetScript(locale);
}
}
@@ -53,7 +51,9 @@
static {
final int version = Build.VERSION.SDK_INT;
- if (version >= 14) {
+ if (version >= 21) {
+ IMPL = new ICUCompatImplLollipop();
+ } else if (version >= 14) {
IMPL = new ICUCompatImplIcs();
} else {
IMPL = new ICUCompatImplBase();
@@ -61,18 +61,11 @@
}
/**
- * Returns the script (language code) of a script.
+ * Returns the script for a given Locale.
*
- * @param locale The locale.
- * @return a String representing the script (language code) of the locale.
- */
- public static String getScript(String locale) {
- return IMPL.getScript(locale);
- }
-
- /**
- * Add the likely subtags for a provided locale ID, per the algorithm described in the following
- * CLDR technical report:
+ * If the locale isn't already in its maximal form, likely subtags for the provided locale
+ * ID are added before we determine the script. For further details, see the following CLDR
+ * technical report :
*
* http://www.unicode.org/reports/tr35/#Likely_Subtags
*
@@ -87,12 +80,10 @@
* "sr" maximizes to "sr_Cyrl_RS"
* "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.)
* "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.)
-
- * @param locale The locale to maximize
*
- * @return the maximized locale
+ * @return
*/
- public static String addLikelySubtags(String locale) {
- return IMPL.addLikelySubtags(locale);
+ public static String maximizeAndGetScript(Locale locale) {
+ return IMPL.maximizeAndGetScript(locale);
}
}
diff --git a/v4/java/android/support/v4/text/TextUtilsCompat.java b/v4/java/android/support/v4/text/TextUtilsCompat.java
index 436d72f..507a006 100644
--- a/v4/java/android/support/v4/text/TextUtilsCompat.java
+++ b/v4/java/android/support/v4/text/TextUtilsCompat.java
@@ -74,8 +74,7 @@
*/
public static int getLayoutDirectionFromLocale(@Nullable Locale locale) {
if (locale != null && !locale.equals(ROOT)) {
- final String scriptSubtag = ICUCompat.getScript(
- ICUCompat.addLikelySubtags(locale.toString()));
+ final String scriptSubtag = ICUCompat.maximizeAndGetScript(locale);
if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale);
if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
diff --git a/v4/java/android/support/v4/util/CircularArray.java b/v4/java/android/support/v4/util/CircularArray.java
index 760c986..e2ac26b 100644
--- a/v4/java/android/support/v4/util/CircularArray.java
+++ b/v4/java/android/support/v4/util/CircularArray.java
@@ -93,7 +93,7 @@
/**
* Remove first element from front of the CircularArray and return it.
* @return The element removed.
- * @throws {@link ArrayIndexOutOfBoundsException} if CircularArray is empty.
+ * @throws ArrayIndexOutOfBoundsException if CircularArray is empty.
*/
public E popFirst() {
if (mHead == mTail) {
@@ -108,7 +108,7 @@
/**
* Remove last element from end of the CircularArray and return it.
* @return The element removed.
- * @throws {@link ArrayIndexOutOfBoundsException} if CircularArray is empty.
+ * @throws ArrayIndexOutOfBoundsException if CircularArray is empty.
*/
public E popLast() {
if (mHead == mTail) {
@@ -132,7 +132,7 @@
* Remove multiple elements from front of the CircularArray, ignore when numOfElements
* is less than or equals to 0.
* @param numOfElements Number of elements to remove.
- * @throws {@link ArrayIndexOutOfBoundsException} if numOfElements is larger than
+ * @throws ArrayIndexOutOfBoundsException if numOfElements is larger than
* {@link #size()}
*/
public void removeFromStart(int numOfElements) {
@@ -165,7 +165,7 @@
* Remove multiple elements from end of the CircularArray, ignore when numOfElements
* is less than or equals to 0.
* @param numOfElements Number of elements to remove.
- * @throws {@link ArrayIndexOutOfBoundsException} if numOfElements is larger than
+ * @throws ArrayIndexOutOfBoundsException if numOfElements is larger than
* {@link #size()}
*/
public void removeFromEnd(int numOfElements) {
diff --git a/v4/java/android/support/v4/util/CircularIntArray.java b/v4/java/android/support/v4/util/CircularIntArray.java
index 2389436..706d73b 100644
--- a/v4/java/android/support/v4/util/CircularIntArray.java
+++ b/v4/java/android/support/v4/util/CircularIntArray.java
@@ -94,7 +94,7 @@
/**
* Remove first integer from front of the CircularIntArray and return it.
* @return The integer removed.
- * @throws {@link ArrayIndexOutOfBoundsException} if CircularIntArray is empty.
+ * @throws ArrayIndexOutOfBoundsException if CircularIntArray is empty.
*/
public int popFirst() {
if (mHead == mTail) throw new ArrayIndexOutOfBoundsException();
@@ -106,7 +106,7 @@
/**
* Remove last integer from end of the CircularIntArray and return it.
* @return The integer removed.
- * @throws {@link ArrayIndexOutOfBoundsException} if CircularIntArray is empty.
+ * @throws ArrayIndexOutOfBoundsException if CircularIntArray is empty.
*/
public int popLast() {
if (mHead == mTail) throw new ArrayIndexOutOfBoundsException();
@@ -127,7 +127,7 @@
* Remove multiple integers from front of the CircularIntArray, ignore when numOfElements
* is less than or equals to 0.
* @param numOfElements Number of integers to remove.
- * @throws {@link ArrayIndexOutOfBoundsException} if numOfElements is larger than
+ * @throws ArrayIndexOutOfBoundsException if numOfElements is larger than
* {@link #size()}
*/
public void removeFromStart(int numOfElements) {
@@ -144,7 +144,7 @@
* Remove multiple elements from end of the CircularIntArray, ignore when numOfElements
* is less than or equals to 0.
* @param numOfElements Number of integers to remove.
- * @throws {@link ArrayIndexOutOfBoundsException} if numOfElements is larger than
+ * @throws ArrayIndexOutOfBoundsException if numOfElements is larger than
* {@link #size()}
*/
public void removeFromEnd(int numOfElements) {
diff --git a/v4/java/android/support/v4/view/MenuItemCompat.java b/v4/java/android/support/v4/view/MenuItemCompat.java
index 8a52e9e..5f776ba 100644
--- a/v4/java/android/support/v4/view/MenuItemCompat.java
+++ b/v4/java/android/support/v4/view/MenuItemCompat.java
@@ -16,6 +16,10 @@
package android.support.v4.view;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.internal.view.SupportMenuItem;
import android.util.Log;
import android.view.MenuItem;
@@ -77,6 +81,8 @@
boolean collapseActionView(MenuItem item);
boolean isActionViewExpanded(MenuItem item);
MenuItem setOnActionExpandListener(MenuItem item, OnActionExpandListener listener);
+ MenuItem setIconTintList(MenuItem item, ColorStateList tintList);
+ MenuItem setIconTintMode(MenuItem item, PorterDuff.Mode tintMode);
}
/**
@@ -150,12 +156,30 @@
public MenuItem setOnActionExpandListener(MenuItem item, OnActionExpandListener listener) {
return item;
}
+
+ @Override
+ public MenuItem setIconTintList(MenuItem item, ColorStateList tintList) {
+ Drawable icon = item.getIcon();
+ if (icon != null) {
+ DrawableCompat.setTintList(icon, tintList);
+ }
+ return item;
+ }
+
+ @Override
+ public MenuItem setIconTintMode(MenuItem item, PorterDuff.Mode tintMode) {
+ Drawable icon = item.getIcon();
+ if (icon != null) {
+ DrawableCompat.setTintMode(icon, tintMode);
+ }
+ return item;
+ }
}
/**
* Interface implementation for devices with at least v11 APIs.
*/
- static class HoneycombMenuVersionImpl implements MenuVersionImpl {
+ static class HoneycombMenuVersionImpl extends BaseMenuVersionImpl {
@Override
public void setShowAsAction(MenuItem item, int actionEnum) {
MenuItemCompatHoneycomb.setShowAsAction(item, actionEnum);
@@ -239,13 +263,27 @@
}
}
+ static class Api23MenuVersionImpl extends IcsMenuVersionImpl {
+ @Override
+ public MenuItem setIconTintList(MenuItem item, ColorStateList tintList) {
+ return MenuItemCompatApi23.setIconTintList(item, tintList);
+ }
+
+ @Override
+ public MenuItem setIconTintMode(MenuItem item, PorterDuff.Mode tintMode) {
+ return MenuItemCompatApi23.setIconTintMode(item, tintMode);
+ }
+ }
+
/**
* Select the correct implementation to use for the current platform.
*/
static final MenuVersionImpl IMPL;
static {
final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 14) {
+ if (version >= 23) {
+ IMPL = new Api23MenuVersionImpl();
+ } else if (version >= 14) {
IMPL = new IcsMenuVersionImpl();
} else if (version >= 11) {
IMPL = new HoneycombMenuVersionImpl();
@@ -437,4 +475,50 @@
}
return IMPL.setOnActionExpandListener(item, listener);
}
+
+ /**
+ * Applies a tint to the icon drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link android.view.MenuItem#setIcon(Drawable)}
+ * will automatically mutate the drawable and apply the specified tint and tint mode.
+ * <p>
+ * Where available, this method will call directly into the framework API. Otherwise it will
+ * try to tint the icon directly using
+ * {@link DrawableCompat#setTintList(Drawable, ColorStateList)}. You should wrap the icon
+ * drawable manually using {@link DrawableCompat#wrap(Drawable)} for this to work on all
+ * API levels.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ * @return This menu item instance for call chaining
+ */
+ public static MenuItem setIconTintList(MenuItem item, ColorStateList tint) {
+ if (item instanceof SupportMenuItem) {
+ return ((SupportMenuItem) item).setIconTintList(tint);
+ } else {
+ return IMPL.setIconTintList(item, tint);
+ }
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setIconTintList(MenuItem, ColorStateList)} to the icon drawable. The default mode is {@link
+ * PorterDuff.Mode#SRC_IN}.
+ * <p>
+ * Where available, this method will call directly into the framework API. Otherwise it will
+ * try to set the mode directly on the icon using
+ * {@link DrawableCompat#setTintMode(Drawable, PorterDuff.Mode)}. You should wrap the icon
+ * drawable manually using {@link DrawableCompat#wrap(Drawable)} for this to work on all
+ * API levels.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ * @return This menu item instance for call chaining
+ */
+ public static MenuItem setIconTintMode(MenuItem item, PorterDuff.Mode tintMode) {
+ if (item instanceof SupportMenuItem) {
+ return ((SupportMenuItem) item).setIconTintMode(tintMode);
+ } else {
+ return IMPL.setIconTintMode(item, tintMode);
+ }
+ }
}
diff --git a/v4/java/android/support/v4/view/PagerTabStrip.java b/v4/java/android/support/v4/view/PagerTabStrip.java
index 834035c..cd0206b 100644
--- a/v4/java/android/support/v4/view/PagerTabStrip.java
+++ b/v4/java/android/support/v4/view/PagerTabStrip.java
@@ -21,6 +21,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
@@ -127,7 +128,7 @@
*
* @param color Color to set as an 0xRRGGBB value. The high byte (alpha) is ignored.
*/
- public void setTabIndicatorColor(int color) {
+ public void setTabIndicatorColor(@ColorInt int color) {
mIndicatorColor = color;
mTabPaint.setColor(mIndicatorColor);
invalidate();
@@ -145,6 +146,7 @@
/**
* @return The current tab indicator color as an 0xRRGGBB value.
*/
+ @ColorInt
public int getTabIndicatorColor() {
return mIndicatorColor;
}
@@ -174,7 +176,7 @@
}
@Override
- public void setBackgroundColor(int color) {
+ public void setBackgroundColor(@ColorInt int color) {
super.setBackgroundColor(color);
if (!mDrawFullUnderlineSet) {
mDrawFullUnderline = (color & 0xFF000000) == 0;
diff --git a/v4/java/android/support/v4/view/PagerTitleStrip.java b/v4/java/android/support/v4/view/PagerTitleStrip.java
index 79c771f..cb9cd75 100644
--- a/v4/java/android/support/v4/view/PagerTitleStrip.java
+++ b/v4/java/android/support/v4/view/PagerTitleStrip.java
@@ -20,6 +20,8 @@
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
+import android.support.annotation.FloatRange;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.util.TypedValue;
@@ -189,7 +191,7 @@
*
* @param alpha Opacity value in the range 0-1f
*/
- public void setNonPrimaryAlpha(float alpha) {
+ public void setNonPrimaryAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {
mNonPrimaryAlpha = (int) (alpha * 255) & 0xFF;
final int transparentColor = (mNonPrimaryAlpha << 24) | (mTextColor & 0xFFFFFF);
mPrevText.setTextColor(transparentColor);
@@ -202,7 +204,7 @@
*
* @param color Color hex code in 0xAARRGGBB format
*/
- public void setTextColor(int color) {
+ public void setTextColor(@ColorInt int color) {
mTextColor = color;
mCurrText.setTextColor(color);
final int transparentColor = (mNonPrimaryAlpha << 24) | (mTextColor & 0xFFFFFF);
diff --git a/v4/java/android/support/v4/view/ViewCompat.java b/v4/java/android/support/v4/view/ViewCompat.java
index 871f633..eeacb32 100644
--- a/v4/java/android/support/v4/view/ViewCompat.java
+++ b/v4/java/android/support/v4/view/ViewCompat.java
@@ -24,6 +24,7 @@
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.FloatRange;
import android.support.annotation.IdRes;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
@@ -2334,7 +2335,7 @@
*
* @param value The opacity of the view.
*/
- public static void setAlpha(View view, float value) {
+ public static void setAlpha(View view, @FloatRange(from=0.0, to=1.0) float value) {
IMPL.setAlpha(view, value);
}
diff --git a/v4/java/android/support/v4/view/ViewPager.java b/v4/java/android/support/v4/view/ViewPager.java
index 92596fc..dc20cb6 100644
--- a/v4/java/android/support/v4/view/ViewPager.java
+++ b/v4/java/android/support/v4/view/ViewPager.java
@@ -28,6 +28,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
+import android.support.annotation.CallSuper;
import android.support.annotation.DrawableRes;
import android.support.v4.os.ParcelableCompat;
import android.support.v4.os.ParcelableCompatCreatorCallbacks;
@@ -1671,6 +1672,7 @@
* @param offset Value from [0, 1) indicating the offset from the page at position.
* @param offsetPixels Value in pixels indicating the offset from position.
*/
+ @CallSuper
protected void onPageScrolled(int position, float offset, int offsetPixels) {
// Offset any decor views if needed - keep them on-screen at all times.
if (mDecorChildCount > 0) {
diff --git a/v4/java/android/support/v4/widget/DrawerLayout.java b/v4/java/android/support/v4/widget/DrawerLayout.java
index a8967a2..d939b35 100644
--- a/v4/java/android/support/v4/widget/DrawerLayout.java
+++ b/v4/java/android/support/v4/widget/DrawerLayout.java
@@ -29,6 +29,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
+import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
@@ -417,7 +418,7 @@
*
* @param color Color to use in 0xAARRGGBB format.
*/
- public void setScrimColor(int color) {
+ public void setScrimColor(@ColorInt int color) {
mScrimColor = color;
invalidate();
}
@@ -1042,7 +1043,7 @@
* @param color Color to use as a background drawable to draw behind the status bar
* in 0xAARRGGBB format.
*/
- public void setStatusBarBackgroundColor(int color) {
+ public void setStatusBarBackgroundColor(@ColorInt int color) {
mStatusBarBackground = new ColorDrawable(color);
invalidate();
}
diff --git a/v4/java/android/support/v4/widget/ExploreByTouchHelper.java b/v4/java/android/support/v4/widget/ExploreByTouchHelper.java
index 7adbc6f..64f6634 100644
--- a/v4/java/android/support/v4/widget/ExploreByTouchHelper.java
+++ b/v4/java/android/support/v4/widget/ExploreByTouchHelper.java
@@ -45,11 +45,11 @@
* and managing accessibility focus. This class does not currently support
* hierarchies of logical items.
* <p>
- * This should be applied to the parent view using
- * {@link ViewCompat#setAccessibilityDelegate}:
+ * Clients should override abstract methods on this class and attach it to the
+ * host view using {@link ViewCompat#setAccessibilityDelegate}:
*
* <pre>
- * mAccessHelper = ExploreByTouchHelper.create(someView, mAccessHelperCallback);
+ * mAccessHelper = new MyExploreByTouchHelper(someView);
* ViewCompat.setAccessibilityDelegate(someView, mAccessHelper);
* </pre>
*/
@@ -57,6 +57,9 @@
/** Virtual node identifier value for invalid nodes. */
public static final int INVALID_ID = Integer.MIN_VALUE;
+ /** Virtual node identifier value for the host view's node. */
+ public static final int HOST_ID = View.NO_ID;
+
/** Default class name used for virtual views. */
private static final String DEFAULT_CLASS_NAME = View.class.getName();
@@ -191,7 +194,7 @@
* parent view.
*/
public void invalidateRoot() {
- invalidateVirtualView(View.NO_ID);
+ invalidateVirtualView(HOST_ID);
}
/**
@@ -243,7 +246,7 @@
/**
* Constructs and returns an {@link AccessibilityEvent} for the specified
- * virtual view id, which includes the host view ({@link View#NO_ID}).
+ * virtual view id, which includes the host view ({@link #HOST_ID}).
*
* @param virtualViewId The virtual view id for the item for which to
* construct an event.
@@ -253,7 +256,7 @@
*/
private AccessibilityEvent createEvent(int virtualViewId, int eventType) {
switch (virtualViewId) {
- case View.NO_ID:
+ case HOST_ID:
return createEventForHost(eventType);
default:
return createEventForChild(virtualViewId, eventType);
@@ -309,7 +312,7 @@
/**
* Constructs and returns an {@link AccessibilityNodeInfoCompat} for the
* specified virtual view id, which includes the host view
- * ({@link View#NO_ID}).
+ * ({@link #HOST_ID}).
*
* @param virtualViewId The virtual view id for the item for which to
* construct a node.
@@ -318,7 +321,7 @@
*/
private AccessibilityNodeInfoCompat createNode(int virtualViewId) {
switch (virtualViewId) {
- case View.NO_ID:
+ case HOST_ID:
return createNodeForHost();
default:
return createNodeForChild(virtualViewId);
@@ -335,6 +338,9 @@
final AccessibilityNodeInfoCompat node = AccessibilityNodeInfoCompat.obtain(mView);
ViewCompat.onInitializeAccessibilityNodeInfo(mView, node);
+ // Allow the client to populate the host node.
+ onPopulateNodeForHost(node);
+
// Add the virtual descendants.
final LinkedList<Integer> virtualViewIds = new LinkedList<Integer>();
getVisibleVirtualViews(virtualViewIds);
@@ -439,7 +445,7 @@
private boolean performAction(int virtualViewId, int action, Bundle arguments) {
switch (virtualViewId) {
- case View.NO_ID:
+ case HOST_ID:
return performActionForHost(action, arguments);
default:
return performActionForChild(virtualViewId, action, arguments);
@@ -542,7 +548,15 @@
}
// TODO: Check virtual view visibility.
if (!isAccessibilityFocused(virtualViewId)) {
+ // Clear focus from the previously focused view, if applicable.
+ if (mFocusedVirtualViewId != INVALID_ID) {
+ sendEventForVirtualView(mFocusedVirtualViewId,
+ AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
+ }
+
+ // Set focus on the new view.
mFocusedVirtualViewId = virtualViewId;
+
// TODO: Only invalidate virtual view bounds.
mView.invalidate();
sendEventForVirtualView(virtualViewId,
@@ -577,7 +591,7 @@
* @param x The view-relative x coordinate
* @param y The view-relative y coordinate
* @return virtual view identifier for the logical item under
- * coordinates (x,y) or {@link View#NO_ID} if there is no item at
+ * coordinates (x,y) or {@link #HOST_ID} if there is no item at
* the given coordinates
*/
protected abstract int getVirtualViewAt(float x, float y);
@@ -683,6 +697,17 @@
int virtualViewId, AccessibilityNodeInfoCompat node);
/**
+ * Populates an {@link AccessibilityNodeInfoCompat} with information
+ * about the host view.
+ * <p>
+ * The following required fields are automatically populated by the
+ * helper class and may not be overridden:
+ */
+ public void onPopulateNodeForHost(AccessibilityNodeInfoCompat node) {
+ // Default implementation is no-op.
+ }
+
+ /**
* Performs the specified accessibility action on the item associated
* with the virtual view identifier. See
* {@link AccessibilityNodeInfoCompat#performAction(int, Bundle)} for
diff --git a/v4/java/android/support/v4/widget/PopupWindowCompat.java b/v4/java/android/support/v4/widget/PopupWindowCompat.java
index be96a73..7f4c828 100644
--- a/v4/java/android/support/v4/widget/PopupWindowCompat.java
+++ b/v4/java/android/support/v4/widget/PopupWindowCompat.java
@@ -17,7 +17,7 @@
package android.support.v4.widget;
import android.view.View;
-import android.view.View.OnTouchListener;
+import android.view.WindowManager;
import android.widget.PopupWindow;
/**
@@ -29,8 +29,11 @@
* Interface for the full API.
*/
interface PopupWindowImpl {
- public void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff,
- int gravity);
+ void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff, int gravity);
+ void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor);
+ boolean getOverlapAnchor(PopupWindow popupWindow);
+ void setWindowLayoutType(PopupWindow popupWindow, int layoutType);
+ int getWindowLayoutType(PopupWindow popupWindow);
}
/**
@@ -42,12 +45,47 @@
int gravity) {
popup.showAsDropDown(anchor, xoff, yoff);
}
+
+ @Override
+ public void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
+ // noop
+ }
+
+ @Override
+ public boolean getOverlapAnchor(PopupWindow popupWindow) {
+ return false;
+ }
+
+ @Override
+ public void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+ // no-op
+ }
+
+ @Override
+ public int getWindowLayoutType(PopupWindow popupWindow) {
+ return 0;
+ }
+ }
+
+ /**
+ * Interface implementation that doesn't use anything above v4 APIs.
+ */
+ static class GingerbreadPopupWindowImpl extends BasePopupWindowImpl {
+ @Override
+ public void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+ PopupWindowCompatGingerbread.setWindowLayoutType(popupWindow, layoutType);
+ }
+
+ @Override
+ public int getWindowLayoutType(PopupWindow popupWindow) {
+ return PopupWindowCompatGingerbread.getWindowLayoutType(popupWindow);
+ }
}
/**
* Interface implementation for devices with at least KitKat APIs.
*/
- static class KitKatPopupWindowImpl extends BasePopupWindowImpl {
+ static class KitKatPopupWindowImpl extends GingerbreadPopupWindowImpl {
@Override
public void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff,
int gravity) {
@@ -55,14 +93,54 @@
}
}
+ static class Api21PopupWindowImpl extends KitKatPopupWindowImpl {
+ @Override
+ public void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
+ PopupWindowCompatApi21.setOverlapAnchor(popupWindow, overlapAnchor);
+ }
+
+ @Override
+ public boolean getOverlapAnchor(PopupWindow popupWindow) {
+ return PopupWindowCompatApi21.getOverlapAnchor(popupWindow);
+ }
+ }
+
+ static class Api23PopupWindowImpl extends Api21PopupWindowImpl {
+ @Override
+ public void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
+ PopupWindowCompatApi23.setOverlapAnchor(popupWindow, overlapAnchor);
+ }
+
+ @Override
+ public boolean getOverlapAnchor(PopupWindow popupWindow) {
+ return PopupWindowCompatApi23.getOverlapAnchor(popupWindow);
+ }
+
+ @Override
+ public void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+ PopupWindowCompatApi23.setWindowLayoutType(popupWindow, layoutType);
+ }
+
+ @Override
+ public int getWindowLayoutType(PopupWindow popupWindow) {
+ return PopupWindowCompatApi23.getWindowLayoutType(popupWindow);
+ }
+ }
+
/**
* Select the correct implementation to use for the current platform.
*/
static final PopupWindowImpl IMPL;
static {
final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 19) {
+ if (version >= 23) {
+ IMPL = new Api23PopupWindowImpl();
+ } else if (version >= 21) {
+ IMPL = new Api21PopupWindowImpl();
+ } else if (version >= 19) {
IMPL = new KitKatPopupWindowImpl();
+ } else if (version >= 9) {
+ IMPL = new GingerbreadPopupWindowImpl();
} else {
IMPL = new BasePopupWindowImpl();
}
@@ -92,4 +170,46 @@
int gravity) {
IMPL.showAsDropDown(popup, anchor, xoff, yoff, gravity);
}
+
+ /**
+ * Sets whether the popup window should overlap its anchor view when
+ * displayed as a drop-down.
+ *
+ * @param overlapAnchor Whether the popup should overlap its anchor.
+ */
+ public static void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
+ IMPL.setOverlapAnchor(popupWindow, overlapAnchor);
+ }
+
+ /**
+ * Returns whether the popup window should overlap its anchor view when
+ * displayed as a drop-down.
+ *
+ * @return Whether the popup should overlap its anchor.
+ */
+ public static boolean getOverlapAnchor(PopupWindow popupWindow) {
+ return IMPL.getOverlapAnchor(popupWindow);
+ }
+
+ /**
+ * Set the layout type for this window. This value will be passed through to
+ * {@link WindowManager.LayoutParams#type} therefore the value should match any value
+ * {@link WindowManager.LayoutParams#type} accepts.
+ *
+ * @param layoutType Layout type for this window.
+ *
+ * @see WindowManager.LayoutParams#type
+ */
+ public static void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+ IMPL.setWindowLayoutType(popupWindow, layoutType);
+ }
+
+ /**
+ * Returns the layout type for this window.
+ *
+ * @see #setWindowLayoutType(PopupWindow popupWindow, int)
+ */
+ public static int getWindowLayoutType(PopupWindow popupWindow) {
+ return IMPL.getWindowLayoutType(popupWindow);
+ }
}
diff --git a/v4/java/android/support/v4/widget/SlidingPaneLayout.java b/v4/java/android/support/v4/widget/SlidingPaneLayout.java
index 391ba99..c5db3ef 100644
--- a/v4/java/android/support/v4/widget/SlidingPaneLayout.java
+++ b/v4/java/android/support/v4/widget/SlidingPaneLayout.java
@@ -29,6 +29,7 @@
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.v4.view.AccessibilityDelegateCompat;
import android.support.v4.view.MotionEventCompat;
@@ -297,13 +298,14 @@
*
* @param color An ARGB-packed color value
*/
- public void setSliderFadeColor(int color) {
+ public void setSliderFadeColor(@ColorInt int color) {
mSliderFadeColor = color;
}
/**
* @return The ARGB-packed color value used to fade the sliding pane
*/
+ @ColorInt
public int getSliderFadeColor() {
return mSliderFadeColor;
}
@@ -314,13 +316,14 @@
*
* @param color An ARGB-packed color value
*/
- public void setCoveredFadeColor(int color) {
+ public void setCoveredFadeColor(@ColorInt int color) {
mCoveredFadeColor = color;
}
/**
* @return The ARGB-packed color value used to fade the fixed pane
*/
+ @ColorInt
public int getCoveredFadeColor() {
return mCoveredFadeColor;
}
diff --git a/v4/java/android/support/v4/widget/SwipeRefreshLayout.java b/v4/java/android/support/v4/widget/SwipeRefreshLayout.java
index 55f2ce2..0618b06 100644
--- a/v4/java/android/support/v4/widget/SwipeRefreshLayout.java
+++ b/v4/java/android/support/v4/widget/SwipeRefreshLayout.java
@@ -19,6 +19,8 @@
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.support.annotation.ColorInt;
+import android.support.annotation.ColorRes;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ScrollingView;
import android.support.v4.view.ViewCompat;
@@ -460,7 +462,7 @@
*
* @param colorRes Resource id of the color.
*/
- public void setProgressBackgroundColorSchemeResource(int colorRes) {
+ public void setProgressBackgroundColorSchemeResource(@ColorRes int colorRes) {
setProgressBackgroundColorSchemeColor(getResources().getColor(colorRes));
}
@@ -469,7 +471,7 @@
*
* @param color
*/
- public void setProgressBackgroundColorSchemeColor(int color) {
+ public void setProgressBackgroundColorSchemeColor(@ColorInt int color) {
mCircleView.setBackgroundColor(color);
mProgress.setBackgroundColor(color);
}
@@ -478,7 +480,7 @@
* @deprecated Use {@link #setColorSchemeResources(int...)}
*/
@Deprecated
- public void setColorScheme(int... colors) {
+ public void setColorScheme(@ColorInt int... colors) {
setColorSchemeResources(colors);
}
@@ -489,7 +491,7 @@
*
* @param colorResIds
*/
- public void setColorSchemeResources(int... colorResIds) {
+ public void setColorSchemeResources(@ColorRes int... colorResIds) {
final Resources res = getResources();
int[] colorRes = new int[colorResIds.length];
for (int i = 0; i < colorResIds.length; i++) {
@@ -505,6 +507,7 @@
*
* @param colors
*/
+ @ColorInt
public void setColorSchemeColors(int... colors) {
ensureTarget();
mProgress.setColorSchemeColors(colors);
diff --git a/v4/jellybean/android/support/v4/content/ContentResolverCompatJellybean.java b/v4/jellybean/android/support/v4/content/ContentResolverCompatJellybean.java
new file mode 100644
index 0000000..ef05746
--- /dev/null
+++ b/v4/jellybean/android/support/v4/content/ContentResolverCompatJellybean.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package android.support.v4.content;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.net.Uri;
+
+class ContentResolverCompatJellybean {
+ public static Cursor query(ContentResolver resolver, Uri uri, String[] projection,
+ String selection, String[] selectionArgs, String sortOrder,
+ Object cancellationSignalObj) {
+ return resolver.query(uri, projection, selection, selectionArgs, sortOrder,
+ (android.os.CancellationSignal)cancellationSignalObj);
+ }
+}
diff --git a/v4/jellybean/android/support/v4/os/CancellationSignalCompatJellybean.java b/v4/jellybean/android/support/v4/os/CancellationSignalCompatJellybean.java
new file mode 100644
index 0000000..6029286
--- /dev/null
+++ b/v4/jellybean/android/support/v4/os/CancellationSignalCompatJellybean.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package android.support.v4.os;
+
+class CancellationSignalCompatJellybean {
+ public static Object create() {
+ return new android.os.CancellationSignal();
+ }
+
+ public static void cancel(Object cancellationSignalObj) {
+ ((android.os.CancellationSignal)cancellationSignalObj).cancel();
+ }
+}
diff --git a/v4/kitkat/android/support/v4/app/NotificationCompatKitKat.java b/v4/kitkat/android/support/v4/app/NotificationCompatKitKat.java
index 1197432..e2fd3b7 100644
--- a/v4/kitkat/android/support/v4/app/NotificationCompatKitKat.java
+++ b/v4/kitkat/android/support/v4/app/NotificationCompatKitKat.java
@@ -102,6 +102,7 @@
return b;
}
+ @Override
public Notification build() {
SparseArray<Bundle> actionExtrasMap = NotificationCompatJellybean.buildActionExtrasMap(
mActionExtrasList);
diff --git a/v7/appcompat/api/current.txt b/v7/appcompat/api/current.txt
index fae4450..d3b33ae 100644
--- a/v7/appcompat/api/current.txt
+++ b/v7/appcompat/api/current.txt
@@ -281,6 +281,27 @@
method public boolean supportRequestWindowFeature(int);
}
+ public class AppCompatDialogFragment extends android.support.v4.app.DialogFragment {
+ ctor public AppCompatDialogFragment();
+ }
+
+ public class NotificationCompat extends android.support.v4.app.NotificationCompat {
+ ctor public NotificationCompat();
+ }
+
+ public static class NotificationCompat.Builder extends android.support.v4.app.NotificationCompat.Builder {
+ ctor public NotificationCompat.Builder(android.content.Context);
+ }
+
+ public static class NotificationCompat.MediaStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.MediaStyle();
+ ctor public NotificationCompat.MediaStyle(android.support.v4.app.NotificationCompat.Builder);
+ method public void setCancelButtonIntent(android.app.PendingIntent);
+ method public android.support.v7.app.NotificationCompat.MediaStyle setMediaSession(android.support.v4.media.session.MediaSessionCompat.Token);
+ method public android.support.v7.app.NotificationCompat.MediaStyle setShowActionsInCompactView(int...);
+ method public void setShowCancelButton(boolean);
+ }
+
}
package android.support.v7.appcompat {
@@ -404,6 +425,8 @@
field public static int homeAsUpIndicator;
field public static int homeLayout;
field public static int icon;
+ field public static int iconTint;
+ field public static int iconTintMode;
field public static int iconifiedByDefault;
field public static int indeterminateProgressStyle;
field public static int initialActivityCount;
@@ -428,6 +451,10 @@
field public static int navigationContentDescription;
field public static int navigationIcon;
field public static int navigationMode;
+ field public static int navigationTint;
+ field public static int navigationTintMode;
+ field public static int overflowTint;
+ field public static int overflowTintMode;
field public static int overlapAnchor;
field public static int paddingEnd;
field public static int paddingStart;
@@ -652,6 +679,9 @@
field public static int dialog_fixed_width_minor;
field public static int disabled_alpha_material_dark;
field public static int disabled_alpha_material_light;
+ field public static int notification_large_icon_height;
+ field public static int notification_large_icon_width;
+ field public static int notification_subtext_size;
}
public static final class R.drawable {
@@ -715,10 +745,12 @@
field public static int abc_textfield_search_activated_mtrl_alpha;
field public static int abc_textfield_search_default_mtrl_alpha;
field public static int abc_textfield_search_material;
+ field public static int notification_template_icon_bg;
}
public static final class R.id {
ctor public R.id();
+ field public static int action0;
field public static int action_bar;
field public static int action_bar_activity_content;
field public static int action_bar_container;
@@ -727,17 +759,21 @@
field public static int action_bar_subtitle;
field public static int action_bar_title;
field public static int action_context_bar;
+ field public static int action_divider;
field public static int action_menu_divider;
field public static int action_menu_presenter;
field public static int action_mode_bar;
field public static int action_mode_bar_stub;
field public static int action_mode_close_button;
field public static int activity_chooser_view_content;
+ field public static int add;
field public static int alertTitle;
field public static int always;
field public static int beginning;
field public static int buttonPanel;
+ field public static int cancel_action;
field public static int checkbox;
+ field public static int chronometer;
field public static int collapseActionView;
field public static int contentPanel;
field public static int custom;
@@ -749,6 +785,7 @@
field public static int dropdown;
field public static int edit_query;
field public static int end;
+ field public static int end_padder;
field public static int expand_activities_button;
field public static int expanded_menu;
field public static int home;
@@ -756,8 +793,12 @@
field public static int icon;
field public static int ifRoom;
field public static int image;
+ field public static int info;
+ field public static int line1;
+ field public static int line3;
field public static int listMode;
field public static int list_item;
+ field public static int media_actions;
field public static int middle;
field public static int multiply;
field public static int never;
@@ -788,9 +829,13 @@
field public static int src_atop;
field public static int src_in;
field public static int src_over;
+ field public static int status_bar_latest_event_content;
field public static int submit_area;
field public static int tabMode;
+ field public static int text;
+ field public static int text2;
field public static int textSpacerNoButtons;
+ field public static int time;
field public static int title;
field public static int title_template;
field public static int topPanel;
@@ -805,6 +850,8 @@
field public static int abc_config_activityDefaultDur;
field public static int abc_config_activityShortDur;
field public static int abc_max_action_buttons;
+ field public static int cancel_button_image_alpha;
+ field public static int status_bar_notification_info_maxnum;
}
public static final class R.layout {
@@ -834,6 +881,14 @@
field public static int abc_search_view;
field public static int abc_select_dialog_material;
field public static int abc_simple_dropdown_hint;
+ field public static int notification_media_action;
+ field public static int notification_media_cancel_action;
+ field public static int notification_template_big_media;
+ field public static int notification_template_big_media_narrow;
+ field public static int notification_template_lines;
+ field public static int notification_template_media;
+ field public static int notification_template_part_chronometer;
+ field public static int notification_template_part_time;
field public static int select_dialog_item_material;
field public static int select_dialog_multichoice_material;
field public static int select_dialog_singlechoice_material;
@@ -859,6 +914,7 @@
field public static int abc_shareactionprovider_share_with;
field public static int abc_shareactionprovider_share_with_application;
field public static int abc_toolbar_collapse_description;
+ field public static int status_bar_notification_info_overflow;
}
public static final class R.style {
@@ -1061,6 +1117,11 @@
field public static int TextAppearance_AppCompat_Widget_PopupMenu_Small;
field public static int TextAppearance_AppCompat_Widget_Switch;
field public static int TextAppearance_AppCompat_Widget_TextView_SpinnerItem;
+ field public static int TextAppearance_StatusBar_EventContent;
+ field public static int TextAppearance_StatusBar_EventContent_Info;
+ field public static int TextAppearance_StatusBar_EventContent_Line2;
+ field public static int TextAppearance_StatusBar_EventContent_Time;
+ field public static int TextAppearance_StatusBar_EventContent_Title;
field public static int TextAppearance_Widget_AppCompat_ExpandedMenu_Item;
field public static int TextAppearance_Widget_AppCompat_Toolbar_Subtitle;
field public static int TextAppearance_Widget_AppCompat_Toolbar_Title;
@@ -1256,6 +1317,8 @@
field public static int MenuItem_android_title;
field public static int MenuItem_android_titleCondensed;
field public static int MenuItem_android_visible;
+ field public static int MenuItem_iconTint;
+ field public static int MenuItem_iconTintMode;
field public static int MenuItem_showAsAction;
field public static final int[] MenuView;
field public static int MenuView_android_headerBackground;
@@ -1437,6 +1500,10 @@
field public static int Toolbar_maxButtonHeight;
field public static int Toolbar_navigationContentDescription;
field public static int Toolbar_navigationIcon;
+ field public static int Toolbar_navigationTint;
+ field public static int Toolbar_navigationTintMode;
+ field public static int Toolbar_overflowTint;
+ field public static int Toolbar_overflowTintMode;
field public static int Toolbar_popupTheme;
field public static int Toolbar_subtitle;
field public static int Toolbar_subtitleTextAppearance;
@@ -1513,6 +1580,8 @@
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onDetachedFromWindow();
method public void setOnMenuItemClickListener(android.support.v7.widget.ActionMenuView.OnMenuItemClickListener);
+ method public void setOverflowTintList(android.content.res.ColorStateList);
+ method public void setOverflowTintMode(android.graphics.PorterDuff.Mode);
method public void setPopupTheme(int);
method public boolean showOverflowMenu();
}
@@ -1703,9 +1772,11 @@
ctor public PopupMenu(android.content.Context, android.view.View, int, int, int);
method public void dismiss();
method public android.view.View.OnTouchListener getDragToOpenListener();
+ method public int getGravity();
method public android.view.Menu getMenu();
method public android.view.MenuInflater getMenuInflater();
method public void inflate(int);
+ method public void setGravity(int);
method public void setOnDismissListener(android.support.v7.widget.PopupMenu.OnDismissListener);
method public void setOnMenuItemClickListener(android.support.v7.widget.PopupMenu.OnMenuItemClickListener);
method public void show();
@@ -1844,7 +1915,11 @@
method public void setNavigationIcon(int);
method public void setNavigationIcon(android.graphics.drawable.Drawable);
method public void setNavigationOnClickListener(android.view.View.OnClickListener);
+ method public void setNavigationTintList(android.content.res.ColorStateList);
+ method public void setNavigationTintMode(android.graphics.PorterDuff.Mode);
method public void setOnMenuItemClickListener(android.support.v7.widget.Toolbar.OnMenuItemClickListener);
+ method public void setOverflowTintList(android.content.res.ColorStateList);
+ method public void setOverflowTintMode(android.graphics.PorterDuff.Mode);
method public void setPopupTheme(int);
method public void setSubtitle(int);
method public void setSubtitle(java.lang.CharSequence);
diff --git a/v7/appcompat/res/layout/notification_media_action.xml b/v7/appcompat/res/layout/notification_media_action.xml
new file mode 100644
index 0000000..d546792
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_media_action.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/borderlessButtonStyle"
+ android:id="@+id/action0"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="2dp"
+ android:layout_marginRight="2dp"
+ android:layout_weight="1"
+ android:gravity="center"/>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout/notification_media_cancel_action.xml b/v7/appcompat/res/layout/notification_media_cancel_action.xml
new file mode 100644
index 0000000..e31d891
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_media_cancel_action.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/borderlessButtonStyle"
+ android:id="@+id/cancel_action"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="2dp"
+ android:layout_marginRight="2dp"
+ android:layout_weight="1"
+ android:src="@drawable/abc_ic_clear_mtrl_alpha"
+ android:gravity="center"
+ android:visibility="gone"/>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout/notification_template_big_media.xml b/v7/appcompat/res/layout/notification_template_big_media.xml
new file mode 100644
index 0000000..2e40b69
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_big_media.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="128dp"
+ >
+ <ImageView android:id="@+id/icon"
+ android:layout_width="@dimen/notification_large_icon_width"
+ android:layout_height="@dimen/notification_large_icon_height"
+ android:scaleType="centerCrop"
+ />
+ <include layout="@layout/notification_media_cancel_action"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_marginLeft="2dp"
+ android:layout_marginRight="2dp"
+ android:layout_alignParentRight="true"/>
+ <include layout="@layout/notification_template_lines"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="fill_vertical"
+ android:layout_marginLeft="@dimen/notification_large_icon_width"
+ android:layout_marginStart="@dimen/notification_large_icon_width"
+ android:layout_toLeftOf="@id/cancel_action"
+ android:layout_toStartOf="@id/cancel_action"/>
+ <LinearLayout
+ android:id="@+id/media_actions"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:layout_alignParentBottom="true"
+ android:layout_marginLeft="12dp"
+ android:layout_marginRight="12dp"
+ android:orientation="horizontal"
+ android:layoutDirection="ltr"
+ >
+ <!-- media buttons will be added here -->
+ </LinearLayout>
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_above="@id/media_actions"
+ android:id="@+id/action_divider"
+ android:background="?android:attr/dividerHorizontal" />
+</RelativeLayout>
diff --git a/v7/appcompat/res/layout/notification_template_big_media_narrow.xml b/v7/appcompat/res/layout/notification_template_big_media_narrow.xml
new file mode 100644
index 0000000..cf64061
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_big_media_narrow.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<!-- Layout to be used with only max 3 actions. It has a much larger picture at the left side-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="128dp"
+ >
+ <ImageView android:id="@+id/icon"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:scaleType="centerCrop"
+ />
+
+ <include layout="@layout/notification_media_cancel_action"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_marginLeft="2dp"
+ android:layout_marginRight="2dp"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"/>
+
+ <include layout="@layout/notification_template_lines"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="128dp"
+ android:layout_marginStart="128dp"
+ android:layout_toLeftOf="@id/cancel_action"
+ android:layout_toStartOf="@id/cancel_action"/>
+
+ <LinearLayout
+ android:id="@+id/media_actions"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:layout_toRightOf="@id/icon"
+ android:layout_toEndOf="@id/icon"
+ android:layout_alignParentBottom="true"
+ android:layout_marginLeft="12dp"
+ android:layout_marginRight="12dp"
+ android:orientation="horizontal"
+ android:layoutDirection="ltr"
+ >
+ <!-- media buttons will be added here -->
+ </LinearLayout>
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_toRightOf="@id/icon"
+ android:layout_toEndOf="@id/icon"
+ android:layout_above="@id/media_actions"
+ android:id="@+id/action_divider"
+ android:background="?android:attr/dividerHorizontal" />
+</RelativeLayout>
diff --git a/v7/appcompat/res/layout/notification_template_lines.xml b/v7/appcompat/res/layout/notification_template_lines.xml
new file mode 100644
index 0000000..42ba776
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_lines.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingRight="8dp"
+ android:paddingEnd="8dp"
+ android:paddingTop="2dp"
+ android:paddingBottom="2dp"
+ >
+ <LinearLayout
+ android:id="@+id/line1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="6dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginStart="8dp"
+ android:orientation="horizontal"
+ >
+ <TextView android:id="@+id/title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:layout_weight="1"
+ />
+ <include
+ layout="@layout/notification_template_part_time"
+ android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ />
+ <include
+ layout="@layout/notification_template_part_chronometer"
+ android:id="@+id/chronometer"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/text2"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="-2dp"
+ android:layout_marginBottom="-2dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginStart="8dp"
+ android:singleLine="true"
+ android:fadingEdge="horizontal"
+ android:ellipsize="marquee"
+ android:visibility="gone"
+ />
+ <LinearLayout
+ android:id="@+id/line3"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginLeft="8dp"
+ android:layout_marginStart="8dp"
+ >
+ <TextView android:id="@+id/text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="center"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ <TextView android:id="@+id/info"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:singleLine="true"
+ android:gravity="center"
+ android:paddingLeft="8dp"
+ android:paddingStart="8dp"
+ />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout/notification_template_media.xml b/v7/appcompat/res/layout/notification_template_media.xml
new file mode 100644
index 0000000..90daa88
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_media.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="64dp"
+ android:orientation="horizontal"
+ >
+ <ImageView android:id="@+id/icon"
+ android:layout_width="@dimen/notification_large_icon_width"
+ android:layout_height="@dimen/notification_large_icon_width"
+ android:scaleType="centerCrop"
+ />
+ <include layout="@layout/notification_template_lines"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+ <LinearLayout
+ android:id="@+id/media_actions"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical|end"
+ android:orientation="horizontal"
+ android:layoutDirection="ltr"
+ >
+ <!-- media buttons will be added here -->
+ </LinearLayout>
+ <include layout="@layout/notification_media_cancel_action"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_marginRight="6dp"
+ android:layout_marginEnd="6dp"/>
+ <ImageView android:id="@+id/end_padder"
+ android:layout_width="6dp"
+ android:layout_height="match_parent"
+ />
+</LinearLayout>
diff --git a/v7/appcompat/res/layout/notification_template_part_chronometer.xml b/v7/appcompat/res/layout/notification_template_part_chronometer.xml
new file mode 100644
index 0000000..6f5f3ac
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_part_chronometer.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<Chronometer android:id="@+id/chronometer" xmlns:android="http://schemas.android.com/apk/res/android"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:singleLine="true"
+ android:gravity="center"
+ android:paddingLeft="8dp"
+ android:paddingStart="8dp"
+ />
diff --git a/v7/appcompat/res/layout/notification_template_part_time.xml b/v7/appcompat/res/layout/notification_template_part_time.xml
new file mode 100644
index 0000000..72d216e
--- /dev/null
+++ b/v7/appcompat/res/layout/notification_template_part_time.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<DateTimeView android:id="@+id/time" xmlns:android="http://schemas.android.com/apk/res/android"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:singleLine="true"
+ android:gravity="center"
+ android:paddingLeft="8dp"
+ android:paddingStart="8dp"
+ />
diff --git a/v7/appcompat/res/values-af/strings.xml b/v7/appcompat/res/values-af/strings.xml
index f7348c4..4bb50b0 100644
--- a/v7/appcompat/res/values-af/strings.xml
+++ b/v7/appcompat/res/values-af/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigeer tuis"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigeer op"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Nog opsies"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Vou in"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Soek"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Soek …"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Soeknavraag"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Vee navraag uit"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Dien navraag in"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Sien alles"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Deel met %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Deel met"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-am/strings.xml b/v7/appcompat/res/values-am/strings.xml
index e849b31..a76c931 100644
--- a/v7/appcompat/res/values-am/strings.xml
+++ b/v7/appcompat/res/values-am/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"ወደ መነሻ ይዳስሱ"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s፣ %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s፣ %2$s፣ %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"መጠይቅ ያስረክቡ"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ሁሉንም ይመልከቱ"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"ከ%s ጋር ያጋሩ"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ከሚከተለው ጋር ያጋሩ"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ar/strings.xml b/v7/appcompat/res/values-ar/strings.xml
index 93dde04..f0046a9 100644
--- a/v7/appcompat/res/values-ar/strings.xml
+++ b/v7/appcompat/res/values-ar/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"التنقل إلى الشاشة الرئيسية"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s، %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s، %2$s، %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"إرسال طلب البحث"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"عرض الكل"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"مشاركة مع %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"مشاركة مع"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"+999"</string>
</resources>
diff --git a/v7/appcompat/res/values-bg/strings.xml b/v7/appcompat/res/values-bg/strings.xml
index de3bde8..d8cbcd0 100644
--- a/v7/appcompat/res/values-bg/strings.xml
+++ b/v7/appcompat/res/values-bg/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Придвижване към „Начало“"</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_action_bar_home_description_format" msgid="1397052879051804371">"„%1$s“ – %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"„%1$s“, „%2$s“ – %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Изпращане на заявката"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Вижте всички"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Споделяне със: %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Споделяне със:"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-bn-rBD/strings.xml b/v7/appcompat/res/values-bn-rBD/strings.xml
index 393240f..872d425 100644
--- a/v7/appcompat/res/values-bn-rBD/strings.xml
+++ b/v7/appcompat/res/values-bn-rBD/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"হোম এ নেভিগেট করুন"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ক্যোয়ারী জমা দিন"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"সবগুলো দেখুন"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s এর সাথে ভাগ করুন"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"এর সাথে ভাগ করুন"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"৯৯৯+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ca/strings.xml b/v7/appcompat/res/values-ca/strings.xml
index bfd4cb0..863e69f 100644
--- a/v7/appcompat/res/values-ca/strings.xml
+++ b/v7/appcompat/res/values-ca/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navega a la pàgina d\'inici"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navega cap a dalt"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Més opcions"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Replega"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Cerca"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Cerca..."</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de cerca"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Esborra la consulta"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Envia la consulta"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Mostra\'ls tots"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Comparteix amb %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Comparteix amb"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"+999"</string>
</resources>
diff --git a/v7/appcompat/res/values-cs/strings.xml b/v7/appcompat/res/values-cs/strings.xml
index 1465fdc..cba91eb 100644
--- a/v7/appcompat/res/values-cs/strings.xml
+++ b/v7/appcompat/res/values-cs/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Přejít na plochu"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Přejít nahoru"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Více možností"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Sbalit"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s – %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s – %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Hledat"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Vyhledat…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Vyhledávací dotaz"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Smazat dotaz"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Odeslat dotaz"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Zobrazit vše"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Sdílet pomocí %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Sdílet pomocí"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-da/strings.xml b/v7/appcompat/res/values-da/strings.xml
index b178513..bda4579 100644
--- a/v7/appcompat/res/values-da/strings.xml
+++ b/v7/appcompat/res/values-da/strings.xml
@@ -20,13 +20,18 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Naviger hjem"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Naviger op"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Flere muligheder"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Skjul"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Søg"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Søg…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Søgeforespørgsel"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Ryd forespørgslen"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Indsend forespørgslen"</string>
- <string name="abc_searchview_description_voice" msgid="893419373245838918">"Stemmesøgning"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Talesøgning"</string>
<string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Vælg en app"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Se alle"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Del med %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Del med"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-de/strings.xml b/v7/appcompat/res/values-de/strings.xml
index 6da4b71..b5a74e9 100644
--- a/v7/appcompat/res/values-de/strings.xml
+++ b/v7/appcompat/res/values-de/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Zur Startseite"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Nach oben"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Weitere Optionen"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Minimieren"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s: %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s: %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Suchen"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Suchen…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Suchanfrage"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Suchanfrage löschen"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Suchanfrage senden"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Alle ansehen"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Freigeben für %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Freigeben für"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-el/strings.xml b/v7/appcompat/res/values-el/strings.xml
index 4c0e286..1ecc119 100644
--- a/v7/appcompat/res/values-el/strings.xml
+++ b/v7/appcompat/res/values-el/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Πλοήγηση στην αρχική σελίδα"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Υποβολή ερωτήματος"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Προβολή όλων"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Κοινή χρήση με %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Κοινή χρήση με"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-en-rAU/strings.xml b/v7/appcompat/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..4db58a9
--- /dev/null
+++ b/v7/appcompat/res/values-en-rAU/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 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_action_mode_done" msgid="4076576682505996667">"Done"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigate home"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigate up"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"More options"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Collapse"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Search"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Search…"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Search query"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Clear query"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Submit query"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Voice search"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Choose an app"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"See all"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Share with %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Share with"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
+</resources>
diff --git a/v7/appcompat/res/values-en-rGB/strings.xml b/v7/appcompat/res/values-en-rGB/strings.xml
index 3ec0b0e..4db58a9 100644
--- a/v7/appcompat/res/values-en-rGB/strings.xml
+++ b/v7/appcompat/res/values-en-rGB/strings.xml
@@ -16,11 +16,15 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="abc_action_mode_done" msgid="4076576682505996667">"Finished"</string>
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Done"</string>
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigate home"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigate up"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"More options"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Collapse"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Search"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Search…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Search query"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Clear query"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Submit query"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"See all"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Share with %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Share with"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-en-rIN/strings.xml b/v7/appcompat/res/values-en-rIN/strings.xml
index 3ec0b0e..4db58a9 100644
--- a/v7/appcompat/res/values-en-rIN/strings.xml
+++ b/v7/appcompat/res/values-en-rIN/strings.xml
@@ -16,11 +16,15 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="abc_action_mode_done" msgid="4076576682505996667">"Finished"</string>
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Done"</string>
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigate home"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigate up"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"More options"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Collapse"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Search"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Search…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Search query"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Clear query"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Submit query"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"See all"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Share with %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Share with"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-es-rUS/strings.xml b/v7/appcompat/res/values-es-rUS/strings.xml
index 6ab7942..043c6ae 100644
--- a/v7/appcompat/res/values-es-rUS/strings.xml
+++ b/v7/appcompat/res/values-es-rUS/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navegar a la página principal"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navegar hacia arriba"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Más opciones"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Contraer"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Búsqueda"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Buscar…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de búsqueda"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Eliminar la consulta"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ver todo"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Compartir con %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Compartir con"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-es/strings.xml b/v7/appcompat/res/values-es/strings.xml
index ed15b35..8f6ea4b 100644
--- a/v7/appcompat/res/values-es/strings.xml
+++ b/v7/appcompat/res/values-es/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Ir a la pantalla de inicio"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Desplazarse hacia arriba"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Más opciones"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Contraer"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Buscar"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Buscar…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Borrar consulta"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ver todo"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Compartir con %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Compartir con"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"+999"</string>
</resources>
diff --git a/v7/appcompat/res/values-et-rEE/strings.xml b/v7/appcompat/res/values-et-rEE/strings.xml
index 2ae925d..b8c7f16 100644
--- a/v7/appcompat/res/values-et-rEE/strings.xml
+++ b/v7/appcompat/res/values-et-rEE/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigeerimine avaekraanile"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigeerimine üles"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Rohkem valikuid"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Ahendamine"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Otsing"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Otsige …"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Otsingupäring"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Päringu tühistamine"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Päringu esitamine"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Kuva kõik"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Jagamine kasutajaga %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Jagamine:"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-eu-rES/strings.xml b/v7/appcompat/res/values-eu-rES/strings.xml
index ee6ac4d..3b0fb90 100644
--- a/v7/appcompat/res/values-eu-rES/strings.xml
+++ b/v7/appcompat/res/values-eu-rES/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Joan orri nagusira"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Joan gora"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Aukera gehiago"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Tolestu"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Bilatu"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Bilatu…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Bilaketa-kontsulta"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Garbitu kontsulta"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Bidali kontsulta"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ikusi guztiak"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Partekatu %s erabiltzailearekin"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Partekatu hauekin"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-fa/strings.xml b/v7/appcompat/res/values-fa/strings.xml
index 8e10e92..ae4eb85 100644
--- a/v7/appcompat/res/values-fa/strings.xml
+++ b/v7/appcompat/res/values-fa/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"پیمایش به صفحه اصلی"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s، %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s، %2$s، %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ارسال عبارت جستجو"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"مشاهده همه"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"اشتراکگذاری با %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"اشتراکگذاری با"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"۹۹۹+"</string>
</resources>
diff --git a/v7/appcompat/res/values-fi/strings.xml b/v7/appcompat/res/values-fi/strings.xml
index 6755cea..4b3e728 100644
--- a/v7/appcompat/res/values-fi/strings.xml
+++ b/v7/appcompat/res/values-fi/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Siirry etusivulle"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Siirry ylös"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Lisää"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Kutista"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Haku"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Haku…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Hakulauseke"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Tyhjennä kysely"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Lähetä kysely"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Näytä kaikki"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Jakaminen: %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Jakaminen:"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-fr-rCA/strings.xml b/v7/appcompat/res/values-fr-rCA/strings.xml
index 417705a..291bd4e 100644
--- a/v7/appcompat/res/values-fr-rCA/strings.xml
+++ b/v7/appcompat/res/values-fr-rCA/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Revenir à l\'accueil"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Revenir en haut de la page"</string>
<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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"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>
@@ -28,5 +32,6 @@
<string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Sélectionnez une application"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Voir toutes les chaînes"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Partager avec %s"</string>
- <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Partager avec"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Partager"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">">999"</string>
</resources>
diff --git a/v7/appcompat/res/values-fr/strings.xml b/v7/appcompat/res/values-fr/strings.xml
index 27b8f38..b7f5604 100644
--- a/v7/appcompat/res/values-fr/strings.xml
+++ b/v7/appcompat/res/values-fr/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Revenir à l\'accueil"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Revenir en haut de la page"</string>
<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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Rechercher"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Rechercher…"</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>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Tout afficher"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Partager avec %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Partager avec"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">">999"</string>
</resources>
diff --git a/v7/appcompat/res/values-gl-rES/strings.xml b/v7/appcompat/res/values-gl-rES/strings.xml
index 1d0d50d..b6b11be 100644
--- a/v7/appcompat/res/values-gl-rES/strings.xml
+++ b/v7/appcompat/res/values-gl-rES/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Ir á páxina de inicio"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Desprazarse cara arriba"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Máis opcións"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Contraer"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Buscar"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Buscar…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de busca"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Borrar consulta"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ver todas"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Compartir con %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Compartir con"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">">999"</string>
</resources>
diff --git a/v7/appcompat/res/values-gu-rIN/strings.xml b/v7/appcompat/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000..b77acd3
--- /dev/null
+++ b/v7/appcompat/res/values-gu-rIN/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 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_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_menu_overflow_description" msgid="3588849162933574182">"વધુ વિકલ્પો"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"સંકુચિત કરો"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"ક્વેરી સબમિટ કરો"</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="7165123711973476752">"%s સાથે શેર કરો"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"આની સાથે શેર કરો"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
+</resources>
diff --git a/v7/appcompat/res/values-hi/strings.xml b/v7/appcompat/res/values-hi/strings.xml
index b236ebb..95daa34 100644
--- a/v7/appcompat/res/values-hi/strings.xml
+++ b/v7/appcompat/res/values-hi/strings.xml
@@ -17,10 +17,14 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
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_home_description" msgid="4600421777120114993">"मुख्यपृष्ठ पर नेविगेट करें"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"क्वेरी सबमिट करें"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"सभी देखें"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s के साथ साझा करें"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"इसके द्वारा साझा करें"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-hr/strings.xml b/v7/appcompat/res/values-hr/strings.xml
index 680e39f..da68332 100644
--- a/v7/appcompat/res/values-hr/strings.xml
+++ b/v7/appcompat/res/values-hr/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Idi na početnu"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Idi gore"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Dodatne opcije"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Sažmi"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Pretraživanje"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Pretražite…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Upit za pretraživanje"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Izbriši upit"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Pošalji upit"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Prikaži sve"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Dijeljenje sa: %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Dijeljenje sa"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-hu/strings.xml b/v7/appcompat/res/values-hu/strings.xml
index 52dafb0..57ab85b 100644
--- a/v7/appcompat/res/values-hu/strings.xml
+++ b/v7/appcompat/res/values-hu/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Ugrás a főoldalra"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Felfelé mozgatás"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"További lehetőségek"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Összecsukás"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Keresés"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Keresés…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Keresési lekérdezés"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Lekérdezés törlése"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Lekérdezés küldése"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Összes megtekintése"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Megosztás a következővel: %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Megosztás a következővel:"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-hy-rAM/strings.xml b/v7/appcompat/res/values-hy-rAM/strings.xml
index 6c0ee27..903fa43 100644
--- a/v7/appcompat/res/values-hy-rAM/strings.xml
+++ b/v7/appcompat/res/values-hy-rAM/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Ուղղվել տուն"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Ուղարկել հարցումը"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Տեսնել բոլորը"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Տարածել ըստ %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Տարածել"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-in/strings.xml b/v7/appcompat/res/values-in/strings.xml
index 9481e83..0e7003c 100644
--- a/v7/appcompat/res/values-in/strings.xml
+++ b/v7/appcompat/res/values-in/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigasi ke beranda"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigasi naik"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Opsi lain"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Ciutkan"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Telusuri"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Telusuri..."</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Kueri penelusuran"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Hapus kueri"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Kirim kueri"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Lihat semua"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Bagikan dengan %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Bagikan dengan"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-is-rIS/strings.xml b/v7/appcompat/res/values-is-rIS/strings.xml
index 8cac570..fb305b2 100644
--- a/v7/appcompat/res/values-is-rIS/strings.xml
+++ b/v7/appcompat/res/values-is-rIS/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Fara heim"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Fara upp"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Fleiri valkostir"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Minnka"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Leita"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Leita…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Leitarfyrirspurn"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Hreinsa fyrirspurn"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Senda fyrirspurn"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Sjá allt"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Deila með %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Deila með"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-it/strings.xml b/v7/appcompat/res/values-it/strings.xml
index a8b0f2c..a2d9bee 100644
--- a/v7/appcompat/res/values-it/strings.xml
+++ b/v7/appcompat/res/values-it/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Vai alla home page"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Vai in alto"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Altre opzioni"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Comprimi"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Cerca"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Cerca…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Query di ricerca"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Cancella query"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Invia query"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Visualizza tutte"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Condividi con %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Condividi con"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-iw/strings.xml b/v7/appcompat/res/values-iw/strings.xml
index 1af07df..329d0ec 100644
--- a/v7/appcompat/res/values-iw/strings.xml
+++ b/v7/appcompat/res/values-iw/strings.xml
@@ -20,13 +20,18 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"נווט לדף הבית"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"שלח שאילתה"</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_activity_chooser_view_see_all" msgid="7468859129482906941">"ראה הכל"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"שתף עם %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"שתף עם"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ja/strings.xml b/v7/appcompat/res/values-ja/strings.xml
index 659358a..fa55b08 100644
--- a/v7/appcompat/res/values-ja/strings.xml
+++ b/v7/appcompat/res/values-ja/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"ホームへ移動"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s、%2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s、%2$s、%3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"検索キーワードを送信"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"すべて表示"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%sと共有"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"共有"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ka-rGE/strings.xml b/v7/appcompat/res/values-ka-rGE/strings.xml
index 0c430b1..b14bcb7 100644
--- a/v7/appcompat/res/values-ka-rGE/strings.xml
+++ b/v7/appcompat/res/values-ka-rGE/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"მთავარზე ნავიგაცია"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"მოთხოვნის გადაგზავნა"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ყველას ნახვა"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s-თან გაზიარება"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"გაზიარება:"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-kk-rKZ/strings.xml b/v7/appcompat/res/values-kk-rKZ/strings.xml
index d3ad9e8..52b9af5 100644
--- a/v7/appcompat/res/values-kk-rKZ/strings.xml
+++ b/v7/appcompat/res/values-kk-rKZ/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Негізгі бетте қозғалу"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Сұрақты жіберу"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Барлығын көру"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s бөлісу"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Бөлісу"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-km-rKH/strings.xml b/v7/appcompat/res/values-km-rKH/strings.xml
index df78372..aa81b7d 100644
--- a/v7/appcompat/res/values-km-rKH/strings.xml
+++ b/v7/appcompat/res/values-km-rKH/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"រកមើលទៅដើម"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ដាក់ស្នើសំណួរ"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"មើលទាំងអស់"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"ចែករំលែកជាមួយ %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ចែករំលែកជាមួយ"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-kn-rIN/strings.xml b/v7/appcompat/res/values-kn-rIN/strings.xml
index 6af7a39..7ef7572 100644
--- a/v7/appcompat/res/values-kn-rIN/strings.xml
+++ b/v7/appcompat/res/values-kn-rIN/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"ಮುಖಪುಟವನ್ನು ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ಪ್ರಶ್ನೆಯನ್ನು ಸಲ್ಲಿಸು"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ಎಲ್ಲವನ್ನೂ ನೋಡಿ"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ಇವರೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳಿ"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ko/strings.xml b/v7/appcompat/res/values-ko/strings.xml
index d331975..7c158f9 100644
--- a/v7/appcompat/res/values-ko/strings.xml
+++ b/v7/appcompat/res/values-ko/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"홈 탐색"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"검색어 보내기"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"전체 보기"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s와(과) 공유"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"공유 대상"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ky-rKG/strings.xml b/v7/appcompat/res/values-ky-rKG/strings.xml
index 52abd9f..a758b96 100644
--- a/v7/appcompat/res/values-ky-rKG/strings.xml
+++ b/v7/appcompat/res/values-ky-rKG/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Үйгө багыттоо"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Талап жөнөтүү"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Бардыгын көрүү"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s аркылуу бөлүшүү"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Бөлүшүү"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-lo-rLA/strings.xml b/v7/appcompat/res/values-lo-rLA/strings.xml
index 7eb42ea..3b93232 100644
--- a/v7/appcompat/res/values-lo-rLA/strings.xml
+++ b/v7/appcompat/res/values-lo-rLA/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"ກັບໄປໜ້າຫຼັກ"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ສົ່ງການຊອກຫາ"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ເບິ່ງທັງຫມົດ"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"ແບ່ງປັນກັບ %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ແບ່ງປັນກັບ"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-lt/strings.xml b/v7/appcompat/res/values-lt/strings.xml
index c4738a7..b070a2f 100644
--- a/v7/appcompat/res/values-lt/strings.xml
+++ b/v7/appcompat/res/values-lt/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Eiti į pagrindinį puslapį"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Eiti į viršų"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Daugiau parinkčių"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Sutraukti"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Paieška"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Ieškoti..."</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Paieškos užklausa"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Išvalyti užklausą"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Pateikti užklausą"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Peržiūrėti viską"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Bendrinti naudojant „%s“"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Bendrinti naudojant"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-lv/strings.xml b/v7/appcompat/res/values-lv/strings.xml
index c33858a..7c4ef4f 100644
--- a/v7/appcompat/res/values-lv/strings.xml
+++ b/v7/appcompat/res/values-lv/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Pārvietoties uz sākuma ekrānu"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Pārvietoties augšup"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Vairāk opciju"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Sakļaut"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s: %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s: %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Meklēt"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Meklējiet…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Meklēšanas vaicājums"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Notīrīt vaicājumu"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Iesniegt vaicājumu"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Skatīt visu"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Kopīgot ar %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Kopīgot ar:"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-mk-rMK/strings.xml b/v7/appcompat/res/values-mk-rMK/strings.xml
index 632728a..ac2b03e 100644
--- a/v7/appcompat/res/values-mk-rMK/strings.xml
+++ b/v7/appcompat/res/values-mk-rMK/strings.xml
@@ -20,7 +20,13 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Движи се кон дома"</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.format failed for translation -->
+ <!-- no translation found for abc_action_bar_home_description_format (1397052879051804371) -->
+ <skip />
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Поднеси барање"</string>
@@ -31,4 +37,5 @@
<!-- no translation found for abc_shareactionprovider_share_with_application (7165123711973476752) -->
<skip />
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Сподели со"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ml-rIN/strings.xml b/v7/appcompat/res/values-ml-rIN/strings.xml
index 2fb368e..53f8e4b 100644
--- a/v7/appcompat/res/values-ml-rIN/strings.xml
+++ b/v7/appcompat/res/values-ml-rIN/strings.xml
@@ -20,13 +20,18 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"ഹോമിലേക്ക് നാവിഗേറ്റുചെയ്യുക"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<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="7165123711973476752">"%s എന്നതുമായി പങ്കിടുക"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ഇവരുമായി പങ്കിടുക"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-mn-rMN/strings.xml b/v7/appcompat/res/values-mn-rMN/strings.xml
index 203e959..a89dc4d 100644
--- a/v7/appcompat/res/values-mn-rMN/strings.xml
+++ b/v7/appcompat/res/values-mn-rMN/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Нүүр хуудас руу шилжих"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Асуулгыг илгээх"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Бүгдийг харах"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s-тай хуваалцах"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Хуваалцах"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-mr-rIN/strings.xml b/v7/appcompat/res/values-mr-rIN/strings.xml
index 41271d4..1afbd81 100644
--- a/v7/appcompat/res/values-mr-rIN/strings.xml
+++ b/v7/appcompat/res/values-mr-rIN/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"मुख्यपृष्ठ नेव्हिगेट करा"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"क्वेरी सबमिट करा"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"सर्व पहा"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s सह सामायिक करा"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"यांच्यासह सामायिक करा"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ms-rMY/strings.xml b/v7/appcompat/res/values-ms-rMY/strings.xml
index b174068..9763618 100644
--- a/v7/appcompat/res/values-ms-rMY/strings.xml
+++ b/v7/appcompat/res/values-ms-rMY/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigasi skrin utama"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigasi ke atas"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Lagi pilihan"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Runtuhkan"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Cari"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Cari…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Pertanyaan carian"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Kosongkan pertanyaan"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Serah pertanyaan"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Lihat semua"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Kongsi dengan %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Kongsi dengan"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-my-rMM/strings.xml b/v7/appcompat/res/values-my-rMM/strings.xml
index d487f50..936ac99 100644
--- a/v7/appcompat/res/values-my-rMM/strings.xml
+++ b/v7/appcompat/res/values-my-rMM/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"မူလနေရာကို သွားရန်"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s၊ %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s ၊ %2$s ၊ %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ရှာဖွေစရာ အချက်အလက်ကို အတည်ပြုရန်"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"အားလုံးကို ကြည့်ရန်"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s ကို မျှဝေပါရန်"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"မျှဝေဖို့ ရွေးပါ"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"၉၉၉+"</string>
</resources>
diff --git a/v7/appcompat/res/values-nb/strings.xml b/v7/appcompat/res/values-nb/strings.xml
index 6630acf..483f707 100644
--- a/v7/appcompat/res/values-nb/strings.xml
+++ b/v7/appcompat/res/values-nb/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Gå til startsiden"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Gå opp"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Flere alternativer"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Skjul"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s – %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s – %2$s – %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Søk"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Søk …"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Søkeord"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Slett søket"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Utfør søket"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Se alle"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Del med %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Del med"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ne-rNP/strings.xml b/v7/appcompat/res/values-ne-rNP/strings.xml
index 69d10dc..4a08778 100644
--- a/v7/appcompat/res/values-ne-rNP/strings.xml
+++ b/v7/appcompat/res/values-ne-rNP/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"गृह खोज्नुहोस्"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"जिज्ञासा पेस गर्नुहोस्"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"सबै हेर्नुहोस्"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s सँग साझेदारी गर्नुहोस्"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"साझेदारी गर्नुहोस्..."</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"९९९+"</string>
</resources>
diff --git a/v7/appcompat/res/values-nl/strings.xml b/v7/appcompat/res/values-nl/strings.xml
index 1375f9e..38a7607 100644
--- a/v7/appcompat/res/values-nl/strings.xml
+++ b/v7/appcompat/res/values-nl/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigeren naar startpositie"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Omhoog navigeren"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Meer opties"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Samenvouwen"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Zoeken"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Zoeken…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Zoekopdracht"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Zoekopdracht wissen"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Zoekopdracht verzenden"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Alles weergeven"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Delen met %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Delen met"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-pa-rIN/strings.xml b/v7/appcompat/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000..af87fdf
--- /dev/null
+++ b/v7/appcompat/res/values-pa-rIN/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 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_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_menu_overflow_description" msgid="3588849162933574182">"ਹੋਰ ਚੋਣਾਂ"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"ਨਸ਼ਟ ਕਰੋ"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"ਸਵਾਲ ਪ੍ਰਸਤੁਤ ਕਰੋ"</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="7165123711973476752">"%s ਨਾਲ ਸ਼ੇਅਰ ਕਰੋ"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ਇਸ ਨਾਲ ਸ਼ੇਅਰ ਕਰੋ"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
+</resources>
diff --git a/v7/appcompat/res/values-pl/strings.xml b/v7/appcompat/res/values-pl/strings.xml
index aa1ba79..72fa439 100644
--- a/v7/appcompat/res/values-pl/strings.xml
+++ b/v7/appcompat/res/values-pl/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Przejdź do strony głównej"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Przejdź wyżej"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Więcej opcji"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Zwiń"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Szukaj"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Szukaj…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Wyszukiwane hasło"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Wyczyść zapytanie"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Wyślij zapytanie"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Zobacz wszystkie"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Udostępnij dla %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Udostępnij dla"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-pt-rPT/strings.xml b/v7/appcompat/res/values-pt-rPT/strings.xml
index 0d63f5f..d76c5c8 100644
--- a/v7/appcompat/res/values-pt-rPT/strings.xml
+++ b/v7/appcompat/res/values-pt-rPT/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navegar para a página inicial"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navegar para cima"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Mais opções"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Reduzir"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Pesquisar"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Pesquisar..."</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de pesquisa"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Limpar consulta"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ver tudo"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Partilhar com %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Partilhar com"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"+999"</string>
</resources>
diff --git a/v7/appcompat/res/values-pt/strings.xml b/v7/appcompat/res/values-pt/strings.xml
index 88b09ea..dfcfce8 100644
--- a/v7/appcompat/res/values-pt/strings.xml
+++ b/v7/appcompat/res/values-pt/strings.xml
@@ -20,13 +20,18 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navegar para a página inicial"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navegar para cima"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Mais opções"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Recolher"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Pesquisar"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Pesquisar..."</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de pesquisa"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Limpar consulta"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
<string name="abc_searchview_description_voice" msgid="893419373245838918">"Pesquisa por voz"</string>
- <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Selecione um aplicativo"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Selecione um app"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ver tudo"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Compartilhar com %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Compartilhar com"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ro/strings.xml b/v7/appcompat/res/values-ro/strings.xml
index 36a7b31..55538ee 100644
--- a/v7/appcompat/res/values-ro/strings.xml
+++ b/v7/appcompat/res/values-ro/strings.xml
@@ -20,13 +20,18 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigați la ecranul de pornire"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigați în sus"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Mai multe opțiuni"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Restrângeți"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Căutați"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Căutați…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Interogare de căutare"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Ștergeți interogarea"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Trimiteți interogarea"</string>
<string name="abc_searchview_description_voice" msgid="893419373245838918">"Căutare vocală"</string>
- <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Alegeți o aplicaţie"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Alegeți o aplicație"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Afișați-le pe toate"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Trimiteți la %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Trimiteți la"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"˃999"</string>
</resources>
diff --git a/v7/appcompat/res/values-ru/strings.xml b/v7/appcompat/res/values-ru/strings.xml
index 5c22e5e..03a2c8f 100644
--- a/v7/appcompat/res/values-ru/strings.xml
+++ b/v7/appcompat/res/values-ru/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Перейти на главный экран"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Отправить запрос"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Показать все"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Открыть доступ пользователю %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Открыть доступ"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">">999"</string>
</resources>
diff --git a/v7/appcompat/res/values-si-rLK/strings.xml b/v7/appcompat/res/values-si-rLK/strings.xml
index a6809c3..a03b5bd 100644
--- a/v7/appcompat/res/values-si-rLK/strings.xml
+++ b/v7/appcompat/res/values-si-rLK/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"ගෙදරට සංචාලනය කරන්න"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"විමසුම යොමු කරන්න"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"සියල්ල බලන්න"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s සමඟ බෙදාගන්න"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"සමඟ බෙදාගන්න"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-sk/strings.xml b/v7/appcompat/res/values-sk/strings.xml
index 253f3e5..f7f0b81 100644
--- a/v7/appcompat/res/values-sk/strings.xml
+++ b/v7/appcompat/res/values-sk/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Prejsť na plochu"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Prejsť hore"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Ďalšie možnosti"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Zbaliť"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Hľadať"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Vyhľadať…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Vyhľadávací dopyt"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Vymazať dopyt"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Odoslať dopyt"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Zobraziť všetko"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Zdieľať pomocou %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Zdieľať pomocou"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-sl/strings.xml b/v7/appcompat/res/values-sl/strings.xml
index 8e3e23e..7d5f0bf 100644
--- a/v7/appcompat/res/values-sl/strings.xml
+++ b/v7/appcompat/res/values-sl/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Krmarjenje domov"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Krmarjenje navzgor"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Več možnosti"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Strni"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Iskanje"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Iskanje …"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Iskalna poizvedba"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Izbris poizvedbe"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Pošiljanje poizvedbe"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Pokaži vse"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Deljenje z:"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Deljenje z"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-sq-rAL/strings.xml b/v7/appcompat/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000..68689a6
--- /dev/null
+++ b/v7/appcompat/res/values-sq-rAL/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 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_action_mode_done" msgid="4076576682505996667">"U krye!"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Orientohu për në shtëpi"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Ngjitu lart"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Opsione të tjera"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Shpalos"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Kërko"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Kërko..."</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Kërko pyetjen"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Pastro pyetjen"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Dërgo pyetjen"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Kërkim me zë"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Zgjidh një aplikacion"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Shikoji të gjitha"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Shpërnda publikisht me %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Shpërnda publikisht me"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
+</resources>
diff --git a/v7/appcompat/res/values-sr/strings.xml b/v7/appcompat/res/values-sr/strings.xml
index 213c939..e147d75 100644
--- a/v7/appcompat/res/values-sr/strings.xml
+++ b/v7/appcompat/res/values-sr/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Одлазак на Почетну"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Слање упита"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Прикажи све"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Дели са апликацијом %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Дели са"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">">999"</string>
</resources>
diff --git a/v7/appcompat/res/values-sv/strings.xml b/v7/appcompat/res/values-sv/strings.xml
index 49c7a5d..feebdb2 100644
--- a/v7/appcompat/res/values-sv/strings.xml
+++ b/v7/appcompat/res/values-sv/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Visa startsidan"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigera uppåt"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Fler alternativ"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Komprimera"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Sök"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Sök …"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Sökfråga"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Ta bort frågan"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Skicka fråga"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Visa alla"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Dela med %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Dela med"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">">999"</string>
</resources>
diff --git a/v7/appcompat/res/values-sw/strings.xml b/v7/appcompat/res/values-sw/strings.xml
index 6455ba5..25c4039 100644
--- a/v7/appcompat/res/values-sw/strings.xml
+++ b/v7/appcompat/res/values-sw/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Nenda mwanzo"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Nenda juu"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Chaguo zaidi"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Kunja"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Tafuta"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Tafuta…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Hoja ya utafutaji"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Futa hoja"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Wasilisha hoja"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Angalia zote"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Shiriki na %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Shiriki na:"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ta-rIN/strings.xml b/v7/appcompat/res/values-ta-rIN/strings.xml
index 4d7d94e..099526b 100644
--- a/v7/appcompat/res/values-ta-rIN/strings.xml
+++ b/v7/appcompat/res/values-ta-rIN/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"முகப்பிற்கு வழிசெலுத்து"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"வினவலைச் சமர்ப்பி"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"எல்லாம் காட்டு"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s உடன் பகிர்"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"இதனுடன் பகிர்"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-te-rIN/strings.xml b/v7/appcompat/res/values-te-rIN/strings.xml
index f6b1775..8ea231a 100644
--- a/v7/appcompat/res/values-te-rIN/strings.xml
+++ b/v7/appcompat/res/values-te-rIN/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"హోమ్కు నావిగేట్ చేయండి"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ప్రశ్నని సమర్పించు"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"అన్నీ చూడండి"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%sతో భాగస్వామ్యం చేయి"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"వీరితో భాగస్వామ్యం చేయి"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-th/strings.xml b/v7/appcompat/res/values-th/strings.xml
index 275dc57..cc5ab0a 100644
--- a/v7/appcompat/res/values-th/strings.xml
+++ b/v7/appcompat/res/values-th/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"นำทางไปหน้าแรก"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ส่งข้อความค้นหา"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ดูทั้งหมด"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"แชร์กับ %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"แชร์กับ"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-tl/strings.xml b/v7/appcompat/res/values-tl/strings.xml
index e0705d6..aa7169f 100644
--- a/v7/appcompat/res/values-tl/strings.xml
+++ b/v7/appcompat/res/values-tl/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Mag-navigate patungo sa home"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Mag-navigate pataas"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Higit pang mga opsyon"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"I-collapse"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Maghanap"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Maghanap…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Query sa paghahanap"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"I-clear ang query"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Isumite ang query"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Tingnan lahat"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Ibahagi sa/kay %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Ibahagi sa/kay"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-tr/strings.xml b/v7/appcompat/res/values-tr/strings.xml
index 61cb966..0d592fc 100644
--- a/v7/appcompat/res/values-tr/strings.xml
+++ b/v7/appcompat/res/values-tr/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Ana ekrana git"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Yukarı git"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Diğer seçenekler"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Daralt"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Ara"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Ara…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Arama sorgusu"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Sorguyu temizle"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Sorguyu gönder"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Tümünü göster"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s ile paylaş"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Şununla paylaş"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-uk/strings.xml b/v7/appcompat/res/values-uk/strings.xml
index f670140..ff08b47 100644
--- a/v7/appcompat/res/values-uk/strings.xml
+++ b/v7/appcompat/res/values-uk/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Перейти на головний"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Надіслати запит"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Переглянути всі"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Надіслати через %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Надіслати через"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-ur-rPK/strings.xml b/v7/appcompat/res/values-ur-rPK/strings.xml
index f209747..5196476 100644
--- a/v7/appcompat/res/values-ur-rPK/strings.xml
+++ b/v7/appcompat/res/values-ur-rPK/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"ہوم پر نیویگیٹ کریں"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"استفسار جمع کرائیں"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"سبھی دیکھیں"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s کے ساتھ اشتراک کریں"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"اشتراک کریں مع"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-uz-rUZ/strings.xml b/v7/appcompat/res/values-uz-rUZ/strings.xml
index 84d9541..fa884f7 100644
--- a/v7/appcompat/res/values-uz-rUZ/strings.xml
+++ b/v7/appcompat/res/values-uz-rUZ/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Boshiga o‘tish"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Yuqoriga o‘tish"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Qo‘shimcha sozlamalar"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Yig‘ish"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Izlash"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Qidirish…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"So‘rovni izlash"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"So‘rovni tozalash"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"So‘rov yaratish"</string>
@@ -31,4 +35,5 @@
<!-- no translation found for abc_shareactionprovider_share_with_application (7165123711973476752) -->
<skip />
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Bo‘lishish:"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-v14/styles.xml b/v7/appcompat/res/values-v14/styles.xml
new file mode 100644
index 0000000..f54796d
--- /dev/null
+++ b/v7/appcompat/res/values-v14/styles.xml
@@ -0,0 +1,33 @@
+<!--
+ ~ Copyright (C) 2015 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>
+
+ <!-- Use platform styles -->
+ <style name="TextAppearance.StatusBar.EventContent"
+ parent="@android:style/TextAppearance.StatusBar.EventContent"/>
+
+ <style name="TextAppearance.StatusBar.EventContent.Title"
+ parent="@android:style/TextAppearance.StatusBar.EventContent.Title"/>
+
+ <!-- Use own styles for which platform styles are not public -->
+ <style name="TextAppearance.StatusBar.EventContent.Line2">
+ <item name="android:textSize">@dimen/notification_subtext_size</item>
+ </style>
+ <style name="TextAppearance.StatusBar.EventContent.Info"/>
+ <style name="TextAppearance.StatusBar.EventContent.Time"/>
+
+</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values-vi/strings.xml b/v7/appcompat/res/values-vi/strings.xml
index 0840f73..8190bc0 100644
--- a/v7/appcompat/res/values-vi/strings.xml
+++ b/v7/appcompat/res/values-vi/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Điều hướng về trang chủ"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Điều hướng lên trên"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Thêm tùy chọn"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Thu gọn"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Tìm kiếm"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Tìm kiếm…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Tìm kiếm truy vấn"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Xóa truy vấn"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Gửi truy vấn"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Xem tất cả"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Chia sẻ với %s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Chia sẻ với"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-zh-rCN/strings.xml b/v7/appcompat/res/values-zh-rCN/strings.xml
index 87b36b0..b0fbc2f 100644
--- a/v7/appcompat/res/values-zh-rCN/strings.xml
+++ b/v7/appcompat/res/values-zh-rCN/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"转到主屏幕"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s:%2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s - %2$s:%3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"提交查询"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"查看全部"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"通过%s分享"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"分享方式"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-zh-rHK/strings.xml b/v7/appcompat/res/values-zh-rHK/strings.xml
index f6a367d..2c46334 100644
--- a/v7/appcompat/res/values-zh-rHK/strings.xml
+++ b/v7/appcompat/res/values-zh-rHK/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"瀏覽主頁"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s:%2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s (%2$s):%3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"提交查詢"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"顯示全部"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"與「%s」分享"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"分享對象"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999 +"</string>
</resources>
diff --git a/v7/appcompat/res/values-zh-rTW/strings.xml b/v7/appcompat/res/values-zh-rTW/strings.xml
index c804ccf..bfabf5a 100644
--- a/v7/appcompat/res/values-zh-rTW/strings.xml
+++ b/v7/appcompat/res/values-zh-rTW/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"瀏覽首頁"</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_action_bar_home_description_format" msgid="1397052879051804371">"%1$s:%2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s - %2$s:%3$s"</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>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"提交查詢"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"查看全部"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"與「%s」分享"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"選擇分享對象"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values-zu/strings.xml b/v7/appcompat/res/values-zu/strings.xml
index 92eac7e..edc265d 100644
--- a/v7/appcompat/res/values-zu/strings.xml
+++ b/v7/appcompat/res/values-zu/strings.xml
@@ -20,7 +20,11 @@
<string name="abc_action_bar_home_description" msgid="4600421777120114993">"Zulazulela ekhaya"</string>
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"Zulazulela phezulu"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Izinketho eziningi"</string>
+ <string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"Goqa"</string>
+ <string name="abc_action_bar_home_description_format" msgid="1397052879051804371">"%1$s, %2$s"</string>
+ <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
<string name="abc_searchview_description_search" msgid="8264924765203268293">"Sesha"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"Iyasesha..."</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"Umbuzo wosesho"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"Sula inkinga"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"Hambisa umbuzo"</string>
@@ -29,4 +33,5 @@
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Buka konke"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Yabelana no-%s"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Yabelana no-"</string>
+ <string name="status_bar_notification_info_overflow" msgid="2869576371154716097">"999+"</string>
</resources>
diff --git a/v7/appcompat/res/values/attrs.xml b/v7/appcompat/res/values/attrs.xml
index 2f32ba3..17286fb 100644
--- a/v7/appcompat/res/values/attrs.xml
+++ b/v7/appcompat/res/values/attrs.xml
@@ -665,6 +665,29 @@
for more info. -->
<attr name="actionProviderClass" format="string" />
+ <!-- An optional tint for the item's icon -->
+ <attr name="iconTint" format="color" />
+
+ <!-- The blending mode used for tinting the item's icon -->
+ <attr name="iconTintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D). Only works on APIv 11+ -->
+ <enum name="add" value="16" />
+ </attr>
</declare-styleable>
<declare-styleable name="Spinner">
@@ -835,6 +858,52 @@
<!-- Allows us to read in the minHeight attr pre-v16 -->
<attr name="android:minHeight" />
+
+ <!-- Tint used for the overflow button -->
+ <attr name="overflowTint" format="color" />
+ <!-- The blending mode used for tinting the overflow button -->
+ <attr name="overflowTintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D). Only works on APIv 11+ -->
+ <enum name="add" value="16" />
+ </attr>
+
+ <!-- Tint used for the navigation button -->
+ <attr name="navigationTint" format="color" />
+ <!-- The blending mode used for tinting the navigation button -->
+ <attr name="navigationTintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D). Only works on APIv 11+ -->
+ <enum name="add" value="16" />
+ </attr>
</declare-styleable>
<declare-styleable name="PopupWindowBackgroundState">
diff --git a/v7/appcompat/res/values/colors.xml b/v7/appcompat/res/values/colors.xml
index 3214201..0ce01d2 100644
--- a/v7/appcompat/res/values/colors.xml
+++ b/v7/appcompat/res/values/colors.xml
@@ -19,4 +19,6 @@
<color name="abc_search_url_text_pressed">@android:color/black</color>
<color name="abc_input_method_navigation_guard">@android:color/black</color>
+
+ <drawable name="notification_template_icon_bg">#3333B5E5</drawable>
</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values/config.xml b/v7/appcompat/res/values/config.xml
index be6a7a1..e0c521b 100644
--- a/v7/appcompat/res/values/config.xml
+++ b/v7/appcompat/res/values/config.xml
@@ -38,4 +38,11 @@
<bool name="abc_config_closeDialogWhenTouchOutside">true</bool>
+ <!-- Maximum numerical value that will be shown in a status bar
+ notification icon or in the notification itself. Will be replaced
+ with @string/status_bar_notification_info_overflow when shown in the
+ UI. -->
+ <integer name="status_bar_notification_info_maxnum">999</integer>
+
+ <integer name="cancel_button_image_alpha">127</integer>
</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values/dimens.xml b/v7/appcompat/res/values/dimens.xml
index b8fa76c..06f1a06 100644
--- a/v7/appcompat/res/values/dimens.xml
+++ b/v7/appcompat/res/values/dimens.xml
@@ -97,4 +97,13 @@
be either a fraction or a dimension. -->
<item type="dimen" name="abc_dialog_min_width_minor">95%</item>
+ <!-- The width of the big icons in notifications. -->
+ <dimen name="notification_large_icon_width">64dp</dimen>
+
+ <!-- The width of the big icons in notifications. -->
+ <dimen name="notification_large_icon_height">64dp</dimen>
+
+ <!-- Size of smaller notification text (see TextAppearance.StatusBar.EventContent.Line2, Info,
+ Time) -->
+ <dimen name="notification_subtext_size">12dp</dimen>
</resources>
diff --git a/v7/appcompat/res/values/strings.xml b/v7/appcompat/res/values/strings.xml
index 87cfd29..a04b396 100644
--- a/v7/appcompat/res/values/strings.xml
+++ b/v7/appcompat/res/values/strings.xml
@@ -62,4 +62,10 @@
<!-- Description of the choose target button in a ShareActionProvider (share UI). [CHAR LIMIT=NONE] -->
<string name="abc_shareactionprovider_share_with">Share with</string>
+ <!-- Text to use when the number in a notification info is too large
+ (greater than status_bar_notification_info_maxnum, defined in
+ values/config.xml) and must be truncated. May need to be localized
+ for most appropriate textual indicator of "more than X".
+ [CHAR LIMIT=4] -->
+ <string name="status_bar_notification_info_overflow">999+</string>
</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values/styles.xml b/v7/appcompat/res/values/styles.xml
index 1f30314..b38c6ad 100644
--- a/v7/appcompat/res/values/styles.xml
+++ b/v7/appcompat/res/values/styles.xml
@@ -321,4 +321,11 @@
<style name="Widget.AppCompat.Light.AutoCompleteTextView" parent="Widget.AppCompat.AutoCompleteTextView" />
<style name="Widget.AppCompat.Light.ActivityChooserView" parent="Widget.AppCompat.ActivityChooserView" />
+ <!-- These styles didn't exist on v7. Since we only use the media template in later versions
+ (ICS+), just define it here and use the correct references in values/v14 -->
+ <style name="TextAppearance.StatusBar.EventContent" parent=""/>
+ <style name="TextAppearance.StatusBar.EventContent.Title" parent=""/>
+ <style name="TextAppearance.StatusBar.EventContent.Line2" parent=""/>
+ <style name="TextAppearance.StatusBar.EventContent.Info" parent=""/>
+ <style name="TextAppearance.StatusBar.EventContent.Time" parent=""/>
</resources>
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java b/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
index 8dbc827..17fb785 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
@@ -19,6 +19,7 @@
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
+import android.support.annotation.CallSuper;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
@@ -201,6 +202,7 @@
*
* @param mode The new action mode.
*/
+ @CallSuper
public void onSupportActionModeStarted(ActionMode mode) {
}
@@ -210,6 +212,7 @@
*
* @param mode The action mode that just finished.
*/
+ @CallSuper
public void onSupportActionModeFinished(ActionMode mode) {
}
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
index 8317ad2..5711b58 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
@@ -89,7 +89,9 @@
private static AppCompatDelegate create(Context context, Window window,
AppCompatCallback callback) {
final int sdk = Build.VERSION.SDK_INT;
- if (sdk >= 14) {
+ if (sdk >= 23) {
+ return new AppCompatDelegateImplV23(context, window, callback);
+ } else if (sdk >= 14) {
return new AppCompatDelegateImplV14(context, window, callback);
} else if (sdk >= 11) {
return new AppCompatDelegateImplV11(context, window, callback);
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
index 9a1a5f0..1c20fd7 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
@@ -54,7 +54,7 @@
@Override
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
// We wrap in a support action mode on v14+ if enabled
- if (mHandleNativeActionModes) {
+ if (isHandleNativeActionModesEnabled()) {
return startAsSupportActionMode(callback);
}
// Else, let the call fall through to the wrapped callback
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV23.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV23.java
new file mode 100644
index 0000000..006827c
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV23.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 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.v7.app;
+
+import android.content.Context;
+import android.view.ActionMode;
+import android.view.Window;
+
+class AppCompatDelegateImplV23 extends AppCompatDelegateImplV14 {
+
+ AppCompatDelegateImplV23(Context context, Window window, AppCompatCallback callback) {
+ super(context, window, callback);
+ }
+
+ @Override
+ Window.Callback wrapWindowCallback(Window.Callback callback) {
+ // Override the window callback so that we can intercept onWindowStartingActionMode(type)
+ // calls
+ return new AppCompatWindowCallbackV23(callback);
+ }
+
+ class AppCompatWindowCallbackV23 extends AppCompatWindowCallbackV14 {
+ AppCompatWindowCallbackV23(Window.Callback callback) {
+ super(callback);
+ }
+
+ @Override
+ public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
+ if (isHandleNativeActionModesEnabled()) {
+ switch (type) {
+ case ActionMode.TYPE_PRIMARY:
+ // We only take over if the type is TYPE_PRIMARY
+ return startAsSupportActionMode(callback);
+ }
+ }
+ // Else, let the call fall through to the wrapped callback
+ return super.onWindowStartingActionMode(callback, type);
+ }
+
+ @Override
+ public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
+ // No-op on API 23+
+ return null;
+ }
+ }
+}
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV7.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV7.java
index 7ea8069..59b33f5 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV7.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV7.java
@@ -37,6 +37,7 @@
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.WindowInsetsCompat;
+import android.support.v4.widget.PopupWindowCompat;
import android.support.v7.appcompat.R;
import android.support.v7.internal.app.AppCompatViewInflater;
import android.support.v7.internal.app.ToolbarActionBar;
@@ -626,6 +627,8 @@
mActionModeView = new ActionBarContextView(actionBarContext);
mActionModePopup = new PopupWindow(actionBarContext, null,
R.attr.actionModePopupWindowStyle);
+ PopupWindowCompat.setWindowLayoutType(mActionModePopup,
+ WindowManager.LayoutParams.TYPE_APPLICATION);
mActionModePopup.setContentView(mActionModeView);
mActionModePopup.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDialogFragment.java b/v7/appcompat/src/android/support/v7/app/AppCompatDialogFragment.java
new file mode 100644
index 0000000..3051e49
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDialogFragment.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 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.v7.app;
+
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.view.Window;
+import android.view.WindowManager;
+
+/**
+ * A special version of {@link DialogFragment} which uses an {@link AppCompatDialog} in place of a
+ * platform-styled dialog.
+ *
+ * @see DialogFragment
+ */
+public class AppCompatDialogFragment extends DialogFragment {
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AppCompatDialog(getActivity(), getTheme());
+ }
+
+ /** @hide */
+ @Override
+ public void setupDialog(Dialog dialog, int style) {
+ if (dialog instanceof AppCompatDialog) {
+ // If the dialog is an AppCompatDialog, we'll handle it
+ AppCompatDialog acd = (AppCompatDialog) dialog;
+ switch (style) {
+ case STYLE_NO_INPUT:
+ dialog.getWindow().addFlags(
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
+ WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+ // fall through...
+ case STYLE_NO_FRAME:
+ case STYLE_NO_TITLE:
+ acd.supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
+ }
+ } else {
+ // Else, just let super handle it
+ super.setupDialog(dialog, style);
+ }
+ }
+
+}
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompat.java b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
new file mode 100644
index 0000000..79e6bc4
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2015 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.v7.app;
+
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.os.Build;
+import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v7.internal.app.NotificationCompatImpl21;
+import android.support.v7.internal.app.NotificationCompatImplBase;
+
+/**
+ * An extension of {@link android.support.v4.app.NotificationCompat} which supports
+ * {@link android.support.v7.app.NotificationCompat.MediaStyle}. You should start using this variant
+ * if you need support for media styled notifications.
+ */
+public class NotificationCompat extends android.support.v4.app.NotificationCompat {
+
+ private static void addMediaStyleToBuilderLollipop(
+ NotificationBuilderWithBuilderAccessor builder, android.support.v4.app.NotificationCompat.Style style) {
+ if (style instanceof MediaStyle) {
+ MediaStyle mediaStyle = (MediaStyle) style;
+ NotificationCompatImpl21.addMediaStyle(builder,
+ mediaStyle.mActionsToShowInCompact,
+ mediaStyle.mToken != null ? mediaStyle.mToken.getToken() : null);
+ }
+ }
+
+ private static void addMediaStyleToBuilderIcs(NotificationBuilderWithBuilderAccessor builder,
+ android.support.v4.app.NotificationCompat.Builder b) {
+ if (b.mStyle instanceof MediaStyle) {
+ MediaStyle mediaStyle = (MediaStyle) b.mStyle;
+ NotificationCompatImplBase.overrideContentView(builder, b.mContext,
+ b.mContentTitle,
+ b.mContentText, b.mContentInfo, b.mNumber, b.mLargeIcon, b.mSubText,
+ b.mUseChronometer, b.mNotification.when, b.mActions,
+ mediaStyle.mActionsToShowInCompact, mediaStyle.mShowCancelButton,
+ mediaStyle.mCancelButtonIntent);
+ }
+ }
+
+ private static void addBigMediaStyleToBuilderJellybean(Notification n,
+ android.support.v4.app.NotificationCompat.Builder b) {
+ if (b.mStyle instanceof MediaStyle) {
+ MediaStyle mediaStyle = (MediaStyle) b.mStyle;
+ NotificationCompatImplBase.overrideBigContentView(n, b.mContext,
+ b.mContentTitle,
+ b.mContentText, b.mContentInfo, b.mNumber, b.mLargeIcon, b.mSubText,
+ b.mUseChronometer, b.mNotification.when, b.mActions,
+ mediaStyle.mShowCancelButton, mediaStyle.mCancelButtonIntent);
+ }
+ }
+
+ /**
+ * See {@link android.support.v4.app.NotificationCompat}. In addition to the builder in v4, this
+ * builder also supports {@link MediaStyle}.
+ */
+ public static class Builder extends android.support.v4.app.NotificationCompat.Builder {
+
+ /**
+ * @inheritDoc
+ */
+ public Builder(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected BuilderExtender getExtender() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ return new LollipopExtender();
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ return new JellybeanExtender();
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ return new IceCreamSandwichExtender();
+ } else {
+ return super.getExtender();
+ }
+ }
+ }
+
+ private static class IceCreamSandwichExtender extends BuilderExtender {
+
+ @Override
+ public Notification build(android.support.v4.app.NotificationCompat.Builder b,
+ NotificationBuilderWithBuilderAccessor builder) {
+ addMediaStyleToBuilderIcs(builder, b);
+ return builder.build();
+ }
+ }
+
+ private static class JellybeanExtender extends BuilderExtender {
+
+ @Override
+ public Notification build(android.support.v4.app.NotificationCompat.Builder b,
+ NotificationBuilderWithBuilderAccessor builder) {
+ addMediaStyleToBuilderIcs(builder, b);
+ Notification n = builder.build();
+ addBigMediaStyleToBuilderJellybean(n, b);
+ return n;
+ }
+ }
+
+ private static class LollipopExtender extends BuilderExtender {
+
+ @Override
+ public Notification build(android.support.v4.app.NotificationCompat.Builder b,
+ NotificationBuilderWithBuilderAccessor builder) {
+ addMediaStyleToBuilderLollipop(builder, b.mStyle);
+ return builder.build();
+ }
+ }
+
+ /**
+ * Notification style for media playback notifications.
+ *
+ * In the expanded form, {@link Notification#bigContentView}, up to 5
+ * {@link android.support.v4.app.NotificationCompat.Action}s specified with
+ * {@link NotificationCompat.Builder#addAction(int, CharSequence, PendingIntent) addAction} will
+ * be shown as icon-only pushbuttons, suitable for transport controls. The Bitmap given to
+ * {@link NotificationCompat.Builder#setLargeIcon(android.graphics.Bitmap) setLargeIcon()} will
+ * be treated as album artwork.
+ *
+ * Unlike the other styles provided here, MediaStyle can also modify the standard-size
+ * {@link Notification#contentView}; by providing action indices to
+ * {@link #setShowActionsInCompactView(int...)} you can promote up to 3 actions to be displayed
+ * in the standard view alongside the usual content.
+ *
+ * Notifications created with MediaStyle will have their category set to
+ * {@link Notification#CATEGORY_TRANSPORT CATEGORY_TRANSPORT} unless you set a different
+ * category using {@link NotificationCompat.Builder#setCategory(String) setCategory()}.
+ *
+ * Finally, if you attach a {@link android.media.session.MediaSession.Token} using
+ * {@link android.support.v7.app.NotificationCompat.MediaStyle#setMediaSession}, the System UI
+ * can identify this as a notification representing an active media session and respond
+ * accordingly (by showing album artwork in the lockscreen, for example).
+ *
+ * To use this style with your Notification, feed it to
+ * {@link NotificationCompat.Builder#setStyle} like so:
+ * <pre class="prettyprint">
+ * Notification noti = new NotificationCompat.Builder()
+ * .setSmallIcon(R.drawable.ic_stat_player)
+ * .setContentTitle("Track title")
+ * .setContentText("Artist - Album")
+ * .setLargeIcon(albumArtBitmap))
+ * .setStyle(<b>new NotificationCompat.MediaStyle()</b>
+ * .setMediaSession(mySession))
+ * .build();
+ * </pre>
+ *
+ * @see Notification#bigContentView
+ */
+ public static class MediaStyle extends android.support.v4.app.NotificationCompat.Style {
+
+ int[] mActionsToShowInCompact = null;
+ MediaSessionCompat.Token mToken;
+ boolean mShowCancelButton;
+ PendingIntent mCancelButtonIntent;
+
+ public MediaStyle() {
+ }
+
+ public MediaStyle(android.support.v4.app.NotificationCompat.Builder builder) {
+ setBuilder(builder);
+ }
+
+ /**
+ * Request up to 3 actions (by index in the order of addition) to be shown in the compact
+ * notification view.
+ *
+ * @param actions the indices of the actions to show in the compact notification view
+ */
+ public MediaStyle setShowActionsInCompactView(int...actions) {
+ mActionsToShowInCompact = actions;
+ return this;
+ }
+
+ /**
+ * Attach a {@link MediaSessionCompat.Token} to this Notification
+ * to provide additional playback information and control to the SystemUI.
+ */
+ public MediaStyle setMediaSession(MediaSessionCompat.Token token) {
+ mToken = token;
+ return this;
+ }
+
+ /**
+ * Sets whether a cancel button at the top right should be shown in the notification on
+ * platforms before Lollipop.
+ *
+ * <p>Prior to Lollipop, there was a bug in the framework which prevented the developer to
+ * make a notification dismissable again after having used the same notification as the
+ * ongoing notification for a foreground service. When the notification was posted by
+ * {@link android.app.Service#startForeground}, but then the service exited foreground mode
+ * via {@link android.app.Service#stopForeground}, without removing the notification, the
+ * notification stayed ongoing, and thus not dismissable.
+ *
+ * <p>This is a common scenario for media notifications, as this is exactly the service
+ * lifecycle that happens when playing/pausing media. Thus, a workaround is provided by the
+ * support library: Instead of making the notification ongoing depending on the playback
+ * state, the support library provides the ability to add an explicit cancel button to the
+ * notification.
+ *
+ * <p>Note that the notification is enforced to be ongoing if a cancel button is shown to
+ * provide a consistent user experience.
+ *
+ * <p>Also note that this method is a no-op when running on Lollipop and later.
+ *
+ * @param show whether to show a cancel button
+ */
+ public void setShowCancelButton(boolean show) {
+ mShowCancelButton = show;
+ }
+
+ /**
+ * Sets the pending intent to be sent when the cancel button is pressed. See {@link
+ * #setShowCancelButton}.
+ *
+ * @param pendingIntent the intent to be sent when the cancel button is pressed
+ */
+ public void setCancelButtonIntent(PendingIntent pendingIntent) {
+ mCancelButtonIntent = pendingIntent;
+ }
+ }
+}
diff --git a/v7/appcompat/src/android/support/v7/graphics/drawable/DrawableUtils.java b/v7/appcompat/src/android/support/v7/graphics/drawable/DrawableUtils.java
new file mode 100644
index 0000000..ffe68d5
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/graphics/drawable/DrawableUtils.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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.v7.graphics.drawable;
+
+import android.graphics.PorterDuff;
+import android.os.Build;
+
+/**
+ * @hide
+ */
+public class DrawableUtils {
+
+ public static PorterDuff.Mode parseTintMode(int value, PorterDuff.Mode defaultMode) {
+ switch (value) {
+ case 3: return PorterDuff.Mode.SRC_OVER;
+ case 5: return PorterDuff.Mode.SRC_IN;
+ case 9: return PorterDuff.Mode.SRC_ATOP;
+ case 14: return PorterDuff.Mode.MULTIPLY;
+ case 15: return PorterDuff.Mode.SCREEN;
+ case 16: return Build.VERSION.SDK_INT >= 11 ? PorterDuff.Mode.valueOf("ADD")
+ : defaultMode;
+ default: return defaultMode;
+ }
+ }
+
+}
diff --git a/v7/appcompat/src/android/support/v7/internal/app/NotificationCompatImpl21.java b/v7/appcompat/src/android/support/v7/internal/app/NotificationCompatImpl21.java
new file mode 100644
index 0000000..a68ad81
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/internal/app/NotificationCompatImpl21.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 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.v7.internal.app;
+
+import android.app.Notification;
+import android.media.session.MediaSession;
+import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
+
+/**
+ * @hide
+ */
+public class NotificationCompatImpl21 {
+
+ public static void addMediaStyle(NotificationBuilderWithBuilderAccessor b,
+ int[] actionsToShowInCompact,
+ Object token) {
+ Notification.MediaStyle style = new Notification.MediaStyle(b.getBuilder());
+ if (actionsToShowInCompact != null) {
+ style.setShowActionsInCompactView(actionsToShowInCompact);
+ }
+ if (token != null) {
+ style.setMediaSession((MediaSession.Token) token);
+ }
+ }
+}
diff --git a/v7/appcompat/src/android/support/v7/internal/app/NotificationCompatImplBase.java b/v7/appcompat/src/android/support/v7/internal/app/NotificationCompatImplBase.java
new file mode 100644
index 0000000..e358fee
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/internal/app/NotificationCompatImplBase.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2015 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.v7.internal.app;
+
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.os.SystemClock;
+import android.support.v7.appcompat.R;
+import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
+import android.support.v4.app.NotificationCompatBase;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.RemoteViews;
+
+import java.text.NumberFormat;
+import java.util.List;
+
+/**
+ * Helper class to generate MediaStyle notifications for pre-Lollipop platforms. Overrides
+ * contentView and bigContentView of the notification.
+ * @hide
+ */
+public class NotificationCompatImplBase {
+
+ static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;
+ static final int MAX_MEDIA_BUTTONS = 5;
+
+ public static <T extends NotificationCompatBase.Action> void overrideContentView(
+ NotificationBuilderWithBuilderAccessor builder,
+ Context context, CharSequence contentTitle, CharSequence contentText,
+ CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
+ boolean useChronometer, long when, List<T> actions, int[] actionsToShowInCompact,
+ boolean showCancelButton, PendingIntent cancelButtonIntent) {
+ RemoteViews views = generateContentView(context, contentTitle, contentText, contentInfo,
+ number, largeIcon, subText, useChronometer, when, actions, actionsToShowInCompact,
+ showCancelButton, cancelButtonIntent);
+ builder.getBuilder().setContent(views);
+ if (showCancelButton) {
+ builder.getBuilder().setOngoing(true);
+ }
+ }
+
+ private static <T extends NotificationCompatBase.Action> RemoteViews generateContentView(
+ Context context, CharSequence contentTitle, CharSequence contentText,
+ CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
+ boolean useChronometer, long when, List<T> actions, int[] actionsToShowInCompact,
+ boolean showCancelButton, PendingIntent cancelButtonIntent) {
+ RemoteViews view = applyStandardTemplate(context, contentTitle, contentText, contentInfo,
+ number, largeIcon, subText, useChronometer, when,
+ R.layout.notification_template_media, true /* fitIn1U */);
+
+ final int numActions = actions.size();
+ final int N = actionsToShowInCompact == null
+ ? 0
+ : Math.min(actionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
+ view.removeAllViews(R.id.media_actions);
+ if (N > 0) {
+ for (int i = 0; i < N; i++) {
+ if (i >= numActions) {
+ throw new IllegalArgumentException(String.format(
+ "setShowActionsInCompactView: action %d out of bounds (max %d)",
+ i, numActions - 1));
+ }
+
+ final NotificationCompatBase.Action action = actions.get(actionsToShowInCompact[i]);
+ final RemoteViews button = generateMediaActionButton(context, action);
+ view.addView(R.id.media_actions, button);
+ }
+ }
+ if (showCancelButton) {
+ view.setViewVisibility(R.id.end_padder, View.GONE);
+ view.setViewVisibility(R.id.cancel_action, View.VISIBLE);
+ view.setOnClickPendingIntent(R.id.cancel_action, cancelButtonIntent);
+ view.setInt(R.id.cancel_action, "setAlpha",
+ context.getResources().getInteger(R.integer.cancel_button_image_alpha));
+ } else {
+ view.setViewVisibility(R.id.end_padder, View.VISIBLE);
+ view.setViewVisibility(R.id.cancel_action, View.GONE);
+ }
+ return view;
+ }
+
+ public static <T extends NotificationCompatBase.Action> void overrideBigContentView(
+ Notification n, Context context, CharSequence contentTitle, CharSequence contentText,
+ CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
+ boolean useChronometer, long when, List<T> actions, boolean showCancelButton,
+ PendingIntent cancelButtonIntent) {
+ n.bigContentView = generateBigContentView(context, contentTitle, contentText, contentInfo,
+ number, largeIcon, subText, useChronometer, when, actions, showCancelButton,
+ cancelButtonIntent);
+ if (showCancelButton) {
+ n.flags |= Notification.FLAG_ONGOING_EVENT;
+ }
+ }
+
+ private static <T extends NotificationCompatBase.Action> RemoteViews generateBigContentView(
+ Context context, CharSequence contentTitle, CharSequence contentText,
+ CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
+ boolean useChronometer, long when, List<T> actions, boolean showCancelButton,
+ PendingIntent cancelButtonIntent) {
+ final int actionCount = Math.min(actions.size(), MAX_MEDIA_BUTTONS);
+ RemoteViews big = applyStandardTemplate(context, contentTitle, contentText, contentInfo,
+ number, largeIcon, subText, useChronometer, when,
+ getBigLayoutResource(actionCount), false /* fitIn1U */);
+
+ big.removeAllViews(R.id.media_actions);
+ if (actionCount > 0) {
+ for (int i = 0; i < actionCount; i++) {
+ final RemoteViews button = generateMediaActionButton(context, actions.get(i));
+ big.addView(R.id.media_actions, button);
+ }
+ }
+ if (showCancelButton) {
+ big.setViewVisibility(R.id.cancel_action, View.VISIBLE);
+ big.setInt(R.id.cancel_action, "setAlpha",
+ context.getResources().getInteger(R.integer.cancel_button_image_alpha));
+ big.setOnClickPendingIntent(R.id.cancel_action, cancelButtonIntent);
+ } else {
+ big.setViewVisibility(R.id.cancel_action, View.GONE);
+ }
+ return big;
+ }
+
+ private static RemoteViews generateMediaActionButton(Context context,
+ NotificationCompatBase.Action action) {
+ final boolean tombstone = (action.getActionIntent() == null);
+ RemoteViews button = new RemoteViews(context.getPackageName(),
+ R.layout.notification_media_action);
+ button.setImageViewResource(R.id.action0, action.getIcon());
+ if (!tombstone) {
+ button.setOnClickPendingIntent(R.id.action0, action.getActionIntent());
+ }
+ button.setContentDescription(R.id.action0, action.getTitle());
+ return button;
+ }
+
+ private static int getBigLayoutResource(int actionCount) {
+ if (actionCount <= 3) {
+ return R.layout.notification_template_big_media_narrow;
+ } else {
+ return R.layout.notification_template_big_media;
+ }
+ }
+
+ private static RemoteViews applyStandardTemplate(Context context,
+ CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
+ int number, Bitmap largeIcon, CharSequence subText, boolean useChronometer, long when,
+ int resId, boolean fitIn1U) {
+ RemoteViews contentView = new RemoteViews(context.getPackageName(), resId);
+ boolean showLine3 = false;
+ boolean showLine2 = false;
+
+ // On versions before Jellybean, the large icon was shown by SystemUI, so we need to hide
+ // it here.
+ if (largeIcon != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ contentView.setImageViewBitmap(R.id.icon, largeIcon);
+ } else {
+ contentView.setViewVisibility(R.id.icon, View.GONE);
+ }
+ if (contentTitle != null) {
+ contentView.setTextViewText(R.id.title, contentTitle);
+ }
+ if (contentText != null) {
+ contentView.setTextViewText(R.id.text, contentText);
+ showLine3 = true;
+ }
+ if (contentInfo != null) {
+ contentView.setTextViewText(R.id.info, contentInfo);
+ contentView.setViewVisibility(R.id.info, View.VISIBLE);
+ showLine3 = true;
+ } else if (number > 0) {
+ final int tooBig = context.getResources().getInteger(
+ R.integer.status_bar_notification_info_maxnum);
+ if (number > tooBig) {
+ contentView.setTextViewText(R.id.info, context.getResources().getString(
+ R.string.status_bar_notification_info_overflow));
+ } else {
+ NumberFormat f = NumberFormat.getIntegerInstance();
+ contentView.setTextViewText(R.id.info, f.format(number));
+ }
+ contentView.setViewVisibility(R.id.info, View.VISIBLE);
+ showLine3 = true;
+ } else {
+ contentView.setViewVisibility(R.id.info, View.GONE);
+ }
+
+ // Need to show three lines? Only allow on Jellybean+
+ if (subText != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ contentView.setTextViewText(R.id.text, subText);
+ if (contentText != null) {
+ contentView.setTextViewText(R.id.text2, contentText);
+ contentView.setViewVisibility(R.id.text2, View.VISIBLE);
+ showLine2 = true;
+ } else {
+ contentView.setViewVisibility(R.id.text2, View.GONE);
+ }
+ }
+
+ // RemoteViews.setViewPadding and RemoteViews.setTextViewTextSize is not available on ICS-
+ if (showLine2 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ if (fitIn1U) {
+ // need to shrink all the type to make sure everything fits
+ final Resources res = context.getResources();
+ final float subTextSize = res.getDimensionPixelSize(
+ R.dimen.notification_subtext_size);
+ contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, subTextSize);
+ }
+ // vertical centering
+ contentView.setViewPadding(R.id.line1, 0, 0, 0, 0);
+ }
+
+ if (when != 0) {
+ if (useChronometer) {
+ contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
+ contentView.setLong(R.id.chronometer, "setBase",
+ when + (SystemClock.elapsedRealtime() - System.currentTimeMillis()));
+ contentView.setBoolean(R.id.chronometer, "setStarted", true);
+ } else {
+ contentView.setViewVisibility(R.id.time, View.VISIBLE);
+ contentView.setLong(R.id.time, "setTime", when);
+ }
+ }
+ contentView.setViewVisibility(R.id.line3, showLine3 ? View.VISIBLE : View.GONE);
+ return contentView;
+ }
+}
diff --git a/v7/appcompat/src/android/support/v7/internal/view/SupportMenuInflater.java b/v7/appcompat/src/android/support/v7/internal/view/SupportMenuInflater.java
index 84a07da..624f3e9 100644
--- a/v7/appcompat/src/android/support/v7/internal/view/SupportMenuInflater.java
+++ b/v7/appcompat/src/android/support/v7/internal/view/SupportMenuInflater.java
@@ -22,12 +22,16 @@
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
import android.support.v4.internal.view.SupportMenu;
import android.support.v4.view.ActionProvider;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.appcompat.R;
+import android.support.v7.graphics.drawable.DrawableUtils;
import android.support.v7.internal.view.menu.MenuItemImpl;
import android.support.v7.internal.view.menu.MenuItemWrapperICS;
import android.util.AttributeSet;
@@ -317,6 +321,11 @@
private ActionProvider itemActionProvider;
+ private ColorStateList itemIconTintList;
+ private boolean itemIconTintListSet;
+ private PorterDuff.Mode itemIconTintMode;
+ private boolean itemIconTintModeSet;
+
private static final int defaultGroupId = NO_ID;
private static final int defaultItemId = NO_ID;
private static final int defaultItemCategory = 0;
@@ -408,6 +417,22 @@
itemActionProvider = null;
}
+ if (a.hasValue(R.styleable.MenuItem_iconTint)) {
+ itemIconTintList = a.getColorStateList(R.styleable.MenuItem_iconTint);
+ itemIconTintListSet = true;
+ } else {
+ itemIconTintList = null;
+ itemIconTintListSet = false;
+ }
+ if (a.hasValue(R.styleable.MenuItem_iconTintMode)) {
+ itemIconTintMode = DrawableUtils.parseTintMode(
+ a.getInt(R.styleable.MenuItem_iconTintMode, -1), null);
+ itemIconTintModeSet = true;
+ } else {
+ itemIconTintMode = null;
+ itemIconTintModeSet = false;
+ }
+
a.recycle();
itemAdded = false;
@@ -472,6 +497,13 @@
if (itemActionProvider != null) {
MenuItemCompat.setActionProvider(item, itemActionProvider);
}
+
+ if (itemIconTintListSet) {
+ MenuItemCompat.setIconTintList(item, itemIconTintList);
+ }
+ if (itemIconTintModeSet) {
+ MenuItemCompat.setIconTintMode(item, itemIconTintMode);
+ }
}
public void addItem() {
@@ -496,6 +528,7 @@
try {
Class<?> clazz = mContext.getClassLoader().loadClass(className);
Constructor<?> constructor = clazz.getConstructor(constructorSignature);
+ constructor.setAccessible(true);
return (T) constructor.newInstance(arguments);
} catch (Exception e) {
Log.w(LOG_TAG, "Cannot instantiate class: " + className, e);
diff --git a/v7/appcompat/src/android/support/v7/internal/view/WindowCallbackWrapper.java b/v7/appcompat/src/android/support/v7/internal/view/WindowCallbackWrapper.java
index d799d00..900d304 100644
--- a/v7/appcompat/src/android/support/v7/internal/view/WindowCallbackWrapper.java
+++ b/v7/appcompat/src/android/support/v7/internal/view/WindowCallbackWrapper.java
@@ -21,6 +21,7 @@
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
+import android.view.SearchEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
@@ -130,6 +131,11 @@
}
@Override
+ public boolean onSearchRequested(SearchEvent searchEvent) {
+ return mWrapped.onSearchRequested(searchEvent);
+ }
+
+ @Override
public boolean onSearchRequested() {
return mWrapped.onSearchRequested();
}
@@ -140,6 +146,11 @@
}
@Override
+ public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
+ return mWrapped.onWindowStartingActionMode(callback, type);
+ }
+
+ @Override
public void onActionModeStarted(ActionMode mode) {
mWrapped.onActionModeStarted(mode);
}
diff --git a/v7/appcompat/src/android/support/v7/internal/view/menu/ActionMenuItem.java b/v7/appcompat/src/android/support/v7/internal/view/menu/ActionMenuItem.java
index b466a0b..bf1db65 100644
--- a/v7/appcompat/src/android/support/v7/internal/view/menu/ActionMenuItem.java
+++ b/v7/appcompat/src/android/support/v7/internal/view/menu/ActionMenuItem.java
@@ -18,8 +18,11 @@
import android.content.Context;
import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.view.ActionProvider;
import android.support.v4.internal.view.SupportMenuItem;
import android.support.v4.view.MenuItemCompat;
@@ -46,6 +49,7 @@
private Drawable mIconDrawable;
private int mIconResId = NO_ICON;
+ private TintInfo mIconTintInfo;
private Context mContext;
@@ -162,12 +166,14 @@
public MenuItem setIcon(Drawable icon) {
mIconDrawable = icon;
mIconResId = NO_ICON;
+ applyIconTint();
return this;
}
public MenuItem setIcon(int iconRes) {
mIconResId = iconRes;
mIconDrawable = ContextCompat.getDrawable(mContext, iconRes);
+ applyIconTint();
return this;
}
@@ -293,4 +299,48 @@
// No need to save the listener; ActionMenuItem does not support collapsing items.
return this;
}
+
+ @Override
+ public MenuItem setIconTintList(ColorStateList tintList) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintList = tintList;
+ mIconTintInfo.mHasTintList = true;
+ applyIconTint();
+ return this;
+ }
+
+ @Override
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintMode = tintMode;
+ mIconTintInfo.mHasTintMode = true;
+ applyIconTint();
+ return this;
+ }
+
+ private void applyIconTint() {
+ final TintInfo tintInfo = mIconTintInfo;
+ if (mIconDrawable != null && tintInfo != null) {
+ if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
+ mIconDrawable = DrawableCompat.wrap(mIconDrawable.mutate());
+ if (tintInfo.mHasTintList) {
+ DrawableCompat.setTintList(mIconDrawable, tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ DrawableCompat.setTintMode(mIconDrawable, tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}
diff --git a/v7/appcompat/src/android/support/v7/internal/view/menu/MenuItemImpl.java b/v7/appcompat/src/android/support/v7/internal/view/menu/MenuItemImpl.java
index a2e9783..5ebf394 100644
--- a/v7/appcompat/src/android/support/v7/internal/view/menu/MenuItemImpl.java
+++ b/v7/appcompat/src/android/support/v7/internal/view/menu/MenuItemImpl.java
@@ -19,9 +19,11 @@
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
-import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.view.ActionProvider;
import android.support.v4.internal.view.SupportMenuItem;
import android.support.v4.view.MenuItemCompat;
@@ -66,6 +68,11 @@
*/
private int mIconResId = NO_ICON;
+ /**
+ * Tint info for the icon
+ */
+ private TintInfo mIconTintInfo;
+
/** The menu to which this item belongs */
private MenuBuilder mMenu;
/** If this item should launch a sub menu, this is the sub menu to launch */
@@ -118,19 +125,6 @@
*/
MenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering,
CharSequence title, int showAsAction) {
-
- /*if (sPrependShortcutLabel == null) {
- // This is instantiated from the UI thread, so no chance of sync issues
- sPrependShortcutLabel = menu.getContext().getResources().getString(
- com.android.internal.R.string.prepend_shortcut_label);
- sEnterShortcutLabel = menu.getContext().getResources().getString(
- com.android.internal.R.string.menu_enter_shortcut_label);
- sDeleteShortcutLabel = menu.getContext().getResources().getString(
- com.android.internal.R.string.menu_delete_shortcut_label);
- sSpaceShortcutLabel = menu.getContext().getResources().getString(
- com.android.internal.R.string.menu_space_shortcut_label);
- }*/
-
mMenu = menu;
mId = id;
mGroup = group;
@@ -419,10 +413,10 @@
}
if (mIconResId != NO_ICON) {
- Drawable icon = TintManager.getDrawable(mMenu.getContext(), mIconResId);
+ mIconDrawable = TintManager.getDrawable(mMenu.getContext(), mIconResId);
mIconResId = NO_ICON;
- mIconDrawable = icon;
- return icon;
+ applyIconTint();
+ return mIconDrawable;
}
return null;
@@ -432,6 +426,7 @@
public MenuItem setIcon(Drawable icon) {
mIconResId = NO_ICON;
mIconDrawable = icon;
+ applyIconTint();
mMenu.onItemsChanged(false);
return this;
@@ -538,7 +533,7 @@
@Override
public String toString() {
- return mTitle.toString();
+ return mTitle != null ? mTitle.toString() : null;
}
void setMenuInfo(ContextMenuInfo menuInfo) {
@@ -715,6 +710,28 @@
return this;
}
+ @Override
+ public MenuItem setIconTintList(ColorStateList tintList) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintList = tintList;
+ mIconTintInfo.mHasTintList = true;
+ applyIconTint();
+ return this;
+ }
+
+ @Override
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintMode = tintMode;
+ mIconTintInfo.mHasTintMode = true;
+ applyIconTint();
+ return this;
+ }
+
public boolean hasCollapsibleActionView() {
if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) != 0) {
if (mActionView == null && mActionProvider != null) {
@@ -740,4 +757,26 @@
throw new UnsupportedOperationException(
"This is not supported, use MenuItemCompat.setOnActionExpandListener()");
}
+
+ private void applyIconTint() {
+ final TintInfo tintInfo = mIconTintInfo;
+ if (mIconDrawable != null && tintInfo != null) {
+ if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
+ mIconDrawable = DrawableCompat.wrap(mIconDrawable.mutate());
+ if (tintInfo.mHasTintList) {
+ DrawableCompat.setTintList(mIconDrawable, tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ DrawableCompat.setTintMode(mIconDrawable, tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}
diff --git a/v7/appcompat/src/android/support/v7/internal/view/menu/MenuItemWrapperICS.java b/v7/appcompat/src/android/support/v7/internal/view/menu/MenuItemWrapperICS.java
index 3e6a99a..e86a0f3 100644
--- a/v7/appcompat/src/android/support/v7/internal/view/menu/MenuItemWrapperICS.java
+++ b/v7/appcompat/src/android/support/v7/internal/view/menu/MenuItemWrapperICS.java
@@ -19,6 +19,8 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.internal.view.SupportMenuItem;
@@ -27,6 +29,7 @@
import android.support.v7.view.CollapsibleActionView;
import android.util.Log;
import android.view.ContextMenu;
+import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
@@ -293,6 +296,18 @@
return this;
}
+ @Override
+ public MenuItem setIconTintList(ColorStateList tint) {
+ mWrappedObject.setIconTintList(tint);
+ return this;
+ }
+
+ @Override
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode) {
+ mWrappedObject.setIconTintMode(tintMode);
+ return this;
+ }
+
public void setExclusiveCheckable(boolean checkable) {
try {
if (mSetExclusiveCheckableMethod == null) {
diff --git a/v7/appcompat/src/android/support/v7/internal/view/menu/MenuPopupHelper.java b/v7/appcompat/src/android/support/v7/internal/view/menu/MenuPopupHelper.java
index af7deef..bdcc79a 100644
--- a/v7/appcompat/src/android/support/v7/internal/view/menu/MenuPopupHelper.java
+++ b/v7/appcompat/src/android/support/v7/internal/view/menu/MenuPopupHelper.java
@@ -121,6 +121,10 @@
mDropDownGravity = gravity;
}
+ public int getGravity() {
+ return mDropDownGravity;
+ }
+
public void show() {
if (!tryShow()) {
throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
diff --git a/v7/appcompat/src/android/support/v7/internal/widget/AppCompatPopupWindow.java b/v7/appcompat/src/android/support/v7/internal/widget/AppCompatPopupWindow.java
index 511a332..d71d606 100644
--- a/v7/appcompat/src/android/support/v7/internal/widget/AppCompatPopupWindow.java
+++ b/v7/appcompat/src/android/support/v7/internal/widget/AppCompatPopupWindow.java
@@ -19,6 +19,7 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
+import android.support.v4.widget.PopupWindowCompat;
import android.support.v7.appcompat.R;
import android.util.AttributeSet;
import android.util.Log;
@@ -35,15 +36,18 @@
public class AppCompatPopupWindow extends PopupWindow {
private static final String TAG = "AppCompatPopupWindow";
+ private static final boolean COMPAT_OVERLAP_ANCHOR = Build.VERSION.SDK_INT < 21;
- private final boolean mOverlapAnchor;
+ private boolean mOverlapAnchor;
public AppCompatPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs,
R.styleable.PopupWindow, defStyleAttr, 0);
- mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false);
+ if (a.hasValue(R.styleable.PopupWindow_overlapAnchor)) {
+ setSupportOverlapAnchor(a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false));
+ }
// We re-set this for tinting purposes
setBackgroundDrawable(a.getDrawable(R.styleable.PopupWindow_android_popupBackground));
a.recycle();
@@ -57,7 +61,7 @@
@Override
public void showAsDropDown(View anchor, int xoff, int yoff) {
- if (Build.VERSION.SDK_INT < 21 && mOverlapAnchor) {
+ if (COMPAT_OVERLAP_ANCHOR && mOverlapAnchor) {
// If we're pre-L, emulate overlapAnchor by modifying the yOff
yoff -= anchor.getHeight();
}
@@ -67,7 +71,7 @@
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
- if (Build.VERSION.SDK_INT < 21 && mOverlapAnchor) {
+ if (COMPAT_OVERLAP_ANCHOR && mOverlapAnchor) {
// If we're pre-L, emulate overlapAnchor by modifying the yOff
yoff -= anchor.getHeight();
}
@@ -76,7 +80,7 @@
@Override
public void update(View anchor, int xoff, int yoff, int width, int height) {
- if (Build.VERSION.SDK_INT < 21 && mOverlapAnchor) {
+ if (COMPAT_OVERLAP_ANCHOR && mOverlapAnchor) {
// If we're pre-L, emulate overlapAnchor by modifying the yOff
yoff -= anchor.getHeight();
}
@@ -117,4 +121,26 @@
}
}
+ /**
+ * @hide
+ */
+ public void setSupportOverlapAnchor(boolean overlapAnchor) {
+ if (COMPAT_OVERLAP_ANCHOR) {
+ mOverlapAnchor = overlapAnchor;
+ } else {
+ PopupWindowCompat.setOverlapAnchor(this, overlapAnchor);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public boolean getSupportOverlapAnchor() {
+ if (COMPAT_OVERLAP_ANCHOR) {
+ return mOverlapAnchor;
+ } else {
+ return PopupWindowCompat.getOverlapAnchor(this);
+ }
+ }
+
}
diff --git a/v7/appcompat/src/android/support/v7/internal/widget/TintImageButton.java b/v7/appcompat/src/android/support/v7/internal/widget/TintImageButton.java
new file mode 100644
index 0000000..d4adc21
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/internal/widget/TintImageButton.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 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.v7.internal.widget;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.ImageButton;
+
+/**
+ * An tint aware {@link android.widget.ImageButton}
+ *
+ * @hide
+ */
+public class TintImageButton extends TintImageView {
+
+ public TintImageButton(Context context) {
+ this(context, null);
+ }
+
+ public TintImageButton(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TintImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setFocusable(true);
+ }
+
+ @Override
+ protected boolean onSetAlpha(int alpha) {
+ return false;
+ }
+
+ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ event.setClassName(ImageButton.class.getName());
+ }
+
+ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setClassName(ImageButton.class.getName());
+ }
+}
diff --git a/v7/appcompat/src/android/support/v7/internal/widget/TintImageView.java b/v7/appcompat/src/android/support/v7/internal/widget/TintImageView.java
index 17dd557..617c7b8 100644
--- a/v7/appcompat/src/android/support/v7/internal/widget/TintImageView.java
+++ b/v7/appcompat/src/android/support/v7/internal/widget/TintImageView.java
@@ -17,7 +17,13 @@
package android.support.v7.internal.widget;
import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.support.annotation.DrawableRes;
+import android.support.annotation.Nullable;
+import android.support.v4.graphics.drawable.DrawableCompat;
import android.util.AttributeSet;
import android.widget.ImageView;
@@ -35,6 +41,11 @@
private final TintManager mTintManager;
+ private ColorStateList mDrawableTintList = null;
+ private PorterDuff.Mode mDrawableTintMode = null;
+ private boolean mHasDrawableTint = false;
+ private boolean mHasDrawableTintMode = false;
+
public TintImageView(Context context) {
this(context, null);
}
@@ -67,4 +78,46 @@
// Intercept this call and instead retrieve the Drawable via the tint manager
setImageDrawable(mTintManager.getDrawable(resId));
}
+
+ @Override
+ public void setImageDrawable(Drawable drawable) {
+ super.setImageDrawable(drawable);
+ applyImageTint();
+ }
+
+ public void setImageTintList(@Nullable ColorStateList tint) {
+ if (Build.VERSION.SDK_INT >= 21) {
+ super.setImageTintList(tint);
+ } else {
+ mDrawableTintList = tint;
+ mHasDrawableTint = true;
+ applyImageTint();
+ }
+ }
+
+ public void setImageTintMode(@Nullable PorterDuff.Mode tintMode) {
+ if (Build.VERSION.SDK_INT >= 21) {
+ super.setImageTintMode(tintMode);
+ } else {
+ mDrawableTintMode = tintMode;
+ mHasDrawableTintMode = true;
+ applyImageTint();
+ }
+ }
+
+ private void applyImageTint() {
+ Drawable drawable = getDrawable();
+ if (drawable != null && (mHasDrawableTint || mHasDrawableTintMode)) {
+ drawable = DrawableCompat.wrap(drawable.mutate());
+ if (mHasDrawableTint) {
+ DrawableCompat.setTintList(drawable, mDrawableTintList);
+ }
+ if (mHasDrawableTintMode) {
+ DrawableCompat.setTintMode(drawable, mDrawableTintMode);
+ }
+ // Drawable may have changed, make sure we re-set
+ super.setImageDrawable(drawable);
+ }
+ }
+
}
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java b/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
index bf167d6..6956311 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
@@ -17,8 +17,10 @@
package android.support.v7.widget;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -35,7 +37,8 @@
import android.support.v7.internal.view.menu.MenuPopupHelper;
import android.support.v7.internal.view.menu.MenuView;
import android.support.v7.internal.view.menu.SubMenuBuilder;
-import android.support.v7.internal.widget.TintImageView;
+import android.support.v7.internal.widget.TintImageButton;
+import android.support.v7.internal.widget.TintInfo;
import android.util.SparseBooleanArray;
import android.view.MenuItem;
import android.view.SoundEffectConstants;
@@ -55,7 +58,7 @@
private static final String TAG = "ActionMenuPresenter";
- private View mOverflowButton;
+ private OverflowMenuButton mOverflowButton;
private boolean mReserveOverflow;
private boolean mReserveOverflowSet;
private int mWidthLimit;
@@ -79,6 +82,8 @@
private OpenOverflowRunnable mPostedOpenRunnable;
private ActionMenuPopupCallback mPopupCallback;
+ private TintInfo mOverflowTintInfo;
+
final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
int mOpenSubMenuId;
@@ -112,6 +117,7 @@
mOverflowButton = new OverflowMenuButton(mSystemContext);
final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
mOverflowButton.measure(spec, spec);
+ applyOverflowTint();
}
width -= mOverflowButton.getMeasuredWidth();
} else {
@@ -235,6 +241,7 @@
if (hasOverflow) {
if (mOverflowButton == null) {
mOverflowButton = new OverflowMenuButton(mSystemContext);
+ applyOverflowTint();
}
ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
if (parent != mMenuView) {
@@ -549,6 +556,40 @@
menuView.initialize(mMenu);
}
+ public void setOverflowTintList(ColorStateList tint) {
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintList = tint;
+ mOverflowTintInfo.mHasTintList = true;
+
+ applyOverflowTint();
+ }
+
+ public void setOverflowTintMode(PorterDuff.Mode tintMode) {
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintMode = tintMode;
+ mOverflowTintInfo.mHasTintMode = true;
+
+ applyOverflowTint();
+ }
+
+ private void applyOverflowTint() {
+ final TintInfo tintInfo = mOverflowTintInfo;
+ if (tintInfo != null && (tintInfo.mHasTintList || tintInfo.mHasTintMode)) {
+ if (mOverflowButton != null) {
+ if (tintInfo.mHasTintList) {
+ mOverflowButton.setImageTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mOverflowButton.setImageTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
private static class SavedState implements Parcelable {
public int openSubMenuId;
@@ -581,7 +622,8 @@
};
}
- private class OverflowMenuButton extends TintImageView implements ActionMenuView.ActionMenuChildView {
+ private class OverflowMenuButton extends TintImageButton
+ implements ActionMenuView.ActionMenuChildView {
private final float[] mTempPts = new float[2];
public OverflowMenuButton(Context context) {
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionMenuView.java b/v7/appcompat/src/android/support/v7/widget/ActionMenuView.java
index b7c9821..a96f2f2 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionMenuView.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionMenuView.java
@@ -16,13 +16,17 @@
package android.support.v7.widget;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
+import android.graphics.PorterDuff;
import android.os.Build;
+import android.support.annotation.StyleRes;
import android.support.v7.internal.view.menu.ActionMenuItemView;
import android.support.v7.internal.view.menu.MenuBuilder;
import android.support.v7.internal.view.menu.MenuItemImpl;
import android.support.v7.internal.view.menu.MenuPresenter;
import android.support.v7.internal.view.menu.MenuView;
+import android.support.v7.internal.widget.TintInfo;
import android.support.v7.internal.widget.ViewUtils;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
@@ -91,7 +95,7 @@
* @param resId theme used to inflate popup menus
* @see #getPopupTheme()
*/
- public void setPopupTheme(int resId) {
+ public void setPopupTheme(@StyleRes int resId) {
if (mPopupTheme != resId) {
mPopupTheme = resId;
if (resId == 0) {
@@ -554,6 +558,31 @@
mReserveOverflow = reserveOverflow;
}
+ /**
+ * Applies a tint to the overflow drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ */
+ public void setOverflowTintList(ColorStateList tint) {
+ if (mPresenter != null) {
+ mPresenter.setOverflowTintList(tint);
+ }
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setOverflowTintList(ColorStateList)} to the overflow drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ */
+ public void setOverflowTintMode(PorterDuff.Mode tintMode) {
+ if (mPresenter != null) {
+ mPresenter.setOverflowTintMode(tintMode);
+ }
+ }
+
@Override
protected LayoutParams generateDefaultLayoutParams() {
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
diff --git a/v7/appcompat/src/android/support/v7/widget/PopupMenu.java b/v7/appcompat/src/android/support/v7/widget/PopupMenu.java
index 5b7d333..5c4dde8 100644
--- a/v7/appcompat/src/android/support/v7/widget/PopupMenu.java
+++ b/v7/appcompat/src/android/support/v7/widget/PopupMenu.java
@@ -114,6 +114,29 @@
}
/**
+ * Sets the gravity used to align the popup window to its anchor view.
+ * <p>
+ * If the popup is showing, calling this method will take effect only
+ * the next time the popup is shown.
+ *
+ * @param gravity the gravity used to align the popup window
+ *
+ * @see #getGravity()
+ */
+ public void setGravity(int gravity) {
+ mPopup.setGravity(gravity);
+ }
+
+ /**
+ * @return the gravity used to align the popup window to its anchor view
+ *
+ * @see #setGravity(int)
+ */
+ public int getGravity() {
+ return mPopup.getGravity();
+ }
+
+ /**
* Returns an {@link android.view.View.OnTouchListener} that can be added to the anchor view
* to implement drag-to-open behavior.
* <p>
diff --git a/v7/appcompat/src/android/support/v7/widget/Toolbar.java b/v7/appcompat/src/android/support/v7/widget/Toolbar.java
index 717a097..9522b33 100644
--- a/v7/appcompat/src/android/support/v7/widget/Toolbar.java
+++ b/v7/appcompat/src/android/support/v7/widget/Toolbar.java
@@ -17,12 +17,18 @@
package android.support.v7.widget;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.ColorInt;
+import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.annotation.StyleRes;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.MarginLayoutParamsCompat;
import android.support.v4.view.MenuItemCompat;
@@ -30,6 +36,7 @@
import android.support.v4.view.ViewCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.appcompat.R;
+import android.support.v7.graphics.drawable.DrawableUtils;
import android.support.v7.internal.view.SupportMenuInflater;
import android.support.v7.internal.view.menu.MenuBuilder;
import android.support.v7.internal.view.menu.MenuItemImpl;
@@ -38,6 +45,8 @@
import android.support.v7.internal.view.menu.SubMenuBuilder;
import android.support.v7.internal.widget.DecorToolbar;
import android.support.v7.internal.widget.RtlSpacingHelper;
+import android.support.v7.internal.widget.TintImageButton;
+import android.support.v7.internal.widget.TintInfo;
import android.support.v7.internal.widget.TintManager;
import android.support.v7.internal.widget.TintTypedArray;
import android.support.v7.internal.widget.ToolbarWidgetWrapper;
@@ -110,12 +119,15 @@
private ActionMenuView mMenuView;
private TextView mTitleTextView;
private TextView mSubtitleTextView;
- private ImageButton mNavButtonView;
+ private TintImageButton mNavButtonView;
private ImageView mLogoView;
+ private TintInfo mOverflowTintInfo;
+ private TintInfo mNavTintInfo;
+
private Drawable mCollapseIcon;
private CharSequence mCollapseDescription;
- private ImageButton mCollapseButtonView;
+ private TintImageButton mCollapseButtonView;
View mExpandedActionView;
/** Context against which to inflate popup menus. */
@@ -271,6 +283,21 @@
setNavigationContentDescription(navDesc);
}
+ if (a.hasValue(R.styleable.Toolbar_overflowTint)) {
+ setOverflowTintList(a.getColorStateList(R.styleable.Toolbar_overflowTint));
+ }
+ if (a.hasValue(R.styleable.Toolbar_overflowTintMode)) {
+ setOverflowTintMode(DrawableUtils.parseTintMode(
+ a.getInt(R.styleable.Toolbar_overflowTintMode, -1), null));
+ }
+ if (a.hasValue(R.styleable.Toolbar_navigationTint)) {
+ setNavigationTintList(a.getColorStateList(R.styleable.Toolbar_navigationTint));
+ }
+ if (a.hasValue(R.styleable.Toolbar_navigationTintMode)) {
+ setNavigationTintMode(DrawableUtils.parseTintMode(
+ a.getInt(R.styleable.Toolbar_navigationTintMode, -1), null));
+ }
+
a.recycle();
// Keep the TintManager in case we need it later
@@ -284,7 +311,7 @@
* @param resId theme used to inflate popup menus
* @see #getPopupTheme()
*/
- public void setPopupTheme(int resId) {
+ public void setPopupTheme(@StyleRes int resId) {
if (mPopupTheme != resId) {
mPopupTheme = resId;
if (resId == 0) {
@@ -320,7 +347,7 @@
*
* @param resId ID of a drawable resource
*/
- public void setLogo(int resId) {
+ public void setLogo(@DrawableRes int resId) {
setLogo(mTintManager.getDrawable(resId));
}
@@ -470,7 +497,7 @@
*
* @param resId String resource id
*/
- public void setLogoDescription(int resId) {
+ public void setLogoDescription(@StringRes int resId) {
setLogoDescription(getContext().getText(resId));
}
@@ -555,7 +582,7 @@
*
* @param resId Resource ID of a string to set as the title
*/
- public void setTitle(int resId) {
+ public void setTitle(@StringRes int resId) {
setTitle(getContext().getText(resId));
}
@@ -610,7 +637,7 @@
*
* @param resId String resource ID
*/
- public void setSubtitle(int resId) {
+ public void setSubtitle(@StringRes int resId) {
setSubtitle(getContext().getText(resId));
}
@@ -652,7 +679,7 @@
* Sets the text color, size, style, hint color, and highlight color
* from the specified TextAppearance resource.
*/
- public void setTitleTextAppearance(Context context, int resId) {
+ public void setTitleTextAppearance(Context context, @StyleRes int resId) {
mTitleTextAppearance = resId;
if (mTitleTextView != null) {
mTitleTextView.setTextAppearance(context, resId);
@@ -663,7 +690,7 @@
* Sets the text color, size, style, hint color, and highlight color
* from the specified TextAppearance resource.
*/
- public void setSubtitleTextAppearance(Context context, int resId) {
+ public void setSubtitleTextAppearance(Context context, @StyleRes int resId) {
mSubtitleTextAppearance = resId;
if (mSubtitleTextView != null) {
mSubtitleTextView.setTextAppearance(context, resId);
@@ -675,7 +702,7 @@
*
* @param color The new text color in 0xAARRGGBB format
*/
- public void setTitleTextColor(int color) {
+ public void setTitleTextColor(@ColorInt int color) {
mTitleTextColor = color;
if (mTitleTextView != null) {
mTitleTextView.setTextColor(color);
@@ -687,7 +714,7 @@
*
* @param color The new text color in 0xAARRGGBB format
*/
- public void setSubtitleTextColor(int color) {
+ public void setSubtitleTextColor(@ColorInt int color) {
mSubtitleTextColor = color;
if (mSubtitleTextView != null) {
mSubtitleTextView.setTextColor(color);
@@ -714,7 +741,7 @@
* @param resId Resource ID of a content description string to set, or 0 to
* clear the description
*/
- public void setNavigationContentDescription(int resId) {
+ public void setNavigationContentDescription(@StringRes int resId) {
setNavigationContentDescription(resId != 0 ? getContext().getText(resId) : null);
}
@@ -734,7 +761,7 @@
mNavButtonView.setContentDescription(description);
}
}
-
+
/**
* Set the icon to use for the toolbar's navigation button.
*
@@ -747,7 +774,7 @@
*
* @param resId Resource ID of a drawable to set
*/
- public void setNavigationIcon(int resId) {
+ public void setNavigationIcon(@DrawableRes int resId) {
setNavigationIcon(mTintManager.getDrawable(resId));
}
@@ -803,6 +830,83 @@
}
/**
+ * Applies a tint to the icon drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link #setNavigationIcon(Drawable)} will automatically mutate
+ * the drawable and apply the specified tint and tint mode.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ */
+ public void setNavigationTintList(ColorStateList tint) {
+ if (mNavTintInfo == null) {
+ mNavTintInfo = new TintInfo();
+ }
+ mNavTintInfo.mTintList = tint;
+ mNavTintInfo.mHasTintList = true;
+
+ applyNavigationTint();
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setNavigationTintList(ColorStateList)} to the navigation drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ */
+ public void setNavigationTintMode(PorterDuff.Mode tintMode) {
+ if (mNavTintInfo == null) {
+ mNavTintInfo = new TintInfo();
+ }
+ mNavTintInfo.mTintMode = tintMode;
+ mNavTintInfo.mHasTintMode = true;
+
+ applyNavigationTint();
+ }
+
+ /**
+ * Applies a tint to the overflow drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ */
+ public void setOverflowTintList(ColorStateList tint) {
+ if (mMenuView != null) {
+ // If the menu view is available, directly set the tint
+ mMenuView.setOverflowTintList(tint);
+ } else {
+ // Otherwise we will record the value
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintList = tint;
+ mOverflowTintInfo.mHasTintList = true;
+ }
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setOverflowTintList(ColorStateList)} to the overflow drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ */
+ public void setOverflowTintMode(PorterDuff.Mode tintMode) {
+ if (mMenuView != null) {
+ // If the menu view is available, directly set the tint mode
+ mMenuView.setOverflowTintMode(tintMode);
+ } else {
+ // Otherwise we will record the value
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintMode = tintMode;
+ mOverflowTintInfo.mHasTintMode = true;
+ }
+ }
+
+ /**
* Return the Menu shown in the toolbar.
*
* <p>Applications that wish to populate the toolbar's menu can do so from here. To use
@@ -838,6 +942,17 @@
lp.gravity = GravityCompat.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
mMenuView.setLayoutParams(lp);
addSystemView(mMenuView);
+
+ if (mOverflowTintInfo != null) {
+ // If we have tint info for the overflow, set it on the menu view now
+ if (mOverflowTintInfo.mHasTintList) {
+ mMenuView.setOverflowTintList(mOverflowTintInfo.mTintList);
+ }
+ if (mOverflowTintInfo.mHasTintMode) {
+ mMenuView.setOverflowTintMode(mOverflowTintInfo.mTintMode);
+ }
+ mOverflowTintInfo = null;
+ }
}
}
@@ -987,17 +1102,18 @@
private void ensureNavButtonView() {
if (mNavButtonView == null) {
- mNavButtonView = new ImageButton(getContext(), null,
+ mNavButtonView = new TintImageButton(getContext(), null,
R.attr.toolbarNavigationButtonStyle);
final LayoutParams lp = generateDefaultLayoutParams();
lp.gravity = GravityCompat.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
mNavButtonView.setLayoutParams(lp);
+ applyNavigationTint();
}
}
private void ensureCollapseButtonView() {
if (mCollapseButtonView == null) {
- mCollapseButtonView = new ImageButton(getContext(), null,
+ mCollapseButtonView = new TintImageButton(getContext(), null,
R.attr.toolbarNavigationButtonStyle);
mCollapseButtonView.setImageDrawable(mCollapseIcon);
mCollapseButtonView.setContentDescription(mCollapseDescription);
@@ -1011,6 +1127,7 @@
collapseActionView();
}
});
+ applyNavigationTint();
}
}
@@ -1766,6 +1883,30 @@
mMenuBuilderCallback = mcb;
}
+ private void applyNavigationTint() {
+ final TintInfo tintInfo = mNavTintInfo;
+ if (tintInfo != null && (tintInfo.mHasTintList || tintInfo.mHasTintMode)) {
+ if (mNavButtonView != null) {
+ if (tintInfo.mHasTintList) {
+ mNavButtonView.setImageTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mNavButtonView.setImageTintMode(tintInfo.mTintMode);
+ }
+ }
+
+ if (mCollapseButtonView != null) {
+ // We will use the same tint for the collapse button
+ if (tintInfo.mHasTintList) {
+ mCollapseButtonView.setImageTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mCollapseButtonView.setImageTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
/**
* Interface responsible for receiving menu item click events if the items themselves
* do not have individual item click listeners.
@@ -2000,5 +2141,4 @@
public void onRestoreInstanceState(Parcelable state) {
}
}
-
}
diff --git a/v7/gridlayout/tests/src/android/support/v7/widget/test/GridLayoutTest.java b/v7/gridlayout/tests/src/android/support/v7/widget/test/GridLayoutTest.java
index 3a3d10a..1a88be5 100644
--- a/v7/gridlayout/tests/src/android/support/v7/widget/test/GridLayoutTest.java
+++ b/v7/gridlayout/tests/src/android/support/v7/widget/test/GridLayoutTest.java
@@ -20,7 +20,7 @@
import android.os.Debug;
import android.support.v7.widget.GridLayout;
import android.test.ActivityInstrumentationTestCase2;
-import android.support.v7.gridlayout.test.R;
+import android.support.v7.gridlayout.R;
import android.test.UiThreadTest;
import android.view.Gravity;
import android.view.View;
diff --git a/v7/mediarouter/api/current.txt b/v7/mediarouter/api/current.txt
index a382a89..0ae96cd 100644
--- a/v7/mediarouter/api/current.txt
+++ b/v7/mediarouter/api/current.txt
@@ -20,6 +20,7 @@
method public void onAttachedToWindow();
method public void onDetachedFromWindow();
method public void setDialogFactory(android.support.v7.app.MediaRouteDialogFactory);
+ method public void setRemoteIndicatorDrawable(android.graphics.drawable.Drawable);
method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
method public boolean showDialog();
}
diff --git a/v7/mediarouter/res/values-af/strings.xml b/v7/mediarouter/res/values-af/strings.xml
index 885af10..0dcfa86 100644
--- a/v7/mediarouter/res/values-af/strings.xml
+++ b/v7/mediarouter/res/values-af/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Stelsel"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Toestelle"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Media-uitvoer"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Saai uit"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Koppel aan toestel"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Soek tans vir toestelle…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Ontkoppel"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Hou op uitsaai"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Roete-instellings"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Speel"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Laat wag"</string>
</resources>
diff --git a/v7/mediarouter/res/values-am/strings.xml b/v7/mediarouter/res/values-am/strings.xml
index 0027737..5d061c9 100644
--- a/v7/mediarouter/res/values-am/strings.xml
+++ b/v7/mediarouter/res/values-am/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"ስርዓት"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"መሣሪያዎች"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"የሚዲያ ውፅዓት"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"ውሰድ"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ከመሳሪያ ጋር ያገናኙ"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"መሳሪያዎችን በመፈለግ ላይ…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ግንኙነት አቋርጥ"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"መውሰድ አቁም"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"የመንገድ ቅንብሮች"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"አጫውት"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"ለአፍታ አቁም"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ar/strings.xml b/v7/mediarouter/res/values-ar/strings.xml
index 9289a35..ac0fb5d 100644
--- a/v7/mediarouter/res/values-ar/strings.xml
+++ b/v7/mediarouter/res/values-ar/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"النظام"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"الأجهزة"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"المنفذ الإعلامي"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"إرسال"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"الاتصال بجهاز"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"جارٍ البحث عن الأجهزة…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"قطع الاتصال"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"إيقاف الإرسال"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"إعدادات المسار"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"تشغيل"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"إيقاف مؤقت"</string>
</resources>
diff --git a/v7/mediarouter/res/values-bg/strings.xml b/v7/mediarouter/res/values-bg/strings.xml
index ff1401e..0918332 100644
--- a/v7/mediarouter/res/values-bg/strings.xml
+++ b/v7/mediarouter/res/values-bg/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Система"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Устройства"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Изходяща мултимедия"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Предаване"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Свързване с устройство"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Търсят се устройства…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Прекратяване на връзката"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Спиране на предаването"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Настройки за маршрута"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Пускане"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Поставяне на пауза"</string>
</resources>
diff --git a/v7/mediarouter/res/values-bn-rBD/strings.xml b/v7/mediarouter/res/values-bn-rBD/strings.xml
index d0b2c32..de862e5 100644
--- a/v7/mediarouter/res/values-bn-rBD/strings.xml
+++ b/v7/mediarouter/res/values-bn-rBD/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"সিস্টেম"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"ডিভাইসগুলি"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"মিডিয়া আউটপুট"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"কাস্ট করুন"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ডিভাইসে সংযোগ করুন"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"ডিভাইসগুলি অনুসন্ধান করা হচ্ছে…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"সংযোগ বিচ্ছিন্ন করুন"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"কাস্ট করা বন্ধ করুন"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"সেটিংস রুট করুন"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"চালান"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"বিরাম দিন"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ca/strings.xml b/v7/mediarouter/res/values-ca/strings.xml
index dd485de..eac6632 100644
--- a/v7/mediarouter/res/values-ca/strings.xml
+++ b/v7/mediarouter/res/values-ca/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositius"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Sortida de contingut multimèdia"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Emet"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connecta al dispositiu"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"S\'estan cercant dispositius…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desconnecta"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Atura l\'emissió"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Configuració de la ruta"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Reprodueix"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Posa en pausa"</string>
</resources>
diff --git a/v7/mediarouter/res/values-cs/strings.xml b/v7/mediarouter/res/values-cs/strings.xml
index 4687100..111c02a 100644
--- a/v7/mediarouter/res/values-cs/strings.xml
+++ b/v7/mediarouter/res/values-cs/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Systém"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Zařízení"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Výstup médií"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Odeslat"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Připojení k zařízení"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Vyhledávání zařízení…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Odpojit"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Ukončit odesílání"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Nastavení trasy"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Přehrát"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pozastavit"</string>
</resources>
diff --git a/v7/mediarouter/res/values-da/strings.xml b/v7/mediarouter/res/values-da/strings.xml
index fd3b0fb..3b4fbf6 100644
--- a/v7/mediarouter/res/values-da/strings.xml
+++ b/v7/mediarouter/res/values-da/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Enheder"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medieudgang"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Cast"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Opret forbindelse til enheden"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Søger efter enheder..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Afbryd forbindelsen"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Stop med at caste"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Ruteindstillinger"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Afspil"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Sæt på pause"</string>
</resources>
diff --git a/v7/mediarouter/res/values-de/strings.xml b/v7/mediarouter/res/values-de/strings.xml
index 9df0ebf..5b8e494 100644
--- a/v7/mediarouter/res/values-de/strings.xml
+++ b/v7/mediarouter/res/values-de/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Geräte"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medienausgabe"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Übertragen"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Mit Gerät verbinden"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Geräte werden gesucht…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Verbindung aufheben"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Übertragung stoppen"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Routingeinstellungen"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Wiedergabe"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pause"</string>
</resources>
diff --git a/v7/mediarouter/res/values-el/strings.xml b/v7/mediarouter/res/values-el/strings.xml
index 5a61395..3640111 100644
--- a/v7/mediarouter/res/values-el/strings.xml
+++ b/v7/mediarouter/res/values-el/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Σύστημα"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Συσκευές"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Έξοδος μέσων"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Μετάδοση"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Σύνδεση με τη συσκευή"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Αναζήτηση συσκευών…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Αποσύνδεση"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Διακοπή μετάδοσης"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Ρυθμίσεις διαδρομής"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Αναπαραγωγή"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Παύση"</string>
</resources>
diff --git a/v7/mediarouter/res/values-en-rAU/strings.xml b/v7/mediarouter/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..f5a8531
--- /dev/null
+++ b/v7/mediarouter/res/values-en-rAU/strings.xml
@@ -0,0 +1,29 @@
+<?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="5441529851481176817">"System"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Devices"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Cast"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connect to device"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Searching for devices…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Disconnect"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Stop casting"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Route settings"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Play"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pause"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-en-rGB/strings.xml b/v7/mediarouter/res/values-en-rGB/strings.xml
index b9af4bf..f5a8531 100644
--- a/v7/mediarouter/res/values-en-rGB/strings.xml
+++ b/v7/mediarouter/res/values-en-rGB/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Devices"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Media output"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Cast"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connect to device"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Searching for devices…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Disconnect"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Stop casting"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Route settings"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Play"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pause"</string>
</resources>
diff --git a/v7/mediarouter/res/values-en-rIN/strings.xml b/v7/mediarouter/res/values-en-rIN/strings.xml
index b9af4bf..f5a8531 100644
--- a/v7/mediarouter/res/values-en-rIN/strings.xml
+++ b/v7/mediarouter/res/values-en-rIN/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Devices"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Media output"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Cast"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connect to device"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Searching for devices…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Disconnect"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Stop casting"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Route settings"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Play"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pause"</string>
</resources>
diff --git a/v7/mediarouter/res/values-es-rUS/strings.xml b/v7/mediarouter/res/values-es-rUS/strings.xml
index 211b400..e1cf915 100644
--- a/v7/mediarouter/res/values-es-rUS/strings.xml
+++ b/v7/mediarouter/res/values-es-rUS/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Salida multimedia"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Transmitir"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Conectar al dispositivo"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Buscando dispositivos…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desconectar"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Detener transmisión"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Configuración de ruta"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Reproducir"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pausar"</string>
</resources>
diff --git a/v7/mediarouter/res/values-es/strings.xml b/v7/mediarouter/res/values-es/strings.xml
index d3a1639..0f2a8ea 100644
--- a/v7/mediarouter/res/values-es/strings.xml
+++ b/v7/mediarouter/res/values-es/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Salida multimedia"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Enviar contenido"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Conectar a dispositivo"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Buscando dispositivos…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desconectar"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Dejar de enviar contenido"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Ajustes de ruta"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Reproducir"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pausa"</string>
</resources>
diff --git a/v7/mediarouter/res/values-et-rEE/strings.xml b/v7/mediarouter/res/values-et-rEE/strings.xml
index 7dbdf74..ebc63fd 100644
--- a/v7/mediarouter/res/values-et-rEE/strings.xml
+++ b/v7/mediarouter/res/values-et-rEE/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Süsteem"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Seadmed"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Meediaväljund"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Ülekandmine"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Seadmega ühendamine"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Seadmete otsimine …"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Katkesta ühendus"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Lõpeta ülekanne"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Marsruudi seaded"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Esitamine"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Peatamine"</string>
</resources>
diff --git a/v7/mediarouter/res/values-eu-rES/strings.xml b/v7/mediarouter/res/values-eu-rES/strings.xml
index 728672d..d177a55 100644
--- a/v7/mediarouter/res/values-eu-rES/strings.xml
+++ b/v7/mediarouter/res/values-eu-rES/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Gailuak"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Multimedia-irteera"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Igorri"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Konektatu gailura"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Gailuak bilatzen…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Deskonektatu"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Utzi igortzeari"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Ibilbidearen ezarpenak"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Erreproduzitu"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pausatu"</string>
</resources>
diff --git a/v7/mediarouter/res/values-fa/strings.xml b/v7/mediarouter/res/values-fa/strings.xml
index 2ffed50..e094982 100644
--- a/v7/mediarouter/res/values-fa/strings.xml
+++ b/v7/mediarouter/res/values-fa/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"سیستم"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"دستگاهها"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"خروجی رسانه"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"فرستادن"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"برقراری ارتباط با دستگاه"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"در حال جستجو برای دستگاهها..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"قطع ارتباط"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"توقف فرستادن"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"تنظیمات مسیر"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"پخش"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"توقف موقت"</string>
</resources>
diff --git a/v7/mediarouter/res/values-fi/strings.xml b/v7/mediarouter/res/values-fi/strings.xml
index 0692c2f..a21dc91 100644
--- a/v7/mediarouter/res/values-fi/strings.xml
+++ b/v7/mediarouter/res/values-fi/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Järjestelmä"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Laitteet"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Median äänentoisto"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Lähetä"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Yhdistä laitteeseen"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Etsitään laitteita…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Katkaise yhteys"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Lopeta suoratoisto"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Reitin asetukset"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Toista"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Keskeytä"</string>
</resources>
diff --git a/v7/mediarouter/res/values-fr-rCA/strings.xml b/v7/mediarouter/res/values-fr-rCA/strings.xml
index 9fa3c9c..0655526 100644
--- a/v7/mediarouter/res/values-fr-rCA/strings.xml
+++ b/v7/mediarouter/res/values-fr-rCA/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Système"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Appareils"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Sortie multimédia"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Diffuser"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connexion au périphérique"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Recherche d\'appareils en cours…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Déconnecter"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Arrêter la diffusion"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Paramètres de l\'itinéraire"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Lecture"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Suspendre"</string>
</resources>
diff --git a/v7/mediarouter/res/values-fr/strings.xml b/v7/mediarouter/res/values-fr/strings.xml
index 5607a1c..9fce08a 100644
--- a/v7/mediarouter/res/values-fr/strings.xml
+++ b/v7/mediarouter/res/values-fr/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Système"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Appareils"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Sortie multimédia"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Caster"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connecter à l\'appareil"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Recherche d\'appareils en cours…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Déconnecter"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Arrêter la diffusion"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Paramètres de l\'itinéraire"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Lecture"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pause"</string>
</resources>
diff --git a/v7/mediarouter/res/values-gl-rES/strings.xml b/v7/mediarouter/res/values-gl-rES/strings.xml
index d700c14..d1d73f9 100644
--- a/v7/mediarouter/res/values-gl-rES/strings.xml
+++ b/v7/mediarouter/res/values-gl-rES/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Saída multimedia"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Emitir"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Conectar co dispositivo"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Buscando dispositivos…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desconectar"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Parar de emitir"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Configuración da ruta"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Reproduce"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pausa"</string>
</resources>
diff --git a/v7/mediarouter/res/values-gu-rIN/strings.xml b/v7/mediarouter/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000..2002115
--- /dev/null
+++ b/v7/mediarouter/res/values-gu-rIN/strings.xml
@@ -0,0 +1,29 @@
+<?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="5441529851481176817">"સિસ્ટમ"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"ઉપકરણો"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"કાસ્ટ કરો"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ઉપકરણ સાથે કનેક્ટ કરો"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"ઉપકરણો માટે શોધી રહ્યું છે…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ડિસ્કનેક્ટ કરો"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"કાસ્ટ કરવાનું રોકો"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"રૂટ સેટિંગ્સ"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"ચલાવો"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"થોભો"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-hi/strings.xml b/v7/mediarouter/res/values-hi/strings.xml
index 8acc2bb..6d100ea 100644
--- a/v7/mediarouter/res/values-hi/strings.xml
+++ b/v7/mediarouter/res/values-hi/strings.xml
@@ -17,9 +17,13 @@
<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="5441529851481176817">"सिस्टम"</string>
- <string name="mr_user_route_category_name" msgid="7498112907524977311">"उपकरण"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"मीडिया आउटपुट"</string>
- <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"उपकरण से कनेक्ट करें"</string>
- <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"उपकरणों की खोज हो रही है…"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"डिवाइस"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"कास्ट करें"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"डिवाइस से कनेक्ट करें"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"डिवाइस की खोज हो रही है…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"डिस्कनेक्ट करें"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"कास्ट करना बंद करें"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"मार्ग सेटिंग"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"चलाएं"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"रोकें"</string>
</resources>
diff --git a/v7/mediarouter/res/values-hr/strings.xml b/v7/mediarouter/res/values-hr/strings.xml
index 2946433..74e9270 100644
--- a/v7/mediarouter/res/values-hr/strings.xml
+++ b/v7/mediarouter/res/values-hr/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sustav"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Uređaji"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medijski izlaz"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Emitiranje"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Povezivanje s uređajem"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Traženje uređaja…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Prekini vezu"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Zaustavi emitiranje"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Postavke rute"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Reprodukcija"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pauziraj"</string>
</resources>
diff --git a/v7/mediarouter/res/values-hu/strings.xml b/v7/mediarouter/res/values-hu/strings.xml
index b68fe16..efbc193 100644
--- a/v7/mediarouter/res/values-hu/strings.xml
+++ b/v7/mediarouter/res/values-hu/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Rendszer"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Eszközök"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Médiakimenet"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Tartalomátküldés"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Csatlakozás adott eszközhöz"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Eszközkeresés…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Leválasztás"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Átküldés leállítása"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Útvonal-beállítások"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Indítás"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Szüneteltetés"</string>
</resources>
diff --git a/v7/mediarouter/res/values-hy-rAM/strings.xml b/v7/mediarouter/res/values-hy-rAM/strings.xml
index 77f1136..faa6020 100644
--- a/v7/mediarouter/res/values-hy-rAM/strings.xml
+++ b/v7/mediarouter/res/values-hy-rAM/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Համակարգ"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Սարքեր"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Մեդիա արտածում"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Հեռարձակում"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Միանալ սարքին"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Որոնվում են սարքեր..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Անջատել"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Դադարեցնել հեռարձակումը"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Ֆայլերի փոխանցման կարգավորումներ"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Նվագարկել"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Դադար"</string>
</resources>
diff --git a/v7/mediarouter/res/values-in/strings.xml b/v7/mediarouter/res/values-in/strings.xml
index 1d3b387..e3123c1 100644
--- a/v7/mediarouter/res/values-in/strings.xml
+++ b/v7/mediarouter/res/values-in/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Perangkat"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Keluaran media"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Transmisi"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Sambungkan ke perangkat"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Menelusuri perangkat…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Putuskan sambungan"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Hentikan transmisi"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Setelan rute"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Putar"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Jeda"</string>
</resources>
diff --git a/v7/mediarouter/res/values-is-rIS/strings.xml b/v7/mediarouter/res/values-is-rIS/strings.xml
index 45d7329..262e4e9 100644
--- a/v7/mediarouter/res/values-is-rIS/strings.xml
+++ b/v7/mediarouter/res/values-is-rIS/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Kerfi"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Tæki"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Margmiðlunarúttak"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Senda út"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Tengjast tæki"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Leitar að tækjum…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Aftengja"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Stöðva útsendingu"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Leiðarstillingar"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Spila"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Hlé"</string>
</resources>
diff --git a/v7/mediarouter/res/values-it/strings.xml b/v7/mediarouter/res/values-it/strings.xml
index bd58755..bedd617 100644
--- a/v7/mediarouter/res/values-it/strings.xml
+++ b/v7/mediarouter/res/values-it/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivi"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Uscita media"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Trasmetti"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connetti al dispositivo"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Ricerca di dispositivi…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Disconnetti"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Interrompi trasmissione"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Impostazioni percorso"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Riproduci"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pausa"</string>
</resources>
diff --git a/v7/mediarouter/res/values-iw/strings.xml b/v7/mediarouter/res/values-iw/strings.xml
index 59753b4..12d17b9 100644
--- a/v7/mediarouter/res/values-iw/strings.xml
+++ b/v7/mediarouter/res/values-iw/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"מערכת"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"מכשירים"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"פלט מדיה"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"העבר"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"התחבר למכשיר"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"מחפש מכשירים…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"התנתק"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"עצור העברה"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"הגדרות נתיב"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"הפעל"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"השהה"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ja/strings.xml b/v7/mediarouter/res/values-ja/strings.xml
index 1367489..e97a65a 100644
--- a/v7/mediarouter/res/values-ja/strings.xml
+++ b/v7/mediarouter/res/values-ja/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"システム"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"端末"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"メディア出力"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"キャスト"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"端末に接続"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"端末を検索しています…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"接続を解除"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"キャストを停止"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"ルーティング設定"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"再生"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"一時停止"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ka-rGE/strings.xml b/v7/mediarouter/res/values-ka-rGE/strings.xml
index 413257e..758fe73 100644
--- a/v7/mediarouter/res/values-ka-rGE/strings.xml
+++ b/v7/mediarouter/res/values-ka-rGE/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"სისტემა"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"მოწყობილობები"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"მედია გამოსასვლელი"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"მსახიობები"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"მოწყობილობასთან დაკავშირება"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"მოწყობილობების ძიება…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"კავშირის გაწყვეტა"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"ტრანსლაციის შეჩერება"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"მარშრუტის პარამეტრები"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"დაკვრა"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"პაუზა"</string>
</resources>
diff --git a/v7/mediarouter/res/values-kk-rKZ/strings.xml b/v7/mediarouter/res/values-kk-rKZ/strings.xml
index e8da02a..c549a8c 100644
--- a/v7/mediarouter/res/values-kk-rKZ/strings.xml
+++ b/v7/mediarouter/res/values-kk-rKZ/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Жүйе"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Құрылғылар"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Meдиа құрылғылары"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Трансляциялау"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Құрылғыға жалғау"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Құрылғыларды іздеуде…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Ажырату"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Трансляциялауды тоқтату"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Жол параметрлері"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Ойнату"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Кідірту"</string>
</resources>
diff --git a/v7/mediarouter/res/values-km-rKH/strings.xml b/v7/mediarouter/res/values-km-rKH/strings.xml
index e001dde..b3e53c5 100644
--- a/v7/mediarouter/res/values-km-rKH/strings.xml
+++ b/v7/mediarouter/res/values-km-rKH/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"ប្រព័ន្ធ"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"ឧបករណ៍"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"លទ្ធផលមេឌៀ"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"បញ្ជូន"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ភ្ជាប់ឧបករណ៍"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"កំពុងស្វែងរកឧបករណ៍..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ផ្ដាច់"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"បញ្ឈប់ការខាស"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"ការកំណត់ផ្លូវ"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"ចាក់"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"ផ្អាក"</string>
</resources>
diff --git a/v7/mediarouter/res/values-kn-rIN/strings.xml b/v7/mediarouter/res/values-kn-rIN/strings.xml
index 147ebc8..36c3aaa 100644
--- a/v7/mediarouter/res/values-kn-rIN/strings.xml
+++ b/v7/mediarouter/res/values-kn-rIN/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"ಸಿಸ್ಟಂ"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"ಸಾಧನಗಳು"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"ಮಾಧ್ಯಮ ಔಟ್ಪುಟ್"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"ಪಾತ್ರ"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ಸಾಧನಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಿ"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"ಸಾಧನಗಳನ್ನು ಹುಡುಕಲಾಗುತ್ತಿದೆ…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸು"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"ಬಿತ್ತರಿಸುವಿಕೆ ನಿಲ್ಲಿಸು"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"ಮಾರ್ಗ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"ಪ್ಲೇ ಮಾಡು"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"ವಿರಾಮ"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ko/strings.xml b/v7/mediarouter/res/values-ko/strings.xml
index 21f82a0..d165e52 100644
--- a/v7/mediarouter/res/values-ko/strings.xml
+++ b/v7/mediarouter/res/values-ko/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"시스템"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"기기"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"미디어 출력"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"전송"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"기기에 연결"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"기기 검색 중…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"연결 해제"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"전송 중지"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"경로 설정"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"재생"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"일시중지"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ky-rKG/strings.xml b/v7/mediarouter/res/values-ky-rKG/strings.xml
index 4a587ac..1f7aba0 100644
--- a/v7/mediarouter/res/values-ky-rKG/strings.xml
+++ b/v7/mediarouter/res/values-ky-rKG/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Систем"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Түзмөктөр"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Медиа чыгаруу"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Тандалгандар"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Түзмөккө туташуу"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Түзмөктөр изделүүдө..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Ажыратуу"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Тышк экранга чыгарну токтотуу"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Багыт жөндөөлөрү"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Ойнотуу"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Тындыруу"</string>
</resources>
diff --git a/v7/mediarouter/res/values-lo-rLA/strings.xml b/v7/mediarouter/res/values-lo-rLA/strings.xml
index 31a03cd..6d61f7d 100644
--- a/v7/mediarouter/res/values-lo-rLA/strings.xml
+++ b/v7/mediarouter/res/values-lo-rLA/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"ລະບົບ"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"ອຸປະກອນ"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"ມີເດຍເອົ້າພຸດ"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"ສົ່ງສັນຍານ"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ເຊື່ອມຕໍ່ຫາອຸປະກອນ"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"ກຳລັງຊອກຫາອຸປະກອນ..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ຕັດການເຊື່ອມຕໍ່"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"ຢຸດການສົ່ງສັນຍານ"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"ການຕັ້ງຄ່າເສັ້ນທາງ"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"ຫຼິ້ນ"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"ຢຸດຊົ່ວຄາວ"</string>
</resources>
diff --git a/v7/mediarouter/res/values-lt/strings.xml b/v7/mediarouter/res/values-lt/strings.xml
index ead3b73..2315618 100644
--- a/v7/mediarouter/res/values-lt/strings.xml
+++ b/v7/mediarouter/res/values-lt/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Įrenginiai"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medijos išvestis"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Perduoti"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Prijungimas prie įrenginio"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Ieškoma įrenginių…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Atjungti"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Sustabdyti perdavimą"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Maršruto nustatymai"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Leisti"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pristabdyti"</string>
</resources>
diff --git a/v7/mediarouter/res/values-lv/strings.xml b/v7/mediarouter/res/values-lv/strings.xml
index 0914990..93e45de 100644
--- a/v7/mediarouter/res/values-lv/strings.xml
+++ b/v7/mediarouter/res/values-lv/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistēma"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Ierīces"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Multivides izeja"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Apraidīt"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Savienojuma izveide ar ierīci"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Notiek ierīču meklēšana..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Atvienot"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Pārtraukt apraidi"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Maršruta iestatījumi"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Atskaņot"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Apturēt"</string>
</resources>
diff --git a/v7/mediarouter/res/values-mk-rMK/strings.xml b/v7/mediarouter/res/values-mk-rMK/strings.xml
index 363f16b..9b3f875 100644
--- a/v7/mediarouter/res/values-mk-rMK/strings.xml
+++ b/v7/mediarouter/res/values-mk-rMK/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Систем"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Уреди"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Излез за медиум"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Емитувај"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Поврзи се со уредот"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Се пребаруваат уреди..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Исклучи се"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Запри префрлување"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Поставки на маршрутата"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Репродуцирај"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Пауза"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ml-rIN/strings.xml b/v7/mediarouter/res/values-ml-rIN/strings.xml
index d20ba1d..64c74b1 100644
--- a/v7/mediarouter/res/values-ml-rIN/strings.xml
+++ b/v7/mediarouter/res/values-ml-rIN/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"സിസ്റ്റം"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"ഉപകരണങ്ങൾ"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"മീഡിയ ഔട്ട്പുട്ട്"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"കാസ്റ്റുചെയ്യുക"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ഉപകരണത്തിലേക്ക് കണക്റ്റുചെയ്യുക"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"ഉപകരണങ്ങൾക്കായി തിരയുന്നു…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"വിച്ഛേദിക്കുക"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"കാസ്റ്റുചെയ്യൽ നിർത്തുക"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"റൂട്ട് ക്രമീകരണം"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"പ്ലേ ചെയ്യുക"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"താൽക്കാലികമായി നിർത്തുക"</string>
</resources>
diff --git a/v7/mediarouter/res/values-mn-rMN/strings.xml b/v7/mediarouter/res/values-mn-rMN/strings.xml
index 4eecdb4..2074767 100644
--- a/v7/mediarouter/res/values-mn-rMN/strings.xml
+++ b/v7/mediarouter/res/values-mn-rMN/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Систем"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Төхөөрөмжүүд"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Медиа гаралт"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Дамжуулах"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Төхөөрөмжтэй холбох"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Төхөөрөмжүүдийг хайж байна…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Салгах"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Нэвтрүүлэхийг зогсоох"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Маршрут тохиргоо"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Тоглуулах"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Түр зогсоох"</string>
</resources>
diff --git a/v7/mediarouter/res/values-mr-rIN/strings.xml b/v7/mediarouter/res/values-mr-rIN/strings.xml
index 9187b5d..bd020a7 100644
--- a/v7/mediarouter/res/values-mr-rIN/strings.xml
+++ b/v7/mediarouter/res/values-mr-rIN/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"सिस्टम"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"डिव्हाइसेस"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"माध्यम आउटपुट"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"कास्ट करा"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"डिव्हाइसला कनेक्ट करा"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"डिव्हाइसेस शोधत आहे…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"डिस्कनेक्ट करा"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"कास्ट करणे थांबवा"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"मार्ग सेटिंग्ज"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"प्ले करा"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"विराम द्या"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ms-rMY/strings.xml b/v7/mediarouter/res/values-ms-rMY/strings.xml
index dadaa30..05e9ffa 100644
--- a/v7/mediarouter/res/values-ms-rMY/strings.xml
+++ b/v7/mediarouter/res/values-ms-rMY/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Peranti"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Output media"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Barisan pelakon"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Sambung kepada peranti"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Mencari peranti..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Putuskan sambungan"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Berhenti menghantar"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Tetapan laluan"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Main"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Jeda"</string>
</resources>
diff --git a/v7/mediarouter/res/values-my-rMM/strings.xml b/v7/mediarouter/res/values-my-rMM/strings.xml
index c417d57..20bfd8d 100644
--- a/v7/mediarouter/res/values-my-rMM/strings.xml
+++ b/v7/mediarouter/res/values-my-rMM/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"စနစ်"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"စက်ပစ္စည်းများ"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"မီဒီယာထွက်ပေါက်"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"သရုပ်ဆောင်များ"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"စက်တစ်ခုကို ချိတ်ဆက်ပါ"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"စက်ပစ္စည်းများကို ရှာဖွေနေပါသည်"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ချိတ်ဆက်ခြင်းရပ်တန့်ရန်"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"ပုံစံသွင်းမှု ရပ်ရန်"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"လမ်းကြောင်း အပြင်အဆင်များ"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"ဖွင့်ရန်"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"ခဏရပ်ရန်"</string>
</resources>
diff --git a/v7/mediarouter/res/values-nb/strings.xml b/v7/mediarouter/res/values-nb/strings.xml
index fa4d9a4..5ee8ec8 100644
--- a/v7/mediarouter/res/values-nb/strings.xml
+++ b/v7/mediarouter/res/values-nb/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Enheter"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medieutgang"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Cast"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Koble til enheten"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Søker etter enheter …"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Koble fra"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Stopp castingen"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Ruteinnstillinger"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Spill av"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Sett på pause"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ne-rNP/strings.xml b/v7/mediarouter/res/values-ne-rNP/strings.xml
index 3fe9ac3..aadcbcf 100644
--- a/v7/mediarouter/res/values-ne-rNP/strings.xml
+++ b/v7/mediarouter/res/values-ne-rNP/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"प्रणाली"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"उपकरणहरू"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"मिडियाको उत्पादन"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"कास्ट"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"उपकरणसँग जडान गर्नुहोस्"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"उपकरणहरूका लागि खोजी गरिँदै..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"विच्छेदन गर्नुहोस्"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"कास्टिंग रोक्नुहोस्"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"मार्ग सेटिङ"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"बजाउनुहोस्"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"रोक्नुहोस्"</string>
</resources>
diff --git a/v7/mediarouter/res/values-nl/strings.xml b/v7/mediarouter/res/values-nl/strings.xml
index 5572449..fcfac4d 100644
--- a/v7/mediarouter/res/values-nl/strings.xml
+++ b/v7/mediarouter/res/values-nl/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Systeem"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Apparaten"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Media-uitvoer"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Casten"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Verbinding maken met apparaat"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Zoeken naar apparaten…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Verbinding verbreken"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Casten stoppen"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Route-instellingen"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Afspelen"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Onderbreken"</string>
</resources>
diff --git a/v7/mediarouter/res/values-pa-rIN/strings.xml b/v7/mediarouter/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000..fb87320
--- /dev/null
+++ b/v7/mediarouter/res/values-pa-rIN/strings.xml
@@ -0,0 +1,29 @@
+<?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="5441529851481176817">"ਸਿਸਟਮ"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"ਡਿਵਾਈਸਾਂ"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"ਜੋੜੋ"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ਡਿਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"ਡਿਵਾਈਸਾਂ ਦੀ ਖੋਜ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"ਜੋੜਨਾ ਰੋਕੋ"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"ਰੂਟ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"ਪਲੇ ਕਰੋ"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"ਰੋਕੋ"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-pl/strings.xml b/v7/mediarouter/res/values-pl/strings.xml
index 95a1d03..34fea86 100644
--- a/v7/mediarouter/res/values-pl/strings.xml
+++ b/v7/mediarouter/res/values-pl/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Urządzenia"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Wyjście multimediów"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Przesyłaj"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Połącz z urządzeniem"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Szukam urządzeń…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Rozłącz"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Zakończ przesyłanie"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Ustawienia trasy"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Odtwórz"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Wstrzymaj"</string>
</resources>
diff --git a/v7/mediarouter/res/values-pt-rPT/strings.xml b/v7/mediarouter/res/values-pt-rPT/strings.xml
index 54b1dfc..1e1dbbb 100644
--- a/v7/mediarouter/res/values-pt-rPT/strings.xml
+++ b/v7/mediarouter/res/values-pt-rPT/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Saída de som multimédia"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Transmitir"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Ligar ao dispositivo"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"A pesquisar dispositivos…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desassociar"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Parar a transmissão"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Definições de trajeto"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Reproduzir"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Colocar em pausa"</string>
</resources>
diff --git a/v7/mediarouter/res/values-pt/strings.xml b/v7/mediarouter/res/values-pt/strings.xml
index 3ce1c38..67648a7 100644
--- a/v7/mediarouter/res/values-pt/strings.xml
+++ b/v7/mediarouter/res/values-pt/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Saída de mídia"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Transmitir"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Conectar ao dispositivo"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Procurando dispositivos…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desconectar"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Interromper transmissão"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Configurações de rota"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Reproduzir"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pausar"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ro/strings.xml b/v7/mediarouter/res/values-ro/strings.xml
index 4c9e4b9..d738bab 100644
--- a/v7/mediarouter/res/values-ro/strings.xml
+++ b/v7/mediarouter/res/values-ro/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispozitive"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Rezultate media"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Trimiteți"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Conectați-vă la dispozitiv"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Se caută dispozitive..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Deconectați-vă"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Nu mai proiectați"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Setări pentru traseu"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Redați"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Întrerupeți"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ru/strings.xml b/v7/mediarouter/res/values-ru/strings.xml
index 5cc2bba..dfa836c 100644
--- a/v7/mediarouter/res/values-ru/strings.xml
+++ b/v7/mediarouter/res/values-ru/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Система"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Устройства"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Перенаправлять поток мультимедиа"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Транслировать."</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Подключение к устройству"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Поиск устройств…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Отключить"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Остановить трансляцию"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Настройки передачи файлов"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Воспроизвести."</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Приостановить."</string>
</resources>
diff --git a/v7/mediarouter/res/values-si-rLK/strings.xml b/v7/mediarouter/res/values-si-rLK/strings.xml
index 2eba3c8..1ac7319 100644
--- a/v7/mediarouter/res/values-si-rLK/strings.xml
+++ b/v7/mediarouter/res/values-si-rLK/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"පද්ධතිය"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"උපාංග"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"මාධ්ය ප්රතිදානය"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Cast"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"උපාංගයට සම්බන්ධ වන්න"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"උපාංග සඳහා සොයමින්…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"විසන්ධි කරන්න"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"කාස්ට් කිරීම නවත්වන්න"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"ගමන් මගේ සැකසීම්"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"ධාවනය කරන්න"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"විරාමය"</string>
</resources>
diff --git a/v7/mediarouter/res/values-sk/strings.xml b/v7/mediarouter/res/values-sk/strings.xml
index 668800f..3156edf 100644
--- a/v7/mediarouter/res/values-sk/strings.xml
+++ b/v7/mediarouter/res/values-sk/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Systém"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Zariadenia"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Výstup médií"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Preniesť"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Pripojenie k zariadeniu"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Prebieha vyhľadávanie zariadení…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Odpojiť"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Zastaviť prenášanie"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Nastavenia trasy"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Prehrať"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pozastaviť"</string>
</resources>
diff --git a/v7/mediarouter/res/values-sl/strings.xml b/v7/mediarouter/res/values-sl/strings.xml
index 3e3e8bb..3de14aa 100644
--- a/v7/mediarouter/res/values-sl/strings.xml
+++ b/v7/mediarouter/res/values-sl/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Naprave"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Izhod za predstavnost"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Predvajanje"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Povezovanje z napravo"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Iskanje naprav …"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Prekini povezavo"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Ustavi predvajanje"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Nastavitve poti"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Predvajaj"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Zaustavi"</string>
</resources>
diff --git a/v7/mediarouter/res/values-sq-rAL/strings.xml b/v7/mediarouter/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000..2df43b1
--- /dev/null
+++ b/v7/mediarouter/res/values-sq-rAL/strings.xml
@@ -0,0 +1,29 @@
+<?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="5441529851481176817">"Sistemi"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Pajisjet"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Transmeto"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Lidhu me pajisjen"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Po kërkon për pajisje…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Shkëputu"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Ndalo transmetimin"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Cilësimet e rrugës"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Luaj"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pauzë"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-sr/strings.xml b/v7/mediarouter/res/values-sr/strings.xml
index 320f3e8..de10685 100644
--- a/v7/mediarouter/res/values-sr/strings.xml
+++ b/v7/mediarouter/res/values-sr/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Систем"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Уређаји"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Излаз медија"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Пребацуј"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Повежите са уређајем"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Претраживање уређаја…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Прекини везу"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Заустави пребацивање"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Подешавања путање"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Пусти"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Паузирај"</string>
</resources>
diff --git a/v7/mediarouter/res/values-sv/strings.xml b/v7/mediarouter/res/values-sv/strings.xml
index 910c6f1..3ac428a 100644
--- a/v7/mediarouter/res/values-sv/strings.xml
+++ b/v7/mediarouter/res/values-sv/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Enheter"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medieuppspelning"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Casta"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Anslut till enhet"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Söker efter enheter ..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Koppla från"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Sluta casta"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Inställningar för omdirigering"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Spela upp"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Pausa"</string>
</resources>
diff --git a/v7/mediarouter/res/values-sw/strings.xml b/v7/mediarouter/res/values-sw/strings.xml
index fcbc590..00ce337 100644
--- a/v7/mediarouter/res/values-sw/strings.xml
+++ b/v7/mediarouter/res/values-sw/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Mfumo"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Vifaa"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Towe la vyombo vya habari"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Tuma"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Unganisha kwenye kifaa"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Inatafuta vifaa..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Tenganisha"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Acha kutuma"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Mipangilio ya njia"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Google Play"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Sitisha"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ta-rIN/strings.xml b/v7/mediarouter/res/values-ta-rIN/strings.xml
index d5d1386..f92c432 100644
--- a/v7/mediarouter/res/values-ta-rIN/strings.xml
+++ b/v7/mediarouter/res/values-ta-rIN/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"அமைப்பு"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"சாதனங்கள்"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"மீடியா வெளியீடு"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"அனுப்பு"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"சாதனத்துடன் இணைக்கவும்"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"சாதனங்களைத் தேடுகிறது..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"துண்டி"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"அனுப்புவதை நிறுத்து"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"வழி அமைப்புகள்"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"இயக்கு"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"இடைநிறுத்து"</string>
</resources>
diff --git a/v7/mediarouter/res/values-te-rIN/strings.xml b/v7/mediarouter/res/values-te-rIN/strings.xml
index 9fa6e90..0913420 100644
--- a/v7/mediarouter/res/values-te-rIN/strings.xml
+++ b/v7/mediarouter/res/values-te-rIN/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"సిస్టమ్"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"పరికరాలు"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"మీడియా అవుట్పుట్"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"ప్రసారం చేయండి"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"పరికరానికి కనెక్ట్ చేయండి"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"పరికరాల కోసం శోధిస్తోంది…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"డిస్కనెక్ట్ చేయి"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"ప్రసారాన్ని ఆపివేయి"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"మార్గ సెట్టింగ్లు"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"ప్లే చేయి"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"పాజ్ చేయి"</string>
</resources>
diff --git a/v7/mediarouter/res/values-th/strings.xml b/v7/mediarouter/res/values-th/strings.xml
index 78e5a73..31fc9c7 100644
--- a/v7/mediarouter/res/values-th/strings.xml
+++ b/v7/mediarouter/res/values-th/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"ระบบ"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"อุปกรณ์"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"เอาต์พุตสื่อ"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"ส่ง"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"เชื่อมต่อกับอุปกรณ์"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"กำลังค้นหาอุปกรณ์…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ยกเลิกการเชื่อมต่อ"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"หยุดการส่ง"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"การตั้งค่าเส้นทาง"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"เล่น"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"หยุดชั่วคราว"</string>
</resources>
diff --git a/v7/mediarouter/res/values-tl/strings.xml b/v7/mediarouter/res/values-tl/strings.xml
index 0953787..d4896b5 100644
--- a/v7/mediarouter/res/values-tl/strings.xml
+++ b/v7/mediarouter/res/values-tl/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Mga Device"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Output ng media"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"I-cast"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Kumonekta sa device"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Naghahanap ng mga device…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Idiskonekta"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Itigil ang pagca-cast"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Mga setting ng ruta"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"I-play"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"I-pause"</string>
</resources>
diff --git a/v7/mediarouter/res/values-tr/strings.xml b/v7/mediarouter/res/values-tr/strings.xml
index 12faaa6..05344ff 100644
--- a/v7/mediarouter/res/values-tr/strings.xml
+++ b/v7/mediarouter/res/values-tr/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Cihazlar"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medya çıkışı"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Yayınla"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Cihaza bağlanın"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Cihaz arayın…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Bağlantıyı kes"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Yayını durdur"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Rota ayarları"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Oynat"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Duraklat"</string>
</resources>
diff --git a/v7/mediarouter/res/values-uk/strings.xml b/v7/mediarouter/res/values-uk/strings.xml
index b036dea..b445b9c 100644
--- a/v7/mediarouter/res/values-uk/strings.xml
+++ b/v7/mediarouter/res/values-uk/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Система"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Пристрої"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Вивід медіа-даних"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Транслювати"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Під’єднатися до пристрою"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Пошук пристроїв…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Від’єднатися"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Зупинити трансляцію"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Налаштування маршруту"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Відтворити"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Призупинити"</string>
</resources>
diff --git a/v7/mediarouter/res/values-ur-rPK/strings.xml b/v7/mediarouter/res/values-ur-rPK/strings.xml
index bce0e0c..e6ce4d6 100644
--- a/v7/mediarouter/res/values-ur-rPK/strings.xml
+++ b/v7/mediarouter/res/values-ur-rPK/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"سسٹم"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"آلات"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"میڈیا آؤٹ پٹ"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"کاسٹ کریں"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"آلہ سے مربوط ہوں"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"آلات تلاش کر رہا ہے…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"غیر مربوط کریں"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"کاسٹ کرنا بند کریں"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"روٹ کی ترتیبات"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"چلائیں"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"موقوف کریں"</string>
</resources>
diff --git a/v7/mediarouter/res/values-uz-rUZ/strings.xml b/v7/mediarouter/res/values-uz-rUZ/strings.xml
index f191fd9..d2829ee 100644
--- a/v7/mediarouter/res/values-uz-rUZ/strings.xml
+++ b/v7/mediarouter/res/values-uz-rUZ/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Tizim"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Qurilmalar"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Media chiqish"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Translatsiya qilish"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Qurilmaga ulanish"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Qurilmalar izlanmoqda…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Uzish"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Translatsiyani to‘xtatish"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Yo‘naltirish sozlamalari"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Ijro qilish"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"To‘xtatib turish"</string>
</resources>
diff --git a/v7/mediarouter/res/values-vi/strings.xml b/v7/mediarouter/res/values-vi/strings.xml
index a58d0e4..01ec106 100644
--- a/v7/mediarouter/res/values-vi/strings.xml
+++ b/v7/mediarouter/res/values-vi/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Hệ thống"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Thiết bị"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Đầu ra phương tiện"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Truyền"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Kết nối với thiết bị"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Đang tìm kiếm thiết bị…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Ngắt kết nối"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Ngừng truyền"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Cài đặt tuyến đường"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Phát"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Tạm dừng"</string>
</resources>
diff --git a/v7/mediarouter/res/values-zh-rCN/strings.xml b/v7/mediarouter/res/values-zh-rCN/strings.xml
index 71c4407..070f1de 100644
--- a/v7/mediarouter/res/values-zh-rCN/strings.xml
+++ b/v7/mediarouter/res/values-zh-rCN/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"系统"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"设备"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"媒体输出线路"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"投射"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"连接到设备"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"正在搜索设备…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"断开连接"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"停止投射"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"路由设置"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"播放"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"暂停"</string>
</resources>
diff --git a/v7/mediarouter/res/values-zh-rHK/strings.xml b/v7/mediarouter/res/values-zh-rHK/strings.xml
index f499169..a73d636 100644
--- a/v7/mediarouter/res/values-zh-rHK/strings.xml
+++ b/v7/mediarouter/res/values-zh-rHK/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"系統"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"裝置"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"媒體輸出"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"投放"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"連線至裝置"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"正在搜尋裝置…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"中斷連線"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"停止投放"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"路由設定"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"播放"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"暫停"</string>
</resources>
diff --git a/v7/mediarouter/res/values-zh-rTW/strings.xml b/v7/mediarouter/res/values-zh-rTW/strings.xml
index a847615..cb07c25 100644
--- a/v7/mediarouter/res/values-zh-rTW/strings.xml
+++ b/v7/mediarouter/res/values-zh-rTW/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"系統"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"裝置"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"媒體輸出"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"投放"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"連線至裝置"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"正在搜尋裝置..."</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"中斷連線"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"停止投放"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"路由設定"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"播放"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"暫停"</string>
</resources>
diff --git a/v7/mediarouter/res/values-zu/strings.xml b/v7/mediarouter/res/values-zu/strings.xml
index be195be..24f0a37 100644
--- a/v7/mediarouter/res/values-zu/strings.xml
+++ b/v7/mediarouter/res/values-zu/strings.xml
@@ -18,8 +18,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mr_system_route_name" msgid="5441529851481176817">"Isistimu"</string>
<string name="mr_user_route_category_name" msgid="7498112907524977311">"Amadivayisi"</string>
- <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Okukhiphayo kwabezindaba"</string>
+ <string name="mr_media_route_button_content_description" msgid="8327680881775995150">"Abalingisi"</string>
<string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Xhumeka kudivayisi"</string>
<string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Iseshela amadivayisi…"</string>
<string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Nqamula"</string>
+ <string name="mr_media_route_controller_stop" msgid="5398645111664294430">"Misa ukusakaza"</string>
+ <string name="mr_media_route_controller_settings_description" msgid="379358765881274425">"Izilungiselelo zomzila"</string>
+ <string name="mr_media_route_controller_play" msgid="5214423499524760404">"Dlala"</string>
+ <string name="mr_media_route_controller_pause" msgid="8315773974194466049">"Misa isikhashana"</string>
</resources>
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
index 896c116..8a5f507 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
@@ -356,7 +356,10 @@
}
}
- private void setRemoteIndicatorDrawable(Drawable d) {
+ /**
+ * Sets a drawable to use as the remote route indicator.
+ */
+ public void setRemoteIndicatorDrawable(Drawable d) {
if (mRemoteIndicator != null) {
mRemoteIndicator.setCallback(null);
unscheduleDrawable(mRemoteIndicator);
diff --git a/v7/preference/Android.mk b/v7/preference/Android.mk
new file mode 100644
index 0000000..e2db0f1
--- /dev/null
+++ b/v7/preference/Android.mk
@@ -0,0 +1,58 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# Build the resources using the current SDK version.
+# We do this here because the final static library must be compiled with an older
+# SDK version than the resources. The resources library and the R class that it
+# contains will not be linked into the final static library.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v7-preference-res
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, dummy)
+LOCAL_RESOURCE_DIR := \
+ frameworks/support/v7/appcompat/res \
+ frameworks/support/v7/recyclerview/res \
+ $(LOCAL_PATH)/res
+LOCAL_AAPT_FLAGS := \
+ --auto-add-overlay
+LOCAL_JAR_EXCLUDE_FILES := none
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Here is the final static library that apps can link against.
+# The R class is automatically excluded from the generated library.
+# Applications that use this library must specify LOCAL_RESOURCE_DIR
+# in their makefiles to include the resources in their package.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v7-preference
+LOCAL_SDK_VERSION := 7
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+# LOCAL_STATIC_JAVA_LIBRARIES :=
+LOCAL_JAVA_LIBRARIES := \
+ android-support-v4 \
+ android-support-v7-appcompat \
+ android-support-v7-recyclerview \
+ android-support-annotations \
+ android-support-v7-preference-res
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# API Check
+# ---------------------------------------------
+support_module := $(LOCAL_MODULE)
+support_module_api_dir := $(LOCAL_PATH)/api
+support_module_src_files := $(LOCAL_SRC_FILES)
+support_module_java_libraries := $(LOCAL_JAVA_LIBRARIES)
+support_module_java_packages := android.support.v7.preference
+include $(SUPPORT_API_CHECK)
diff --git a/v7/preference/AndroidManifest.xml b/v7/preference/AndroidManifest.xml
new file mode 100644
index 0000000..e5aa094
--- /dev/null
+++ b/v7/preference/AndroidManifest.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v7.preference"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="7" />
+ <application />
+</manifest>
diff --git a/v7/preference/api/current.txt b/v7/preference/api/current.txt
new file mode 100644
index 0000000..a432b43
--- /dev/null
+++ b/v7/preference/api/current.txt
@@ -0,0 +1,318 @@
+package android.support.v7.preference {
+
+ public class CheckBoxPreference extends android.support.v7.preference.TwoStatePreference {
+ ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet);
+ ctor public CheckBoxPreference(android.content.Context);
+ }
+
+ public abstract class DialogPreference extends android.support.v7.preference.Preference {
+ ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public DialogPreference(android.content.Context, android.util.AttributeSet);
+ ctor public DialogPreference(android.content.Context);
+ method public android.graphics.drawable.Drawable getDialogIcon();
+ method public int getDialogLayoutResource();
+ method public java.lang.CharSequence getDialogMessage();
+ method public java.lang.CharSequence getDialogTitle();
+ method public java.lang.CharSequence getNegativeButtonText();
+ method public java.lang.CharSequence getPositiveButtonText();
+ method public void setDialogIcon(android.graphics.drawable.Drawable);
+ method public void setDialogIcon(int);
+ method public void setDialogLayoutResource(int);
+ method public void setDialogMessage(java.lang.CharSequence);
+ method public void setDialogMessage(int);
+ method public void setDialogTitle(java.lang.CharSequence);
+ method public void setDialogTitle(int);
+ method public void setNegativeButtonText(java.lang.CharSequence);
+ method public void setNegativeButtonText(int);
+ method public void setPositiveButtonText(java.lang.CharSequence);
+ method public void setPositiveButtonText(int);
+ }
+
+ public static abstract interface DialogPreference.TargetFragment {
+ method public abstract android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ }
+
+ public class EditTextPreference extends android.support.v7.preference.DialogPreference {
+ ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public EditTextPreference(android.content.Context, android.util.AttributeSet);
+ ctor public EditTextPreference(android.content.Context);
+ method public java.lang.String getText();
+ method public void setText(java.lang.String);
+ }
+
+ public class EditTextPreferenceDialogFragmentCompat extends android.support.v7.preference.PreferenceDialogFragmentCompat {
+ ctor public EditTextPreferenceDialogFragmentCompat();
+ method public static android.support.v7.preference.EditTextPreferenceDialogFragmentCompat newInstance(java.lang.String);
+ method protected void onAddEditTextToDialogView(android.view.View, android.widget.EditText);
+ method public void onDialogClosed(boolean);
+ }
+
+ public class ListPreference extends android.support.v7.preference.DialogPreference {
+ ctor public ListPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public ListPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public ListPreference(android.content.Context, android.util.AttributeSet);
+ ctor public ListPreference(android.content.Context);
+ method public int findIndexOfValue(java.lang.String);
+ method public java.lang.CharSequence[] getEntries();
+ method public java.lang.CharSequence getEntry();
+ method public java.lang.CharSequence[] getEntryValues();
+ method public java.lang.String getValue();
+ method public void setEntries(java.lang.CharSequence[]);
+ method public void setEntries(int);
+ method public void setEntryValues(java.lang.CharSequence[]);
+ method public void setEntryValues(int);
+ method public void setValue(java.lang.String);
+ method public void setValueIndex(int);
+ }
+
+ public class ListPreferenceDialogFragmentCompat extends android.support.v7.preference.PreferenceDialogFragmentCompat {
+ ctor public ListPreferenceDialogFragmentCompat();
+ method public static android.support.v7.preference.ListPreferenceDialogFragmentCompat newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
+ public class Preference {
+ ctor public Preference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public Preference(android.content.Context, android.util.AttributeSet, int);
+ ctor public Preference(android.content.Context, android.util.AttributeSet);
+ ctor public Preference(android.content.Context);
+ method public boolean callChangeListener(java.lang.Object);
+ method public int compareTo(android.support.v7.preference.Preference);
+ method protected android.support.v7.preference.Preference findPreferenceInHierarchy(java.lang.String);
+ method public android.content.Context getContext();
+ method public java.lang.String getDependency();
+ method public android.os.Bundle getExtras();
+ method public java.lang.String getFragment();
+ method public android.graphics.drawable.Drawable getIcon();
+ method public android.content.Intent getIntent();
+ method public java.lang.String getKey();
+ method public final int getLayoutResource();
+ method public android.support.v7.preference.Preference.OnPreferenceChangeListener getOnPreferenceChangeListener();
+ method public android.support.v7.preference.Preference.OnPreferenceClickListener getOnPreferenceClickListener();
+ method public int getOrder();
+ method protected boolean getPersistedBoolean(boolean);
+ method protected float getPersistedFloat(float);
+ method protected int getPersistedInt(int);
+ method protected long getPersistedLong(long);
+ method protected java.lang.String getPersistedString(java.lang.String);
+ method public android.support.v7.preference.PreferenceManager getPreferenceManager();
+ method public android.content.SharedPreferences getSharedPreferences();
+ method public boolean getShouldDisableView();
+ method public java.lang.CharSequence getSummary();
+ method public java.lang.CharSequence getTitle();
+ method public final int getWidgetLayoutResource();
+ method public boolean hasKey();
+ method public boolean isEnabled();
+ method public boolean isPersistent();
+ method public boolean isSelectable();
+ method public final boolean isVisible();
+ method protected void notifyChanged();
+ method public void notifyDependencyChange(boolean);
+ method protected void notifyHierarchyChanged();
+ method protected void onAttached();
+ method protected void onAttachedToHierarchy(android.support.v7.preference.PreferenceManager);
+ method public void onBindViewHolder(android.support.v7.preference.PreferenceViewHolder);
+ method protected void onClick();
+ method public void onDependencyChanged(android.support.v7.preference.Preference, boolean);
+ method protected java.lang.Object onGetDefaultValue(android.content.res.TypedArray, int);
+ method public void onParentChanged(android.support.v7.preference.Preference, boolean);
+ method protected void onPrepareForRemoval();
+ method protected void onRestoreInstanceState(android.os.Parcelable);
+ method protected android.os.Parcelable onSaveInstanceState();
+ method protected void onSetInitialValue(boolean, java.lang.Object);
+ method public android.os.Bundle peekExtras();
+ method protected boolean persistBoolean(boolean);
+ method protected boolean persistFloat(float);
+ method protected boolean persistInt(int);
+ method protected boolean persistLong(long);
+ method protected boolean persistString(java.lang.String);
+ method public void restoreHierarchyState(android.os.Bundle);
+ method public void saveHierarchyState(android.os.Bundle);
+ method public void setDefaultValue(java.lang.Object);
+ method public void setDependency(java.lang.String);
+ method public void setEnabled(boolean);
+ method public void setFragment(java.lang.String);
+ method public void setIcon(android.graphics.drawable.Drawable);
+ method public void setIcon(int);
+ method public void setIntent(android.content.Intent);
+ method public void setKey(java.lang.String);
+ method public void setLayoutResource(int);
+ method public void setOnPreferenceChangeListener(android.support.v7.preference.Preference.OnPreferenceChangeListener);
+ method public void setOnPreferenceClickListener(android.support.v7.preference.Preference.OnPreferenceClickListener);
+ method public void setOrder(int);
+ method public void setPersistent(boolean);
+ method public void setSelectable(boolean);
+ method public void setShouldDisableView(boolean);
+ method public void setSummary(java.lang.CharSequence);
+ method public void setSummary(int);
+ method public void setTitle(java.lang.CharSequence);
+ method public void setTitle(int);
+ method public final void setVisible(boolean);
+ method public void setWidgetLayoutResource(int);
+ method public boolean shouldDisableDependents();
+ method protected boolean shouldPersist();
+ field public static final int DEFAULT_ORDER = 2147483647; // 0x7fffffff
+ }
+
+ public static class Preference.BaseSavedState extends android.view.AbsSavedState {
+ ctor public Preference.BaseSavedState(android.os.Parcel);
+ ctor public Preference.BaseSavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.v7.preference.Preference.BaseSavedState> CREATOR;
+ }
+
+ public static abstract interface Preference.OnPreferenceChangeListener {
+ method public abstract boolean onPreferenceChange(android.support.v7.preference.Preference, java.lang.Object);
+ }
+
+ public static abstract interface Preference.OnPreferenceClickListener {
+ method public abstract boolean onPreferenceClick(android.support.v7.preference.Preference);
+ }
+
+ public class PreferenceCategory extends android.support.v7.preference.PreferenceGroup {
+ ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int);
+ ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet);
+ ctor public PreferenceCategory(android.content.Context);
+ }
+
+ public abstract class PreferenceDialogFragmentCompat extends android.support.v4.app.DialogFragment implements android.content.DialogInterface.OnClickListener {
+ ctor public PreferenceDialogFragmentCompat();
+ method public android.support.v7.preference.DialogPreference getPreference();
+ method protected void onBindDialogView(android.view.View);
+ method public void onClick(android.content.DialogInterface, int);
+ method protected android.view.View onCreateDialogView(android.content.Context);
+ method public abstract void onDialogClosed(boolean);
+ method protected void onPrepareDialogBuilder(android.support.v7.app.AlertDialog.Builder);
+ field protected static final java.lang.String ARG_KEY = "key";
+ }
+
+ public abstract class PreferenceFragmentCompat extends android.support.v4.app.Fragment implements android.support.v7.preference.DialogPreference.TargetFragment android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener {
+ ctor public PreferenceFragmentCompat();
+ method public void addPreferencesFromResource(int);
+ method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ method public final android.support.v7.widget.RecyclerView getListView();
+ method public android.support.v7.preference.PreferenceManager getPreferenceManager();
+ method public android.support.v7.preference.PreferenceScreen getPreferenceScreen();
+ method protected android.support.v7.widget.RecyclerView.Adapter onCreateAdapter(android.support.v7.preference.PreferenceScreen);
+ method public android.support.v7.widget.RecyclerView.LayoutManager onCreateLayoutManager();
+ method public abstract void onCreatePreferences(android.os.Bundle, java.lang.String);
+ method public android.support.v7.widget.RecyclerView onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void onDisplayPreferenceDialog(android.support.v7.preference.Preference);
+ method public void onNavigateToScreen(android.support.v7.preference.PreferenceScreen);
+ method public boolean onPreferenceTreeClick(android.support.v7.preference.Preference);
+ method public void setPreferenceScreen(android.support.v7.preference.PreferenceScreen);
+ method public void setPreferencesFromResource(int, java.lang.String);
+ field public static final java.lang.String ARG_PREFERENCE_ROOT = "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT";
+ }
+
+ public static abstract interface PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {
+ method public abstract boolean onPreferenceDisplayDialog(android.support.v7.preference.PreferenceFragmentCompat, android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
+ method public abstract boolean onPreferenceStartFragment(android.support.v7.preference.PreferenceFragmentCompat, android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
+ method public abstract boolean onPreferenceStartScreen(android.support.v7.preference.PreferenceFragmentCompat, android.support.v7.preference.PreferenceScreen);
+ }
+
+ public abstract class PreferenceGroup extends android.support.v7.preference.Preference {
+ ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int);
+ ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet);
+ method public void addItemFromInflater(android.support.v7.preference.Preference);
+ method public boolean addPreference(android.support.v7.preference.Preference);
+ method protected void dispatchRestoreInstanceState(android.os.Bundle);
+ method protected void dispatchSaveInstanceState(android.os.Bundle);
+ method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ method public android.support.v7.preference.Preference getPreference(int);
+ method public int getPreferenceCount();
+ method protected boolean isOnSameScreenAsChildren();
+ method public boolean isOrderingAsAdded();
+ method protected boolean onPrepareAddPreference(android.support.v7.preference.Preference);
+ method public void removeAll();
+ method public boolean removePreference(android.support.v7.preference.Preference);
+ method public void setOrderingAsAdded(boolean);
+ }
+
+ public class PreferenceManager {
+ method public android.support.v7.preference.PreferenceScreen createPreferenceScreen(android.content.Context);
+ method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ method public static android.content.SharedPreferences getDefaultSharedPreferences(android.content.Context);
+ method public android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener getOnDisplayPreferenceDialogListener();
+ method public android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener getOnNavigateToScreenListener();
+ method public android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener getOnPreferenceTreeClickListener();
+ method public android.support.v7.preference.PreferenceScreen getPreferenceScreen();
+ method public android.content.SharedPreferences getSharedPreferences();
+ method public int getSharedPreferencesMode();
+ method public java.lang.String getSharedPreferencesName();
+ method public static void setDefaultValues(android.content.Context, int, boolean);
+ method public static void setDefaultValues(android.content.Context, java.lang.String, int, int, boolean);
+ method public void setOnDisplayPreferenceDialogListener(android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener);
+ method public void setOnNavigateToScreenListener(android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener);
+ method public void setOnPreferenceTreeClickListener(android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener);
+ method public boolean setPreferences(android.support.v7.preference.PreferenceScreen);
+ method public void setSharedPreferencesMode(int);
+ method public void setSharedPreferencesName(java.lang.String);
+ method public void showDialog(android.support.v7.preference.Preference);
+ field public static final java.lang.String KEY_HAS_SET_DEFAULT_VALUES = "_has_set_default_values";
+ }
+
+ public static abstract interface PreferenceManager.OnDisplayPreferenceDialogListener {
+ method public abstract void onDisplayPreferenceDialog(android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceManager.OnNavigateToScreenListener {
+ method public abstract void onNavigateToScreen(android.support.v7.preference.PreferenceScreen);
+ }
+
+ public static abstract interface PreferenceManager.OnPreferenceTreeClickListener {
+ method public abstract boolean onPreferenceTreeClick(android.support.v7.preference.Preference);
+ }
+
+ public final class PreferenceScreen extends android.support.v7.preference.PreferenceGroup {
+ }
+
+ public class PreferenceViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder {
+ method public android.view.View findViewById(int);
+ }
+
+ public class SwitchPreferenceCompat extends android.support.v7.preference.TwoStatePreference {
+ ctor public SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int);
+ ctor public SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet);
+ ctor public SwitchPreferenceCompat(android.content.Context);
+ method public java.lang.CharSequence getSwitchTextOff();
+ method public java.lang.CharSequence getSwitchTextOn();
+ method public void setSwitchTextOff(java.lang.CharSequence);
+ method public void setSwitchTextOff(int);
+ method public void setSwitchTextOn(java.lang.CharSequence);
+ method public void setSwitchTextOn(int);
+ }
+
+ public abstract class TwoStatePreference extends android.support.v7.preference.Preference {
+ ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet);
+ ctor public TwoStatePreference(android.content.Context);
+ method public boolean getDisableDependentsState();
+ method public java.lang.CharSequence getSummaryOff();
+ method public java.lang.CharSequence getSummaryOn();
+ method public boolean isChecked();
+ method public void setChecked(boolean);
+ method public void setDisableDependentsState(boolean);
+ method public void setSummaryOff(java.lang.CharSequence);
+ method public void setSummaryOff(int);
+ method public void setSummaryOn(java.lang.CharSequence);
+ method public void setSummaryOn(int);
+ method protected void syncSummaryView(android.support.v7.preference.PreferenceViewHolder);
+ field protected boolean mChecked;
+ }
+
+}
+
diff --git a/v7/preference/api/removed.txt b/v7/preference/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/v7/preference/api/removed.txt
diff --git a/v7/preference/build.gradle b/v7/preference/build.gradle
new file mode 100644
index 0000000..6576e5f
--- /dev/null
+++ b/v7/preference/build.gradle
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 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
+ */
+
+apply plugin: 'android-library'
+
+archivesBaseName = 'preference-v7'
+
+dependencies {
+ compile project(':support-v4')
+ compile project(':support-appcompat-v7')
+ compile project(':support-recyclerview-v7')
+}
+
+android {
+ compileSdkVersion 'current'
+
+ sourceSets {
+ main.manifest.srcFile 'AndroidManifest.xml'
+ main.java.srcDir 'src'
+ main.res.srcDir 'res'
+ main.assets.srcDir 'assets'
+ main.resources.srcDir 'src'
+
+ // this moves src/instrumentTest to tests so all folders follow:
+ // tests/java, tests/res, tests/assets, ...
+ // This is a *reset* so it replaces the default paths
+ androidTest.setRoot('tests')
+ androidTest.java.srcDir 'tests/src'
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
+ lintOptions {
+ // TODO: fix errors and reenable.
+ abortOnError false
+ }
+}
diff --git a/v7/preference/res/layout-v11/preference.xml b/v7/preference/res/layout-v11/preference.xml
new file mode 100644
index 0000000..dbf6210
--- /dev/null
+++ b/v7/preference/res/layout-v11/preference.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingEnd="?android:attr/scrollbarSize"
+ android:background="?android:attr/selectableItemBackground"
+ android:focusable="true" >
+
+ <FrameLayout
+ android:id="@+id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ />
+ </FrameLayout>
+
+ <RelativeLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="15dip"
+ android:layout_marginEnd="6dip"
+ android:layout_marginTop="6dip"
+ android:layout_marginBottom="6dip"
+ android:layout_weight="1">
+
+ <TextView android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textColor="?android:attr/textColorPrimary"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal" />
+
+ <TextView android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="4" />
+
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout android:id="@+id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/v7/preference/res/layout/preference.xml b/v7/preference/res/layout/preference.xml
new file mode 100644
index 0000000..9f610a3
--- /dev/null
+++ b/v7/preference/res/layout/preference.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingEnd="?android:attr/scrollbarSize"
+ android:background="@android:drawable/list_selector_background"
+ android:focusable="true" >
+
+ <FrameLayout
+ android:id="@+id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ />
+ </FrameLayout>
+
+ <RelativeLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="15dip"
+ android:layout_marginEnd="6dip"
+ android:layout_marginTop="6dip"
+ android:layout_marginBottom="6dip"
+ android:layout_weight="1">
+
+ <TextView android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textColor="?android:attr/textColorPrimary"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal" />
+
+ <TextView android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="4" />
+
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout android:id="@+id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/v7/preference/res/layout/preference_category.xml b/v7/preference/res/layout/preference_category.xml
new file mode 100644
index 0000000..280d952
--- /dev/null
+++ b/v7/preference/res/layout/preference_category.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- Layout used for PreferenceCategory in a PreferenceActivity. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:id="@+android:id/title"
+/>
diff --git a/v7/preference/res/layout/preference_dialog_edittext.xml b/v7/preference/res/layout/preference_dialog_edittext.xml
new file mode 100644
index 0000000..527a7de
--- /dev/null
+++ b/v7/preference/res/layout/preference_dialog_edittext.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginTop="48dp"
+ android:layout_marginBottom="48dp"
+ android:overScrollMode="ifContentScrolls">
+
+ <LinearLayout
+ android:id="@+id/edittext_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:orientation="vertical">
+
+ <TextView android:id="@android:id/message"
+ style="?android:attr/textAppearanceSmall"
+ android:layout_marginBottom="48dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textColor="?android:attr/textColorSecondary" />
+
+ </LinearLayout>
+
+</ScrollView>
diff --git a/v7/preference/res/layout/preference_information.xml b/v7/preference/res/layout/preference_information.xml
new file mode 100644
index 0000000..e3be382
--- /dev/null
+++ b/v7/preference/res/layout/preference_information.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- Layout for a Preference in a PreferenceActivity. The
+ Preference is able to place a specific widget for its particular
+ type in the "widget_frame" layout. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingEnd="?android:attr/scrollbarSize">
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16sp"
+ android:layout_marginEnd="6sp"
+ android:layout_marginTop="6sp"
+ android:layout_marginBottom="6sp"
+ android:layout_weight="1">
+
+ <TextView android:id="@+android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textColor="?android:attr/textColorSecondary" />
+
+ <TextView android:id="@+android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="2" />
+
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout android:id="@+android:id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/v7/preference/res/layout/preference_list_fragment.xml b/v7/preference/res/layout/preference_list_fragment.xml
new file mode 100644
index 0000000..44c5438
--- /dev/null
+++ b/v7/preference/res/layout/preference_list_fragment.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent" >
+
+ <FrameLayout
+ android:id="@+id/list_container"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <TextView android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ android:gravity="center"
+ android:visibility="gone" />
+
+</LinearLayout>
diff --git a/v7/preference/res/layout/preference_recyclerview.xml b/v7/preference/res/layout/preference_recyclerview.xml
new file mode 100644
index 0000000..13385e6
--- /dev/null
+++ b/v7/preference/res/layout/preference_recyclerview.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/list"
+ style="?attr/preferenceFragmentListStyle"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingTop="0dp"
+ android:paddingBottom="0dp"
+ android:clipToPadding="false" />
diff --git a/v7/preference/res/layout/preference_widget_checkbox.xml b/v7/preference/res/layout/preference_widget_checkbox.xml
new file mode 100644
index 0000000..e53b7df
--- /dev/null
+++ b/v7/preference/res/layout/preference_widget_checkbox.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<!-- Layout used by CheckBoxPreference for the checkbox style. This is inflated
+ inside android.R.layout.preference. -->
+<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:focusable="false"
+ android:clickable="false"
+ android:background="@null" />
diff --git a/v7/preference/res/layout/preference_widget_switch_compat.xml b/v7/preference/res/layout/preference_widget_switch_compat.xml
new file mode 100644
index 0000000..3324073
--- /dev/null
+++ b/v7/preference/res/layout/preference_widget_switch_compat.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<!-- Layout used by SwitchPreference for the switch widget style. This is inflated
+ inside android.R.layout.preference. -->
+<android.support.v7.widget.SwitchCompat xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/switchWidget"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:focusable="false"
+ android:clickable="false"
+ android:background="@null" />
diff --git a/v7/preference/res/values-v17/styles.xml b/v7/preference/res/values-v17/styles.xml
new file mode 100644
index 0000000..20168b2
--- /dev/null
+++ b/v7/preference/res/values-v17/styles.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<resources>
+ <style name="PreferenceFragment">
+ <item name="android:paddingStart">0dp</item>
+ <item name="android:paddingEnd">0dp</item>
+ </style>
+
+ <style name="PreferenceFragmentList">
+ <item name="android:paddingStart">16dp</item>
+ <item name="android:paddingEnd">16dp</item>
+ </style>
+
+</resources>
diff --git a/v7/preference/res/values/attrs.xml b/v7/preference/res/values/attrs.xml
new file mode 100644
index 0000000..b93c1e6
--- /dev/null
+++ b/v7/preference/res/values/attrs.xml
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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>
+ <declare-styleable name="Theme">
+
+ <!-- =================== -->
+ <!-- Preference styles -->
+ <!-- =================== -->
+ <eat-comment />
+
+ <!-- Theme for inflating Preference objects -->
+ <attr name="preferenceTheme" format="reference" />
+
+ <!-- Default style for PreferenceScreen. -->
+ <attr name="preferenceScreenStyle" format="reference" />
+ <!-- Default style for the PreferenceActivity. -->
+ <attr name="preferenceActivityStyle" format="reference" />
+ <!-- Default style for Headers pane in PreferenceActivity. -->
+ <attr name="preferenceFragmentStyle" format="reference" />
+ <!-- Default style for PreferenceCategory. -->
+ <attr name="preferenceCategoryStyle" format="reference" />
+ <!-- Default style for Preference. -->
+ <attr name="preferenceStyle" format="reference" />
+ <!-- Default style for informational Preference. -->
+ <attr name="preferenceInformationStyle" format="reference" />
+ <!-- Default style for CheckBoxPreference. -->
+ <attr name="checkBoxPreferenceStyle" format="reference" />
+ <!-- Default style for YesNoPreference. -->
+ <attr name="yesNoPreferenceStyle" format="reference" />
+ <!-- Default style for DialogPreference. -->
+ <attr name="dialogPreferenceStyle" format="reference" />
+ <!-- Default style for EditTextPreference. -->
+ <attr name="editTextPreferenceStyle" format="reference" />
+ <!-- Default style for RingtonePreference. -->
+ <attr name="ringtonePreferenceStyle" format="reference" />
+ <!-- The preference layout that has the child/tabbed effect. -->
+ <attr name="preferenceLayoutChild" format="reference" />
+ <!-- Preference panel style -->
+ <attr name="preferencePanelStyle" format="reference" />
+ <!-- Preference headers panel style -->
+ <attr name="preferenceHeaderPanelStyle" format="reference" />
+ <!-- Preference list style -->
+ <attr name="preferenceListStyle" format="reference" />
+ <!-- Preference fragment list style -->
+ <attr name="preferenceFragmentListStyle" format="reference" />
+ <!-- Preference fragment padding side -->
+ <attr name="preferenceFragmentPaddingSide" format="dimension" />
+ <!-- Default style for switch preferences. -->
+ <attr name="switchPreferenceStyle" format="reference" />
+ <!-- Default style for switch compat preferences. -->
+ <attr name="switchPreferenceCompatStyle" format="reference" />
+ <!-- Default style for seekbar preferences. -->
+ <attr name="seekBarPreferenceStyle" format="reference" />
+ </declare-styleable>
+
+ <!-- Base attributes available to PreferenceFragment. -->
+ <declare-styleable name="PreferenceFragmentCompat">
+ <!-- The layout for the PreferenceFragment. This should rarely need to be changed. -->
+ <attr name="layout" />
+ <attr name="android:layout" />
+ </declare-styleable>
+
+ <!-- Base attributes available to PreferenceGroup. -->
+ <declare-styleable name="PreferenceGroup">
+ <!-- Whether to order the Preference under this group as they appear in the XML file.
+ If this is false, the ordering will follow the Preference order attribute and
+ default to alphabetic for those without the order attribute. -->
+ <attr name="orderingFromXml" format="boolean" />
+ <attr name="android:orderingFromXml" />
+ </declare-styleable>
+
+ <!-- Base attributes available to Preference. -->
+ <declare-styleable name="Preference">
+ <!-- The optional icon for the preference -->
+ <attr name="icon" />
+ <attr name="android:icon" />
+ <!-- The key to store the Preference value. -->
+ <attr name="key" format="string" />
+ <attr name="android:key" />
+ <!-- The title for the Preference in a PreferenceActivity screen. -->
+ <attr name="title" />
+ <attr name="android:title" />
+ <!-- The summary for the Preference in a PreferenceActivity screen. -->
+ <attr name="summary" format="string" />
+ <attr name="android:summary" />
+ <!-- The order for the Preference (lower values are to be ordered first). If this is not
+ specified, the default ordering will be alphabetic. -->
+ <attr name="order" format="integer" />
+ <attr name="android:order" />
+ <!-- When used inside of a modern PreferenceActivity, this declares
+ a new PreferenceFragment to be shown when the user selects this item. -->
+ <attr name="fragment" format="string" />
+ <attr name="android:fragment" />
+ <!-- The layout for the Preference in a PreferenceActivity screen. This should
+ rarely need to be changed, look at widgetLayout instead. -->
+ <attr name="layout" />
+ <attr name="android:layout" />
+ <!-- The layout for the controllable widget portion of a Preference. This is inflated
+ into the layout for a Preference and should be used more frequently than
+ the layout attribute. For example, a checkbox preference would specify
+ a custom layout (consisting of just the CheckBox) here. -->
+ <attr name="widgetLayout" format="reference" />
+ <attr name="android:widgetLayout" />
+ <!-- Whether the Preference is enabled. -->
+ <attr name="enabled" format="boolean" />
+ <attr name="android:enabled" />
+ <!-- Whether the Preference is selectable. -->
+ <attr name="selectable" format="boolean" />
+ <attr name="android:selectable" />
+ <!-- The key of another Preference that this Preference will depend on. If the other
+ Preference is not set or is off, this Preference will be disabled. -->
+ <attr name="dependency" format="string" />
+ <attr name="android:dependency" />
+ <!-- Whether the Preference stores its value to the shared preferences. -->
+ <attr name="persistent" format="boolean" />
+ <attr name="android:persistent" />
+ <!-- The default value for the preference, which will be set either if persistence
+ is off or persistence is on and the preference is not found in the persistent
+ storage. -->
+ <attr name="defaultValue" format="string|boolean|integer|reference|float" />
+ <attr name="android:defaultValue" />
+ <!-- Whether the view of this Preference should be disabled when
+ this Preference is disabled. -->
+ <attr name="shouldDisableView" format="boolean" />
+ <attr name="android:shouldDisableView" />
+ </declare-styleable>
+
+ <!-- Base attributes available to CheckBoxPreference. -->
+ <declare-styleable name="CheckBoxPreference">
+ <!-- The summary for the Preference in a PreferenceActivity screen when the
+ CheckBoxPreference is checked. If separate on/off summaries are not
+ needed, the summary attribute can be used instead. -->
+ <attr name="summaryOn" format="string" />
+ <attr name="android:summaryOn" />
+ <!-- The summary for the Preference in a PreferenceActivity screen when the
+ CheckBoxPreference is unchecked. If separate on/off summaries are not
+ needed, the summary attribute can be used instead. -->
+ <attr name="summaryOff" format="string" />
+ <attr name="android:summaryOff" />
+ <!-- The state (true for on, or false for off) that causes dependents to be disabled. By default,
+ dependents will be disabled when this is unchecked, so the value of this preference is false. -->
+ <attr name="disableDependentsState" format="boolean" />
+ <attr name="android:disableDependentsState" />
+ </declare-styleable>
+
+ <!-- Base attributes available to DialogPreference. -->
+ <declare-styleable name="DialogPreference">
+ <!-- The title in the dialog. -->
+ <attr name="dialogTitle" format="string" />
+ <attr name="android:dialogTitle" />
+ <!-- The message in the dialog. If a dialogLayout is provided and contains
+ a TextView with ID android:id/message, this message will be placed in there. -->
+ <attr name="dialogMessage" format="string" />
+ <attr name="android:dialogMessage" />
+ <!-- The icon for the dialog. -->
+ <attr name="dialogIcon" format="reference" />
+ <attr name="android:dialogIcon" />
+ <!-- The positive button text for the dialog. Set to @null to hide the positive button. -->
+ <attr name="positiveButtonText" format="string" />
+ <attr name="android:positiveButtonText" />
+ <!-- The negative button text for the dialog. Set to @null to hide the negative button. -->
+ <attr name="negativeButtonText" format="string" />
+ <attr name="android:negativeButtonText" />
+ <!-- A layout to be used as the content View for the dialog. By default, this shouldn't
+ be needed. If a custom DialogPreference is required, this should be set. For example,
+ the EditTextPreference uses a layout with an EditText as this attribute. -->
+ <attr name="dialogLayout" format="reference" />
+ <attr name="android:dialogLayout" />
+ </declare-styleable>
+
+ <!-- Base attributes available to ListPreference. -->
+ <declare-styleable name="ListPreference">
+ <!-- The human-readable array to present as a list. Each entry must have a corresponding
+ index in entryValues. -->
+ <attr name="entries" format="reference" />
+ <attr name="android:entries" />
+ <!-- The array to find the value to save for a preference when an entry from
+ entries is selected. If a user clicks on the second item in entries, the
+ second item in this array will be saved to the preference. -->
+ <attr name="entryValues" format="reference" />
+ <attr name="android:entryValues" />
+ </declare-styleable>
+
+ <declare-styleable name="MultiSelectListPreference">
+ <!-- The human-readable array to present as a list. Each entry must have a corresponding
+ index in entryValues. -->
+ <attr name="entries" />
+ <attr name="android:entries" />
+ <!-- The array to find the value to save for a preference when an entry from
+ entries is selected. If a user clicks the second item in entries, the
+ second item in this array will be saved to the preference. -->
+ <attr name="entryValues" />
+ <attr name="android:entryValues" />
+ </declare-styleable>
+
+ <declare-styleable name="SwitchPreferenceCompat">
+ <!-- The summary for the Preference in a PreferenceActivity screen when the
+ SwitchPreference is checked. If separate on/off summaries are not
+ needed, the summary attribute can be used instead. -->
+ <attr name="summaryOn" />
+ <attr name="android:summaryOn" />
+ <!-- The summary for the Preference in a PreferenceActivity screen when the
+ SwitchPreference is unchecked. If separate on/off summaries are not
+ needed, the summary attribute can be used instead. -->
+ <attr name="summaryOff" />
+ <attr name="android:summaryOff" />
+ <!-- The text used on the switch itself when in the "on" state.
+ This should be a very SHORT string, as it appears in a small space. -->
+ <attr name="switchTextOn" format="string" />
+ <attr name="android:switchTextOn" />
+ <!-- The text used on the switch itself when in the "off" state.
+ This should be a very SHORT string, as it appears in a small space. -->
+ <attr name="switchTextOff" format="string" />
+ <attr name="android:switchTextOff" />
+ <!-- The state (true for on, or false for off) that causes dependents to be disabled. By default,
+ dependents will be disabled when this is unchecked, so the value of this preference is false. -->
+ <attr name="disableDependentsState" />
+ <attr name="android:disableDependentsState" />
+ </declare-styleable>
+
+ <declare-styleable name="PreferenceImageView">
+ <attr name="maxWidth" format="dimension" />
+ <attr name="android:maxWidth" />
+ <attr name="maxHeight" format="dimension" />
+ <attr name="android:maxHeight" />
+ </declare-styleable>
+
+</resources>
diff --git a/v7/preference/res/values/strings.xml b/v7/preference/res/values/strings.xml
new file mode 100644
index 0000000..3414e44
--- /dev/null
+++ b/v7/preference/res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="v7_preference_on">ON</string>
+ <string name="v7_preference_off">OFF</string>
+</resources>
diff --git a/v7/preference/res/values/styles.xml b/v7/preference/res/values/styles.xml
new file mode 100644
index 0000000..3af31a4
--- /dev/null
+++ b/v7/preference/res/values/styles.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<resources>
+ <style name="Preference">
+ <item name="layout">@layout/preference</item>
+ </style>
+
+ <style name="PreferenceFragment">
+ <item name="android:paddingLeft">0dp</item>
+ <item name="android:paddingRight">0dp</item>
+ </style>
+
+ <style name="Preference.Information">
+ <item name="layout">@layout/preference_information</item>
+ <item name="enabled">false</item>
+ <item name="shouldDisableView">false</item>
+ </style>
+
+ <style name="Preference.Category">
+ <item name="layout">@layout/preference_category</item>
+ <!-- The title should not dim if the category is disabled, instead only the preference children should dim. -->
+ <item name="shouldDisableView">false</item>
+ <item name="selectable">false</item>
+ </style>
+
+ <style name="Preference.CheckBoxPreference">
+ <item name="widgetLayout">@layout/preference_widget_checkbox</item>
+ </style>
+
+ <style name="Preference.SwitchPreferenceCompat">
+ <item name="widgetLayout">@layout/preference_widget_switch_compat</item>
+ <item name="switchTextOn">@string/v7_preference_on</item>
+ <item name="switchTextOff">@string/v7_preference_off</item>
+ </style>
+
+ <style name="Preference.PreferenceScreen">
+ </style>
+
+ <style name="Preference.DialogPreference">
+ <item name="positiveButtonText">@android:string/ok</item>
+ <item name="negativeButtonText">@android:string/cancel</item>
+ </style>
+
+ <style name="Preference.DialogPreference.EditTextPreference">
+ <item name="dialogLayout">@layout/preference_dialog_edittext</item>
+ </style>
+
+ <style name="PreferenceFragmentList">
+ <item name="android:paddingLeft">16dp</item>
+ <item name="android:paddingRight">16dp</item>
+ </style>
+</resources>
diff --git a/v7/preference/res/values/themes.xml b/v7/preference/res/values/themes.xml
new file mode 100644
index 0000000..c2c2c3c
--- /dev/null
+++ b/v7/preference/res/values/themes.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<resources>
+ <style name="PreferenceThemeOverlay">
+ <item name="preferenceScreenStyle">@style/Preference.PreferenceScreen</item>
+ <item name="preferenceFragmentStyle">@style/PreferenceFragment</item>
+ <item name="preferenceCategoryStyle">@style/Preference.Category</item>
+ <item name="preferenceStyle">@style/Preference</item>
+ <item name="preferenceInformationStyle">@style/Preference.Information</item>
+ <item name="checkBoxPreferenceStyle">@style/Preference.CheckBoxPreference</item>
+ <item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat</item>
+ <item name="dialogPreferenceStyle">@style/Preference.DialogPreference</item>
+ <item name="editTextPreferenceStyle">@style/Preference.DialogPreference.EditTextPreference</item>
+ <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList</item>
+ </style>
+</resources>
diff --git a/v7/preference/src/android/support/v7/internal/widget/PreferenceImageView.java b/v7/preference/src/android/support/v7/internal/widget/PreferenceImageView.java
new file mode 100644
index 0000000..e3d430d
--- /dev/null
+++ b/v7/preference/src/android/support/v7/internal/widget/PreferenceImageView.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 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.v7.internal.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.v7.preference.R;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+/**
+ * Extension of ImageView that correctly applies maxWidth and maxHeight.
+ * @hide
+ */
+public class PreferenceImageView extends ImageView {
+
+ private int mMaxWidth = Integer.MAX_VALUE;
+ private int mMaxHeight = Integer.MAX_VALUE;
+
+ public PreferenceImageView(Context context) {
+ this(context, null);
+ }
+
+ public PreferenceImageView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public PreferenceImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.PreferenceImageView, defStyleAttr, 0);
+
+ setMaxWidth(a.getDimensionPixelSize(
+ R.styleable.PreferenceImageView_maxWidth, Integer.MAX_VALUE));
+
+ setMaxHeight(a.getDimensionPixelSize(
+ R.styleable.PreferenceImageView_maxHeight, Integer.MAX_VALUE));
+
+ a.recycle();
+ }
+
+// public PreferenceImageView(Context context, AttributeSet attrs, int defStyleAttr,
+// int defStyleRes) {
+// super(context, attrs, defStyleAttr, defStyleRes);
+// }
+
+ @Override
+ public void setMaxWidth(int maxWidth) {
+ mMaxWidth = maxWidth;
+ super.setMaxWidth(maxWidth);
+ }
+
+ public int getMaxWidth() {
+ return mMaxWidth;
+ }
+
+ @Override
+ public void setMaxHeight(int maxHeight) {
+ mMaxHeight = maxHeight;
+ super.setMaxHeight(maxHeight);
+ }
+
+ public int getMaxHeight() {
+ return mMaxHeight;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED) {
+ final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ final int maxWidth = getMaxWidth();
+ if (maxWidth != Integer.MAX_VALUE
+ && (maxWidth < widthSize || widthMode == MeasureSpec.UNSPECIFIED)) {
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST);
+ }
+ }
+
+ final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ if (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED) {
+ final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+ final int maxHeight = getMaxHeight();
+ if (maxHeight != Integer.MAX_VALUE
+ && (maxHeight < heightSize || heightMode == MeasureSpec.UNSPECIFIED)) {
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
+ }
+ }
+
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+}
diff --git a/v7/preference/src/android/support/v7/preference/CheckBoxPreference.java b/v7/preference/src/android/support/v7/preference/CheckBoxPreference.java
new file mode 100644
index 0000000..f49b0d6
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/CheckBoxPreference.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Checkable;
+
+/**
+ * A {@link Preference} that provides checkbox widget
+ * functionality.
+ * <p>
+ * This preference will store a boolean into the SharedPreferences.
+ *
+ * @attr ref android.R.styleable#CheckBoxPreference_summaryOff
+ * @attr ref android.R.styleable#CheckBoxPreference_summaryOn
+ * @attr ref android.R.styleable#CheckBoxPreference_disableDependentsState
+ */
+public class CheckBoxPreference extends TwoStatePreference {
+
+ public CheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public CheckBoxPreference(
+ Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ final TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.CheckBoxPreference, defStyleAttr, defStyleRes);
+
+ setSummaryOn(TypedArrayUtils.getString(a, R.styleable.CheckBoxPreference_summaryOn,
+ R.styleable.CheckBoxPreference_android_summaryOn));
+
+ setSummaryOff(TypedArrayUtils.getString(a, R.styleable.CheckBoxPreference_summaryOff,
+ R.styleable.CheckBoxPreference_android_summaryOff));
+
+ setDisableDependentsState(TypedArrayUtils.getBoolean(a,
+ R.styleable.CheckBoxPreference_disableDependentsState,
+ R.styleable.CheckBoxPreference_android_disableDependentsState, false));
+
+ a.recycle();
+ }
+
+ public CheckBoxPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.checkBoxPreferenceStyle);
+ }
+
+ public CheckBoxPreference(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ View checkboxView = holder.findViewById(R.id.checkbox);
+ if (checkboxView != null && checkboxView instanceof Checkable) {
+ ((Checkable) checkboxView).setChecked(mChecked);
+ }
+
+ syncSummaryView(holder);
+ }
+}
diff --git a/v7/preference/src/android/support/v7/preference/DialogPreference.java b/v7/preference/src/android/support/v7/preference/DialogPreference.java
new file mode 100644
index 0000000..bf0f4ef
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/DialogPreference.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * A base class for {@link Preference} objects that are
+ * dialog-based. These preferences will, when clicked, open a dialog showing the
+ * actual preference controls.
+ *
+ * @attr ref android.R.styleable#DialogPreference_dialogTitle
+ * @attr ref android.R.styleable#DialogPreference_dialogMessage
+ * @attr ref android.R.styleable#DialogPreference_dialogIcon
+ * @attr ref android.R.styleable#DialogPreference_dialogLayout
+ * @attr ref android.R.styleable#DialogPreference_positiveButtonText
+ * @attr ref android.R.styleable#DialogPreference_negativeButtonText
+ */
+public abstract class DialogPreference extends Preference {
+
+ public interface TargetFragment {
+ Preference findPreference(CharSequence key);
+ }
+
+ private CharSequence mDialogTitle;
+ private CharSequence mDialogMessage;
+ private Drawable mDialogIcon;
+ private CharSequence mPositiveButtonText;
+ private CharSequence mNegativeButtonText;
+ private int mDialogLayoutResId;
+
+ public DialogPreference(
+ Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ final TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.DialogPreference, defStyleAttr, defStyleRes);
+
+ mDialogTitle = TypedArrayUtils.getString(a, R.styleable.DialogPreference_dialogTitle,
+ R.styleable.DialogPreference_android_dialogTitle);
+ if (mDialogTitle == null) {
+ // Fall back on the regular title of the preference
+ // (the one that is seen in the list)
+ mDialogTitle = getTitle();
+ }
+
+ mDialogMessage = TypedArrayUtils.getString(a, R.styleable.DialogPreference_dialogMessage,
+ R.styleable.DialogPreference_android_dialogMessage);
+
+ mDialogIcon = TypedArrayUtils.getDrawable(a, R.styleable.DialogPreference_dialogIcon,
+ R.styleable.DialogPreference_android_dialogIcon);
+
+ mPositiveButtonText = TypedArrayUtils.getString(a,
+ R.styleable.DialogPreference_positiveButtonText,
+ R.styleable.DialogPreference_android_positiveButtonText);
+
+ mNegativeButtonText = TypedArrayUtils.getString(a,
+ R.styleable.DialogPreference_negativeButtonText,
+ R.styleable.DialogPreference_android_negativeButtonText);
+
+ mDialogLayoutResId = TypedArrayUtils.getResourceId(a,
+ R.styleable.DialogPreference_dialogLayout,
+ R.styleable.DialogPreference_android_dialogLayout, 0);
+
+ a.recycle();
+ }
+
+ public DialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public DialogPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.dialogPreferenceStyle);
+ }
+
+ public DialogPreference(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Sets the title of the dialog. This will be shown on subsequent dialogs.
+ *
+ * @param dialogTitle The title.
+ */
+ public void setDialogTitle(CharSequence dialogTitle) {
+ mDialogTitle = dialogTitle;
+ }
+
+ /**
+ * @see #setDialogTitle(CharSequence)
+ * @param dialogTitleResId The dialog title as a resource.
+ */
+ public void setDialogTitle(int dialogTitleResId) {
+ setDialogTitle(getContext().getString(dialogTitleResId));
+ }
+
+ /**
+ * Returns the title to be shown on subsequent dialogs.
+ * @return The title.
+ */
+ public CharSequence getDialogTitle() {
+ return mDialogTitle;
+ }
+
+ /**
+ * Sets the message of the dialog. This will be shown on subsequent dialogs.
+ * <p>
+ * This message forms the content View of the dialog and conflicts with
+ * list-based dialogs, for example. If setting a custom View on a dialog via
+ * {@link #setDialogLayoutResource(int)}, include a text View with ID
+ * {@link android.R.id#message} and it will be populated with this message.
+ *
+ * @param dialogMessage The message.
+ */
+ public void setDialogMessage(CharSequence dialogMessage) {
+ mDialogMessage = dialogMessage;
+ }
+
+ /**
+ * @see #setDialogMessage(CharSequence)
+ * @param dialogMessageResId The dialog message as a resource.
+ */
+ public void setDialogMessage(int dialogMessageResId) {
+ setDialogMessage(getContext().getString(dialogMessageResId));
+ }
+
+ /**
+ * Returns the message to be shown on subsequent dialogs.
+ * @return The message.
+ */
+ public CharSequence getDialogMessage() {
+ return mDialogMessage;
+ }
+
+ /**
+ * Sets the icon of the dialog. This will be shown on subsequent dialogs.
+ *
+ * @param dialogIcon The icon, as a {@link Drawable}.
+ */
+ public void setDialogIcon(Drawable dialogIcon) {
+ mDialogIcon = dialogIcon;
+ }
+
+ /**
+ * Sets the icon (resource ID) of the dialog. This will be shown on
+ * subsequent dialogs.
+ *
+ * @param dialogIconRes The icon, as a resource ID.
+ */
+ public void setDialogIcon(int dialogIconRes) {
+ mDialogIcon = ContextCompat.getDrawable(getContext(), dialogIconRes);
+ }
+
+ /**
+ * Returns the icon to be shown on subsequent dialogs.
+ * @return The icon, as a {@link Drawable}.
+ */
+ public Drawable getDialogIcon() {
+ return mDialogIcon;
+ }
+
+ /**
+ * Sets the text of the positive button of the dialog. This will be shown on
+ * subsequent dialogs.
+ *
+ * @param positiveButtonText The text of the positive button.
+ */
+ public void setPositiveButtonText(CharSequence positiveButtonText) {
+ mPositiveButtonText = positiveButtonText;
+ }
+
+ /**
+ * @see #setPositiveButtonText(CharSequence)
+ * @param positiveButtonTextResId The positive button text as a resource.
+ */
+ public void setPositiveButtonText(int positiveButtonTextResId) {
+ setPositiveButtonText(getContext().getString(positiveButtonTextResId));
+ }
+
+ /**
+ * Returns the text of the positive button to be shown on subsequent
+ * dialogs.
+ *
+ * @return The text of the positive button.
+ */
+ public CharSequence getPositiveButtonText() {
+ return mPositiveButtonText;
+ }
+
+ /**
+ * Sets the text of the negative button of the dialog. This will be shown on
+ * subsequent dialogs.
+ *
+ * @param negativeButtonText The text of the negative button.
+ */
+ public void setNegativeButtonText(CharSequence negativeButtonText) {
+ mNegativeButtonText = negativeButtonText;
+ }
+
+ /**
+ * @see #setNegativeButtonText(CharSequence)
+ * @param negativeButtonTextResId The negative button text as a resource.
+ */
+ public void setNegativeButtonText(int negativeButtonTextResId) {
+ setNegativeButtonText(getContext().getString(negativeButtonTextResId));
+ }
+
+ /**
+ * Returns the text of the negative button to be shown on subsequent
+ * dialogs.
+ *
+ * @return The text of the negative button.
+ */
+ public CharSequence getNegativeButtonText() {
+ return mNegativeButtonText;
+ }
+
+ /**
+ * Sets the layout resource that is inflated as the {@link View} to be shown
+ * as the content View of subsequent dialogs.
+ *
+ * @param dialogLayoutResId The layout resource ID to be inflated.
+ * @see #setDialogMessage(CharSequence)
+ */
+ public void setDialogLayoutResource(int dialogLayoutResId) {
+ mDialogLayoutResId = dialogLayoutResId;
+ }
+
+ /**
+ * Returns the layout resource that is used as the content View for
+ * subsequent dialogs.
+ *
+ * @return The layout resource.
+ */
+ public int getDialogLayoutResource() {
+ return mDialogLayoutResId;
+ }
+
+ @Override
+ protected void onClick() {
+ getPreferenceManager().showDialog(this);
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/EditTextPreference.java b/v7/preference/src/android/support/v7/preference/EditTextPreference.java
new file mode 100644
index 0000000..c4941e6
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/EditTextPreference.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.widget.EditText;
+
+/**
+ * A {@link Preference} that allows for string
+ * input.
+ * <p>
+ * It is a subclass of {@link DialogPreference} and shows the {@link EditText}
+ * in a dialog.
+ * <p>
+ * This preference will store a string into the SharedPreferences.
+ */
+public class EditTextPreference extends DialogPreference {
+ private String mText;
+
+ public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public EditTextPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.editTextPreferenceStyle);
+ }
+
+ public EditTextPreference(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Saves the text to the {@link android.content.SharedPreferences}.
+ *
+ * @param text The text to save
+ */
+ public void setText(String text) {
+ final boolean wasBlocking = shouldDisableDependents();
+
+ mText = text;
+
+ persistString(text);
+
+ final boolean isBlocking = shouldDisableDependents();
+ if (isBlocking != wasBlocking) {
+ notifyDependencyChange(isBlocking);
+ }
+ }
+
+ /**
+ * Gets the text from the {@link android.content.SharedPreferences}.
+ *
+ * @return The current preference value.
+ */
+ public String getText() {
+ return mText;
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getString(index);
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setText(restoreValue ? getPersistedString(mText) : (String) defaultValue);
+ }
+
+ @Override
+ public boolean shouldDisableDependents() {
+ return TextUtils.isEmpty(mText) || super.shouldDisableDependents();
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ if (isPersistent()) {
+ // No need to save instance state since it's persistent
+ return superState;
+ }
+
+ final SavedState myState = new SavedState(superState);
+ myState.text = getText();
+ return myState;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ if (state == null || !state.getClass().equals(SavedState.class)) {
+ // Didn't save state for us in onSaveInstanceState
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ SavedState myState = (SavedState) state;
+ super.onRestoreInstanceState(myState.getSuperState());
+ setText(myState.text);
+ }
+
+ private static class SavedState extends BaseSavedState {
+ String text;
+
+ public SavedState(Parcel source) {
+ super(source);
+ text = source.readString();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(text);
+ }
+
+ public SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR =
+ new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java b/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java
new file mode 100644
index 0000000..182cf28
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.EditText;
+
+public class EditTextPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
+
+ private EditText mEditText;
+
+ public static EditTextPreferenceDialogFragmentCompat newInstance(String key) {
+ final EditTextPreferenceDialogFragmentCompat
+ fragment = new EditTextPreferenceDialogFragmentCompat();
+ final Bundle b = new Bundle(1);
+ b.putString(ARG_KEY, key);
+ fragment.setArguments(b);
+ return fragment;
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ super.onBindDialogView(view);
+
+ mEditText = new EditText(view.getContext());
+ // Give it an ID so it can be saved/restored
+ mEditText.setId(android.R.id.edit);
+
+ mEditText.setText(getEditTextPreference().getText());
+
+ ViewParent oldParent = mEditText.getParent();
+ if (oldParent != view) {
+ if (oldParent != null) {
+ ((ViewGroup) oldParent).removeView(mEditText);
+ }
+ onAddEditTextToDialogView(view, mEditText);
+ }
+ }
+
+ private EditTextPreference getEditTextPreference() {
+ return (EditTextPreference) getPreference();
+ }
+
+ /** @hide */
+ @Override
+ protected boolean needInputMethod() {
+ // We want the input method to show, if possible, when dialog is displayed
+ return true;
+ }
+
+ /**
+ * Adds the EditText widget of this preference to the dialog's view.
+ *
+ * @param dialogView The dialog view.
+ */
+ protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
+ ViewGroup container = (ViewGroup) dialogView
+ .findViewById(R.id.edittext_container);
+ if (container != null) {
+ container.addView(editText, ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ }
+ }
+
+ @Override
+ public void onDialogClosed(boolean positiveResult) {
+
+ if (positiveResult) {
+ String value = mEditText.getText().toString();
+ if (getEditTextPreference().callChangeListener(value)) {
+ getEditTextPreference().setText(value);
+ }
+ }
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/ListPreference.java b/v7/preference/src/android/support/v7/preference/ListPreference.java
new file mode 100644
index 0000000..848cfad
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/ListPreference.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.ArrayRes;
+import android.support.annotation.NonNull;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+
+/**
+ * A {@link Preference} that displays a list of entries as
+ * a dialog.
+ * <p>
+ * This preference will store a string into the SharedPreferences. This string will be the value
+ * from the {@link #setEntryValues(CharSequence[])} array.
+ *
+ * @attr ref android.R.styleable#ListPreference_entries
+ * @attr ref android.R.styleable#ListPreference_entryValues
+ */
+public class ListPreference extends DialogPreference {
+ private CharSequence[] mEntries;
+ private CharSequence[] mEntryValues;
+ private String mValue;
+ private String mSummary;
+ private boolean mValueSet;
+
+ public ListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.ListPreference, defStyleAttr, defStyleRes);
+
+ mEntries = TypedArrayUtils.getTextArray(a, R.styleable.ListPreference_entries,
+ R.styleable.ListPreference_android_entries);
+
+ mEntryValues = TypedArrayUtils.getTextArray(a, R.styleable.ListPreference_entryValues,
+ R.styleable.ListPreference_android_entryValues);
+
+ a.recycle();
+
+ /* Retrieve the Preference summary attribute since it's private
+ * in the Preference class.
+ */
+ a = context.obtainStyledAttributes(attrs,
+ R.styleable.Preference, defStyleAttr, defStyleRes);
+
+ mSummary = TypedArrayUtils.getString(a, R.styleable.Preference_summary,
+ R.styleable.Preference_android_summary);
+
+ a.recycle();
+ }
+
+ public ListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public ListPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.dialogPreferenceStyle);
+ }
+
+ public ListPreference(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Sets the human-readable entries to be shown in the list. This will be
+ * shown in subsequent dialogs.
+ * <p>
+ * Each entry must have a corresponding index in
+ * {@link #setEntryValues(CharSequence[])}.
+ *
+ * @param entries The entries.
+ * @see #setEntryValues(CharSequence[])
+ */
+ public void setEntries(CharSequence[] entries) {
+ mEntries = entries;
+ }
+
+ /**
+ * @see #setEntries(CharSequence[])
+ * @param entriesResId The entries array as a resource.
+ */
+ public void setEntries(@ArrayRes int entriesResId) {
+ setEntries(getContext().getResources().getTextArray(entriesResId));
+ }
+
+ /**
+ * The list of entries to be shown in the list in subsequent dialogs.
+ *
+ * @return The list as an array.
+ */
+ public CharSequence[] getEntries() {
+ return mEntries;
+ }
+
+ /**
+ * The array to find the value to save for a preference when an entry from
+ * entries is selected. If a user clicks on the second item in entries, the
+ * second item in this array will be saved to the preference.
+ *
+ * @param entryValues The array to be used as values to save for the preference.
+ */
+ public void setEntryValues(CharSequence[] entryValues) {
+ mEntryValues = entryValues;
+ }
+
+ /**
+ * @see #setEntryValues(CharSequence[])
+ * @param entryValuesResId The entry values array as a resource.
+ */
+ public void setEntryValues(@ArrayRes int entryValuesResId) {
+ setEntryValues(getContext().getResources().getTextArray(entryValuesResId));
+ }
+
+ /**
+ * Returns the array of values to be saved for the preference.
+ *
+ * @return The array of values.
+ */
+ public CharSequence[] getEntryValues() {
+ return mEntryValues;
+ }
+
+ /**
+ * Sets the value of the key. This should be one of the entries in
+ * {@link #getEntryValues()}.
+ *
+ * @param value The value to set for the key.
+ */
+ public void setValue(String value) {
+ // Always persist/notify the first time.
+ final boolean changed = !TextUtils.equals(mValue, value);
+ if (changed || !mValueSet) {
+ mValue = value;
+ mValueSet = true;
+ persistString(value);
+ if (changed) {
+ notifyChanged();
+ }
+ }
+ }
+
+ /**
+ * Returns the summary of this ListPreference. If the summary
+ * has a {@linkplain java.lang.String#format String formatting}
+ * marker in it (i.e. "%s" or "%1$s"), then the current entry
+ * value will be substituted in its place.
+ *
+ * @return the summary with appropriate string substitution
+ */
+ @Override
+ public CharSequence getSummary() {
+ final CharSequence entry = getEntry();
+ if (mSummary == null) {
+ return super.getSummary();
+ } else {
+ return String.format(mSummary, entry == null ? "" : entry);
+ }
+ }
+
+ /**
+ * Sets the summary for this Preference with a CharSequence.
+ * If the summary has a
+ * {@linkplain java.lang.String#format String formatting}
+ * marker in it (i.e. "%s" or "%1$s"), then the current entry
+ * value will be substituted in its place when it's retrieved.
+ *
+ * @param summary The summary for the preference.
+ */
+ @Override
+ public void setSummary(CharSequence summary) {
+ super.setSummary(summary);
+ if (summary == null && mSummary != null) {
+ mSummary = null;
+ } else if (summary != null && !summary.equals(mSummary)) {
+ mSummary = summary.toString();
+ }
+ }
+
+ /**
+ * Sets the value to the given index from the entry values.
+ *
+ * @param index The index of the value to set.
+ */
+ public void setValueIndex(int index) {
+ if (mEntryValues != null) {
+ setValue(mEntryValues[index].toString());
+ }
+ }
+
+ /**
+ * Returns the value of the key. This should be one of the entries in
+ * {@link #getEntryValues()}.
+ *
+ * @return The value of the key.
+ */
+ public String getValue() {
+ return mValue;
+ }
+
+ /**
+ * Returns the entry corresponding to the current value.
+ *
+ * @return The entry corresponding to the current value, or null.
+ */
+ public CharSequence getEntry() {
+ int index = getValueIndex();
+ return index >= 0 && mEntries != null ? mEntries[index] : null;
+ }
+
+ /**
+ * Returns the index of the given value (in the entry values array).
+ *
+ * @param value The value whose index should be returned.
+ * @return The index of the value, or -1 if not found.
+ */
+ public int findIndexOfValue(String value) {
+ if (value != null && mEntryValues != null) {
+ for (int i = mEntryValues.length - 1; i >= 0; i--) {
+ if (mEntryValues[i].equals(value)) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ private int getValueIndex() {
+ return findIndexOfValue(mValue);
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getString(index);
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue);
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ if (isPersistent()) {
+ // No need to save instance state since it's persistent
+ return superState;
+ }
+
+ final SavedState myState = new SavedState(superState);
+ myState.value = getValue();
+ return myState;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ if (state == null || !state.getClass().equals(SavedState.class)) {
+ // Didn't save state for us in onSaveInstanceState
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ SavedState myState = (SavedState) state;
+ super.onRestoreInstanceState(myState.getSuperState());
+ setValue(myState.value);
+ }
+
+ private static class SavedState extends BaseSavedState {
+ String value;
+
+ public SavedState(Parcel source) {
+ super(source);
+ value = source.readString();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(value);
+ }
+
+ public SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR =
+ new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/ListPreferenceDialogFragmentCompat.java b/v7/preference/src/android/support/v7/preference/ListPreferenceDialogFragmentCompat.java
new file mode 100644
index 0000000..351ed0b
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/ListPreferenceDialogFragmentCompat.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
+
+public class ListPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
+
+ private int mClickedDialogEntryIndex;
+
+ public static ListPreferenceDialogFragmentCompat newInstance(String key) {
+ final ListPreferenceDialogFragmentCompat fragment =
+ new ListPreferenceDialogFragmentCompat();
+ final Bundle b = new Bundle(1);
+ b.putString(ARG_KEY, key);
+ fragment.setArguments(b);
+ return fragment;
+ }
+
+ private ListPreference getListPreference() {
+ return (ListPreference) getPreference();
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+ super.onPrepareDialogBuilder(builder);
+
+ final ListPreference preference = getListPreference();
+
+ if (preference.getEntries() == null || preference.getEntryValues() == null) {
+ throw new IllegalStateException(
+ "ListPreference requires an entries array and an entryValues array.");
+ }
+
+ mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
+ builder.setSingleChoiceItems(preference.getEntries(), mClickedDialogEntryIndex,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mClickedDialogEntryIndex = which;
+
+ /*
+ * Clicking on an item simulates the positive button
+ * click, and dismisses the dialog.
+ */
+ ListPreferenceDialogFragmentCompat.this.onClick(dialog,
+ DialogInterface.BUTTON_POSITIVE);
+ dialog.dismiss();
+ }
+ });
+
+ /*
+ * The typical interaction for list-based dialogs is to have
+ * click-on-an-item dismiss the dialog instead of the user having to
+ * press 'Ok'.
+ */
+ builder.setPositiveButton(null, null);
+ }
+
+ @Override
+ public void onDialogClosed(boolean positiveResult) {
+ final ListPreference preference = getListPreference();
+ if (positiveResult && mClickedDialogEntryIndex >= 0 &&
+ preference.getEntryValues() != null) {
+ String value = preference.getEntryValues()[mClickedDialogEntryIndex].toString();
+ if (preference.callChangeListener(value)) {
+ preference.setValue(value);
+ }
+ }
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/Preference.java b/v7/preference/src/android/support/v7/preference/Preference.java
new file mode 100644
index 0000000..7d01005
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/Preference.java
@@ -0,0 +1,1688 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.NonNull;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.content.SharedPreferencesCompat;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.AbsSavedState;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents the basic Preference UI building
+ * block displayed by a {@link PreferenceFragmentCompat} in the form of a
+ * {@link android.support.v7.widget.RecyclerView}. This class provides data for the
+ * {@link android.view.View} to be displayed
+ * in the list and associates with a {@link SharedPreferences} to
+ * store/retrieve the preference data.
+ * <p>
+ * When specifying a preference hierarchy in XML, each element can point to a
+ * subclass of {@link Preference}, similar to the view hierarchy and layouts.
+ * <p>
+ * This class contains a {@code key} that will be used as the key into the
+ * {@link SharedPreferences}. It is up to the subclass to decide how to store
+ * the value.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about building a settings UI with Preferences,
+ * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>
+ * guide.</p>
+ * </div>
+ *
+ * @attr ref android.R.styleable#Preference_icon
+ * @attr ref android.R.styleable#Preference_key
+ * @attr ref android.R.styleable#Preference_title
+ * @attr ref android.R.styleable#Preference_summary
+ * @attr ref android.R.styleable#Preference_order
+ * @attr ref android.R.styleable#Preference_fragment
+ * @attr ref android.R.styleable#Preference_layout
+ * @attr ref android.R.styleable#Preference_widgetLayout
+ * @attr ref android.R.styleable#Preference_enabled
+ * @attr ref android.R.styleable#Preference_selectable
+ * @attr ref android.R.styleable#Preference_dependency
+ * @attr ref android.R.styleable#Preference_persistent
+ * @attr ref android.R.styleable#Preference_defaultValue
+ * @attr ref android.R.styleable#Preference_shouldDisableView
+ */
+public class Preference implements Comparable<Preference> {
+ /**
+ * Specify for {@link #setOrder(int)} if a specific order is not required.
+ */
+ public static final int DEFAULT_ORDER = Integer.MAX_VALUE;
+
+ private Context mContext;
+ private PreferenceManager mPreferenceManager;
+
+ /**
+ * Set when added to hierarchy since we need a unique ID within that
+ * hierarchy.
+ */
+ private long mId;
+
+ private OnPreferenceChangeListener mOnChangeListener;
+ private OnPreferenceClickListener mOnClickListener;
+
+ private int mOrder = DEFAULT_ORDER;
+ private CharSequence mTitle;
+ private CharSequence mSummary;
+ /**
+ * mIconResId is overridden by mIcon, if mIcon is specified.
+ */
+ private int mIconResId;
+ private Drawable mIcon;
+ private String mKey;
+ private Intent mIntent;
+ private String mFragment;
+ private Bundle mExtras;
+ private boolean mEnabled = true;
+ private boolean mSelectable = true;
+ private boolean mRequiresKey;
+ private boolean mPersistent = true;
+ private String mDependencyKey;
+ private Object mDefaultValue;
+ private boolean mDependencyMet = true;
+ private boolean mParentDependencyMet = true;
+ private boolean mVisible = true;
+
+ /**
+ * @see #setShouldDisableView(boolean)
+ */
+ private boolean mShouldDisableView = true;
+
+ private int mLayoutResId = R.layout.preference;
+ private int mWidgetLayoutResId;
+
+ private OnPreferenceChangeInternalListener mListener;
+
+ private List<Preference> mDependents;
+
+ private boolean mBaseMethodCalled;
+
+ private final View.OnClickListener mClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ performClick();
+ }
+ };
+
+ /**
+ * Interface definition for a callback to be invoked when the value of this
+ * {@link Preference} has been changed by the user and is
+ * about to be set and/or persisted. This gives the client a chance
+ * to prevent setting and/or persisting the value.
+ */
+ public interface OnPreferenceChangeListener {
+ /**
+ * Called when a Preference has been changed by the user. This is
+ * called before the state of the Preference is about to be updated and
+ * before the state is persisted.
+ *
+ * @param preference The changed Preference.
+ * @param newValue The new value of the Preference.
+ * @return True to update the state of the Preference with the new value.
+ */
+ boolean onPreferenceChange(Preference preference, Object newValue);
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when a {@link Preference} is
+ * clicked.
+ */
+ public interface OnPreferenceClickListener {
+ /**
+ * Called when a Preference has been clicked.
+ *
+ * @param preference The Preference that was clicked.
+ * @return True if the click was handled.
+ */
+ boolean onPreferenceClick(Preference preference);
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when this
+ * {@link Preference} is changed or, if this is a group, there is an
+ * addition/removal of {@link Preference}(s). This is used internally.
+ */
+ interface OnPreferenceChangeInternalListener {
+ /**
+ * Called when this Preference has changed.
+ *
+ * @param preference This preference.
+ */
+ void onPreferenceChange(Preference preference);
+
+ /**
+ * Called when this group has added/removed {@link Preference}(s).
+ *
+ * @param preference This Preference.
+ */
+ void onPreferenceHierarchyChange(Preference preference);
+
+ /**
+ * Called when this preference has changed its visibility.
+ *
+ * @param preference This Preference.
+ */
+ void onPreferenceVisibilityChange(Preference preference);
+ }
+
+ /**
+ * Perform inflation from XML and apply a class-specific base style. This
+ * constructor of Preference allows subclasses to use their own base style
+ * when they are inflating. For example, a {@link CheckBoxPreference}
+ * constructor calls this version of the super class constructor and
+ * supplies {@code android.R.attr.checkBoxPreferenceStyle} for
+ * <var>defStyleAttr</var>. This allows the theme's checkbox preference
+ * style to modify all of the base preference attributes as well as the
+ * {@link CheckBoxPreference} class's attributes.
+ *
+ * @param context The Context this is associated with, through which it can
+ * access the current theme, resources,
+ * {@link android.content.SharedPreferences}, etc.
+ * @param attrs The attributes of the XML tag that is inflating the
+ * preference.
+ * @param defStyleAttr An attribute in the current theme that contains a
+ * reference to a style resource that supplies default values for
+ * the view. Can be 0 to not look for defaults.
+ * @param defStyleRes A resource identifier of a style resource that
+ * supplies default values for the view, used only if
+ * defStyleAttr is 0 or can not be found in the theme. Can be 0
+ * to not look for defaults.
+ * @see #Preference(Context, android.util.AttributeSet)
+ */
+ public Preference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ mContext = context;
+
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.Preference, defStyleAttr, defStyleRes);
+
+ mIconResId = TypedArrayUtils.getResourceId(a, R.styleable.Preference_icon,
+ R.styleable.Preference_android_icon, 0);
+
+ mKey = TypedArrayUtils.getString(a, R.styleable.Preference_key,
+ R.styleable.Preference_android_key);
+
+ mTitle = TypedArrayUtils.getString(a, R.styleable.Preference_title,
+ R.styleable.Preference_android_title);
+
+ mSummary = TypedArrayUtils.getString(a, R.styleable.Preference_summary,
+ R.styleable.Preference_android_summary);
+
+ mOrder = TypedArrayUtils.getInt(a, R.styleable.Preference_order,
+ R.styleable.Preference_android_order, DEFAULT_ORDER);
+
+ mFragment = TypedArrayUtils.getString(a, R.styleable.Preference_fragment,
+ R.styleable.Preference_android_fragment);
+
+ mLayoutResId = TypedArrayUtils.getResourceId(a, R.styleable.Preference_layout,
+ R.styleable.Preference_android_layout, R.layout.preference);
+
+ mWidgetLayoutResId = TypedArrayUtils.getResourceId(a, R.styleable.Preference_widgetLayout,
+ R.styleable.Preference_android_widgetLayout, 0);
+
+ mEnabled = TypedArrayUtils.getBoolean(a, R.styleable.Preference_enabled,
+ R.styleable.Preference_android_enabled, true);
+
+ mSelectable = TypedArrayUtils.getBoolean(a, R.styleable.Preference_selectable,
+ R.styleable.Preference_android_selectable, true);
+
+ mPersistent = TypedArrayUtils.getBoolean(a, R.styleable.Preference_persistent,
+ R.styleable.Preference_android_persistent, true);
+
+ mDependencyKey = TypedArrayUtils.getString(a, R.styleable.Preference_dependency,
+ R.styleable.Preference_android_dependency);
+
+ if (a.hasValue(R.styleable.Preference_defaultValue)) {
+ mDefaultValue = onGetDefaultValue(a, R.styleable.Preference_defaultValue);
+ } else if (a.hasValue(R.styleable.Preference_android_defaultValue)) {
+ mDefaultValue = onGetDefaultValue(a, R.styleable.Preference_android_defaultValue);
+ }
+
+ mShouldDisableView =
+ TypedArrayUtils.getBoolean(a, R.styleable.Preference_shouldDisableView,
+ R.styleable.Preference_shouldDisableView, true);
+
+ a.recycle();
+ }
+
+ /**
+ * Perform inflation from XML and apply a class-specific base style. This
+ * constructor of Preference allows subclasses to use their own base style
+ * when they are inflating. For example, a {@link CheckBoxPreference}
+ * constructor calls this version of the super class constructor and
+ * supplies {@code android.R.attr.checkBoxPreferenceStyle} for
+ * <var>defStyleAttr</var>. This allows the theme's checkbox preference
+ * style to modify all of the base preference attributes as well as the
+ * {@link CheckBoxPreference} class's attributes.
+ *
+ * @param context The Context this is associated with, through which it can
+ * access the current theme, resources,
+ * {@link android.content.SharedPreferences}, etc.
+ * @param attrs The attributes of the XML tag that is inflating the
+ * preference.
+ * @param defStyleAttr An attribute in the current theme that contains a
+ * reference to a style resource that supplies default values for
+ * the view. Can be 0 to not look for defaults.
+ * @see #Preference(Context, AttributeSet)
+ */
+ public Preference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ /**
+ * Constructor that is called when inflating a Preference from XML. This is
+ * called when a Preference is being constructed from an XML file, supplying
+ * attributes that were specified in the XML file. This version uses a
+ * default style of 0, so the only attribute values applied are those in the
+ * Context's Theme and the given AttributeSet.
+ *
+ * @param context The Context this is associated with, through which it can
+ * access the current theme, resources, {@link android.content.SharedPreferences},
+ * etc.
+ * @param attrs The attributes of the XML tag that is inflating the
+ * preference.
+ * @see #Preference(Context, AttributeSet, int)
+ */
+ public Preference(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.preferenceStyle);
+ }
+
+ /**
+ * Constructor to create a Preference.
+ *
+ * @param context The Context in which to store Preference values.
+ */
+ public Preference(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Called when a Preference is being inflated and the default value
+ * attribute needs to be read. Since different Preference types have
+ * different value types, the subclass should get and return the default
+ * value which will be its value type.
+ * <p>
+ * For example, if the value type is String, the body of the method would
+ * proxy to {@link TypedArray#getString(int)}.
+ *
+ * @param a The set of attributes.
+ * @param index The index of the default value attribute.
+ * @return The default value of this preference type.
+ */
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ return null;
+ }
+
+ /**
+ * Sets an {@link Intent} to be used for
+ * {@link Context#startActivity(Intent)} when this Preference is clicked.
+ *
+ * @param intent The intent associated with this Preference.
+ */
+ public void setIntent(Intent intent) {
+ mIntent = intent;
+ }
+
+ /**
+ * Return the {@link Intent} associated with this Preference.
+ *
+ * @return The {@link Intent} last set via {@link #setIntent(Intent)} or XML.
+ */
+ public Intent getIntent() {
+ return mIntent;
+ }
+
+ /**
+ * Sets the class name of a fragment to be shown when this Preference is clicked.
+ *
+ * @param fragment The class name of the fragment associated with this Preference.
+ */
+ public void setFragment(String fragment) {
+ mFragment = fragment;
+ }
+
+ /**
+ * Return the fragment class name associated with this Preference.
+ *
+ * @return The fragment class name last set via {@link #setFragment} or XML.
+ */
+ public String getFragment() {
+ return mFragment;
+ }
+
+ /**
+ * Return the extras Bundle object associated with this preference, creating
+ * a new Bundle if there currently isn't one. You can use this to get and
+ * set individual extra key/value pairs.
+ */
+ public Bundle getExtras() {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ return mExtras;
+ }
+
+ /**
+ * Return the extras Bundle object associated with this preference,
+ * returning null if there is not currently one.
+ */
+ public Bundle peekExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Sets the layout resource that is inflated as the {@link View} to be shown
+ * for this Preference. In most cases, the default layout is sufficient for
+ * custom Preference objects and only the widget layout needs to be changed.
+ * <p>
+ * This layout should contain a {@link ViewGroup} with ID
+ * {@link android.R.id#widget_frame} to be the parent of the specific widget
+ * for this Preference. It should similarly contain
+ * {@link android.R.id#title} and {@link android.R.id#summary}.
+ * <p>
+ * It is an error to change the layout after adding the preference to a {@link PreferenceGroup}
+ *
+ * @param layoutResId The layout resource ID to be inflated and returned as
+ * a {@link View}.
+ * @see #setWidgetLayoutResource(int)
+ */
+ public void setLayoutResource(int layoutResId) {
+ mLayoutResId = layoutResId;
+ }
+
+ /**
+ * Gets the layout resource that will be shown as the {@link View} for this Preference.
+ *
+ * @return The layout resource ID.
+ */
+ public final int getLayoutResource() {
+ return mLayoutResId;
+ }
+
+ /**
+ * Sets the layout for the controllable widget portion of this Preference. This
+ * is inflated into the main layout. For example, a {@link CheckBoxPreference}
+ * would specify a custom layout (consisting of just the CheckBox) here,
+ * instead of creating its own main layout.
+ * <p>
+ * It is an error to change the layout after adding the preference to a {@link PreferenceGroup}
+ *
+ * @param widgetLayoutResId The layout resource ID to be inflated into the
+ * main layout.
+ * @see #setLayoutResource(int)
+ */
+ public void setWidgetLayoutResource(int widgetLayoutResId) {
+ mWidgetLayoutResId = widgetLayoutResId;
+ }
+
+ /**
+ * Gets the layout resource for the controllable widget portion of this Preference.
+ *
+ * @return The layout resource ID.
+ */
+ public final int getWidgetLayoutResource() {
+ return mWidgetLayoutResId;
+ }
+
+ /**
+ * Binds the created View to the data for this Preference.
+ * <p>
+ * This is a good place to grab references to custom Views in the layout and
+ * set properties on them.
+ * <p>
+ * Make sure to call through to the superclass's implementation.
+ *
+ * @param holder The ViewHolder that provides references to the views to fill in. These views
+ * will be recycled, so you should not hold a reference to them after this method
+ * returns.
+ */
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ holder.itemView.setOnClickListener(mClickListener);
+
+ final TextView titleView = (TextView) holder.findViewById(android.R.id.title);
+ if (titleView != null) {
+ final CharSequence title = getTitle();
+ if (!TextUtils.isEmpty(title)) {
+ titleView.setText(title);
+ titleView.setVisibility(View.VISIBLE);
+ } else {
+ titleView.setVisibility(View.GONE);
+ }
+ }
+
+ final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
+ if (summaryView != null) {
+ final CharSequence summary = getSummary();
+ if (!TextUtils.isEmpty(summary)) {
+ summaryView.setText(summary);
+ summaryView.setVisibility(View.VISIBLE);
+ } else {
+ summaryView.setVisibility(View.GONE);
+ }
+ }
+
+ final ImageView imageView = (ImageView) holder.findViewById(android.R.id.icon);
+ if (imageView != null) {
+ if (mIconResId != 0 || mIcon != null) {
+ if (mIcon == null) {
+ mIcon = ContextCompat.getDrawable(getContext(), mIconResId);
+ }
+ if (mIcon != null) {
+ imageView.setImageDrawable(mIcon);
+ }
+ }
+ imageView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
+ }
+
+ final View imageFrame = holder.findViewById(R.id.icon_frame);
+ if (imageFrame != null) {
+ imageFrame.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
+ }
+
+ if (mShouldDisableView) {
+ setEnabledStateOnViews(holder.itemView, isEnabled());
+ } else {
+ setEnabledStateOnViews(holder.itemView, true);
+ }
+ }
+
+ /**
+ * Makes sure the view (and any children) get the enabled state changed.
+ */
+ private void setEnabledStateOnViews(View v, boolean enabled) {
+ v.setEnabled(enabled);
+
+ if (v instanceof ViewGroup) {
+ final ViewGroup vg = (ViewGroup) v;
+ for (int i = vg.getChildCount() - 1; i >= 0; i--) {
+ setEnabledStateOnViews(vg.getChildAt(i), enabled);
+ }
+ }
+ }
+
+ /**
+ * Sets the order of this Preference with respect to other
+ * Preference objects on the same level. If this is not specified, the
+ * default behavior is to sort alphabetically. The
+ * {@link PreferenceGroup#setOrderingAsAdded(boolean)} can be used to order
+ * Preference objects based on the order they appear in the XML.
+ *
+ * @param order The order for this Preference. A lower value will be shown
+ * first. Use {@link #DEFAULT_ORDER} to sort alphabetically or
+ * allow ordering from XML.
+ * @see PreferenceGroup#setOrderingAsAdded(boolean)
+ * @see #DEFAULT_ORDER
+ */
+ public void setOrder(int order) {
+ if (order != mOrder) {
+ mOrder = order;
+
+ // Reorder the list
+ notifyHierarchyChanged();
+ }
+ }
+
+ /**
+ * Gets the order of this Preference with respect to other Preference objects
+ * on the same level.
+ *
+ * @return The order of this Preference.
+ * @see #setOrder(int)
+ */
+ public int getOrder() {
+ return mOrder;
+ }
+
+ /**
+ * Sets the title for this Preference with a CharSequence.
+ * This title will be placed into the ID
+ * {@link android.R.id#title} within the View bound by
+ * {@link #onBindViewHolder(PreferenceViewHolder)}.
+ *
+ * @param title The title for this Preference.
+ */
+ public void setTitle(CharSequence title) {
+ if (title == null && mTitle != null || title != null && !title.equals(mTitle)) {
+ mTitle = title;
+ notifyChanged();
+ }
+ }
+
+ /**
+ * Sets the title for this Preference with a resource ID.
+ *
+ * @see #setTitle(CharSequence)
+ * @param titleResId The title as a resource ID.
+ */
+ public void setTitle(int titleResId) {
+ setTitle(mContext.getString(titleResId));
+ }
+
+ /**
+ * Returns the title of this Preference.
+ *
+ * @return The title.
+ * @see #setTitle(CharSequence)
+ */
+ public CharSequence getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Sets the icon for this Preference with a Drawable.
+ * This icon will be placed into the ID
+ * {@link android.R.id#icon} within the View created by
+ * {@link #onBindViewHolder(PreferenceViewHolder)}.
+ *
+ * @param icon The optional icon for this Preference.
+ */
+ public void setIcon(Drawable icon) {
+ if ((icon == null && mIcon != null) || (icon != null && mIcon != icon)) {
+ mIcon = icon;
+ mIconResId = 0;
+ notifyChanged();
+ }
+ }
+
+ /**
+ * Sets the icon for this Preference with a resource ID.
+ *
+ * @see #setIcon(Drawable)
+ * @param iconResId The icon as a resource ID.
+ */
+ public void setIcon(int iconResId) {
+ setIcon(ContextCompat.getDrawable(mContext, iconResId));
+ mIconResId = iconResId;
+ }
+
+ /**
+ * Returns the icon of this Preference.
+ *
+ * @return The icon.
+ * @see #setIcon(Drawable)
+ */
+ public Drawable getIcon() {
+ return mIcon;
+ }
+
+ /**
+ * Returns the summary of this Preference.
+ *
+ * @return The summary.
+ * @see #setSummary(CharSequence)
+ */
+ public CharSequence getSummary() {
+ return mSummary;
+ }
+
+ /**
+ * Sets the summary for this Preference with a CharSequence.
+ *
+ * @param summary The summary for the preference.
+ */
+ public void setSummary(CharSequence summary) {
+ if (summary == null && mSummary != null || summary != null && !summary.equals(mSummary)) {
+ mSummary = summary;
+ notifyChanged();
+ }
+ }
+
+ /**
+ * Sets the summary for this Preference with a resource ID.
+ *
+ * @see #setSummary(CharSequence)
+ * @param summaryResId The summary as a resource.
+ */
+ public void setSummary(int summaryResId) {
+ setSummary(mContext.getString(summaryResId));
+ }
+
+ /**
+ * Sets whether this Preference is enabled. If disabled, it will
+ * not handle clicks.
+ *
+ * @param enabled Set true to enable it.
+ */
+ public void setEnabled(boolean enabled) {
+ if (mEnabled != enabled) {
+ mEnabled = enabled;
+
+ // Enabled state can change dependent preferences' states, so notify
+ notifyDependencyChange(shouldDisableDependents());
+
+ notifyChanged();
+ }
+ }
+
+ /**
+ * Checks whether this Preference should be enabled in the list.
+ *
+ * @return True if this Preference is enabled, false otherwise.
+ */
+ public boolean isEnabled() {
+ return mEnabled && mDependencyMet && mParentDependencyMet;
+ }
+
+ /**
+ * Sets whether this Preference is selectable.
+ *
+ * @param selectable Set true to make it selectable.
+ */
+ public void setSelectable(boolean selectable) {
+ if (mSelectable != selectable) {
+ mSelectable = selectable;
+ notifyChanged();
+ }
+ }
+
+ /**
+ * Checks whether this Preference should be selectable in the list.
+ *
+ * @return True if it is selectable, false otherwise.
+ */
+ public boolean isSelectable() {
+ return mSelectable;
+ }
+
+ /**
+ * Sets whether this Preference should disable its view when it gets
+ * disabled.
+ * <p>
+ * For example, set this and {@link #setEnabled(boolean)} to false for
+ * preferences that are only displaying information and 1) should not be
+ * clickable 2) should not have the view set to the disabled state.
+ *
+ * @param shouldDisableView Set true if this preference should disable its view
+ * when the preference is disabled.
+ */
+ public void setShouldDisableView(boolean shouldDisableView) {
+ mShouldDisableView = shouldDisableView;
+ notifyChanged();
+ }
+
+ /**
+ * Checks whether this Preference should disable its view when it's action is disabled.
+ * @see #setShouldDisableView(boolean)
+ * @return True if it should disable the view.
+ */
+ public boolean getShouldDisableView() {
+ return mShouldDisableView;
+ }
+
+ /**
+ * Sets whether this preference should be visible in the list. If false, it is excluded from
+ * the adapter, but can still be retrieved using
+ * {@link PreferenceFragmentCompat#findPreference(CharSequence)}.
+ *
+ * @param visible Set false if this preference should be hidden from the list.
+ */
+ public final void setVisible(boolean visible) {
+ mVisible = visible;
+ if (mListener != null) {
+ mListener.onPreferenceVisibilityChange(this);
+ }
+ }
+
+ /**
+ * Checks whether this preference should be visible to the user in the list.
+ * @see #setVisible(boolean)
+ * @return True if this preference should be displayed.
+ */
+ public final boolean isVisible() {
+ return mVisible;
+ }
+
+ /**
+ * Returns a unique ID for this Preference. This ID should be unique across all
+ * Preference objects in a hierarchy.
+ *
+ * @return A unique ID for this Preference.
+ */
+ long getId() {
+ return mId;
+ }
+
+ /**
+ * Processes a click on the preference. This includes saving the value to
+ * the {@link android.content.SharedPreferences}. However, the overridden method should
+ * call {@link #callChangeListener(Object)} to make sure the client wants to
+ * update the preference's state with the new value.
+ */
+ protected void onClick() {
+ }
+
+ /**
+ * Sets the key for this Preference, which is used as a key to the
+ * {@link android.content.SharedPreferences}. This should be unique for the package.
+ *
+ * @param key The key for the preference.
+ */
+ public void setKey(String key) {
+ mKey = key;
+
+ if (mRequiresKey && !hasKey()) {
+ requireKey();
+ }
+ }
+
+ /**
+ * Gets the key for this Preference, which is also the key used for storing
+ * values into SharedPreferences.
+ *
+ * @return The key.
+ */
+ public String getKey() {
+ return mKey;
+ }
+
+ /**
+ * Checks whether the key is present, and if it isn't throws an
+ * exception. This should be called by subclasses that store preferences in
+ * the {@link android.content.SharedPreferences}.
+ *
+ * @throws IllegalStateException If there is no key assigned.
+ */
+ void requireKey() {
+ if (TextUtils.isEmpty(mKey)) {
+ throw new IllegalStateException("Preference does not have a key assigned.");
+ }
+
+ mRequiresKey = true;
+ }
+
+ /**
+ * Checks whether this Preference has a valid key.
+ *
+ * @return True if the key exists and is not a blank string, false otherwise.
+ */
+ public boolean hasKey() {
+ return !TextUtils.isEmpty(mKey);
+ }
+
+ /**
+ * Checks whether this Preference is persistent. If it is, it stores its value(s) into
+ * the persistent {@link android.content.SharedPreferences} storage.
+ *
+ * @return True if it is persistent.
+ */
+ public boolean isPersistent() {
+ return mPersistent;
+ }
+
+ /**
+ * Checks whether, at the given time this method is called,
+ * this Preference should store/restore its value(s) into the
+ * {@link android.content.SharedPreferences}. This, at minimum, checks whether this
+ * Preference is persistent and it currently has a key. Before you
+ * save/restore from the {@link android.content.SharedPreferences}, check this first.
+ *
+ * @return True if it should persist the value.
+ */
+ protected boolean shouldPersist() {
+ return mPreferenceManager != null && isPersistent() && hasKey();
+ }
+
+ /**
+ * Sets whether this Preference is persistent. When persistent,
+ * it stores its value(s) into the persistent {@link android.content.SharedPreferences}
+ * storage.
+ *
+ * @param persistent Set true if it should store its value(s) into the
+ * {@link android.content.SharedPreferences}.
+ */
+ public void setPersistent(boolean persistent) {
+ mPersistent = persistent;
+ }
+
+ /**
+ * Call this method after the user changes the preference, but before the
+ * internal state is set. This allows the client to ignore the user value.
+ *
+ * @param newValue The new value of this Preference.
+ * @return True if the user value should be set as the preference
+ * value (and persisted).
+ */
+ public boolean callChangeListener(Object newValue) {
+ return mOnChangeListener == null || mOnChangeListener.onPreferenceChange(this, newValue);
+ }
+
+ /**
+ * Sets the callback to be invoked when this Preference is changed by the
+ * user (but before the internal state has been updated).
+ *
+ * @param onPreferenceChangeListener The callback to be invoked.
+ */
+ public void setOnPreferenceChangeListener(
+ OnPreferenceChangeListener onPreferenceChangeListener) {
+ mOnChangeListener = onPreferenceChangeListener;
+ }
+
+ /**
+ * Returns the callback to be invoked when this Preference is changed by the
+ * user (but before the internal state has been updated).
+ *
+ * @return The callback to be invoked.
+ */
+ public OnPreferenceChangeListener getOnPreferenceChangeListener() {
+ return mOnChangeListener;
+ }
+
+ /**
+ * Sets the callback to be invoked when this Preference is clicked.
+ *
+ * @param onPreferenceClickListener The callback to be invoked.
+ */
+ public void setOnPreferenceClickListener(OnPreferenceClickListener onPreferenceClickListener) {
+ mOnClickListener = onPreferenceClickListener;
+ }
+
+ /**
+ * Returns the callback to be invoked when this Preference is clicked.
+ *
+ * @return The callback to be invoked.
+ */
+ public OnPreferenceClickListener getOnPreferenceClickListener() {
+ return mOnClickListener;
+ }
+
+ /**
+ * Called when a click should be performed.
+ *
+ * @hide
+ */
+ public void performClick() {
+
+ if (!isEnabled()) {
+ return;
+ }
+
+ onClick();
+
+ if (mOnClickListener != null && mOnClickListener.onPreferenceClick(this)) {
+ return;
+ }
+
+ PreferenceManager preferenceManager = getPreferenceManager();
+ if (preferenceManager != null) {
+ PreferenceManager.OnPreferenceTreeClickListener listener = preferenceManager
+ .getOnPreferenceTreeClickListener();
+ if (listener != null && listener.onPreferenceTreeClick(this)) {
+ return;
+ }
+ }
+
+ if (mIntent != null) {
+ Context context = getContext();
+ context.startActivity(mIntent);
+ }
+ }
+
+ /**
+ * Returns the {@link android.content.Context} of this Preference.
+ * Each Preference in a Preference hierarchy can be
+ * from different Context (for example, if multiple activities provide preferences into a single
+ * {@link PreferenceFragmentCompat}). This Context will be used to save the Preference values.
+ *
+ * @return The Context of this Preference.
+ */
+ public Context getContext() {
+ return mContext;
+ }
+
+ /**
+ * Returns the {@link android.content.SharedPreferences} where this Preference can read its
+ * value(s). Usually, it's easier to use one of the helper read methods:
+ * {@link #getPersistedBoolean(boolean)}, {@link #getPersistedFloat(float)},
+ * {@link #getPersistedInt(int)}, {@link #getPersistedLong(long)},
+ * {@link #getPersistedString(String)}. To save values, see
+ * {@link #getEditor()}.
+ * <p>
+ * In some cases, writes to the {@link #getEditor()} will not be committed
+ * right away and hence not show up in the returned
+ * {@link android.content.SharedPreferences}, this is intended behavior to improve
+ * performance.
+ *
+ * @return The {@link android.content.SharedPreferences} where this Preference reads its
+ * value(s), or null if it isn't attached to a Preference hierarchy.
+ * @see #getEditor()
+ */
+ public SharedPreferences getSharedPreferences() {
+ if (mPreferenceManager == null) {
+ return null;
+ }
+
+ return mPreferenceManager.getSharedPreferences();
+ }
+
+ /**
+ * Compares Preference objects based on order (if set), otherwise alphabetically on the titles.
+ *
+ * @param another The Preference to compare to this one.
+ * @return 0 if the same; less than 0 if this Preference sorts ahead of <var>another</var>;
+ * greater than 0 if this Preference sorts after <var>another</var>.
+ */
+ @Override
+ public int compareTo(@NonNull Preference another) {
+ if (mOrder != another.mOrder) {
+ // Do order comparison
+ return mOrder - another.mOrder;
+ } else if (mTitle == another.mTitle) {
+ // If titles are null or share same object comparison
+ return 0;
+ } else if (mTitle == null) {
+ return 1;
+ } else if (another.mTitle == null) {
+ return -1;
+ } else {
+ // Do name comparison
+ return mTitle.toString().compareToIgnoreCase(another.mTitle.toString());
+ }
+ }
+
+ /**
+ * Sets the internal change listener.
+ *
+ * @param listener The listener.
+ * @see #notifyChanged()
+ */
+ final void setOnPreferenceChangeInternalListener(OnPreferenceChangeInternalListener listener) {
+ mListener = listener;
+ }
+
+ /**
+ * Should be called when the data of this {@link Preference} has changed.
+ */
+ protected void notifyChanged() {
+ if (mListener != null) {
+ mListener.onPreferenceChange(this);
+ }
+ }
+
+ /**
+ * Should be called when a Preference has been
+ * added/removed from this group, or the ordering should be
+ * re-evaluated.
+ */
+ protected void notifyHierarchyChanged() {
+ if (mListener != null) {
+ mListener.onPreferenceHierarchyChange(this);
+ }
+ }
+
+ /**
+ * Gets the {@link PreferenceManager} that manages this Preference object's tree.
+ *
+ * @return The {@link PreferenceManager}.
+ */
+ public PreferenceManager getPreferenceManager() {
+ return mPreferenceManager;
+ }
+
+ /**
+ * Called when this Preference has been attached to a Preference hierarchy.
+ * Make sure to call the super implementation.
+ *
+ * @param preferenceManager The PreferenceManager of the hierarchy.
+ */
+ protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
+ mPreferenceManager = preferenceManager;
+
+ mId = preferenceManager.getNextId();
+
+ dispatchSetInitialValue();
+ }
+
+ /**
+ * Called when the Preference hierarchy has been attached to the
+ * list of preferences. This can also be called when this
+ * Preference has been attached to a group that was already attached
+ * to the list of preferences.
+ */
+ protected void onAttached() {
+ // At this point, the hierarchy that this preference is in is connected
+ // with all other preferences.
+ registerDependency();
+ }
+
+ private void registerDependency() {
+
+ if (TextUtils.isEmpty(mDependencyKey)) return;
+
+ Preference preference = findPreferenceInHierarchy(mDependencyKey);
+ if (preference != null) {
+ preference.registerDependent(this);
+ } else {
+ throw new IllegalStateException("Dependency \"" + mDependencyKey
+ + "\" not found for preference \"" + mKey + "\" (title: \"" + mTitle + "\"");
+ }
+ }
+
+ private void unregisterDependency() {
+ if (mDependencyKey != null) {
+ final Preference oldDependency = findPreferenceInHierarchy(mDependencyKey);
+ if (oldDependency != null) {
+ oldDependency.unregisterDependent(this);
+ }
+ }
+ }
+
+ /**
+ * Finds a Preference in this hierarchy (the whole thing,
+ * even above/below your {@link PreferenceScreen} screen break) with the given
+ * key.
+ * <p>
+ * This only functions after we have been attached to a hierarchy.
+ *
+ * @param key The key of the Preference to find.
+ * @return The Preference that uses the given key.
+ */
+ protected Preference findPreferenceInHierarchy(String key) {
+ if (TextUtils.isEmpty(key) || mPreferenceManager == null) {
+ return null;
+ }
+
+ return mPreferenceManager.findPreference(key);
+ }
+
+ /**
+ * Adds a dependent Preference on this Preference so we can notify it.
+ * Usually, the dependent Preference registers itself (it's good for it to
+ * know it depends on something), so please use
+ * {@link Preference#setDependency(String)} on the dependent Preference.
+ *
+ * @param dependent The dependent Preference that will be enabled/disabled
+ * according to the state of this Preference.
+ */
+ private void registerDependent(Preference dependent) {
+ if (mDependents == null) {
+ mDependents = new ArrayList<Preference>();
+ }
+
+ mDependents.add(dependent);
+
+ dependent.onDependencyChanged(this, shouldDisableDependents());
+ }
+
+ /**
+ * Removes a dependent Preference on this Preference.
+ *
+ * @param dependent The dependent Preference that will be enabled/disabled
+ * according to the state of this Preference.
+ * @return Returns the same Preference object, for chaining multiple calls
+ * into a single statement.
+ */
+ private void unregisterDependent(Preference dependent) {
+ if (mDependents != null) {
+ mDependents.remove(dependent);
+ }
+ }
+
+ /**
+ * Notifies any listening dependents of a change that affects the
+ * dependency.
+ *
+ * @param disableDependents Whether this Preference should disable
+ * its dependents.
+ */
+ public void notifyDependencyChange(boolean disableDependents) {
+ final List<Preference> dependents = mDependents;
+
+ if (dependents == null) {
+ return;
+ }
+
+ final int dependentsCount = dependents.size();
+ for (int i = 0; i < dependentsCount; i++) {
+ dependents.get(i).onDependencyChanged(this, disableDependents);
+ }
+ }
+
+ /**
+ * Called when the dependency changes.
+ *
+ * @param dependency The Preference that this Preference depends on.
+ * @param disableDependent Set true to disable this Preference.
+ */
+ public void onDependencyChanged(Preference dependency, boolean disableDependent) {
+ if (mDependencyMet == disableDependent) {
+ mDependencyMet = !disableDependent;
+
+ // Enabled state can change dependent preferences' states, so notify
+ notifyDependencyChange(shouldDisableDependents());
+
+ notifyChanged();
+ }
+ }
+
+ /**
+ * Called when the implicit parent dependency changes.
+ *
+ * @param parent The Preference that this Preference depends on.
+ * @param disableChild Set true to disable this Preference.
+ */
+ public void onParentChanged(Preference parent, boolean disableChild) {
+ if (mParentDependencyMet == disableChild) {
+ mParentDependencyMet = !disableChild;
+
+ // Enabled state can change dependent preferences' states, so notify
+ notifyDependencyChange(shouldDisableDependents());
+
+ notifyChanged();
+ }
+ }
+
+ /**
+ * Checks whether this preference's dependents should currently be
+ * disabled.
+ *
+ * @return True if the dependents should be disabled, otherwise false.
+ */
+ public boolean shouldDisableDependents() {
+ return !isEnabled();
+ }
+
+ /**
+ * Sets the key of a Preference that this Preference will depend on. If that
+ * Preference is not set or is off, this Preference will be disabled.
+ *
+ * @param dependencyKey The key of the Preference that this depends on.
+ */
+ public void setDependency(String dependencyKey) {
+ // Unregister the old dependency, if we had one
+ unregisterDependency();
+
+ // Register the new
+ mDependencyKey = dependencyKey;
+ registerDependency();
+ }
+
+ /**
+ * Returns the key of the dependency on this Preference.
+ *
+ * @return The key of the dependency.
+ * @see #setDependency(String)
+ */
+ public String getDependency() {
+ return mDependencyKey;
+ }
+
+ /**
+ * Called when this Preference is being removed from the hierarchy. You
+ * should remove any references to this Preference that you know about. Make
+ * sure to call through to the superclass implementation.
+ */
+ protected void onPrepareForRemoval() {
+ unregisterDependency();
+ }
+
+ /**
+ * Sets the default value for this Preference, which will be set either if
+ * persistence is off or persistence is on and the preference is not found
+ * in the persistent storage.
+ *
+ * @param defaultValue The default value.
+ */
+ public void setDefaultValue(Object defaultValue) {
+ mDefaultValue = defaultValue;
+ }
+
+ private void dispatchSetInitialValue() {
+ // By now, we know if we are persistent.
+ final boolean shouldPersist = shouldPersist();
+ if (!shouldPersist || !getSharedPreferences().contains(mKey)) {
+ if (mDefaultValue != null) {
+ onSetInitialValue(false, mDefaultValue);
+ }
+ } else {
+ onSetInitialValue(true, null);
+ }
+ }
+
+ /**
+ * Implement this to set the initial value of the Preference.
+ * <p>
+ * If <var>restorePersistedValue</var> is true, you should restore the
+ * Preference value from the {@link android.content.SharedPreferences}. If
+ * <var>restorePersistedValue</var> is false, you should set the Preference
+ * value to defaultValue that is given (and possibly store to SharedPreferences
+ * if {@link #shouldPersist()} is true).
+ * <p>
+ * This may not always be called. One example is if it should not persist
+ * but there is no default value given.
+ *
+ * @param restorePersistedValue True to restore the persisted value;
+ * false to use the given <var>defaultValue</var>.
+ * @param defaultValue The default value for this Preference. Only use this
+ * if <var>restorePersistedValue</var> is false.
+ */
+ protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
+ }
+
+ private void tryCommit(@NonNull SharedPreferences.Editor editor) {
+ if (mPreferenceManager.shouldCommit()) {
+ SharedPreferencesCompat.EditorCompat.getInstance().apply(editor);
+ }
+ }
+
+ /**
+ * Attempts to persist a String to the {@link android.content.SharedPreferences}.
+ * <p>
+ * This will check if this Preference is persistent, get an editor from
+ * the {@link PreferenceManager}, put in the string, and check if we should commit (and
+ * commit if so).
+ *
+ * @param value The value to persist.
+ * @return True if the Preference is persistent. (This is not whether the
+ * value was persisted, since we may not necessarily commit if there
+ * will be a batch commit later.)
+ * @see #getPersistedString(String)
+ */
+ protected boolean persistString(String value) {
+ if (shouldPersist()) {
+ // Shouldn't store null
+ if (value == getPersistedString(null)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ SharedPreferences.Editor editor = mPreferenceManager.getEditor();
+ editor.putString(mKey, value);
+ tryCommit(editor);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Attempts to get a persisted String from the {@link android.content.SharedPreferences}.
+ * <p>
+ * This will check if this Preference is persistent, get the SharedPreferences
+ * from the {@link PreferenceManager}, and get the value.
+ *
+ * @param defaultReturnValue The default value to return if either the
+ * Preference is not persistent or the Preference is not in the
+ * shared preferences.
+ * @return The value from the SharedPreferences or the default return
+ * value.
+ * @see #persistString(String)
+ */
+ protected String getPersistedString(String defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ return mPreferenceManager.getSharedPreferences().getString(mKey, defaultReturnValue);
+ }
+
+ /**
+ * Attempts to persist an int to the {@link android.content.SharedPreferences}.
+ *
+ * @param value The value to persist.
+ * @return True if the Preference is persistent. (This is not whether the
+ * value was persisted, since we may not necessarily commit if there
+ * will be a batch commit later.)
+ * @see #persistString(String)
+ * @see #getPersistedInt(int)
+ */
+ protected boolean persistInt(int value) {
+ if (shouldPersist()) {
+ if (value == getPersistedInt(~value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ SharedPreferences.Editor editor = mPreferenceManager.getEditor();
+ editor.putInt(mKey, value);
+ tryCommit(editor);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Attempts to get a persisted int from the {@link android.content.SharedPreferences}.
+ *
+ * @param defaultReturnValue The default value to return if either this
+ * Preference is not persistent or this Preference is not in the
+ * SharedPreferences.
+ * @return The value from the SharedPreferences or the default return
+ * value.
+ * @see #getPersistedString(String)
+ * @see #persistInt(int)
+ */
+ protected int getPersistedInt(int defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ return mPreferenceManager.getSharedPreferences().getInt(mKey, defaultReturnValue);
+ }
+
+ /**
+ * Attempts to persist a float to the {@link android.content.SharedPreferences}.
+ *
+ * @param value The value to persist.
+ * @return True if this Preference is persistent. (This is not whether the
+ * value was persisted, since we may not necessarily commit if there
+ * will be a batch commit later.)
+ * @see #persistString(String)
+ * @see #getPersistedFloat(float)
+ */
+ protected boolean persistFloat(float value) {
+ if (shouldPersist()) {
+ if (value == getPersistedFloat(Float.NaN)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ SharedPreferences.Editor editor = mPreferenceManager.getEditor();
+ editor.putFloat(mKey, value);
+ tryCommit(editor);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Attempts to get a persisted float from the {@link android.content.SharedPreferences}.
+ *
+ * @param defaultReturnValue The default value to return if either this
+ * Preference is not persistent or this Preference is not in the
+ * SharedPreferences.
+ * @return The value from the SharedPreferences or the default return
+ * value.
+ * @see #getPersistedString(String)
+ * @see #persistFloat(float)
+ */
+ protected float getPersistedFloat(float defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ return mPreferenceManager.getSharedPreferences().getFloat(mKey, defaultReturnValue);
+ }
+
+ /**
+ * Attempts to persist a long to the {@link android.content.SharedPreferences}.
+ *
+ * @param value The value to persist.
+ * @return True if this Preference is persistent. (This is not whether the
+ * value was persisted, since we may not necessarily commit if there
+ * will be a batch commit later.)
+ * @see #persistString(String)
+ * @see #getPersistedLong(long)
+ */
+ protected boolean persistLong(long value) {
+ if (shouldPersist()) {
+ if (value == getPersistedLong(~value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ SharedPreferences.Editor editor = mPreferenceManager.getEditor();
+ editor.putLong(mKey, value);
+ tryCommit(editor);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Attempts to get a persisted long from the {@link android.content.SharedPreferences}.
+ *
+ * @param defaultReturnValue The default value to return if either this
+ * Preference is not persistent or this Preference is not in the
+ * SharedPreferences.
+ * @return The value from the SharedPreferences or the default return
+ * value.
+ * @see #getPersistedString(String)
+ * @see #persistLong(long)
+ */
+ protected long getPersistedLong(long defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ return mPreferenceManager.getSharedPreferences().getLong(mKey, defaultReturnValue);
+ }
+
+ /**
+ * Attempts to persist a boolean to the {@link android.content.SharedPreferences}.
+ *
+ * @param value The value to persist.
+ * @return True if this Preference is persistent. (This is not whether the
+ * value was persisted, since we may not necessarily commit if there
+ * will be a batch commit later.)
+ * @see #persistString(String)
+ * @see #getPersistedBoolean(boolean)
+ */
+ protected boolean persistBoolean(boolean value) {
+ if (shouldPersist()) {
+ if (value == getPersistedBoolean(!value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ SharedPreferences.Editor editor = mPreferenceManager.getEditor();
+ editor.putBoolean(mKey, value);
+ tryCommit(editor);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Attempts to get a persisted boolean from the {@link android.content.SharedPreferences}.
+ *
+ * @param defaultReturnValue The default value to return if either this
+ * Preference is not persistent or this Preference is not in the
+ * SharedPreferences.
+ * @return The value from the SharedPreferences or the default return
+ * value.
+ * @see #getPersistedString(String)
+ * @see #persistBoolean(boolean)
+ */
+ protected boolean getPersistedBoolean(boolean defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ return mPreferenceManager.getSharedPreferences().getBoolean(mKey, defaultReturnValue);
+ }
+
+ @Override
+ public String toString() {
+ return getFilterableStringBuilder().toString();
+ }
+
+ /**
+ * Returns the text that will be used to filter this Preference depending on
+ * user input.
+ * <p>
+ * If overridding and calling through to the superclass, make sure to prepend
+ * your additions with a space.
+ *
+ * @return Text as a {@link StringBuilder} that will be used to filter this
+ * preference. By default, this is the title and summary
+ * (concatenated with a space).
+ */
+ StringBuilder getFilterableStringBuilder() {
+ StringBuilder sb = new StringBuilder();
+ CharSequence title = getTitle();
+ if (!TextUtils.isEmpty(title)) {
+ sb.append(title).append(' ');
+ }
+ CharSequence summary = getSummary();
+ if (!TextUtils.isEmpty(summary)) {
+ sb.append(summary).append(' ');
+ }
+ if (sb.length() > 0) {
+ // Drop the last space
+ sb.setLength(sb.length() - 1);
+ }
+ return sb;
+ }
+
+ /**
+ * Store this Preference hierarchy's frozen state into the given container.
+ *
+ * @param container The Bundle in which to save the instance of this Preference.
+ *
+ * @see #restoreHierarchyState
+ * @see #onSaveInstanceState
+ */
+ public void saveHierarchyState(Bundle container) {
+ dispatchSaveInstanceState(container);
+ }
+
+ /**
+ * Called by {@link #saveHierarchyState} to store the instance for this Preference and its children.
+ * May be overridden to modify how the save happens for children. For example, some
+ * Preference objects may want to not store an instance for their children.
+ *
+ * @param container The Bundle in which to save the instance of this Preference.
+ *
+ * @see #saveHierarchyState
+ * @see #onSaveInstanceState
+ */
+ void dispatchSaveInstanceState(Bundle container) {
+ if (hasKey()) {
+ mBaseMethodCalled = false;
+ Parcelable state = onSaveInstanceState();
+ if (!mBaseMethodCalled) {
+ throw new IllegalStateException(
+ "Derived class did not call super.onSaveInstanceState()");
+ }
+ if (state != null) {
+ container.putParcelable(mKey, state);
+ }
+ }
+ }
+
+ /**
+ * Hook allowing a Preference to generate a representation of its internal
+ * state that can later be used to create a new instance with that same
+ * state. This state should only contain information that is not persistent
+ * or can be reconstructed later.
+ *
+ * @return A Parcelable object containing the current dynamic state of
+ * this Preference, or null if there is nothing interesting to save.
+ * The default implementation returns null.
+ * @see #onRestoreInstanceState
+ * @see #saveHierarchyState
+ */
+ protected Parcelable onSaveInstanceState() {
+ mBaseMethodCalled = true;
+ return BaseSavedState.EMPTY_STATE;
+ }
+
+ /**
+ * Restore this Preference hierarchy's previously saved state from the given container.
+ *
+ * @param container The Bundle that holds the previously saved state.
+ *
+ * @see #saveHierarchyState
+ * @see #onRestoreInstanceState
+ */
+ public void restoreHierarchyState(Bundle container) {
+ dispatchRestoreInstanceState(container);
+ }
+
+ /**
+ * Called by {@link #restoreHierarchyState} to retrieve the saved state for this
+ * Preference and its children. May be overridden to modify how restoring
+ * happens to the children of a Preference. For example, some Preference objects may
+ * not want to save state for their children.
+ *
+ * @param container The Bundle that holds the previously saved state.
+ * @see #restoreHierarchyState
+ * @see #onRestoreInstanceState
+ */
+ void dispatchRestoreInstanceState(Bundle container) {
+ if (hasKey()) {
+ Parcelable state = container.getParcelable(mKey);
+ if (state != null) {
+ mBaseMethodCalled = false;
+ onRestoreInstanceState(state);
+ if (!mBaseMethodCalled) {
+ throw new IllegalStateException(
+ "Derived class did not call super.onRestoreInstanceState()");
+ }
+ }
+ }
+ }
+
+ /**
+ * Hook allowing a Preference to re-apply a representation of its internal
+ * state that had previously been generated by {@link #onSaveInstanceState}.
+ * This function will never be called with a null state.
+ *
+ * @param state The saved state that had previously been returned by
+ * {@link #onSaveInstanceState}.
+ * @see #onSaveInstanceState
+ * @see #restoreHierarchyState
+ */
+ protected void onRestoreInstanceState(Parcelable state) {
+ mBaseMethodCalled = true;
+ if (state != BaseSavedState.EMPTY_STATE && state != null) {
+ throw new IllegalArgumentException("Wrong state class -- expecting Preference State");
+ }
+ }
+
+ /**
+ * A base class for managing the instance state of a {@link Preference}.
+ */
+ public static class BaseSavedState extends AbsSavedState {
+ public BaseSavedState(Parcel source) {
+ super(source);
+ }
+
+ public BaseSavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public static final Parcelable.Creator<BaseSavedState> CREATOR =
+ new Parcelable.Creator<BaseSavedState>() {
+ public BaseSavedState createFromParcel(Parcel in) {
+ return new BaseSavedState(in);
+ }
+
+ public BaseSavedState[] newArray(int size) {
+ return new BaseSavedState[size];
+ }
+ };
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceCategory.java b/v7/preference/src/android/support/v7/preference/PreferenceCategory.java
new file mode 100644
index 0000000..bed7f7e
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/PreferenceCategory.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+/**
+ * Used to group {@link android.preference.Preference} objects
+ * and provide a disabled title above the group.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about building a settings UI with Preferences,
+ * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>
+ * guide.</p>
+ * </div>
+ */
+public class PreferenceCategory extends PreferenceGroup {
+ private static final String TAG = "PreferenceCategory";
+
+ public PreferenceCategory(
+ Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public PreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public PreferenceCategory(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.preferenceCategoryStyle);
+ }
+
+ public PreferenceCategory(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ protected boolean onPrepareAddPreference(Preference preference) {
+ if (preference instanceof PreferenceCategory) {
+ throw new IllegalArgumentException(
+ "Cannot add a " + TAG + " directly to a " + TAG);
+ }
+
+ return super.onPrepareAddPreference(preference);
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean shouldDisableDependents() {
+ return !super.isEnabled();
+ }
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java b/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java
new file mode 100644
index 0000000..f96d2ce
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.Fragment;
+import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+public abstract class PreferenceDialogFragmentCompat extends DialogFragment implements
+ DialogInterface.OnClickListener {
+
+ protected static final String ARG_KEY = "key";
+
+ private DialogPreference mPreference;
+
+ /** Which button was clicked. */
+ private int mWhichButtonClicked;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final Fragment rawFragment = getTargetFragment();
+ if (!(rawFragment instanceof DialogPreference.TargetFragment)) {
+ throw new IllegalStateException("Target fragment must implement TargetFragment" +
+ " interface");
+ }
+
+ final DialogPreference.TargetFragment fragment =
+ (DialogPreference.TargetFragment) rawFragment;
+
+ final String key = getArguments().getString(ARG_KEY);
+ mPreference = (DialogPreference) fragment.findPreference(key);
+ }
+
+ @Override
+ public @NonNull Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Context context = getActivity();
+ mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE;
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context)
+ .setTitle(mPreference.getDialogTitle())
+ .setIcon(mPreference.getDialogIcon())
+ .setPositiveButton(mPreference.getPositiveButtonText(), this)
+ .setNegativeButton(mPreference.getNegativeButtonText(), this);
+
+ View contentView = onCreateDialogView(context);
+ if (contentView != null) {
+ onBindDialogView(contentView);
+ builder.setView(contentView);
+ } else {
+ builder.setMessage(mPreference.getDialogMessage());
+ }
+
+ onPrepareDialogBuilder(builder);
+
+ // Create the dialog
+ final Dialog dialog = builder.create();
+ if (needInputMethod()) {
+ requestInputMethod(dialog);
+ }
+
+
+ return builder.create();
+ }
+
+ /**
+ * Get the preference that requested this dialog. Available after {@link #onCreate(Bundle)} has
+ * been called.
+ *
+ * @return The {@link DialogPreference} associated with this
+ * dialog.
+ */
+ public DialogPreference getPreference() {
+ return mPreference;
+ }
+
+ /**
+ * Prepares the dialog builder to be shown when the preference is clicked.
+ * Use this to set custom properties on the dialog.
+ * <p>
+ * Do not {@link AlertDialog.Builder#create()} or
+ * {@link AlertDialog.Builder#show()}.
+ */
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {}
+
+ /**
+ * Returns whether the preference needs to display a soft input method when the dialog
+ * is displayed. Default is false. Subclasses should override this method if they need
+ * the soft input method brought up automatically.
+ * @hide
+ */
+ protected boolean needInputMethod() {
+ return false;
+ }
+
+ /**
+ * Sets the required flags on the dialog window to enable input method window to show up.
+ */
+ private void requestInputMethod(Dialog dialog) {
+ Window window = dialog.getWindow();
+ window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+ }
+
+ /**
+ * Creates the content view for the dialog (if a custom content view is
+ * required). By default, it inflates the dialog layout resource if it is
+ * set.
+ *
+ * @return The content View for the dialog.
+ * @see DialogPreference#setLayoutResource(int)
+ */
+ protected View onCreateDialogView(Context context) {
+ final int resId = mPreference.getDialogLayoutResource();
+ if (resId == 0) {
+ return null;
+ }
+
+ LayoutInflater inflater = LayoutInflater.from(context);
+ return inflater.inflate(resId, null);
+ }
+
+ /**
+ * Binds views in the content View of the dialog to data.
+ * <p>
+ * Make sure to call through to the superclass implementation.
+ *
+ * @param view The content View of the dialog, if it is custom.
+ */
+ protected void onBindDialogView(View view) {
+ View dialogMessageView = view.findViewById(android.R.id.message);
+
+ if (dialogMessageView != null) {
+ final CharSequence message = mPreference.getDialogMessage();
+ int newVisibility = View.GONE;
+
+ if (!TextUtils.isEmpty(message)) {
+ if (dialogMessageView instanceof TextView) {
+ ((TextView) dialogMessageView).setText(message);
+ }
+
+ newVisibility = View.VISIBLE;
+ }
+
+ if (dialogMessageView.getVisibility() != newVisibility) {
+ dialogMessageView.setVisibility(newVisibility);
+ }
+ }
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mWhichButtonClicked = which;
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON_POSITIVE);
+ }
+
+ public abstract void onDialogClosed(boolean positiveResult);
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java b/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
new file mode 100644
index 0000000..adff8e8
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
@@ -0,0 +1,568 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.annotation.Nullable;
+import android.support.annotation.XmlRes;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.Fragment;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Shows a hierarchy of {@link Preference} objects as
+ * lists. These preferences will
+ * automatically save to {@link android.content.SharedPreferences} as the user interacts with
+ * them. To retrieve an instance of {@link android.content.SharedPreferences} that the
+ * preference hierarchy in this fragment will use, call
+ * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)}
+ * with a context in the same package as this fragment.
+ * <p>
+ * Furthermore, the preferences shown will follow the visual style of system
+ * preferences. It is easy to create a hierarchy of preferences (that can be
+ * shown on multiple screens) via XML. For these reasons, it is recommended to
+ * use this fragment (as a superclass) to deal with preferences in applications.
+ * <p>
+ * A {@link PreferenceScreen} object should be at the top of the preference
+ * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy
+ * denote a screen break--that is the preferences contained within subsequent
+ * {@link PreferenceScreen} should be shown on another screen. The preference
+ * framework handles showing these other screens from the preference hierarchy.
+ * <p>
+ * The preference hierarchy can be formed in multiple ways:
+ * <li> From an XML file specifying the hierarchy
+ * <li> From different {@link android.app.Activity Activities} that each specify its own
+ * preferences in an XML file via {@link android.app.Activity} meta-data
+ * <li> From an object hierarchy rooted with {@link PreferenceScreen}
+ * <p>
+ * To inflate from XML, use the {@link #addPreferencesFromResource(int)}. The
+ * root element should be a {@link PreferenceScreen}. Subsequent elements can point
+ * to actual {@link Preference} subclasses. As mentioned above, subsequent
+ * {@link PreferenceScreen} in the hierarchy will result in the screen break.
+ * <p>
+ * To specify an object hierarchy rooted with {@link PreferenceScreen}, use
+ * {@link #setPreferenceScreen(PreferenceScreen)}.
+ * <p>
+ * As a convenience, this fragment implements a click listener for any
+ * preference in the current hierarchy, see
+ * {@link #onPreferenceTreeClick(Preference)}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about using {@code PreferenceFragment},
+ * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>
+ * guide.</p>
+ * </div>
+ *
+ * <a name="SampleCode"></a>
+ * <h3>Sample Code</h3>
+ *
+ * <p>The following sample code shows a simple preference fragment that is
+ * populated from a resource. The resource it loads is:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/xml/preferences.xml preferences}
+ *
+ * <p>The fragment implementation itself simply populates the preferences
+ * when created. Note that the preferences framework takes care of loading
+ * the current values out of the app preferences and writing them when changed:</p>
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java
+ * fragment}
+ *
+ * @see Preference
+ * @see PreferenceScreen
+ */
+public abstract class PreferenceFragmentCompat extends Fragment implements
+ PreferenceManager.OnPreferenceTreeClickListener,
+ PreferenceManager.OnDisplayPreferenceDialogListener,
+ PreferenceManager.OnNavigateToScreenListener,
+ DialogPreference.TargetFragment {
+
+ /**
+ * Fragment argument used to specify the tag of the desired root
+ * {@link android.support.v7.preference.PreferenceScreen} object.
+ */
+ public static final String ARG_PREFERENCE_ROOT =
+ "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT";
+
+ private static final String PREFERENCES_TAG = "android:preferences";
+
+ private static final String DIALOG_FRAGMENT_TAG =
+ "android.support.v7.preference.PreferenceFragment.DIALOG";
+
+ private PreferenceManager mPreferenceManager;
+ private RecyclerView mList;
+ private boolean mHavePrefs;
+ private boolean mInitDone;
+
+ private Context mStyledContext;
+
+ private int mLayoutResId = R.layout.preference_list_fragment;
+
+ /**
+ * The starting request code given out to preference framework.
+ */
+ private static final int FIRST_REQUEST_CODE = 100;
+
+ private static final int MSG_BIND_PREFERENCES = 1;
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+
+ case MSG_BIND_PREFERENCES:
+ bindPreferences();
+ break;
+ }
+ }
+ };
+
+ final private Runnable mRequestFocus = new Runnable() {
+ public void run() {
+ mList.focusableViewAvailable(mList);
+ }
+ };
+
+ /**
+ * Interface that PreferenceFragment's containing activity should
+ * implement to be able to process preference items that wish to
+ * switch to a specified fragment.
+ */
+ public interface OnPreferenceStartFragmentCallback {
+ /**
+ * Called when the user has clicked on a Preference that has
+ * a fragment class name associated with it. The implementation
+ * should instantiate and switch to an instance of the given
+ * fragment.
+ * @param caller The fragment requesting navigation.
+ * @param pref The preference requesting the fragment.
+ * @return true if the fragment creation has been handled
+ */
+ boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref);
+ }
+
+ /**
+ * Interface that PreferenceFragment's containing activity should
+ * implement to be able to process preference items that wish to
+ * switch to a new screen of preferences.
+ */
+ public interface OnPreferenceStartScreenCallback {
+ /**
+ * Called when the user has clicked on a PreferenceScreen item in order to navigate to a new
+ * screen of preferences.
+ * @param caller The fragment requesting navigation.
+ * @param pref The preference screen to navigate to.
+ * @return true if the screen navigation has been handled
+ */
+ boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen pref);
+ }
+
+ public interface OnPreferenceDisplayDialogCallback {
+
+ /**
+ *
+ * @param caller The fragment containing the preference requesting the dialog.
+ * @param pref The preference requesting the dialog.
+ * @return true if the dialog creation has been handled.
+ */
+ boolean onPreferenceDisplayDialog(PreferenceFragmentCompat caller, Preference pref);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final TypedValue tv = new TypedValue();
+ getActivity().getTheme().resolveAttribute(R.attr.preferenceTheme, tv, true);
+ final int theme = tv.resourceId;
+ if (theme <= 0) {
+ throw new IllegalStateException("Must specify preferenceTheme in theme");
+ }
+ mStyledContext = new ContextThemeWrapper(getActivity(), theme);
+
+ mPreferenceManager = new PreferenceManager(mStyledContext);
+ mPreferenceManager.setOnNavigateToScreenListener(this);
+ final Bundle args = getArguments();
+ final String rootKey;
+ if (args != null) {
+ rootKey = getArguments().getString(ARG_PREFERENCE_ROOT);
+ } else {
+ rootKey = null;
+ }
+ onCreatePreferences(savedInstanceState, rootKey);
+ }
+
+ /**
+ * Called during {@link #onCreate(Bundle)} to supply the preferences for this fragment.
+ * Subclasses are expected to call {@link #setPreferenceScreen(PreferenceScreen)} either
+ * directly or via helper methods such as {@link #addPreferencesFromResource(int)}.
+ *
+ * @param savedInstanceState If the fragment is being re-created from
+ * a previous saved state, this is the state.
+ * @param rootKey If non-null, this preference fragment should be rooted at the
+ * {@link android.support.v7.preference.PreferenceScreen} with this key.
+ */
+ public abstract void onCreatePreferences(Bundle savedInstanceState, String rootKey);
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ TypedArray a = mStyledContext.obtainStyledAttributes(null,
+ R.styleable.PreferenceFragmentCompat,
+ R.attr.preferenceFragmentStyle,
+ 0);
+
+ mLayoutResId = a.getResourceId(R.styleable.PreferenceFragmentCompat_layout,
+ mLayoutResId);
+
+ a.recycle();
+
+ final View view = inflater.inflate(mLayoutResId, container, false);
+
+ final View rawListContainer = view.findViewById(R.id.list_container);
+ if (!(rawListContainer instanceof ViewGroup)) {
+ throw new RuntimeException("Content has view with id attribute 'R.id.list_container' "
+ + "that is not a ViewGroup class");
+ }
+
+ final ViewGroup listContainer = (ViewGroup) rawListContainer;
+
+ final RecyclerView listView = onCreateRecyclerView(inflater, listContainer,
+ savedInstanceState);
+ if (listView == null) {
+ throw new RuntimeException("Could not create RecyclerView");
+ }
+
+ mList = listView;
+ listContainer.addView(mList);
+ mHandler.post(mRequestFocus);
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ if (mHavePrefs) {
+ bindPreferences();
+ }
+
+ mInitDone = true;
+
+ if (savedInstanceState != null) {
+ Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG);
+ if (container != null) {
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ preferenceScreen.restoreHierarchyState(container);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mPreferenceManager.setOnPreferenceTreeClickListener(this);
+ mPreferenceManager.setOnDisplayPreferenceDialogListener(this);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mPreferenceManager.setOnPreferenceTreeClickListener(null);
+ mPreferenceManager.setOnDisplayPreferenceDialogListener(null);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mList = null;
+ mHandler.removeCallbacks(mRequestFocus);
+ mHandler.removeMessages(MSG_BIND_PREFERENCES);
+ super.onDestroyView();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ Bundle container = new Bundle();
+ preferenceScreen.saveHierarchyState(container);
+ outState.putBundle(PREFERENCES_TAG, container);
+ }
+ }
+
+ /**
+ * Returns the {@link PreferenceManager} used by this fragment.
+ * @return The {@link PreferenceManager}.
+ */
+ public PreferenceManager getPreferenceManager() {
+ return mPreferenceManager;
+ }
+
+ /**
+ * Sets the root of the preference hierarchy that this fragment is showing.
+ *
+ * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
+ */
+ public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+ if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {
+ onUnbindPreferences();
+ mHavePrefs = true;
+ if (mInitDone) {
+ postBindPreferences();
+ }
+ }
+ }
+
+ /**
+ * Gets the root of the preference hierarchy that this fragment is showing.
+ *
+ * @return The {@link PreferenceScreen} that is the root of the preference
+ * hierarchy.
+ */
+ public PreferenceScreen getPreferenceScreen() {
+ return mPreferenceManager.getPreferenceScreen();
+ }
+
+ /**
+ * Inflates the given XML resource and adds the preference hierarchy to the current
+ * preference hierarchy.
+ *
+ * @param preferencesResId The XML resource ID to inflate.
+ */
+ public void addPreferencesFromResource(@XmlRes int preferencesResId) {
+ requirePreferenceManager();
+
+ setPreferenceScreen(mPreferenceManager.inflateFromResource(mStyledContext,
+ preferencesResId, getPreferenceScreen()));
+ }
+
+ /**
+ * Inflates the given XML resource and replaces the current preference hierarchy (if any) with
+ * the preference hierarchy rooted at {@code key}.
+ *
+ * @param preferencesResId The XML resource ID to inflate.
+ * @param key The preference key of the {@link android.support.v7.preference.PreferenceScreen}
+ * to use as the root of the preference hierarchy, or null to use the root
+ * {@link android.support.v7.preference.PreferenceScreen}.
+ */
+ public void setPreferencesFromResource(@XmlRes int preferencesResId, @Nullable String key) {
+ requirePreferenceManager();
+
+ final PreferenceScreen xmlRoot = mPreferenceManager.inflateFromResource(mStyledContext,
+ preferencesResId, null);
+
+ final Preference root;
+ if (key != null) {
+ root = xmlRoot.findPreference(key);
+ if (!(root instanceof PreferenceScreen)) {
+ throw new IllegalArgumentException("Preference object with key " + key
+ + " is not a PreferenceScreen");
+ }
+ } else {
+ root = xmlRoot;
+ }
+
+ setPreferenceScreen((PreferenceScreen) root);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean onPreferenceTreeClick(Preference preference) {
+ if (preference.getFragment() != null) {
+ boolean handled = false;
+ if (getTargetFragment() instanceof OnPreferenceStartFragmentCallback) {
+ handled = ((OnPreferenceStartFragmentCallback) getTargetFragment())
+ .onPreferenceStartFragment(this, preference);
+ }
+ if (!handled && getActivity() instanceof OnPreferenceStartFragmentCallback){
+ handled = ((OnPreferenceStartFragmentCallback) getActivity())
+ .onPreferenceStartFragment(this, preference);
+ }
+ return handled;
+ }
+ return false;
+ }
+
+ /**
+ * Called by
+ * {@link android.support.v7.preference.PreferenceScreen#onClick()} in order to navigate to a
+ * new screen of preferences. Calls
+ * {@link PreferenceFragmentCompat.OnPreferenceStartScreenCallback#onPreferenceStartScreen}
+ * if the target fragment or containing activity implements
+ * {@link PreferenceFragmentCompat.OnPreferenceStartScreenCallback}.
+ * @param preferenceScreen The {@link android.support.v7.preference.PreferenceScreen} to
+ * navigate to.
+ */
+ @Override
+ public void onNavigateToScreen(PreferenceScreen preferenceScreen) {
+ boolean handled = false;
+ if (getTargetFragment() instanceof OnPreferenceStartScreenCallback) {
+ handled = ((OnPreferenceStartScreenCallback) getTargetFragment())
+ .onPreferenceStartScreen(this, preferenceScreen);
+ }
+ if (!handled && getActivity() instanceof OnPreferenceStartScreenCallback) {
+ ((OnPreferenceStartScreenCallback) getActivity())
+ .onPreferenceStartScreen(this, preferenceScreen);
+ }
+ }
+
+ /**
+ * Finds a {@link Preference} based on its key.
+ *
+ * @param key The key of the preference to retrieve.
+ * @return The {@link Preference} with the key, or null.
+ * @see android.support.v7.preference.PreferenceGroup#findPreference(CharSequence)
+ */
+ public Preference findPreference(CharSequence key) {
+ if (mPreferenceManager == null) {
+ return null;
+ }
+ return mPreferenceManager.findPreference(key);
+ }
+
+ private void requirePreferenceManager() {
+ if (mPreferenceManager == null) {
+ throw new RuntimeException("This should be called after super.onCreate.");
+ }
+ }
+
+ private void postBindPreferences() {
+ if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
+ mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
+ }
+
+ private void bindPreferences() {
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ getListView().setAdapter(onCreateAdapter(preferenceScreen));
+ }
+ onBindPreferences();
+ }
+
+ /** @hide */
+ protected void onBindPreferences() {
+ }
+
+ /** @hide */
+ protected void onUnbindPreferences() {
+ }
+
+ public final RecyclerView getListView() {
+ return mList;
+ }
+
+ /**
+ * Creates the {@link android.support.v7.widget.RecyclerView} used to display the preferences.
+ * Subclasses may override this to return a customized
+ * {@link android.support.v7.widget.RecyclerView}.
+ * @param inflater The LayoutInflater object that can be used to inflate the
+ * {@link android.support.v7.widget.RecyclerView}.
+ * @param parent The parent {@link android.view.View} that the RecyclerView will be attached to.
+ * This method should not add the view itself, but this can be used to generate
+ * the LayoutParams of the view.
+ * @param savedInstanceState If non-null, this view is being re-constructed from a previous
+ * saved state as given here
+ * @return A new RecyclerView object to be placed into the view hierarchy
+ */
+ public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
+ Bundle savedInstanceState) {
+ RecyclerView recyclerView = (RecyclerView) inflater
+ .inflate(R.layout.preference_recyclerview, parent, false);
+
+ recyclerView.setLayoutManager(onCreateLayoutManager());
+
+ return recyclerView;
+ }
+
+ /**
+ * Called from {@link #onCreateRecyclerView} to create the
+ * {@link android.support.v7.widget.RecyclerView.LayoutManager} for the created
+ * {@link android.support.v7.widget.RecyclerView}.
+ * @return A new {@link android.support.v7.widget.RecyclerView.LayoutManager} instance.
+ */
+ public RecyclerView.LayoutManager onCreateLayoutManager() {
+ return new LinearLayoutManager(getActivity());
+ }
+
+ /**
+ * Creates the root adapter.
+ *
+ * @param preferenceScreen Preference screen object to create the adapter for.
+ * @return An adapter that contains the preferences contained in this {@link PreferenceScreen}.
+ */
+ protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
+ return new PreferenceGroupAdapter(preferenceScreen);
+ }
+
+ /**
+ * Called when a preference in the tree requests to display a dialog. Subclasses should
+ * override this method to display custom dialogs or to handle dialogs for custom preference
+ * classes.
+ *
+ * @param preference The Preference object requesting the dialog.
+ */
+ @Override
+ public void onDisplayPreferenceDialog(Preference preference) {
+
+ boolean handled = false;
+ if (getTargetFragment() instanceof OnPreferenceDisplayDialogCallback) {
+ handled = ((OnPreferenceDisplayDialogCallback) getTargetFragment())
+ .onPreferenceDisplayDialog(this, preference);
+ }
+ if (!handled && getActivity() instanceof OnPreferenceDisplayDialogCallback) {
+ handled = ((OnPreferenceDisplayDialogCallback) getActivity())
+ .onPreferenceDisplayDialog(this, preference);
+ }
+
+ if (handled) {
+ return;
+ }
+
+ // check if dialog is already showing
+ if (getFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
+ return;
+ }
+
+ final DialogFragment f;
+ if (preference instanceof EditTextPreference) {
+ f = EditTextPreferenceDialogFragmentCompat.newInstance(preference.getKey());
+ } else if (preference instanceof ListPreference) {
+ f = ListPreferenceDialogFragmentCompat.newInstance(preference.getKey());
+ } else {
+ throw new IllegalArgumentException("Tried to display dialog for unknown " +
+ "preference type. Did you forget to override onDisplayPreferenceDialog()?");
+ }
+ f.setTargetFragment(this, 0);
+ f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceGroup.java b/v7/preference/src/android/support/v7/preference/PreferenceGroup.java
new file mode 100644
index 0000000..f1c79dd
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/PreferenceGroup.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A container for multiple
+ * {@link Preference} objects. It is a base class for Preference objects that are
+ * parents, such as {@link PreferenceCategory} and {@link PreferenceScreen}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about building a settings UI with Preferences,
+ * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>
+ * guide.</p>
+ * </div>
+ *
+ * @attr ref android.R.styleable#PreferenceGroup_orderingFromXml
+ */
+public abstract class PreferenceGroup extends Preference {
+ /**
+ * The container for child {@link Preference}s. This is sorted based on the
+ * ordering, please use {@link #addPreference(Preference)} instead of adding
+ * to this directly.
+ */
+ private List<Preference> mPreferenceList;
+
+ private boolean mOrderingAsAdded = true;
+
+ private int mCurrentPreferenceOrder = 0;
+
+ private boolean mAttachedToActivity = false;
+
+ public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ mPreferenceList = new ArrayList<>();
+
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.PreferenceGroup, defStyleAttr, defStyleRes);
+
+ mOrderingAsAdded =
+ TypedArrayUtils.getBoolean(a, R.styleable.PreferenceGroup_orderingFromXml,
+ R.styleable.PreferenceGroup_orderingFromXml, true);
+
+ a.recycle();
+ }
+
+ public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public PreferenceGroup(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ /**
+ * Whether to order the {@link Preference} children of this group as they
+ * are added. If this is false, the ordering will follow each Preference
+ * order and default to alphabetic for those without an order.
+ * <p>
+ * If this is called after preferences are added, they will not be
+ * re-ordered in the order they were added, hence call this method early on.
+ *
+ * @param orderingAsAdded Whether to order according to the order added.
+ * @see Preference#setOrder(int)
+ */
+ public void setOrderingAsAdded(boolean orderingAsAdded) {
+ mOrderingAsAdded = orderingAsAdded;
+ }
+
+ /**
+ * Whether this group is ordering preferences in the order they are added.
+ *
+ * @return Whether this group orders based on the order the children are added.
+ * @see #setOrderingAsAdded(boolean)
+ */
+ public boolean isOrderingAsAdded() {
+ return mOrderingAsAdded;
+ }
+
+ /**
+ * Called by the inflater to add an item to this group.
+ */
+ public void addItemFromInflater(Preference preference) {
+ addPreference(preference);
+ }
+
+ /**
+ * Returns the number of children {@link Preference}s.
+ * @return The number of preference children in this group.
+ */
+ public int getPreferenceCount() {
+ return mPreferenceList.size();
+ }
+
+ /**
+ * Returns the {@link Preference} at a particular index.
+ *
+ * @param index The index of the {@link Preference} to retrieve.
+ * @return The {@link Preference}.
+ */
+ public Preference getPreference(int index) {
+ return mPreferenceList.get(index);
+ }
+
+ /**
+ * Adds a {@link Preference} at the correct position based on the
+ * preference's order.
+ *
+ * @param preference The preference to add.
+ * @return Whether the preference is now in this group.
+ */
+ public boolean addPreference(Preference preference) {
+ if (mPreferenceList.contains(preference)) {
+ // Exists
+ return true;
+ }
+
+ if (preference.getOrder() == DEFAULT_ORDER) {
+ if (mOrderingAsAdded) {
+ preference.setOrder(mCurrentPreferenceOrder++);
+ }
+
+ if (preference instanceof PreferenceGroup) {
+ // TODO: fix (method is called tail recursively when inflating,
+ // so we won't end up properly passing this flag down to children
+ ((PreferenceGroup)preference).setOrderingAsAdded(mOrderingAsAdded);
+ }
+ }
+
+ int insertionIndex = Collections.binarySearch(mPreferenceList, preference);
+ if (insertionIndex < 0) {
+ insertionIndex = insertionIndex * -1 - 1;
+ }
+
+ if (!onPrepareAddPreference(preference)) {
+ return false;
+ }
+
+ synchronized(this) {
+ mPreferenceList.add(insertionIndex, preference);
+ }
+
+ preference.onAttachedToHierarchy(getPreferenceManager());
+
+ if (mAttachedToActivity) {
+ preference.onAttached();
+ }
+
+ notifyHierarchyChanged();
+
+ return true;
+ }
+
+ /**
+ * Removes a {@link Preference} from this group.
+ *
+ * @param preference The preference to remove.
+ * @return Whether the preference was found and removed.
+ */
+ public boolean removePreference(Preference preference) {
+ final boolean returnValue = removePreferenceInt(preference);
+ notifyHierarchyChanged();
+ return returnValue;
+ }
+
+ private boolean removePreferenceInt(Preference preference) {
+ synchronized(this) {
+ preference.onPrepareForRemoval();
+ return mPreferenceList.remove(preference);
+ }
+ }
+
+ /**
+ * Removes all {@link Preference Preferences} from this group.
+ */
+ public void removeAll() {
+ synchronized(this) {
+ List<Preference> preferenceList = mPreferenceList;
+ for (int i = preferenceList.size() - 1; i >= 0; i--) {
+ removePreferenceInt(preferenceList.get(0));
+ }
+ }
+ notifyHierarchyChanged();
+ }
+
+ /**
+ * Prepares a {@link Preference} to be added to the group.
+ *
+ * @param preference The preference to add.
+ * @return Whether to allow adding the preference (true), or not (false).
+ */
+ protected boolean onPrepareAddPreference(Preference preference) {
+ preference.onParentChanged(this, shouldDisableDependents());
+ return true;
+ }
+
+ /**
+ * Finds a {@link Preference} based on its key. If two {@link Preference}
+ * share the same key (not recommended), the first to appear will be
+ * returned (to retrieve the other preference with the same key, call this
+ * method on the first preference). If this preference has the key, it will
+ * not be returned.
+ * <p>
+ * This will recursively search for the preference into children that are
+ * also {@link PreferenceGroup PreferenceGroups}.
+ *
+ * @param key The key of the preference to retrieve.
+ * @return The {@link Preference} with the key, or null.
+ */
+ public Preference findPreference(CharSequence key) {
+ if (TextUtils.equals(getKey(), key)) {
+ return this;
+ }
+ final int preferenceCount = getPreferenceCount();
+ for (int i = 0; i < preferenceCount; i++) {
+ final Preference preference = getPreference(i);
+ final String curKey = preference.getKey();
+
+ if (curKey != null && curKey.equals(key)) {
+ return preference;
+ }
+
+ if (preference instanceof PreferenceGroup) {
+ final Preference returnedPreference = ((PreferenceGroup)preference)
+ .findPreference(key);
+ if (returnedPreference != null) {
+ return returnedPreference;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Whether this preference group should be shown on the same screen as its
+ * contained preferences.
+ *
+ * @return True if the contained preferences should be shown on the same
+ * screen as this preference.
+ */
+ protected boolean isOnSameScreenAsChildren() {
+ return true;
+ }
+
+ @Override
+ protected void onAttached() {
+ super.onAttached();
+
+ // Mark as attached so if a preference is later added to this group, we
+ // can tell it we are already attached
+ mAttachedToActivity = true;
+
+ // Dispatch to all contained preferences
+ final int preferenceCount = getPreferenceCount();
+ for (int i = 0; i < preferenceCount; i++) {
+ getPreference(i).onAttached();
+ }
+ }
+
+ @Override
+ protected void onPrepareForRemoval() {
+ super.onPrepareForRemoval();
+
+ // We won't be attached to the activity anymore
+ mAttachedToActivity = false;
+ }
+
+ @Override
+ public void notifyDependencyChange(boolean disableDependents) {
+ super.notifyDependencyChange(disableDependents);
+
+ // Child preferences have an implicit dependency on their containing
+ // group. Dispatch dependency change to all contained preferences.
+ final int preferenceCount = getPreferenceCount();
+ for (int i = 0; i < preferenceCount; i++) {
+ getPreference(i).onParentChanged(this, disableDependents);
+ }
+ }
+
+ void sortPreferences() {
+ synchronized (this) {
+ Collections.sort(mPreferenceList);
+ }
+ }
+
+ @Override
+ protected void dispatchSaveInstanceState(Bundle container) {
+ super.dispatchSaveInstanceState(container);
+
+ // Dispatch to all contained preferences
+ final int preferenceCount = getPreferenceCount();
+ for (int i = 0; i < preferenceCount; i++) {
+ getPreference(i).dispatchSaveInstanceState(container);
+ }
+ }
+
+ @Override
+ protected void dispatchRestoreInstanceState(Bundle container) {
+ super.dispatchRestoreInstanceState(container);
+
+ // Dispatch to all contained preferences
+ final int preferenceCount = getPreferenceCount();
+ for (int i = 0; i < preferenceCount; i++) {
+ getPreference(i).dispatchRestoreInstanceState(container);
+ }
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceGroupAdapter.java b/v7/preference/src/android/support/v7/preference/PreferenceGroupAdapter.java
new file mode 100644
index 0000000..5ba0f90
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/PreferenceGroupAdapter.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.os.Handler;
+import android.support.v7.widget.RecyclerView;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An adapter that connects a RecyclerView to the {@link Preference} objects contained in the
+ * associated {@link PreferenceGroup}.
+ *
+ * @hide
+ */
+public class PreferenceGroupAdapter extends RecyclerView.Adapter<PreferenceViewHolder>
+ implements Preference.OnPreferenceChangeInternalListener {
+
+ private static final String TAG = "PreferenceGroupAdapter";
+
+ /**
+ * The group that we are providing data from.
+ */
+ private PreferenceGroup mPreferenceGroup;
+
+ /**
+ * Maps a position into this adapter -> {@link Preference}. These
+ * {@link Preference}s don't have to be direct children of this
+ * {@link PreferenceGroup}, they can be grand children or younger)
+ */
+ private List<Preference> mPreferenceList;
+
+ /**
+ * Contains a sorted list of all preferences in this adapter regardless of visibility. This is
+ * used to construct {@link #mPreferenceList}
+ */
+ private List<Preference> mPreferenceListInternal;
+
+ /**
+ * List of unique Preference and its subclasses' names and layouts.
+ */
+ private List<PreferenceLayout> mPreferenceLayouts;
+
+
+ private PreferenceLayout mTempPreferenceLayout = new PreferenceLayout();
+
+ private volatile boolean mIsSyncing = false;
+
+ private Handler mHandler = new Handler();
+
+ private Runnable mSyncRunnable = new Runnable() {
+ public void run() {
+ syncMyPreferences();
+ }
+ };
+
+ private static class PreferenceLayout {
+ private int resId;
+ private int widgetResId;
+ private String name;
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof PreferenceLayout)) {
+ return false;
+ }
+ final PreferenceLayout other = (PreferenceLayout) o;
+ return resId == other.resId
+ && widgetResId == other.widgetResId
+ && TextUtils.equals(name, other.name);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + resId;
+ result = 31 * result + widgetResId;
+ result = 31 * result + name.hashCode();
+ return result;
+ }
+ }
+
+ public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
+ mPreferenceGroup = preferenceGroup;
+ // If this group gets or loses any children, let us know
+ mPreferenceGroup.setOnPreferenceChangeInternalListener(this);
+
+ mPreferenceList = new ArrayList<>();
+ mPreferenceListInternal = new ArrayList<>();
+ mPreferenceLayouts = new ArrayList<>();
+
+ setHasStableIds(true);
+
+ syncMyPreferences();
+ }
+
+ private void syncMyPreferences() {
+ synchronized(this) {
+ if (mIsSyncing) {
+ return;
+ }
+
+ mIsSyncing = true;
+ }
+
+ List<Preference> newPreferenceList = new ArrayList<>(mPreferenceListInternal.size());
+ flattenPreferenceGroup(newPreferenceList, mPreferenceGroup);
+ mPreferenceListInternal = newPreferenceList;
+
+ mPreferenceList = new ArrayList<>(mPreferenceListInternal.size());
+ // Copy only the visible preferences to the active list
+ for (final Preference preference : mPreferenceListInternal) {
+ if (preference.isVisible()) {
+ mPreferenceList.add(preference);
+ }
+ }
+
+ notifyDataSetChanged();
+
+ synchronized(this) {
+ mIsSyncing = false;
+ notifyAll();
+ }
+ }
+
+ private void flattenPreferenceGroup(List<Preference> preferences, PreferenceGroup group) {
+ group.sortPreferences();
+
+ final int groupSize = group.getPreferenceCount();
+ for (int i = 0; i < groupSize; i++) {
+ final Preference preference = group.getPreference(i);
+
+ preferences.add(preference);
+
+ addPreferenceClassName(preference);
+
+ if (preference instanceof PreferenceGroup) {
+ final PreferenceGroup preferenceAsGroup = (PreferenceGroup) preference;
+ if (preferenceAsGroup.isOnSameScreenAsChildren()) {
+ flattenPreferenceGroup(preferences, preferenceAsGroup);
+ }
+ }
+
+ preference.setOnPreferenceChangeInternalListener(this);
+ }
+ }
+
+ /**
+ * Creates a string that includes the preference name, layout id and widget layout id.
+ * If a particular preference type uses 2 different resources, they will be treated as
+ * different view types.
+ */
+ private PreferenceLayout createPreferenceLayout(Preference preference, PreferenceLayout in) {
+ PreferenceLayout pl = in != null? in : new PreferenceLayout();
+ pl.name = preference.getClass().getName();
+ pl.resId = preference.getLayoutResource();
+ pl.widgetResId = preference.getWidgetLayoutResource();
+ return pl;
+ }
+
+ private void addPreferenceClassName(Preference preference) {
+ final PreferenceLayout pl = createPreferenceLayout(preference, null);
+ if (!mPreferenceLayouts.contains(pl)) {
+ mPreferenceLayouts.add(pl);
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return mPreferenceList.size();
+ }
+
+ public Preference getItem(int position) {
+ if (position < 0 || position >= getItemCount()) return null;
+ return mPreferenceList.get(position);
+ }
+
+ public long getItemId(int position) {
+ if (position < 0 || position >= getItemCount()) return ListView.INVALID_ROW_ID;
+ return this.getItem(position).getId();
+ }
+
+ public void onPreferenceChange(Preference preference) {
+ notifyDataSetChanged();
+ }
+
+ public void onPreferenceHierarchyChange(Preference preference) {
+ mHandler.removeCallbacks(mSyncRunnable);
+ mHandler.post(mSyncRunnable);
+ }
+
+ @Override
+ public void onPreferenceVisibilityChange(Preference preference) {
+ if (preference.isVisible()) {
+ // The preference has become visible, we need to add it in the correct location.
+
+ // Index (inferred) in mPreferenceList of the item preceding the newly visible pref
+ int previousVisibleIndex = -1;
+ for (final Preference pref : mPreferenceListInternal) {
+ if (preference.equals(pref)) {
+ break;
+ }
+ if (pref.isVisible()) {
+ previousVisibleIndex++;
+ }
+ }
+ // Insert this preference into the active list just after the previous visible entry
+ mPreferenceList.add(previousVisibleIndex + 1, preference);
+
+ notifyItemInserted(previousVisibleIndex + 1);
+ } else {
+ // The preference has become invisibile. Find it in the list and remove it.
+
+ int removalIndex;
+ final int listSize = mPreferenceList.size();
+ for (removalIndex = 0; removalIndex < listSize; removalIndex++) {
+ if (preference.equals(mPreferenceList.get(removalIndex))) {
+ break;
+ }
+ }
+ mPreferenceList.remove(removalIndex);
+ notifyItemRemoved(removalIndex);
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ final Preference preference = this.getItem(position);
+
+ mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout);
+
+ return mPreferenceLayouts.indexOf(mTempPreferenceLayout);
+ }
+
+ @Override
+ public PreferenceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ final PreferenceLayout pl = mPreferenceLayouts.get(viewType);
+ final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+
+ final ViewGroup view = (ViewGroup) inflater.inflate(pl.resId, parent, false);
+
+ final ViewGroup widgetFrame = (ViewGroup) view.findViewById(R.id.widget_frame);
+ if (widgetFrame != null) {
+ if (pl.widgetResId != 0) {
+ inflater.inflate(pl.widgetResId, widgetFrame);
+ } else {
+ widgetFrame.setVisibility(View.GONE);
+ }
+ }
+
+ return new PreferenceViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder, int position) {
+ final Preference preference = getItem(position);
+ preference.onBindViewHolder(holder);
+ }
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceInflater.java b/v7/preference/src/android/support/v7/preference/PreferenceInflater.java
new file mode 100644
index 0000000..fa4e29f
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/PreferenceInflater.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.XmlResourceParser;
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.util.Xml;
+import android.view.InflateException;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+
+/**
+ * The {@link PreferenceInflater} is used to inflate preference hierarchies from
+ * XML files.
+ */
+class PreferenceInflater {
+ private static final String TAG = "PreferenceInflater";
+
+ private static final Class<?>[] CONSTRUCTOR_SIGNATURE = new Class[] {
+ Context.class, AttributeSet.class};
+
+ private static final HashMap<String, Constructor> CONSTRUCTOR_MAP = new HashMap<>();
+
+ private final Context mContext;
+
+ private final Object[] mConstructorArgs = new Object[2];
+
+ private PreferenceManager mPreferenceManager;
+
+ private String[] mDefaultPackages;
+
+ private static final String INTENT_TAG_NAME = "intent";
+ private static final String EXTRA_TAG_NAME = "extra";
+
+ public PreferenceInflater(Context context, PreferenceManager preferenceManager) {
+ mContext = context;
+ init(preferenceManager);
+ }
+
+ private void init(PreferenceManager preferenceManager) {
+ mPreferenceManager = preferenceManager;
+ if (Build.VERSION.SDK_INT >= 14) {
+ setDefaultPackages(new String[] {"android.support.v14.preference.",
+ "android.support.v7.preference."});
+ } else {
+ setDefaultPackages(new String[] {"android.support.v7.preference."});
+ }
+ }
+
+ /**
+ * Sets the default package that will be searched for classes to construct
+ * for tag names that have no explicit package.
+ *
+ * @param defaultPackage The default package. This will be prepended to the
+ * tag name, so it should end with a period.
+ */
+ public void setDefaultPackages(String[] defaultPackage) {
+ mDefaultPackages = defaultPackage;
+ }
+
+ /**
+ * Returns the default package, or null if it is not set.
+ *
+ * @see #setDefaultPackages(String[])
+ * @return The default package.
+ */
+ public String[] getDefaultPackages() {
+ return mDefaultPackages;
+ }
+
+ /**
+ * Return the context we are running in, for access to resources, class
+ * loader, etc.
+ */
+ public Context getContext() {
+ return mContext;
+ }
+
+ /**
+ * Inflate a new item hierarchy from the specified xml resource. Throws
+ * InflaterException if there is an error.
+ *
+ * @param resource ID for an XML resource to load (e.g.,
+ * <code>R.layout.main_page</code>)
+ * @param root Optional parent of the generated hierarchy.
+ * @return The root of the inflated hierarchy. If root was supplied,
+ * this is the root item; otherwise it is the root of the inflated
+ * XML file.
+ */
+ public Preference inflate(int resource, @Nullable PreferenceGroup root) {
+ XmlResourceParser parser = getContext().getResources().getXml(resource);
+ try {
+ return inflate(parser, root);
+ } finally {
+ parser.close();
+ }
+ }
+
+ /**
+ * Inflate a new hierarchy from the specified XML node. Throws
+ * InflaterException if there is an error.
+ * <p>
+ * <em><strong>Important</strong></em> For performance
+ * reasons, inflation relies heavily on pre-processing of XML files
+ * that is done at build time. Therefore, it is not currently possible to
+ * use inflater with an XmlPullParser over a plain XML file at runtime.
+ *
+ * @param parser XML dom node containing the description of the
+ * hierarchy.
+ * @param root Optional to be the parent of the generated hierarchy (if
+ * <em>attachToRoot</em> is true), or else simply an object that
+ * provides a set of values for root of the returned
+ * hierarchy (if <em>attachToRoot</em> is false.)
+ * @return The root of the inflated hierarchy. If root was supplied,
+ * this is root; otherwise it is the root of
+ * the inflated XML file.
+ */
+ public Preference inflate(XmlPullParser parser, @Nullable PreferenceGroup root) {
+ synchronized (mConstructorArgs) {
+ final AttributeSet attrs = Xml.asAttributeSet(parser);
+ mConstructorArgs[0] = mContext;
+ final Preference result;
+
+ try {
+ // Look for the root node.
+ int type;
+ do {
+ type = parser.next();
+ } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);
+
+ if (type != XmlPullParser.START_TAG) {
+ throw new InflateException(parser.getPositionDescription()
+ + ": No start tag found!");
+ }
+
+ // Temp is the root that was found in the xml
+ Preference xmlRoot = createItemFromTag(parser.getName(),
+ attrs);
+
+ result = onMergeRoots(root, (PreferenceGroup) xmlRoot);
+
+ // Inflate all children under temp
+ rInflate(parser, result, attrs);
+
+ } catch (InflateException e) {
+ throw e;
+ } catch (XmlPullParserException e) {
+ final InflateException ex = new InflateException(e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ } catch (IOException e) {
+ final InflateException ex = new InflateException(
+ parser.getPositionDescription()
+ + ": " + e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ }
+
+ return result;
+ }
+ }
+
+ private @NonNull PreferenceGroup onMergeRoots(PreferenceGroup givenRoot,
+ @NonNull PreferenceGroup xmlRoot) {
+ // If we were given a Preferences, use it as the root (ignoring the root
+ // Preferences from the XML file).
+ if (givenRoot == null) {
+ xmlRoot.onAttachedToHierarchy(mPreferenceManager);
+ return xmlRoot;
+ } else {
+ return givenRoot;
+ }
+ }
+
+ /**
+ * Low-level function for instantiating by name. This attempts to
+ * instantiate class of the given <var>name</var> found in this
+ * inflater's ClassLoader.
+ *
+ * <p>
+ * There are two things that can happen in an error case: either the
+ * exception describing the error will be thrown, or a null will be
+ * returned. You must deal with both possibilities -- the former will happen
+ * the first time createItem() is called for a class of a particular name,
+ * the latter every time there-after for that class name.
+ *
+ * @param name The full name of the class to be instantiated.
+ * @param attrs The XML attributes supplied for this instance.
+ *
+ * @return The newly instantied item, or null.
+ */
+ private Preference createItem(@NonNull String name, @Nullable String[] prefixes,
+ AttributeSet attrs)
+ throws ClassNotFoundException, InflateException {
+ Constructor constructor = CONSTRUCTOR_MAP.get(name);
+
+ try {
+ if (constructor == null) {
+ // Class not found in the cache, see if it's real,
+ // and try to add it
+ final ClassLoader classLoader = mContext.getClassLoader();
+ Class<?> clazz = null;
+ if (prefixes == null || prefixes.length == 0) {
+ clazz = classLoader.loadClass(name);
+ } else {
+ ClassNotFoundException notFoundException = null;
+ for (final String prefix : prefixes) {
+ try {
+ clazz = classLoader.loadClass(prefix + name);
+ } catch (final ClassNotFoundException e) {
+ notFoundException = e;
+ }
+ }
+ if (clazz == null) {
+ if (notFoundException == null) {
+ throw new InflateException(attrs
+ .getPositionDescription()
+ + ": Error inflating class " + name);
+ } else {
+ throw notFoundException;
+ }
+ }
+ }
+ constructor = clazz.getConstructor(CONSTRUCTOR_SIGNATURE);
+ constructor.setAccessible(true);
+ CONSTRUCTOR_MAP.put(name, constructor);
+ }
+
+ Object[] args = mConstructorArgs;
+ args[1] = attrs;
+ return (Preference) constructor.newInstance(args);
+
+ } catch (ClassNotFoundException e) {
+ // If loadClass fails, we should propagate the exception.
+ throw e;
+ } catch (Exception e) {
+ final InflateException ie = new InflateException(attrs
+ .getPositionDescription() + ": Error inflating class " + name);
+ ie.initCause(e);
+ throw ie;
+ }
+ }
+
+ /**
+ * This routine is responsible for creating the correct subclass of item
+ * given the xml element name. Override it to handle custom item objects. If
+ * you override this in your subclass be sure to call through to
+ * super.onCreateItem(name) for names you do not recognize.
+ *
+ * @param name The fully qualified class name of the item to be create.
+ * @param attrs An AttributeSet of attributes to apply to the item.
+ * @return The item created.
+ */
+ protected Preference onCreateItem(String name, AttributeSet attrs)
+ throws ClassNotFoundException {
+ return createItem(name, mDefaultPackages, attrs);
+ }
+
+ private Preference createItemFromTag(String name,
+ AttributeSet attrs) {
+ try {
+ final Preference item;
+
+ if (-1 == name.indexOf('.')) {
+ item = onCreateItem(name, attrs);
+ } else {
+ item = createItem(name, null, attrs);
+ }
+
+ return item;
+
+ } catch (InflateException e) {
+ throw e;
+
+ } catch (ClassNotFoundException e) {
+ final InflateException ie = new InflateException(attrs
+ .getPositionDescription()
+ + ": Error inflating class (not found)" + name);
+ ie.initCause(e);
+ throw ie;
+
+ } catch (Exception e) {
+ final InflateException ie = new InflateException(attrs
+ .getPositionDescription()
+ + ": Error inflating class " + name);
+ ie.initCause(e);
+ throw ie;
+ }
+ }
+
+ /**
+ * Recursive method used to descend down the xml hierarchy and instantiate
+ * items, instantiate their children, and then call onFinishInflate().
+ */
+ private void rInflate(XmlPullParser parser, Preference parent, final AttributeSet attrs)
+ throws XmlPullParserException, IOException {
+ final int depth = parser.getDepth();
+
+ int type;
+ while (((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ final String name = parser.getName();
+
+ if (INTENT_TAG_NAME.equals(name)) {
+ final Intent intent;
+
+ try {
+ intent = Intent.parseIntent(getContext().getResources(), parser, attrs);
+ } catch (IOException e) {
+ XmlPullParserException ex = new XmlPullParserException(
+ "Error parsing preference");
+ ex.initCause(e);
+ throw ex;
+ }
+
+ parent.setIntent(intent);
+ } else if (EXTRA_TAG_NAME.equals(name)) {
+ getContext().getResources().parseBundleExtra(EXTRA_TAG_NAME, attrs,
+ parent.getExtras());
+ try {
+ skipCurrentTag(parser);
+ } catch (IOException e) {
+ XmlPullParserException ex = new XmlPullParserException(
+ "Error parsing preference");
+ ex.initCause(e);
+ throw ex;
+ }
+ } else {
+ final Preference item = createItemFromTag(name, attrs);
+ ((PreferenceGroup) parent).addItemFromInflater(item);
+ rInflate(parser, item, attrs);
+ }
+ }
+
+ }
+
+ private static void skipCurrentTag(XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ do {
+ type = parser.next();
+ } while (type != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth));
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceManager.java b/v7/preference/src/android/support/v7/preference/PreferenceManager.java
new file mode 100644
index 0000000..7e8c5d1
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/PreferenceManager.java
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.support.v4.content.SharedPreferencesCompat;
+
+/**
+ * Used to help create {@link Preference} hierarchies
+ * from activities or XML.
+ * <p>
+ * In most cases, clients should use
+ * {@link PreferenceFragment#addPreferencesFromResource(int)}, or
+ * {@link PreferenceFragmentCompat#addPreferencesFromResource(int)}.
+ *
+ * @see PreferenceFragment
+ * @see PreferenceFragmentCompat
+ */
+public class PreferenceManager {
+
+ private static final String TAG = "PreferenceManager";
+
+ public static final String KEY_HAS_SET_DEFAULT_VALUES = "_has_set_default_values";
+
+ /**
+ * The context to use. This should always be set.
+ */
+ private Context mContext;
+
+ /**
+ * The counter for unique IDs.
+ */
+ private long mNextId = 0;
+
+ /**
+ * Cached shared preferences.
+ */
+ private SharedPreferences mSharedPreferences;
+
+ /**
+ * If in no-commit mode, the shared editor to give out (which will be
+ * committed when exiting no-commit mode).
+ */
+ private SharedPreferences.Editor mEditor;
+
+ /**
+ * Blocks commits from happening on the shared editor. This is used when
+ * inflating the hierarchy. Do not set this directly, use {@link #setNoCommit(boolean)}
+ */
+ private boolean mNoCommit;
+
+ /**
+ * The SharedPreferences name that will be used for all {@link Preference}s
+ * managed by this instance.
+ */
+ private String mSharedPreferencesName;
+
+ /**
+ * The SharedPreferences mode that will be used for all {@link Preference}s
+ * managed by this instance.
+ */
+ private int mSharedPreferencesMode;
+
+ /**
+ * The {@link PreferenceScreen} at the root of the preference hierarchy.
+ */
+ private PreferenceScreen mPreferenceScreen;
+
+ private OnPreferenceTreeClickListener mOnPreferenceTreeClickListener;
+ private OnDisplayPreferenceDialogListener mOnDisplayPreferenceDialogListener;
+ private OnNavigateToScreenListener mOnNavigateToScreenListener;
+
+ /**
+ * @hide
+ */
+ public PreferenceManager(Context context) {
+ mContext = context;
+
+ setSharedPreferencesName(getDefaultSharedPreferencesName(context));
+ }
+
+ /**
+ * Inflates a preference hierarchy from XML. If a preference hierarchy is
+ * given, the new preference hierarchies will be merged in.
+ *
+ * @param context The context of the resource.
+ * @param resId The resource ID of the XML to inflate.
+ * @param rootPreferences Optional existing hierarchy to merge the new
+ * hierarchies into.
+ * @return The root hierarchy (if one was not provided, the new hierarchy's
+ * root).
+ * @hide
+ */
+ public PreferenceScreen inflateFromResource(Context context, int resId,
+ PreferenceScreen rootPreferences) {
+ // Block commits
+ setNoCommit(true);
+
+ final PreferenceInflater inflater = new PreferenceInflater(context, this);
+ rootPreferences = (PreferenceScreen) inflater.inflate(resId, rootPreferences);
+ rootPreferences.onAttachedToHierarchy(this);
+
+ // Unblock commits
+ setNoCommit(false);
+
+ return rootPreferences;
+ }
+
+ public PreferenceScreen createPreferenceScreen(Context context) {
+ final PreferenceScreen preferenceScreen = new PreferenceScreen(context, null);
+ preferenceScreen.onAttachedToHierarchy(this);
+ return preferenceScreen;
+ }
+
+ /**
+ * Called by a preference to get a unique ID in its hierarchy.
+ *
+ * @return A unique ID.
+ */
+ long getNextId() {
+ synchronized (this) {
+ return mNextId++;
+ }
+ }
+
+ /**
+ * Returns the current name of the SharedPreferences file that preferences managed by
+ * this will use.
+ *
+ * @return The name that can be passed to {@link Context#getSharedPreferences(String, int)}.
+ * @see Context#getSharedPreferences(String, int)
+ */
+ public String getSharedPreferencesName() {
+ return mSharedPreferencesName;
+ }
+
+ /**
+ * Sets the name of the SharedPreferences file that preferences managed by this
+ * will use.
+ *
+ * @param sharedPreferencesName The name of the SharedPreferences file.
+ * @see Context#getSharedPreferences(String, int)
+ */
+ public void setSharedPreferencesName(String sharedPreferencesName) {
+ mSharedPreferencesName = sharedPreferencesName;
+ mSharedPreferences = null;
+ }
+
+ /**
+ * Returns the current mode of the SharedPreferences file that preferences managed by
+ * this will use.
+ *
+ * @return The mode that can be passed to {@link Context#getSharedPreferences(String, int)}.
+ * @see Context#getSharedPreferences(String, int)
+ */
+ public int getSharedPreferencesMode() {
+ return mSharedPreferencesMode;
+ }
+
+ /**
+ * Sets the mode of the SharedPreferences file that preferences managed by this
+ * will use.
+ *
+ * @param sharedPreferencesMode The mode of the SharedPreferences file.
+ * @see Context#getSharedPreferences(String, int)
+ */
+ public void setSharedPreferencesMode(int sharedPreferencesMode) {
+ mSharedPreferencesMode = sharedPreferencesMode;
+ mSharedPreferences = null;
+ }
+
+ /**
+ * Gets a SharedPreferences instance that preferences managed by this will
+ * use.
+ *
+ * @return A SharedPreferences instance pointing to the file that contains
+ * the values of preferences that are managed by this.
+ */
+ public SharedPreferences getSharedPreferences() {
+ if (mSharedPreferences == null) {
+ mSharedPreferences = mContext.getSharedPreferences(mSharedPreferencesName,
+ mSharedPreferencesMode);
+ }
+
+ return mSharedPreferences;
+ }
+
+ /**
+ * Gets a SharedPreferences instance that points to the default file that is
+ * used by the preference framework in the given context.
+ *
+ * @param context The context of the preferences whose values are wanted.
+ * @return A SharedPreferences instance that can be used to retrieve and
+ * listen to values of the preferences.
+ */
+ public static SharedPreferences getDefaultSharedPreferences(Context context) {
+ return context.getSharedPreferences(getDefaultSharedPreferencesName(context),
+ getDefaultSharedPreferencesMode());
+ }
+
+ private static String getDefaultSharedPreferencesName(Context context) {
+ return context.getPackageName() + "_preferences";
+ }
+
+ private static int getDefaultSharedPreferencesMode() {
+ return Context.MODE_PRIVATE;
+ }
+
+ /**
+ * Returns the root of the preference hierarchy managed by this class.
+ *
+ * @return The {@link PreferenceScreen} object that is at the root of the hierarchy.
+ */
+ public PreferenceScreen getPreferenceScreen() {
+ return mPreferenceScreen;
+ }
+
+ /**
+ * Sets the root of the preference hierarchy.
+ *
+ * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
+ * @return Whether the {@link PreferenceScreen} given is different than the previous.
+ */
+ public boolean setPreferences(PreferenceScreen preferenceScreen) {
+ if (preferenceScreen != mPreferenceScreen) {
+ mPreferenceScreen = preferenceScreen;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Finds a {@link Preference} based on its key.
+ *
+ * @param key The key of the preference to retrieve.
+ * @return The {@link Preference} with the key, or null.
+ * @see PreferenceGroup#findPreference(CharSequence)
+ */
+ public Preference findPreference(CharSequence key) {
+ if (mPreferenceScreen == null) {
+ return null;
+ }
+
+ return mPreferenceScreen.findPreference(key);
+ }
+
+ /**
+ * Sets the default values from an XML preference file by reading the values defined
+ * by each {@link Preference} item's {@code android:defaultValue} attribute. This should
+ * be called by the application's main activity.
+ * <p>
+ *
+ * @param context The context of the shared preferences.
+ * @param resId The resource ID of the preference XML file.
+ * @param readAgain Whether to re-read the default values.
+ * If false, this method sets the default values only if this
+ * method has never been called in the past (or if the
+ * {@link #KEY_HAS_SET_DEFAULT_VALUES} in the default value shared
+ * preferences file is false). To attempt to set the default values again
+ * bypassing this check, set {@code readAgain} to true.
+ * <p class="note">
+ * Note: this will NOT reset preferences back to their default
+ * values. For that functionality, use
+ * {@link PreferenceManager#getDefaultSharedPreferences(Context)}
+ * and clear it followed by a call to this method with this
+ * parameter set to true.
+ */
+ public static void setDefaultValues(Context context, int resId, boolean readAgain) {
+
+ // Use the default shared preferences name and mode
+ setDefaultValues(context, getDefaultSharedPreferencesName(context),
+ getDefaultSharedPreferencesMode(), resId, readAgain);
+ }
+
+ /**
+ * Similar to {@link #setDefaultValues(Context, int, boolean)} but allows
+ * the client to provide the filename and mode of the shared preferences
+ * file.
+ *
+ * @param context The context of the shared preferences.
+ * @param sharedPreferencesName A custom name for the shared preferences file.
+ * @param sharedPreferencesMode The file creation mode for the shared preferences file, such
+ * as {@link android.content.Context#MODE_PRIVATE} or {@link
+ * android.content.Context#MODE_PRIVATE}
+ * @param resId The resource ID of the preference XML file.
+ * @param readAgain Whether to re-read the default values.
+ * If false, this method will set the default values only if this
+ * method has never been called in the past (or if the
+ * {@link #KEY_HAS_SET_DEFAULT_VALUES} in the default value shared
+ * preferences file is false). To attempt to set the default values again
+ * bypassing this check, set {@code readAgain} to true.
+ * <p class="note">
+ * Note: this will NOT reset preferences back to their default
+ * values. For that functionality, use
+ * {@link PreferenceManager#getDefaultSharedPreferences(Context)}
+ * and clear it followed by a call to this method with this
+ * parameter set to true.
+ *
+ * @see #setDefaultValues(Context, int, boolean)
+ * @see #setSharedPreferencesName(String)
+ * @see #setSharedPreferencesMode(int)
+ */
+ public static void setDefaultValues(Context context, String sharedPreferencesName,
+ int sharedPreferencesMode, int resId, boolean readAgain) {
+ final SharedPreferences defaultValueSp = context.getSharedPreferences(
+ KEY_HAS_SET_DEFAULT_VALUES, Context.MODE_PRIVATE);
+
+ if (readAgain || !defaultValueSp.getBoolean(KEY_HAS_SET_DEFAULT_VALUES, false)) {
+ final PreferenceManager pm = new PreferenceManager(context);
+ pm.setSharedPreferencesName(sharedPreferencesName);
+ pm.setSharedPreferencesMode(sharedPreferencesMode);
+ pm.inflateFromResource(context, resId, null);
+
+ SharedPreferences.Editor editor =
+ defaultValueSp.edit().putBoolean(KEY_HAS_SET_DEFAULT_VALUES, true);
+
+ SharedPreferencesCompat.EditorCompat.getInstance().apply(editor);
+ }
+ }
+
+ /**
+ * Returns an editor to use when modifying the shared preferences.
+ * <p>
+ * Do NOT commit unless {@link #shouldCommit()} returns true.
+ *
+ * @return An editor to use to write to shared preferences.
+ * @see #shouldCommit()
+ */
+ SharedPreferences.Editor getEditor() {
+
+ if (mNoCommit) {
+ if (mEditor == null) {
+ mEditor = getSharedPreferences().edit();
+ }
+
+ return mEditor;
+ } else {
+ return getSharedPreferences().edit();
+ }
+ }
+
+ /**
+ * Whether it is the client's responsibility to commit on the
+ * {@link #getEditor()}. This will return false in cases where the writes
+ * should be batched, for example when inflating preferences from XML.
+ *
+ * @return Whether the client should commit.
+ */
+ boolean shouldCommit() {
+ return !mNoCommit;
+ }
+
+ private void setNoCommit(boolean noCommit) {
+ if (!noCommit && mEditor != null) {
+ SharedPreferencesCompat.EditorCompat.getInstance().apply(mEditor);
+ }
+ mNoCommit = noCommit;
+ }
+
+ /**
+ * Returns the context.
+ *
+ * @return The context.
+ */
+ Context getContext() {
+ return mContext;
+ }
+
+ public OnDisplayPreferenceDialogListener getOnDisplayPreferenceDialogListener() {
+ return mOnDisplayPreferenceDialogListener;
+ }
+
+ public void setOnDisplayPreferenceDialogListener(
+ OnDisplayPreferenceDialogListener onDisplayPreferenceDialogListener) {
+ mOnDisplayPreferenceDialogListener = onDisplayPreferenceDialogListener;
+ }
+
+ /**
+ * Called when a preference requests that a dialog be shown to complete a user interaction.
+ *
+ * @param preference The preference requesting the dialog.
+ */
+ public void showDialog(Preference preference) {
+ if (mOnDisplayPreferenceDialogListener != null) {
+ mOnDisplayPreferenceDialogListener.onDisplayPreferenceDialog(preference);
+ }
+ }
+
+ /**
+ * Sets the callback to be invoked when a {@link Preference} in the
+ * hierarchy rooted at this {@link PreferenceManager} is clicked.
+ *
+ * @param listener The callback to be invoked.
+ */
+ public void setOnPreferenceTreeClickListener(OnPreferenceTreeClickListener listener) {
+ mOnPreferenceTreeClickListener = listener;
+ }
+
+ public OnPreferenceTreeClickListener getOnPreferenceTreeClickListener() {
+ return mOnPreferenceTreeClickListener;
+ }
+
+ /**
+ * Sets the callback to be invoked when a {@link PreferenceScreen} in the hierarchy rooted at
+ * this {@link PreferenceManager} is clicked.
+ *
+ * @param listener The callback to be invoked.
+ */
+ public void setOnNavigateToScreenListener(OnNavigateToScreenListener listener) {
+ mOnNavigateToScreenListener = listener;
+ }
+
+ /**
+ * Returns the {@link PreferenceManager.OnNavigateToScreenListener}, if one has been set.
+ */
+ public OnNavigateToScreenListener getOnNavigateToScreenListener() {
+ return mOnNavigateToScreenListener;
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when a
+ * {@link Preference} in the hierarchy rooted at this {@link PreferenceScreen} is
+ * clicked.
+ */
+ public interface OnPreferenceTreeClickListener {
+ /**
+ * Called when a preference in the tree rooted at this
+ * {@link PreferenceScreen} has been clicked.
+ *
+ * @param preference The preference that was clicked.
+ * @return Whether the click was handled.
+ */
+ boolean onPreferenceTreeClick(Preference preference);
+ }
+
+ /**
+ * Interface definition for a class that will be called when a
+ * {@link android.support.v7.preference.Preference} requests to display a dialog.
+ */
+ public interface OnDisplayPreferenceDialogListener {
+
+ /**
+ * Called when a preference in the tree requests to display a dialog.
+ *
+ * @param preference The Preference object requesting the dialog.
+ */
+ void onDisplayPreferenceDialog(Preference preference);
+ }
+
+ /**
+ * Interface definition for a class that will be called when a
+ * {@link android.support.v7.preference.PreferenceScreen} requests navigation.
+ */
+ public interface OnNavigateToScreenListener {
+
+ /**
+ * Called when a PreferenceScreen in the tree requests to navigate to its contents.
+ *
+ * @param preferenceScreen The PreferenceScreen requesting navigation.
+ */
+ void onNavigateToScreen(PreferenceScreen preferenceScreen);
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceScreen.java b/v7/preference/src/android/support/v7/preference/PreferenceScreen.java
new file mode 100644
index 0000000..2010080
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/PreferenceScreen.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+/**
+ * Represents a top-level {@link Preference} that
+ * is the root of a Preference hierarchy. A {@link PreferenceFragmentCompat}
+ * points to an instance of this class to show the preferences. To instantiate
+ * this class, use {@link PreferenceManager#createPreferenceScreen(android.content.Context)}.
+ * <ul>
+ * This class can appear in two places:
+ * <li> When a {@link PreferenceFragmentCompat} points to this, it is used as the root
+ * and is not shown (only the contained preferences are shown).
+ * <li> When it appears inside another preference hierarchy, it is shown and
+ * serves as the gateway to another screen of preferences (either by showing
+ * another screen of preferences as a {@link android.app.Dialog} or via a
+ * {@link android.content.Context#startActivity(android.content.Intent)} from the
+ * {@link Preference#getIntent()}). The children of this {@link PreferenceScreen}
+ * are NOT shown in the screen that this {@link PreferenceScreen} is shown in.
+ * Instead, a separate screen will be shown when this preference is clicked.
+ * </ul>
+ * <p>Here's an example XML layout of a PreferenceScreen:</p>
+ * <pre>
+ <PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="first_preferencescreen">
+ <CheckBoxPreference
+ android:key="wifi enabled"
+ android:title="WiFi" />
+ <PreferenceScreen
+ android:key="second_preferencescreen"
+ android:title="WiFi settings">
+ <CheckBoxPreference
+ android:key="prefer wifi"
+ android:title="Prefer WiFi" />
+ ... other preferences here ...
+ </PreferenceScreen>
+ </PreferenceScreen> </pre>
+ * <p>
+ * In this example, the "first_preferencescreen" will be used as the root of the
+ * hierarchy and given to a {@link PreferenceFragment} or {@link PreferenceFragmentCompat}.
+ * The first screen will
+ * show preferences "WiFi" (which can be used to quickly enable/disable WiFi)
+ * and "WiFi settings". The "WiFi settings" is the "second_preferencescreen" and when
+ * clicked will show another screen of preferences such as "Prefer WiFi" (and
+ * the other preferences that are children of the "second_preferencescreen" tag).
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about building a settings UI with Preferences,
+ * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>
+ * guide.</p>
+ * </div>
+ *
+ * @see PreferenceCategory
+ */
+public final class PreferenceScreen extends PreferenceGroup {
+
+ /**
+ * Do NOT use this constructor, use {@link PreferenceManager#createPreferenceScreen(Context)}.
+ * @hide-
+ */
+ public PreferenceScreen(Context context, AttributeSet attrs) {
+ super(context, attrs, R.attr.preferenceScreenStyle);
+ }
+
+ @Override
+ protected void onClick() {
+ if (getIntent() != null || getFragment() != null || getPreferenceCount() == 0) {
+ return;
+ }
+ final PreferenceManager.OnNavigateToScreenListener listener =
+ getPreferenceManager().getOnNavigateToScreenListener();
+ if (listener != null) {
+ listener.onNavigateToScreen(this);
+ }
+ }
+
+ @Override
+ protected boolean isOnSameScreenAsChildren() {
+ return false;
+ }
+
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceViewHolder.java b/v7/preference/src/android/support/v7/preference/PreferenceViewHolder.java
new file mode 100644
index 0000000..c7e247c
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/PreferenceViewHolder.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.support.annotation.IdRes;
+import android.support.v7.widget.RecyclerView;
+import android.util.SparseArray;
+import android.view.View;
+
+/**
+ * A {@link android.support.v7.widget.RecyclerView.ViewHolder} class which caches views associated
+ * with the default {@link Preference} layouts. Cached views can be retrieved by calling
+ * {@link #findViewById(int)}.
+ */
+public class PreferenceViewHolder extends RecyclerView.ViewHolder {
+ private final SparseArray<View> mCachedViews = new SparseArray<>(4);
+
+ /* package */ PreferenceViewHolder(View itemView) {
+ super(itemView);
+
+ // Pre-cache the views that we know in advance we'll want to find
+ mCachedViews.put(android.R.id.title, itemView.findViewById(android.R.id.title));
+ mCachedViews.put(android.R.id.summary, itemView.findViewById(android.R.id.summary));
+ mCachedViews.put(android.R.id.icon, itemView.findViewById(android.R.id.icon));
+ mCachedViews.put(R.id.icon_frame, itemView.findViewById(R.id.icon_frame));
+ }
+
+ /**
+ * Returns a cached reference to a subview managed by this object. If the view reference is not
+ * yet cached, it falls back to calling {@link View#findViewById(int)} and caches the result.
+ *
+ * @param id Resource ID of the view to find
+ * @return The view, or null if no view with the requested ID is found.
+ */
+ public View findViewById(@IdRes int id) {
+ final View cachedView = mCachedViews.get(id);
+ if (cachedView != null) {
+ return cachedView;
+ } else {
+ final View v = itemView.findViewById(id);
+ if (v != null) {
+ mCachedViews.put(id, v);
+ }
+ return v;
+ }
+ }
+}
diff --git a/v7/preference/src/android/support/v7/preference/SwitchPreferenceCompat.java b/v7/preference/src/android/support/v7/preference/SwitchPreferenceCompat.java
new file mode 100644
index 0000000..2e0e38b
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/SwitchPreferenceCompat.java
@@ -0,0 +1,212 @@
+/*
+* Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.support.v7.widget.SwitchCompat;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Checkable;
+import android.widget.CompoundButton;
+
+/**
+* A {@link Preference} that provides a two-state toggleable option.
+* <p>
+* This preference will store a boolean into the SharedPreferences.
+*
+* @attr ref android.R.styleable#SwitchPreference_summaryOff
+* @attr ref android.R.styleable#SwitchPreference_summaryOn
+* @attr ref android.R.styleable#SwitchPreference_switchTextOff
+* @attr ref android.R.styleable#SwitchPreference_switchTextOn
+* @attr ref android.R.styleable#SwitchPreference_disableDependentsState
+*/
+public class SwitchPreferenceCompat extends TwoStatePreference {
+ private final Listener mListener = new Listener();
+
+ // Switch text for on and off states
+ private CharSequence mSwitchOn;
+ private CharSequence mSwitchOff;
+
+ private class Listener implements CompoundButton.OnCheckedChangeListener {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!callChangeListener(isChecked)) {
+ // Listener didn't like it, change it back.
+ // CompoundButton will make sure we don't recurse.
+ buttonView.setChecked(!isChecked);
+ return;
+ }
+
+ SwitchPreferenceCompat.this.setChecked(isChecked);
+ }
+ }
+
+ /**
+ * Construct a new SwitchPreference with the given style options.
+ *
+ * @param context The Context that will style this preference
+ * @param attrs Style attributes that differ from the default
+ * @param defStyleAttr An attribute in the current theme that contains a
+ * reference to a style resource that supplies default values for
+ * the view. Can be 0 to not look for defaults.
+ * @param defStyleRes A resource identifier of a style resource that
+ * supplies default values for the view, used only if
+ * defStyleAttr is 0 or can not be found in the theme. Can be 0
+ * to not look for defaults.
+ */
+ public SwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.SwitchPreferenceCompat, defStyleAttr, defStyleRes);
+
+ setSummaryOn(TypedArrayUtils.getString(a, R.styleable.SwitchPreferenceCompat_summaryOn,
+ R.styleable.SwitchPreferenceCompat_android_summaryOn));
+
+ setSummaryOff(TypedArrayUtils.getString(a, R.styleable.SwitchPreferenceCompat_summaryOff,
+ R.styleable.SwitchPreferenceCompat_android_summaryOff));
+
+ setSwitchTextOn(TypedArrayUtils.getString(a,
+ R.styleable.SwitchPreferenceCompat_switchTextOn,
+ R.styleable.SwitchPreferenceCompat_android_switchTextOn));
+
+ setSwitchTextOff(TypedArrayUtils.getString(a,
+ R.styleable.SwitchPreferenceCompat_switchTextOff,
+ R.styleable.SwitchPreferenceCompat_android_switchTextOff));
+
+ setDisableDependentsState(TypedArrayUtils.getBoolean(a,
+ R.styleable.SwitchPreferenceCompat_disableDependentsState,
+ R.styleable.SwitchPreferenceCompat_android_disableDependentsState, false));
+
+ a.recycle();
+ }
+
+ /**
+ * Construct a new SwitchPreference with the given style options.
+ *
+ * @param context The Context that will style this preference
+ * @param attrs Style attributes that differ from the default
+ * @param defStyleAttr An attribute in the current theme that contains a
+ * reference to a style resource that supplies default values for
+ * the view. Can be 0 to not look for defaults.
+ */
+ public SwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ /**
+ * Construct a new SwitchPreference with the given style options.
+ *
+ * @param context The Context that will style this preference
+ * @param attrs Style attributes that differ from the default
+ */
+ public SwitchPreferenceCompat(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.switchPreferenceCompatStyle);
+ }
+
+ /**
+ * Construct a new SwitchPreference with default style options.
+ *
+ * @param context The Context that will style this preference
+ */
+ public SwitchPreferenceCompat(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ View checkableView = holder.findViewById(R.id.switchWidget);
+ if (checkableView != null && checkableView instanceof Checkable) {
+ if (checkableView instanceof SwitchCompat) {
+ final SwitchCompat switchView = (SwitchCompat) checkableView;
+ switchView.setOnCheckedChangeListener(null);
+ }
+
+ ((Checkable) checkableView).setChecked(mChecked);
+
+ if (checkableView instanceof SwitchCompat) {
+ final SwitchCompat switchView = (SwitchCompat) checkableView;
+ switchView.setTextOn(mSwitchOn);
+ switchView.setTextOff(mSwitchOff);
+ switchView.setOnCheckedChangeListener(mListener);
+ }
+ }
+
+ syncSummaryView(holder);
+ }
+
+ /**
+ * Set the text displayed on the switch widget in the on state.
+ * This should be a very short string; one word if possible.
+ *
+ * @param onText Text to display in the on state
+ */
+ public void setSwitchTextOn(CharSequence onText) {
+ mSwitchOn = onText;
+ notifyChanged();
+ }
+
+ /**
+ * Set the text displayed on the switch widget in the off state.
+ * This should be a very short string; one word if possible.
+ *
+ * @param offText Text to display in the off state
+ */
+ public void setSwitchTextOff(CharSequence offText) {
+ mSwitchOff = offText;
+ notifyChanged();
+ }
+
+ /**
+ * Set the text displayed on the switch widget in the on state.
+ * This should be a very short string; one word if possible.
+ *
+ * @param resId The text as a string resource ID
+ */
+ public void setSwitchTextOn(int resId) {
+ setSwitchTextOn(getContext().getString(resId));
+ }
+
+ /**
+ * Set the text displayed on the switch widget in the off state.
+ * This should be a very short string; one word if possible.
+ *
+ * @param resId The text as a string resource ID
+ */
+ public void setSwitchTextOff(int resId) {
+ setSwitchTextOff(getContext().getString(resId));
+ }
+
+ /**
+ * @return The text that will be displayed on the switch widget in the on state
+ */
+ public CharSequence getSwitchTextOn() {
+ return mSwitchOn;
+ }
+
+ /**
+ * @return The text that will be displayed on the switch widget in the off state
+ */
+ public CharSequence getSwitchTextOff() {
+ return mSwitchOff;
+ }
+}
diff --git a/v7/preference/src/android/support/v7/preference/TwoStatePreference.java b/v7/preference/src/android/support/v7/preference/TwoStatePreference.java
new file mode 100644
index 0000000..e7748cc
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/TwoStatePreference.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 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.v7.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * Common base class for preferences that have two selectable states, persist a
+ * boolean value in SharedPreferences, and may have dependent preferences that are
+ * enabled/disabled based on the current state.
+ */
+public abstract class TwoStatePreference extends Preference {
+
+ private CharSequence mSummaryOn;
+ private CharSequence mSummaryOff;
+ protected boolean mChecked;
+ private boolean mCheckedSet;
+ private boolean mDisableDependentsState;
+
+ public TwoStatePreference(
+ Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public TwoStatePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public TwoStatePreference(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TwoStatePreference(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ protected void onClick() {
+ super.onClick();
+
+ final boolean newValue = !isChecked();
+ if (callChangeListener(newValue)) {
+ setChecked(newValue);
+ }
+ }
+
+ /**
+ * Sets the checked state and saves it to the {@link SharedPreferences}.
+ *
+ * @param checked The checked state.
+ */
+ public void setChecked(boolean checked) {
+ // Always persist/notify the first time; don't assume the field's default of false.
+ final boolean changed = mChecked != checked;
+ if (changed || !mCheckedSet) {
+ mChecked = checked;
+ mCheckedSet = true;
+ persistBoolean(checked);
+ if (changed) {
+ notifyDependencyChange(shouldDisableDependents());
+ notifyChanged();
+ }
+ }
+ }
+
+ /**
+ * Returns the checked state.
+ *
+ * @return The checked state.
+ */
+ public boolean isChecked() {
+ return mChecked;
+ }
+
+ @Override
+ public boolean shouldDisableDependents() {
+ boolean shouldDisable = mDisableDependentsState ? mChecked : !mChecked;
+ return shouldDisable || super.shouldDisableDependents();
+ }
+
+ /**
+ * Sets the summary to be shown when checked.
+ *
+ * @param summary The summary to be shown when checked.
+ */
+ public void setSummaryOn(CharSequence summary) {
+ mSummaryOn = summary;
+ if (isChecked()) {
+ notifyChanged();
+ }
+ }
+
+ /**
+ * @see #setSummaryOn(CharSequence)
+ * @param summaryResId The summary as a resource.
+ */
+ public void setSummaryOn(int summaryResId) {
+ setSummaryOn(getContext().getString(summaryResId));
+ }
+
+ /**
+ * Returns the summary to be shown when checked.
+ * @return The summary.
+ */
+ public CharSequence getSummaryOn() {
+ return mSummaryOn;
+ }
+
+ /**
+ * Sets the summary to be shown when unchecked.
+ *
+ * @param summary The summary to be shown when unchecked.
+ */
+ public void setSummaryOff(CharSequence summary) {
+ mSummaryOff = summary;
+ if (!isChecked()) {
+ notifyChanged();
+ }
+ }
+
+ /**
+ * @see #setSummaryOff(CharSequence)
+ * @param summaryResId The summary as a resource.
+ */
+ public void setSummaryOff(int summaryResId) {
+ setSummaryOff(getContext().getString(summaryResId));
+ }
+
+ /**
+ * Returns the summary to be shown when unchecked.
+ * @return The summary.
+ */
+ public CharSequence getSummaryOff() {
+ return mSummaryOff;
+ }
+
+ /**
+ * Returns whether dependents are disabled when this preference is on ({@code true})
+ * or when this preference is off ({@code false}).
+ *
+ * @return Whether dependents are disabled when this preference is on ({@code true})
+ * or when this preference is off ({@code false}).
+ */
+ public boolean getDisableDependentsState() {
+ return mDisableDependentsState;
+ }
+
+ /**
+ * Sets whether dependents are disabled when this preference is on ({@code true})
+ * or when this preference is off ({@code false}).
+ *
+ * @param disableDependentsState The preference state that should disable dependents.
+ */
+ public void setDisableDependentsState(boolean disableDependentsState) {
+ mDisableDependentsState = disableDependentsState;
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getBoolean(index, false);
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setChecked(restoreValue ? getPersistedBoolean(mChecked)
+ : (Boolean) defaultValue);
+ }
+
+ /**
+ * Sync a summary holder contained within holder's subhierarchy with the correct summary text.
+ * @param holder PreferenceViewHolder which holds a reference to the summary view
+ */
+ protected void syncSummaryView(PreferenceViewHolder holder) {
+ // Sync the summary holder
+ TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
+ if (summaryView != null) {
+ boolean useDefaultSummary = true;
+ if (mChecked && !TextUtils.isEmpty(mSummaryOn)) {
+ summaryView.setText(mSummaryOn);
+ useDefaultSummary = false;
+ } else if (!mChecked && !TextUtils.isEmpty(mSummaryOff)) {
+ summaryView.setText(mSummaryOff);
+ useDefaultSummary = false;
+ }
+
+ if (useDefaultSummary) {
+ final CharSequence summary = getSummary();
+ if (!TextUtils.isEmpty(summary)) {
+ summaryView.setText(summary);
+ useDefaultSummary = false;
+ }
+ }
+
+ int newVisibility = View.GONE;
+ if (!useDefaultSummary) {
+ // Someone has written to it
+ newVisibility = View.VISIBLE;
+ }
+ if (newVisibility != summaryView.getVisibility()) {
+ summaryView.setVisibility(newVisibility);
+ }
+ }
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ if (isPersistent()) {
+ // No need to save instance state since it's persistent
+ return superState;
+ }
+
+ final SavedState myState = new SavedState(superState);
+ myState.checked = isChecked();
+ return myState;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ if (state == null || !state.getClass().equals(SavedState.class)) {
+ // Didn't save state for us in onSaveInstanceState
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ SavedState myState = (SavedState) state;
+ super.onRestoreInstanceState(myState.getSuperState());
+ setChecked(myState.checked);
+ }
+
+ static class SavedState extends BaseSavedState {
+ boolean checked;
+
+ public SavedState(Parcel source) {
+ super(source);
+ checked = source.readInt() == 1;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(checked ? 1 : 0);
+ }
+
+ public SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR =
+ new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+}
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index 30a147a..112c4af 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -27,6 +27,7 @@
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.CallSuper;
import android.support.annotation.Nullable;
import android.support.v4.os.TraceCompat;
import android.support.v4.util.ArrayMap;
@@ -2272,7 +2273,9 @@
if (event.getAction() == MotionEventCompat.ACTION_SCROLL) {
final float vScroll, hScroll;
if (mLayout.canScrollVertically()) {
- vScroll = MotionEventCompat
+ // Inverse the sign of the vertical scroll to align the scroll orientation
+ // with AbsListView.
+ vScroll = -MotionEventCompat
.getAxisValue(event, MotionEventCompat.AXIS_VSCROLL);
} else {
vScroll = 0f;
@@ -5636,6 +5639,7 @@
*
* @param view The RecyclerView this LayoutManager is bound to
*/
+ @CallSuper
public void onAttachedToWindow(RecyclerView view) {
}
@@ -5659,6 +5663,7 @@
* @param recycler The recycler to use if you prefer to recycle your children instead of
* keeping them around.
*/
+ @CallSuper
public void onDetachedFromWindow(RecyclerView view, Recycler recycler) {
onDetachedFromWindow(view);
}
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
index f8739cf..e8894b2 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
@@ -211,20 +211,6 @@
checkForMainThreadException();
}
- public void testGrowLookup() throws Throwable {
- setupByConfig(new Config(VERTICAL, false, 3, GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS));
- waitFirstLayout();
- mLayoutManager.expectLayouts(1);
- mAdapter.mItems.clear();
- mAdapter.dispatchDataSetChanged();
- mLayoutManager.waitForLayout(2);
- checkForMainThreadException();
- mLayoutManager.expectLayouts(2);
- mAdapter.addAndNotify(0, 30);
- mLayoutManager.waitForLayout(2);
- checkForMainThreadException();
- }
-
public void testRTL() throws Throwable {
for (boolean changeRtlAfter : new boolean[]{false, true}) {
for (Config config : mBaseVariations) {
diff --git a/v8/renderscript/Android.mk b/v8/renderscript/Android.mk
index a7755aa..522adbc 100644
--- a/v8/renderscript/Android.mk
+++ b/v8/renderscript/Android.mk
@@ -29,6 +29,15 @@
include $(BUILD_STATIC_JAVA_LIBRARY)
+# API Check
+# ---------------------------------------------
+support_module := $(LOCAL_MODULE)
+support_module_api_dir := $(LOCAL_PATH)/api
+support_module_src_files := $(LOCAL_SRC_FILES)
+support_module_java_libraries := $(LOCAL_MODULE)
+support_module_java_packages := android.support.v8.renderscript
+include $(SUPPORT_API_CHECK)
+
# TODO: Build the tests as an APK here
include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/v8/renderscript/api/current.txt b/v8/renderscript/api/current.txt
new file mode 100644
index 0000000..5b96cc8
--- /dev/null
+++ b/v8/renderscript/api/current.txt
@@ -0,0 +1,899 @@
+package android.support.v8.renderscript {
+
+ public class Allocation extends android.support.v8.renderscript.BaseObj {
+ method public void copy1DRangeFrom(int, int, java.lang.Object);
+ method public void copy1DRangeFrom(int, int, int[]);
+ method public void copy1DRangeFrom(int, int, short[]);
+ method public void copy1DRangeFrom(int, int, byte[]);
+ method public void copy1DRangeFrom(int, int, float[]);
+ method public void copy1DRangeFrom(int, int, android.support.v8.renderscript.Allocation, int);
+ method public void copy1DRangeFromUnchecked(int, int, java.lang.Object);
+ method public void copy1DRangeFromUnchecked(int, int, int[]);
+ method public void copy1DRangeFromUnchecked(int, int, short[]);
+ method public void copy1DRangeFromUnchecked(int, int, byte[]);
+ method public void copy1DRangeFromUnchecked(int, int, float[]);
+ method public void copy1DRangeTo(int, int, java.lang.Object);
+ method public void copy1DRangeTo(int, int, int[]);
+ method public void copy1DRangeTo(int, int, short[]);
+ method public void copy1DRangeTo(int, int, byte[]);
+ method public void copy1DRangeTo(int, int, float[]);
+ method public void copy1DRangeToUnchecked(int, int, java.lang.Object);
+ method public void copy1DRangeToUnchecked(int, int, int[]);
+ method public void copy1DRangeToUnchecked(int, int, short[]);
+ method public void copy1DRangeToUnchecked(int, int, byte[]);
+ method public void copy1DRangeToUnchecked(int, int, float[]);
+ method public void copy2DRangeFrom(int, int, int, int, java.lang.Object);
+ method public void copy2DRangeFrom(int, int, int, int, byte[]);
+ method public void copy2DRangeFrom(int, int, int, int, short[]);
+ method public void copy2DRangeFrom(int, int, int, int, int[]);
+ method public void copy2DRangeFrom(int, int, int, int, float[]);
+ method public void copy2DRangeFrom(int, int, int, int, android.support.v8.renderscript.Allocation, int, int);
+ method public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
+ method public void copy2DRangeTo(int, int, int, int, java.lang.Object);
+ method public void copy2DRangeTo(int, int, int, int, byte[]);
+ method public void copy2DRangeTo(int, int, int, int, short[]);
+ method public void copy2DRangeTo(int, int, int, int, int[]);
+ method public void copy2DRangeTo(int, int, int, int, float[]);
+ method public void copy3DRangeFrom(int, int, int, int, int, int, java.lang.Object);
+ method public void copy3DRangeFrom(int, int, int, int, int, int, android.support.v8.renderscript.Allocation, int, int, int);
+ method public void copyFrom(android.support.v8.renderscript.BaseObj[]);
+ method public void copyFrom(java.lang.Object);
+ method public void copyFrom(int[]);
+ method public void copyFrom(short[]);
+ method public void copyFrom(byte[]);
+ method public void copyFrom(float[]);
+ method public void copyFrom(android.graphics.Bitmap);
+ method public void copyFrom(android.support.v8.renderscript.Allocation);
+ method public void copyFromUnchecked(java.lang.Object);
+ method public void copyFromUnchecked(int[]);
+ method public void copyFromUnchecked(short[]);
+ method public void copyFromUnchecked(byte[]);
+ method public void copyFromUnchecked(float[]);
+ method public void copyTo(android.graphics.Bitmap);
+ method public void copyTo(java.lang.Object);
+ method public void copyTo(byte[]);
+ method public void copyTo(short[]);
+ method public void copyTo(int[]);
+ method public void copyTo(float[]);
+ method public static android.support.v8.renderscript.Allocation createCubemapFromBitmap(android.support.v8.renderscript.RenderScript, android.graphics.Bitmap, android.support.v8.renderscript.Allocation.MipmapControl, int);
+ method public static android.support.v8.renderscript.Allocation createCubemapFromBitmap(android.support.v8.renderscript.RenderScript, android.graphics.Bitmap);
+ method public static android.support.v8.renderscript.Allocation createCubemapFromCubeFaces(android.support.v8.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.support.v8.renderscript.Allocation.MipmapControl, int);
+ method public static android.support.v8.renderscript.Allocation createCubemapFromCubeFaces(android.support.v8.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap);
+ method public static android.support.v8.renderscript.Allocation createFromBitmap(android.support.v8.renderscript.RenderScript, android.graphics.Bitmap, android.support.v8.renderscript.Allocation.MipmapControl, int);
+ method public static android.support.v8.renderscript.Allocation createFromBitmap(android.support.v8.renderscript.RenderScript, android.graphics.Bitmap);
+ method public static android.support.v8.renderscript.Allocation createFromBitmapResource(android.support.v8.renderscript.RenderScript, android.content.res.Resources, int, android.support.v8.renderscript.Allocation.MipmapControl, int);
+ method public static android.support.v8.renderscript.Allocation createFromBitmapResource(android.support.v8.renderscript.RenderScript, android.content.res.Resources, int);
+ method public static android.support.v8.renderscript.Allocation createFromString(android.support.v8.renderscript.RenderScript, java.lang.String, int);
+ method public static android.support.v8.renderscript.Allocation createSized(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element, int, int);
+ method public static android.support.v8.renderscript.Allocation createSized(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element, int);
+ method public static android.support.v8.renderscript.Allocation createTyped(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Type, android.support.v8.renderscript.Allocation.MipmapControl, int);
+ method public static android.support.v8.renderscript.Allocation createTyped(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Type, int);
+ method public static android.support.v8.renderscript.Allocation createTyped(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Type);
+ method public void generateMipmaps();
+ method public int getBytesSize();
+ method public android.support.v8.renderscript.Element getElement();
+ method public long getIncAllocID();
+ method public android.support.v8.renderscript.Type getType();
+ method public int getUsage();
+ method public void ioReceive();
+ method public void ioSend();
+ method public void ioSendOutput();
+ method public void setAutoPadding(boolean);
+ method public void setFromFieldPacker(int, android.support.v8.renderscript.FieldPacker);
+ method public void setFromFieldPacker(int, int, android.support.v8.renderscript.FieldPacker);
+ method public void setIncAllocID(long);
+ method public void setSurface(android.view.Surface);
+ method public void syncAll(int);
+ field public static final int USAGE_GRAPHICS_TEXTURE = 2; // 0x2
+ field public static final int USAGE_IO_INPUT = 32; // 0x20
+ field public static final int USAGE_IO_OUTPUT = 64; // 0x40
+ field public static final int USAGE_SCRIPT = 1; // 0x1
+ field public static final int USAGE_SHARED = 128; // 0x80
+ }
+
+ public static final class Allocation.MipmapControl extends java.lang.Enum {
+ method public static android.support.v8.renderscript.Allocation.MipmapControl valueOf(java.lang.String);
+ method public static final android.support.v8.renderscript.Allocation.MipmapControl[] values();
+ enum_constant public static final android.support.v8.renderscript.Allocation.MipmapControl MIPMAP_FULL;
+ enum_constant public static final android.support.v8.renderscript.Allocation.MipmapControl MIPMAP_NONE;
+ enum_constant public static final android.support.v8.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
+ }
+
+ public class BaseObj {
+ method public void destroy();
+ }
+
+ public class Byte2 {
+ ctor public Byte2();
+ ctor public Byte2(byte, byte);
+ field public byte x;
+ field public byte y;
+ }
+
+ public class Byte3 {
+ ctor public Byte3();
+ ctor public Byte3(byte, byte, byte);
+ field public byte x;
+ field public byte y;
+ field public byte z;
+ }
+
+ public class Byte4 {
+ ctor public Byte4();
+ ctor public Byte4(byte, byte, byte, byte);
+ field public byte w;
+ field public byte x;
+ field public byte y;
+ field public byte z;
+ }
+
+ public class Double2 {
+ ctor public Double2();
+ ctor public Double2(double, double);
+ field public double x;
+ field public double y;
+ }
+
+ public class Double3 {
+ ctor public Double3();
+ ctor public Double3(double, double, double);
+ field public double x;
+ field public double y;
+ field public double z;
+ }
+
+ public class Double4 {
+ ctor public Double4();
+ ctor public Double4(double, double, double, double);
+ field public double w;
+ field public double x;
+ field public double y;
+ field public double z;
+ }
+
+ public class Element extends android.support.v8.renderscript.BaseObj {
+ method public static android.support.v8.renderscript.Element ALLOCATION(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element A_8(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element BOOLEAN(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element ELEMENT(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element F32(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element F32_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element F32_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element F32_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element F64(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element F64_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element F64_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element F64_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I16(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I16_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I16_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I16_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I32(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I32_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I32_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I32_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I64(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I64_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I64_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I64_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I8(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I8_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I8_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element I8_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element MATRIX_2X2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element MATRIX_3X3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element MATRIX_4X4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element RGBA_4444(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element RGBA_5551(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element RGBA_8888(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element RGB_565(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element RGB_888(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element SAMPLER(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element SCRIPT(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element TYPE(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U16(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U16_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U16_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U16_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U32(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U32_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U32_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U32_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U64(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U64_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U64_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U64_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U8(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U8_2(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U8_3(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element U8_4(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Element createPixel(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element.DataType, android.support.v8.renderscript.Element.DataKind);
+ method public static android.support.v8.renderscript.Element createVector(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element.DataType, int);
+ method public int getBytesSize();
+ method public android.support.v8.renderscript.Element.DataKind getDataKind();
+ method public android.support.v8.renderscript.Element.DataType getDataType();
+ method public long getDummyElement(android.support.v8.renderscript.RenderScript);
+ method public android.support.v8.renderscript.Element getSubElement(int);
+ method public int getSubElementArraySize(int);
+ method public int getSubElementCount();
+ method public java.lang.String getSubElementName(int);
+ method public int getSubElementOffsetBytes(int);
+ method public int getVectorSize();
+ method public boolean isCompatible(android.support.v8.renderscript.Element);
+ method public boolean isComplex();
+ }
+
+ public static class Element.Builder {
+ ctor public Element.Builder(android.support.v8.renderscript.RenderScript);
+ method public android.support.v8.renderscript.Element.Builder add(android.support.v8.renderscript.Element, java.lang.String, int);
+ method public android.support.v8.renderscript.Element.Builder add(android.support.v8.renderscript.Element, java.lang.String);
+ method public android.support.v8.renderscript.Element create();
+ }
+
+ public static final class Element.DataKind extends java.lang.Enum {
+ method public static android.support.v8.renderscript.Element.DataKind valueOf(java.lang.String);
+ method public static final android.support.v8.renderscript.Element.DataKind[] values();
+ enum_constant public static final android.support.v8.renderscript.Element.DataKind PIXEL_A;
+ enum_constant public static final android.support.v8.renderscript.Element.DataKind PIXEL_DEPTH;
+ enum_constant public static final android.support.v8.renderscript.Element.DataKind PIXEL_L;
+ enum_constant public static final android.support.v8.renderscript.Element.DataKind PIXEL_LA;
+ enum_constant public static final android.support.v8.renderscript.Element.DataKind PIXEL_RGB;
+ enum_constant public static final android.support.v8.renderscript.Element.DataKind PIXEL_RGBA;
+ enum_constant public static final android.support.v8.renderscript.Element.DataKind PIXEL_YUV;
+ enum_constant public static final android.support.v8.renderscript.Element.DataKind USER;
+ }
+
+ public static final class Element.DataType extends java.lang.Enum {
+ method public static android.support.v8.renderscript.Element.DataType valueOf(java.lang.String);
+ method public static final android.support.v8.renderscript.Element.DataType[] values();
+ enum_constant public static final android.support.v8.renderscript.Element.DataType BOOLEAN;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType FLOAT_32;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType FLOAT_64;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType MATRIX_2X2;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType MATRIX_3X3;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType MATRIX_4X4;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType NONE;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType RS_ALLOCATION;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType RS_ELEMENT;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType RS_SAMPLER;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType RS_SCRIPT;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType RS_TYPE;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType SIGNED_16;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType SIGNED_32;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType SIGNED_64;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType SIGNED_8;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType UNSIGNED_16;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType UNSIGNED_32;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType UNSIGNED_4_4_4_4;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType UNSIGNED_5_5_5_1;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType UNSIGNED_5_6_5;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType UNSIGNED_64;
+ enum_constant public static final android.support.v8.renderscript.Element.DataType UNSIGNED_8;
+ }
+
+ public class FieldPacker {
+ ctor public FieldPacker(int);
+ ctor public FieldPacker(byte[]);
+ method public void addBoolean(boolean);
+ method public void addF32(float);
+ method public void addF32(android.support.v8.renderscript.Float2);
+ method public void addF32(android.support.v8.renderscript.Float3);
+ method public void addF32(android.support.v8.renderscript.Float4);
+ method public void addF64(double);
+ method public void addF64(android.support.v8.renderscript.Double2);
+ method public void addF64(android.support.v8.renderscript.Double3);
+ method public void addF64(android.support.v8.renderscript.Double4);
+ method public void addI16(short);
+ method public void addI16(android.support.v8.renderscript.Short2);
+ method public void addI16(android.support.v8.renderscript.Short3);
+ method public void addI16(android.support.v8.renderscript.Short4);
+ method public void addI32(int);
+ method public void addI32(android.support.v8.renderscript.Int2);
+ method public void addI32(android.support.v8.renderscript.Int3);
+ method public void addI32(android.support.v8.renderscript.Int4);
+ method public void addI64(long);
+ method public void addI64(android.support.v8.renderscript.Long2);
+ method public void addI64(android.support.v8.renderscript.Long3);
+ method public void addI64(android.support.v8.renderscript.Long4);
+ method public void addI8(byte);
+ method public void addI8(android.support.v8.renderscript.Byte2);
+ method public void addI8(android.support.v8.renderscript.Byte3);
+ method public void addI8(android.support.v8.renderscript.Byte4);
+ method public void addMatrix(android.support.v8.renderscript.Matrix4f);
+ method public void addMatrix(android.support.v8.renderscript.Matrix3f);
+ method public void addMatrix(android.support.v8.renderscript.Matrix2f);
+ method public void addObj(android.support.v8.renderscript.BaseObj);
+ method public void addU16(int);
+ method public void addU16(android.support.v8.renderscript.Int2);
+ method public void addU16(android.support.v8.renderscript.Int3);
+ method public void addU16(android.support.v8.renderscript.Int4);
+ method public void addU32(long);
+ method public void addU32(android.support.v8.renderscript.Long2);
+ method public void addU32(android.support.v8.renderscript.Long3);
+ method public void addU32(android.support.v8.renderscript.Long4);
+ method public void addU64(long);
+ method public void addU64(android.support.v8.renderscript.Long2);
+ method public void addU64(android.support.v8.renderscript.Long3);
+ method public void addU64(android.support.v8.renderscript.Long4);
+ method public void addU8(short);
+ method public void addU8(android.support.v8.renderscript.Short2);
+ method public void addU8(android.support.v8.renderscript.Short3);
+ method public void addU8(android.support.v8.renderscript.Short4);
+ method public void align(int);
+ method public final byte[] getData();
+ method public void reset();
+ method public void reset(int);
+ method public void skip(int);
+ method public boolean subBoolean();
+ method public android.support.v8.renderscript.Byte2 subByte2();
+ method public android.support.v8.renderscript.Byte3 subByte3();
+ method public android.support.v8.renderscript.Byte4 subByte4();
+ method public android.support.v8.renderscript.Double2 subDouble2();
+ method public android.support.v8.renderscript.Double3 subDouble3();
+ method public android.support.v8.renderscript.Double4 subDouble4();
+ method public float subF32();
+ method public double subF64();
+ method public android.support.v8.renderscript.Float2 subFloat2();
+ method public android.support.v8.renderscript.Float3 subFloat3();
+ method public android.support.v8.renderscript.Float4 subFloat4();
+ method public short subI16();
+ method public int subI32();
+ method public long subI64();
+ method public byte subI8();
+ method public android.support.v8.renderscript.Int2 subInt2();
+ method public android.support.v8.renderscript.Int3 subInt3();
+ method public android.support.v8.renderscript.Int4 subInt4();
+ method public android.support.v8.renderscript.Long2 subLong2();
+ method public android.support.v8.renderscript.Long3 subLong3();
+ method public android.support.v8.renderscript.Long4 subLong4();
+ method public android.support.v8.renderscript.Matrix2f subMatrix2f();
+ method public android.support.v8.renderscript.Matrix3f subMatrix3f();
+ method public android.support.v8.renderscript.Matrix4f subMatrix4f();
+ method public android.support.v8.renderscript.Short2 subShort2();
+ method public android.support.v8.renderscript.Short3 subShort3();
+ method public android.support.v8.renderscript.Short4 subShort4();
+ method public void subalign(int);
+ }
+
+ public class Float2 {
+ ctor public Float2();
+ ctor public Float2(float, float);
+ field public float x;
+ field public float y;
+ }
+
+ public class Float3 {
+ ctor public Float3();
+ ctor public Float3(float, float, float);
+ field public float x;
+ field public float y;
+ field public float z;
+ }
+
+ public class Float4 {
+ ctor public Float4();
+ ctor public Float4(float, float, float, float);
+ field public float w;
+ field public float x;
+ field public float y;
+ field public float z;
+ }
+
+ public class Int2 {
+ ctor public Int2();
+ ctor public Int2(int, int);
+ field public int x;
+ field public int y;
+ }
+
+ public class Int3 {
+ ctor public Int3();
+ ctor public Int3(int, int, int);
+ field public int x;
+ field public int y;
+ field public int z;
+ }
+
+ public class Int4 {
+ ctor public Int4();
+ ctor public Int4(int, int, int, int);
+ field public int w;
+ field public int x;
+ field public int y;
+ field public int z;
+ }
+
+ public class Long2 {
+ ctor public Long2();
+ ctor public Long2(long, long);
+ field public long x;
+ field public long y;
+ }
+
+ public class Long3 {
+ ctor public Long3();
+ ctor public Long3(long, long, long);
+ field public long x;
+ field public long y;
+ field public long z;
+ }
+
+ public class Long4 {
+ ctor public Long4();
+ ctor public Long4(long, long, long, long);
+ field public long w;
+ field public long x;
+ field public long y;
+ field public long z;
+ }
+
+ public class Matrix2f {
+ ctor public Matrix2f();
+ ctor public Matrix2f(float[]);
+ method public float get(int, int);
+ method public float[] getArray();
+ method public void load(android.support.v8.renderscript.Matrix2f);
+ method public void loadIdentity();
+ method public void loadMultiply(android.support.v8.renderscript.Matrix2f, android.support.v8.renderscript.Matrix2f);
+ method public void loadRotate(float);
+ method public void loadScale(float, float);
+ method public void multiply(android.support.v8.renderscript.Matrix2f);
+ method public void rotate(float);
+ method public void scale(float, float);
+ method public void set(int, int, float);
+ method public void transpose();
+ }
+
+ public class Matrix3f {
+ ctor public Matrix3f();
+ ctor public Matrix3f(float[]);
+ method public float get(int, int);
+ method public float[] getArray();
+ method public void load(android.support.v8.renderscript.Matrix3f);
+ method public void loadIdentity();
+ method public void loadMultiply(android.support.v8.renderscript.Matrix3f, android.support.v8.renderscript.Matrix3f);
+ method public void loadRotate(float, float, float, float);
+ method public void loadRotate(float);
+ method public void loadScale(float, float);
+ method public void loadScale(float, float, float);
+ method public void loadTranslate(float, float);
+ method public void multiply(android.support.v8.renderscript.Matrix3f);
+ method public void rotate(float, float, float, float);
+ method public void rotate(float);
+ method public void scale(float, float);
+ method public void scale(float, float, float);
+ method public void set(int, int, float);
+ method public void translate(float, float);
+ method public void transpose();
+ }
+
+ public class Matrix4f {
+ ctor public Matrix4f();
+ ctor public Matrix4f(float[]);
+ method public float get(int, int);
+ method public float[] getArray();
+ method public boolean inverse();
+ method public boolean inverseTranspose();
+ method public void load(android.support.v8.renderscript.Matrix4f);
+ method public void loadFrustum(float, float, float, float, float, float);
+ method public void loadIdentity();
+ method public void loadMultiply(android.support.v8.renderscript.Matrix4f, android.support.v8.renderscript.Matrix4f);
+ method public void loadOrtho(float, float, float, float, float, float);
+ method public void loadOrthoWindow(int, int);
+ method public void loadPerspective(float, float, float, float);
+ method public void loadProjectionNormalized(int, int);
+ method public void loadRotate(float, float, float, float);
+ method public void loadScale(float, float, float);
+ method public void loadTranslate(float, float, float);
+ method public void multiply(android.support.v8.renderscript.Matrix4f);
+ method public void rotate(float, float, float, float);
+ method public void scale(float, float, float);
+ method public void set(int, int, float);
+ method public void translate(float, float, float);
+ method public void transpose();
+ }
+
+ public class RSDriverException extends android.support.v8.renderscript.RSRuntimeException {
+ ctor public RSDriverException(java.lang.String);
+ }
+
+ public class RSIllegalArgumentException extends android.support.v8.renderscript.RSRuntimeException {
+ ctor public RSIllegalArgumentException(java.lang.String);
+ }
+
+ public class RSInvalidStateException extends android.support.v8.renderscript.RSRuntimeException {
+ ctor public RSInvalidStateException(java.lang.String);
+ }
+
+ public class RSRuntimeException extends java.lang.RuntimeException {
+ ctor public RSRuntimeException(java.lang.String);
+ }
+
+ public class RenderScript {
+ method public void contextDump();
+ method public static android.support.v8.renderscript.RenderScript create(android.content.Context);
+ method public static android.support.v8.renderscript.RenderScript create(android.content.Context, android.support.v8.renderscript.RenderScript.ContextType);
+ method public static android.support.v8.renderscript.RenderScript create(android.content.Context, android.support.v8.renderscript.RenderScript.ContextType, int);
+ method public static android.support.v8.renderscript.RenderScript create(android.content.Context, int, android.support.v8.renderscript.RenderScript.ContextType, int);
+ method public static android.support.v8.renderscript.RenderScript createMultiContext(android.content.Context, android.support.v8.renderscript.RenderScript.ContextType, int, int);
+ method public void destroy();
+ method public void finish();
+ method public final android.content.Context getApplicationContext();
+ method public android.support.v8.renderscript.RenderScript.RSErrorHandler getErrorHandler();
+ method public android.support.v8.renderscript.RenderScript.RSMessageHandler getMessageHandler();
+ method public static void releaseAllContexts();
+ method public void sendMessage(int, int[]);
+ method public void setErrorHandler(android.support.v8.renderscript.RenderScript.RSErrorHandler);
+ method public void setMessageHandler(android.support.v8.renderscript.RenderScript.RSMessageHandler);
+ method public void setPriority(android.support.v8.renderscript.RenderScript.Priority);
+ field public static final int CREATE_FLAG_NONE = 0; // 0x0
+ }
+
+ public static final class RenderScript.ContextType extends java.lang.Enum {
+ method public static android.support.v8.renderscript.RenderScript.ContextType valueOf(java.lang.String);
+ method public static final android.support.v8.renderscript.RenderScript.ContextType[] values();
+ enum_constant public static final android.support.v8.renderscript.RenderScript.ContextType DEBUG;
+ enum_constant public static final android.support.v8.renderscript.RenderScript.ContextType NORMAL;
+ enum_constant public static final android.support.v8.renderscript.RenderScript.ContextType PROFILE;
+ }
+
+ public static final class RenderScript.Priority extends java.lang.Enum {
+ method public static android.support.v8.renderscript.RenderScript.Priority valueOf(java.lang.String);
+ method public static final android.support.v8.renderscript.RenderScript.Priority[] values();
+ enum_constant public static final android.support.v8.renderscript.RenderScript.Priority LOW;
+ enum_constant public static final android.support.v8.renderscript.RenderScript.Priority NORMAL;
+ }
+
+ public static class RenderScript.RSErrorHandler implements java.lang.Runnable {
+ ctor public RenderScript.RSErrorHandler();
+ method public void run();
+ field protected java.lang.String mErrorMessage;
+ field protected int mErrorNum;
+ }
+
+ public static class RenderScript.RSMessageHandler implements java.lang.Runnable {
+ ctor public RenderScript.RSMessageHandler();
+ method public void run();
+ field protected int[] mData;
+ field protected int mID;
+ field protected int mLength;
+ }
+
+ public class Sampler extends android.support.v8.renderscript.BaseObj {
+ method public static android.support.v8.renderscript.Sampler CLAMP_LINEAR(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Sampler CLAMP_NEAREST(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Sampler MIRRORED_REPEAT_LINEAR(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Sampler MIRRORED_REPEAT_NEAREST(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Sampler WRAP_LINEAR(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Sampler WRAP_LINEAR_MIP_LINEAR(android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.Sampler WRAP_NEAREST(android.support.v8.renderscript.RenderScript);
+ method public float getAnisotropy();
+ method public android.support.v8.renderscript.Sampler.Value getMagnification();
+ method public android.support.v8.renderscript.Sampler.Value getMinification();
+ method public android.support.v8.renderscript.Sampler.Value getWrapS();
+ method public android.support.v8.renderscript.Sampler.Value getWrapT();
+ }
+
+ public static class Sampler.Builder {
+ ctor public Sampler.Builder(android.support.v8.renderscript.RenderScript);
+ method public android.support.v8.renderscript.Sampler create();
+ method public void setAnisotropy(float);
+ method public void setMagnification(android.support.v8.renderscript.Sampler.Value);
+ method public void setMinification(android.support.v8.renderscript.Sampler.Value);
+ method public void setWrapS(android.support.v8.renderscript.Sampler.Value);
+ method public void setWrapT(android.support.v8.renderscript.Sampler.Value);
+ }
+
+ public static final class Sampler.Value extends java.lang.Enum {
+ method public static android.support.v8.renderscript.Sampler.Value valueOf(java.lang.String);
+ method public static final android.support.v8.renderscript.Sampler.Value[] values();
+ enum_constant public static final android.support.v8.renderscript.Sampler.Value CLAMP;
+ enum_constant public static final android.support.v8.renderscript.Sampler.Value LINEAR;
+ enum_constant public static final android.support.v8.renderscript.Sampler.Value LINEAR_MIP_LINEAR;
+ enum_constant public static final android.support.v8.renderscript.Sampler.Value LINEAR_MIP_NEAREST;
+ enum_constant public static final android.support.v8.renderscript.Sampler.Value MIRRORED_REPEAT;
+ enum_constant public static final android.support.v8.renderscript.Sampler.Value NEAREST;
+ enum_constant public static final android.support.v8.renderscript.Sampler.Value WRAP;
+ }
+
+ public class Script extends android.support.v8.renderscript.BaseObj {
+ method public void bindAllocation(android.support.v8.renderscript.Allocation, int);
+ method protected android.support.v8.renderscript.Script.FieldID createFieldID(int, android.support.v8.renderscript.Element);
+ method protected android.support.v8.renderscript.Script.InvokeID createInvokeID(int);
+ method protected android.support.v8.renderscript.Script.KernelID createKernelID(int, int, android.support.v8.renderscript.Element, android.support.v8.renderscript.Element);
+ method protected void forEach(int, android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation, android.support.v8.renderscript.FieldPacker);
+ method protected void forEach(int, android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation, android.support.v8.renderscript.FieldPacker, android.support.v8.renderscript.Script.LaunchOptions);
+ method protected void invoke(int);
+ method protected void invoke(int, android.support.v8.renderscript.FieldPacker);
+ method protected boolean isIncSupp();
+ method protected void setIncSupp(boolean);
+ method public void setTimeZone(java.lang.String);
+ method public void setVar(int, float);
+ method public void setVar(int, double);
+ method public void setVar(int, int);
+ method public void setVar(int, long);
+ method public void setVar(int, boolean);
+ method public void setVar(int, android.support.v8.renderscript.BaseObj);
+ method public void setVar(int, android.support.v8.renderscript.FieldPacker);
+ method public void setVar(int, android.support.v8.renderscript.FieldPacker, android.support.v8.renderscript.Element, int[]);
+ }
+
+ public static class Script.Builder {
+ }
+
+ public static class Script.FieldBase {
+ ctor protected Script.FieldBase();
+ method public android.support.v8.renderscript.Allocation getAllocation();
+ method public android.support.v8.renderscript.Element getElement();
+ method public android.support.v8.renderscript.Type getType();
+ method protected void init(android.support.v8.renderscript.RenderScript, int);
+ method protected void init(android.support.v8.renderscript.RenderScript, int, int);
+ method public void updateAllocation();
+ field protected android.support.v8.renderscript.Allocation mAllocation;
+ field protected android.support.v8.renderscript.Element mElement;
+ }
+
+ public static final class Script.FieldID extends android.support.v8.renderscript.BaseObj {
+ }
+
+ public static final class Script.InvokeID extends android.support.v8.renderscript.BaseObj {
+ }
+
+ public static final class Script.KernelID extends android.support.v8.renderscript.BaseObj {
+ }
+
+ public static final class Script.LaunchOptions {
+ ctor public Script.LaunchOptions();
+ method public int getXEnd();
+ method public int getXStart();
+ method public int getYEnd();
+ method public int getYStart();
+ method public int getZEnd();
+ method public int getZStart();
+ method public android.support.v8.renderscript.Script.LaunchOptions setX(int, int);
+ method public android.support.v8.renderscript.Script.LaunchOptions setY(int, int);
+ method public android.support.v8.renderscript.Script.LaunchOptions setZ(int, int);
+ }
+
+ public class ScriptC extends android.support.v8.renderscript.Script {
+ ctor protected ScriptC(long, android.support.v8.renderscript.RenderScript);
+ ctor protected ScriptC(android.support.v8.renderscript.RenderScript, android.content.res.Resources, int);
+ ctor protected ScriptC(android.support.v8.renderscript.RenderScript, java.lang.String, byte[], byte[]);
+ }
+
+ public class ScriptGroup extends android.support.v8.renderscript.BaseObj {
+ method public java.lang.Object[] execute(java.lang.Object...);
+ method public deprecated void execute();
+ method public deprecated void setInput(android.support.v8.renderscript.Script.KernelID, android.support.v8.renderscript.Allocation);
+ method public deprecated void setOutput(android.support.v8.renderscript.Script.KernelID, android.support.v8.renderscript.Allocation);
+ }
+
+ public static final class ScriptGroup.Binding {
+ ctor public ScriptGroup.Binding(android.support.v8.renderscript.Script.FieldID, java.lang.Object);
+ field public android.support.v8.renderscript.Script.FieldID mField;
+ field public java.lang.Object mValue;
+ }
+
+ public static final deprecated class ScriptGroup.Builder {
+ ctor public ScriptGroup.Builder(android.support.v8.renderscript.RenderScript);
+ method public android.support.v8.renderscript.ScriptGroup.Builder addConnection(android.support.v8.renderscript.Type, android.support.v8.renderscript.Script.KernelID, android.support.v8.renderscript.Script.FieldID);
+ method public android.support.v8.renderscript.ScriptGroup.Builder addConnection(android.support.v8.renderscript.Type, android.support.v8.renderscript.Script.KernelID, android.support.v8.renderscript.Script.KernelID);
+ method public android.support.v8.renderscript.ScriptGroup.Builder addKernel(android.support.v8.renderscript.Script.KernelID);
+ method public android.support.v8.renderscript.ScriptGroup create();
+ }
+
+ public static final class ScriptGroup.Builder2 {
+ ctor public ScriptGroup.Builder2(android.support.v8.renderscript.RenderScript);
+ method public android.support.v8.renderscript.ScriptGroup.Input addInput();
+ method public android.support.v8.renderscript.ScriptGroup.Closure addInvoke(android.support.v8.renderscript.Script.InvokeID, java.lang.Object...);
+ method public android.support.v8.renderscript.ScriptGroup.Closure addKernel(android.support.v8.renderscript.Script.KernelID, android.support.v8.renderscript.Type, java.lang.Object...);
+ method public android.support.v8.renderscript.ScriptGroup create(java.lang.String, android.support.v8.renderscript.ScriptGroup.Future...);
+ }
+
+ public static final class ScriptGroup.Closure extends android.support.v8.renderscript.BaseObj {
+ method public android.support.v8.renderscript.ScriptGroup.Future getGlobal(android.support.v8.renderscript.Script.FieldID);
+ method public android.support.v8.renderscript.ScriptGroup.Future getReturn();
+ }
+
+ public static final class ScriptGroup.Future {
+ }
+
+ public static final class ScriptGroup.Input {
+ }
+
+ public abstract class ScriptIntrinsic extends android.support.v8.renderscript.Script {
+ }
+
+ public class ScriptIntrinsic3DLUT extends android.support.v8.renderscript.ScriptIntrinsic {
+ ctor protected ScriptIntrinsic3DLUT(long, android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public static android.support.v8.renderscript.ScriptIntrinsic3DLUT create(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public void forEach(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public android.support.v8.renderscript.Script.KernelID getKernelID();
+ method public void setLUT(android.support.v8.renderscript.Allocation);
+ }
+
+ public class ScriptIntrinsicBlend extends android.support.v8.renderscript.ScriptIntrinsic {
+ method public static android.support.v8.renderscript.ScriptIntrinsicBlend create(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public void forEachAdd(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachClear(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachDst(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachDstAtop(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachDstIn(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachDstOut(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachDstOver(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachMultiply(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachSrc(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachSrcAtop(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachSrcIn(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachSrcOut(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachSrcOver(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachSubtract(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEachXor(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDAdd();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDClear();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDDst();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDDstAtop();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDDstIn();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDDstOut();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDDstOver();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDMultiply();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDSrc();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDSrcAtop();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDSrcIn();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDSrcOut();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDSrcOver();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDSubtract();
+ method public android.support.v8.renderscript.Script.KernelID getKernelIDXor();
+ }
+
+ public class ScriptIntrinsicBlur extends android.support.v8.renderscript.ScriptIntrinsic {
+ ctor protected ScriptIntrinsicBlur(long, android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.ScriptIntrinsicBlur create(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public void forEach(android.support.v8.renderscript.Allocation);
+ method public android.support.v8.renderscript.Script.FieldID getFieldID_Input();
+ method public android.support.v8.renderscript.Script.KernelID getKernelID();
+ method public void setInput(android.support.v8.renderscript.Allocation);
+ method public void setRadius(float);
+ }
+
+ public class ScriptIntrinsicColorMatrix extends android.support.v8.renderscript.ScriptIntrinsic {
+ ctor protected ScriptIntrinsicColorMatrix(long, android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.ScriptIntrinsicColorMatrix create(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public void forEach(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public void forEach(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Script.LaunchOptions);
+ method public android.support.v8.renderscript.Script.KernelID getKernelID();
+ method public void setAdd(android.support.v8.renderscript.Float4);
+ method public void setAdd(float, float, float, float);
+ method public void setColorMatrix(android.support.v8.renderscript.Matrix4f);
+ method public void setColorMatrix(android.support.v8.renderscript.Matrix3f);
+ method public void setGreyscale();
+ method public void setRGBtoYUV();
+ method public void setYUVtoRGB();
+ }
+
+ public class ScriptIntrinsicConvolve3x3 extends android.support.v8.renderscript.ScriptIntrinsic {
+ method public static android.support.v8.renderscript.ScriptIntrinsicConvolve3x3 create(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public void forEach(android.support.v8.renderscript.Allocation);
+ method public void forEach(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Script.LaunchOptions);
+ method public android.support.v8.renderscript.Script.FieldID getFieldID_Input();
+ method public android.support.v8.renderscript.Script.KernelID getKernelID();
+ method public void setCoefficients(float[]);
+ method public void setInput(android.support.v8.renderscript.Allocation);
+ }
+
+ public class ScriptIntrinsicConvolve5x5 extends android.support.v8.renderscript.ScriptIntrinsic {
+ method public static android.support.v8.renderscript.ScriptIntrinsicConvolve5x5 create(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public void forEach(android.support.v8.renderscript.Allocation);
+ method public void forEach(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Script.LaunchOptions);
+ method public android.support.v8.renderscript.Script.FieldID getFieldID_Input();
+ method public android.support.v8.renderscript.Script.KernelID getKernelID();
+ method public void setCoefficients(float[]);
+ method public void setInput(android.support.v8.renderscript.Allocation);
+ }
+
+ public class ScriptIntrinsicHistogram extends android.support.v8.renderscript.ScriptIntrinsic {
+ ctor protected ScriptIntrinsicHistogram(long, android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.ScriptIntrinsicHistogram create(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public void forEach(android.support.v8.renderscript.Allocation);
+ method public void forEach(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Script.LaunchOptions);
+ method public void forEach_Dot(android.support.v8.renderscript.Allocation);
+ method public void forEach_Dot(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Script.LaunchOptions);
+ method public android.support.v8.renderscript.Script.FieldID getFieldID_Input();
+ method public android.support.v8.renderscript.Script.KernelID getKernelID_Separate();
+ method public void setDotCoefficients(float, float, float, float);
+ method public void setOutput(android.support.v8.renderscript.Allocation);
+ }
+
+ public class ScriptIntrinsicLUT extends android.support.v8.renderscript.ScriptIntrinsic {
+ ctor protected ScriptIntrinsicLUT(long, android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.ScriptIntrinsicLUT create(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public void forEach(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Allocation);
+ method public android.support.v8.renderscript.Script.KernelID getKernelID();
+ method public void setAlpha(int, int);
+ method public void setBlue(int, int);
+ method public void setGreen(int, int);
+ method public void setRed(int, int);
+ }
+
+ public class ScriptIntrinsicResize extends android.support.v8.renderscript.ScriptIntrinsic {
+ ctor protected ScriptIntrinsicResize(long, android.support.v8.renderscript.RenderScript);
+ method public static android.support.v8.renderscript.ScriptIntrinsicResize create(android.support.v8.renderscript.RenderScript);
+ method public void forEach_bicubic(android.support.v8.renderscript.Allocation);
+ method public void forEach_bicubic(android.support.v8.renderscript.Allocation, android.support.v8.renderscript.Script.LaunchOptions);
+ method public android.support.v8.renderscript.Script.FieldID getFieldID_Input();
+ method public android.support.v8.renderscript.Script.KernelID getKernelID_bicubic();
+ method public void setInput(android.support.v8.renderscript.Allocation);
+ }
+
+ public class ScriptIntrinsicYuvToRGB extends android.support.v8.renderscript.ScriptIntrinsic {
+ method public static android.support.v8.renderscript.ScriptIntrinsicYuvToRGB create(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public void forEach(android.support.v8.renderscript.Allocation);
+ method public android.support.v8.renderscript.Script.FieldID getFieldID_Input();
+ method public android.support.v8.renderscript.Script.KernelID getKernelID();
+ method public void setInput(android.support.v8.renderscript.Allocation);
+ }
+
+ public class Short2 {
+ ctor public Short2();
+ ctor public Short2(short, short);
+ field public short x;
+ field public short y;
+ }
+
+ public class Short3 {
+ ctor public Short3();
+ ctor public Short3(short, short, short);
+ field public short x;
+ field public short y;
+ field public short z;
+ }
+
+ public class Short4 {
+ ctor public Short4();
+ ctor public Short4(short, short, short, short);
+ field public short w;
+ field public short x;
+ field public short y;
+ field public short z;
+ }
+
+ public class Type extends android.support.v8.renderscript.BaseObj {
+ method public static android.support.v8.renderscript.Type createX(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element, int);
+ method public static android.support.v8.renderscript.Type createXY(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element, int, int);
+ method public static android.support.v8.renderscript.Type createXYZ(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element, int, int, int);
+ method public int getCount();
+ method public long getDummyType(android.support.v8.renderscript.RenderScript, long);
+ method public android.support.v8.renderscript.Element getElement();
+ method public int getX();
+ method public int getY();
+ method public int getYuv();
+ method public int getZ();
+ method public boolean hasFaces();
+ method public boolean hasMipmaps();
+ }
+
+ public static class Type.Builder {
+ ctor public Type.Builder(android.support.v8.renderscript.RenderScript, android.support.v8.renderscript.Element);
+ method public android.support.v8.renderscript.Type create();
+ method public android.support.v8.renderscript.Type.Builder setFaces(boolean);
+ method public android.support.v8.renderscript.Type.Builder setMipmaps(boolean);
+ method public android.support.v8.renderscript.Type.Builder setX(int);
+ method public android.support.v8.renderscript.Type.Builder setY(int);
+ method public android.support.v8.renderscript.Type.Builder setYuvFormat(int);
+ method public android.support.v8.renderscript.Type.Builder setZ(int);
+ }
+
+ public static final class Type.CubemapFace extends java.lang.Enum {
+ method public static android.support.v8.renderscript.Type.CubemapFace valueOf(java.lang.String);
+ method public static final android.support.v8.renderscript.Type.CubemapFace[] values();
+ enum_constant public static final android.support.v8.renderscript.Type.CubemapFace NEGATIVE_X;
+ enum_constant public static final android.support.v8.renderscript.Type.CubemapFace NEGATIVE_Y;
+ enum_constant public static final android.support.v8.renderscript.Type.CubemapFace NEGATIVE_Z;
+ enum_constant public static final android.support.v8.renderscript.Type.CubemapFace POSITIVE_X;
+ enum_constant public static final android.support.v8.renderscript.Type.CubemapFace POSITIVE_Y;
+ enum_constant public static final android.support.v8.renderscript.Type.CubemapFace POSITIVE_Z;
+ }
+
+}
+
diff --git a/v8/renderscript/api/removed.txt b/v8/renderscript/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/v8/renderscript/api/removed.txt
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java b/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java
index 92c3eb5..03244ff 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java
@@ -265,7 +265,6 @@
}
/**
- * @hide
* Enable/Disable AutoPadding for Vec3 elements.
*
* @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding
@@ -463,7 +462,6 @@
/**
* Delete once code is updated.
- * @hide
*/
public void ioSendOutput() {
ioSend();
@@ -1214,10 +1212,7 @@
}
}
- /**
- * @hide
- *
- */
+
private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
Object array, Element.DataType dt, int arrayLen) {
mRS.validate();
@@ -1243,7 +1238,6 @@
}
/**
- * @hide
* Copy a rectangular region from the array into the allocation.
* The array is assumed to be tightly packed.
*
@@ -1262,7 +1256,6 @@
}
/**
- * @hide
* Copy a rectangular region into the allocation from another
* allocation.
*
@@ -1437,7 +1430,6 @@
}
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* guarantee that the Allocation is compatible with the input buffer.
*
@@ -1452,7 +1444,6 @@
}
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* guarantee that the Allocation is compatible with the input buffer.
*
@@ -1465,7 +1456,6 @@
}
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* guarantee that the Allocation is compatible with the input buffer.
*
@@ -1478,7 +1468,6 @@
}
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* guarantee that the Allocation is compatible with the input buffer.
*
@@ -1491,7 +1480,6 @@
}
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* guarantee that the Allocation is compatible with the input buffer.
*
@@ -1505,7 +1493,6 @@
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* and will generate exceptions if the Allocation type does not
* match the component type of the array passed in.
@@ -1521,7 +1508,6 @@
}
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* and will generate exceptions if the Allocation type is not a 32 bit
* integer type.
@@ -1536,7 +1522,6 @@
}
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* and will generate exceptions if the Allocation type is not a 16 bit
* integer type.
@@ -1551,7 +1536,6 @@
}
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* and will generate exceptions if the Allocation type is not an 8 bit
* integer type.
@@ -1566,7 +1550,6 @@
}
/**
- * @hide
* Copy part of this Allocation into an array. This method does not
* and will generate exceptions if the Allocation type is not a 32 bit float
* type.
@@ -1605,7 +1588,6 @@
}
/**
- * @hide
* Copy from a rectangular region in this Allocation into an array.
*
* @param xoff X offset of the region to copy in this Allocation
@@ -1621,7 +1603,6 @@
}
/**
- * @hide
* Copy from a rectangular region in this Allocation into an array.
*
* @param xoff X offset of the region to copy in this Allocation
@@ -1637,7 +1618,6 @@
}
/**
- * @hide
* Copy from a rectangular region in this Allocation into an array.
*
* @param xoff X offset of the region to copy in this Allocation
@@ -1653,7 +1633,6 @@
}
/**
- * @hide
* Copy from a rectangular region in this Allocation into an array.
*
* @param xoff X offset of the region to copy in this Allocation
@@ -1669,7 +1648,6 @@
}
/**
- * @hide
* Copy from a rectangular region in this Allocation into an array.
*
* @param xoff X offset of the region to copy in this Allocation
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java b/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
index 7922b9e..fc867f0 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
@@ -1018,8 +1018,6 @@
* Place a message into the message queue to be sent back to the message
* handler once all previous commands have been executed.
*
- * @hide
- *
* @param id
* @param data
*/
@@ -1364,7 +1362,6 @@
/**
* Gets or creates a RenderScript context of the specified type.
*
- * @hide
* @param ctx The context.
* @param ct The type of context to be created.
* @param sdkVersion The target SDK Version.
@@ -1390,7 +1387,6 @@
}
/**
- * @hide
*
* Releases all the process contexts. This is the same as
* calling .destroy() on each unique context retreived with
@@ -1428,7 +1424,6 @@
*
* If you need a single context please use create()
*
- * @hide
* @param ctx The context.
* @return RenderScript
*/
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Script.java b/v8/renderscript/java/src/android/support/v8/renderscript/Script.java
index 41e7e08..7cef892 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Script.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/Script.java
@@ -109,7 +109,6 @@
* This class should not be directly created. Instead use the method in the
* reflected or intrinsic code "getInvokeID_funcname()".
*
- * @hide
*/
public static final class InvokeID extends BaseObj {
Script mScript;
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic3DLUT.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic3DLUT.java
index dcd1bc1..7fc71f3 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic3DLUT.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic3DLUT.java
@@ -25,7 +25,6 @@
* allocation. The 8 nearest values are sampled and linearly interpolated. The
* result is placed in the output.
*
- * @hide
**/
public class ScriptIntrinsic3DLUT extends ScriptIntrinsic {
private Allocation mLUT;
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Type.java b/v8/renderscript/java/src/android/support/v8/renderscript/Type.java
index 2fd894b..6aeb9ea 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Type.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/Type.java
@@ -114,8 +114,6 @@
/**
* Get the YUV format
*
- * @hide
- *
* @return int
*/
public int getYuv() {
@@ -344,8 +342,6 @@
/**
* Set the YUV layout for a Type.
*
- * @hide
- *
* @param yuvFormat {@link android.graphics.ImageFormat#YV12} or {@link android.graphics.ImageFormat#NV21}
*/
public Builder setYuvFormat(int yuvFormat) {