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
+ *  (&#64;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
+ *  &#64;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 &#64;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>
+     *  &#64;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(&#64;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
+ *  &#64;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 = &#123;NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS&#125;)
  * }</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
+ *  &#64;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
+ *  &#64;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
+ *  &#64;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
+ *   &#64;RequiresPermission(Manifest.permission.SET_WALLPAPER)
+ *   public abstract void setWallpaper(Bitmap bitmap) throws IOException;
+ *
+ *   &#64;RequiresPermission(ACCESS_COARSE_LOCATION)
+ *   public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring at least one permission from a set:
+ * <pre>{@code
+ *   &#64;RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+ *   public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring multiple permissions:
+ * <pre>{@code
+ *   &#64;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
+ *   &#64;RequiresPermission.Read(&#64;RequiresPermission(READ_HISTORY_BOOKMARKS))
+ *   &#64;RequiresPermission.Write(&#64;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(&#64;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(&#64;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
+ *  &#64;UiThread
+ *
+ *  public abstract void setText(&#64;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
+ *  (&#64;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>
+ * &lt;vector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ *     android:height=&quot;64dp&quot;
+ *     android:width=&quot;64dp&quot;
+ *     android:viewportHeight=&quot;600&quot;
+ *     android:viewportWidth=&quot;600&quot; &gt;
+ *     &lt;group
+ *         android:name=&quot;rotationGroup&quot;
+ *         android:pivotX=&quot;300.0&quot;
+ *         android:pivotY=&quot;300.0&quot;
+ *         android:rotation=&quot;45.0&quot; &gt;
+ *         &lt;path
+ *             android:name=&quot;v&quot;
+ *             android:fillColor=&quot;#000000&quot;
+ *             android:pathData=&quot;M300,70 l 0,-70 70,70 0,0 -70,70z&quot; /&gt;
+ *     &lt;/group&gt;
+ * &lt;/vector&gt;
+ * </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>
+ * &lt;animated-vector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ *   android:drawable=&quot;@drawable/vectordrawable&quot; &gt;
+ *     &lt;target
+ *         android:name=&quot;rotationGroup&quot;
+ *         android:animation=&quot;@anim/rotation&quot; /&gt;
+ *     &lt;target
+ *         android:name=&quot;v&quot;
+ *         android:animation=&quot;@anim/path_morph&quot; /&gt;
+ * &lt;/animated-vector&gt;
+ * </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>
+ * &lt;objectAnimator
+ *     android:duration=&quot;6000&quot;
+ *     android:propertyName=&quot;rotation&quot;
+ *     android:valueFrom=&quot;0&quot;
+ *     android:valueTo=&quot;360&quot; /&gt;
+ * </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>
+ * &lt;set xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
+ *     &lt;objectAnimator
+ *         android:duration=&quot;3000&quot;
+ *         android:propertyName=&quot;pathData&quot;
+ *         android:valueFrom=&quot;M300,70 l 0,-70 70,70 0,0   -70,70z&quot;
+ *         android:valueTo=&quot;M300,70 l 0,-70 70,0  0,140 -70,0 z&quot;
+ *         android:valueType=&quot;pathType&quot;/&gt;
+ * &lt;/set&gt;
+ * </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>&lt;vector></code> element.
+ * <p/>
+ * The vector drawable has the following elements:
+ * <p/>
+ * <dt><code>&lt;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>&lt;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>&lt;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>&lt;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>
+ * &lt;vector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ *     android:height=&quot;64dp&quot;
+ *     android:width=&quot;64dp&quot;
+ *     android:viewportHeight=&quot;600&quot;
+ *     android:viewportWidth=&quot;600&quot; &gt;
+ *     &lt;group
+ *         android:name=&quot;rotationGroup&quot;
+ *         android:pivotX=&quot;300.0&quot;
+ *         android:pivotY=&quot;300.0&quot;
+ *         android:rotation=&quot;45.0&quot; &gt;
+ *         &lt;path
+ *             android:name=&quot;v&quot;
+ *             android:fillColor=&quot;#000000&quot;
+ *             android:pathData=&quot;M300,70 l 0,-70 70,70 0,0 -70,70z&quot; /&gt;
+ *     &lt;/group&gt;
+ * &lt;/vector&gt;
+ * </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) { }
+ *
+ *         &#064;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);
+ *
+ *         &#064;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 &lt;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">"&gt;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">"&gt;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">"&gt;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">"&gt;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">"&gt;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">"&gt;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(&quot;Track title&quot;)
+     *     .setContentText(&quot;Artist - Album&quot;)
+     *     .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>&nbsp;&nbsp;&nbsp;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>
+ &lt;PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="first_preferencescreen"&gt;
+ &lt;CheckBoxPreference
+ android:key="wifi enabled"
+ android:title="WiFi" /&gt;
+ &lt;PreferenceScreen
+ android:key="second_preferencescreen"
+ android:title="WiFi settings"&gt;
+ &lt;CheckBoxPreference
+ android:key="prefer wifi"
+ android:title="Prefer WiFi" /&gt;
+ ... other preferences here ...
+ &lt;/PreferenceScreen&gt;
+ &lt;/PreferenceScreen&gt; </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) {