Merge "Don't update mTaskToReturnTo when task is cleared" into nyc-dev
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index a48065b..2c2f6c1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5260,7 +5260,7 @@
         // code is loaded to prevent issues with instances of TLS objects being created before
         // the provider is installed.
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "NetworkSecurityConfigProvider.install");
-        NetworkSecurityConfigProvider.install(appContext, data.appInfo);
+        NetworkSecurityConfigProvider.install(appContext);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
         // Continue loading instrumentation.
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 87511ee..8cc1bc4 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1245,15 +1245,18 @@
             return mContext.mMainThread.getSystemContext().getResources();
         }
         final boolean sameUid = (app.uid == Process.myUid());
-        final Resources r = mContext.mMainThread.getTopLevelResources(
-                sameUid ? app.sourceDir : app.publicSourceDir,
-                sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
-                app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
-                mContext.mPackageInfo);
-        if (r != null) {
-            return r;
+        try {
+            return mContext.mMainThread.getTopLevelResources(
+                    sameUid ? app.sourceDir : app.publicSourceDir,
+                    sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
+                    app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
+                    mContext.mPackageInfo);
+        } catch (Resources.NotFoundException cause) {
+            final NameNotFoundException ex =
+                    new NameNotFoundException("Unable to open " + app.publicSourceDir);
+            ex.initCause(cause);
+            throw ex;
         }
-        throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
     }
 
     @Override
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 31d254dc..a4688d1 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -156,7 +156,7 @@
      * Protected so that tests can override and returns something a fixed value.
      */
     @VisibleForTesting
-    protected DisplayMetrics getDisplayMetrics(int displayId) {
+    protected @NonNull DisplayMetrics getDisplayMetrics(int displayId) {
         DisplayMetrics dm = new DisplayMetrics();
         final Display display =
                 getAdjustedDisplay(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
@@ -250,14 +250,14 @@
         // already.
         if (key.mResDir != null) {
             if (assets.addAssetPath(key.mResDir) == 0) {
-                throw new IllegalArgumentException("failed to add asset path " + key.mResDir);
+                throw new Resources.NotFoundException("failed to add asset path " + key.mResDir);
             }
         }
 
         if (key.mSplitResDirs != null) {
             for (final String splitResDir : key.mSplitResDirs) {
                 if (assets.addAssetPath(splitResDir) == 0) {
-                    throw new IllegalArgumentException(
+                    throw new Resources.NotFoundException(
                             "failed to add split asset path " + splitResDir);
                 }
             }
@@ -303,7 +303,7 @@
         return config;
     }
 
-    private ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key) {
+    private @NonNull ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key) {
         AssetManager assets = createAssetManager(key);
         DisplayMetrics dm = getDisplayMetrics(key.mDisplayId);
         Configuration config = generateConfig(key, dm);
@@ -359,7 +359,7 @@
      * Gets an existing Resources object tied to this Activity, or creates one if it doesn't exist
      * or the class loader is different.
      */
-    private Resources getOrCreateResourcesForActivityLocked(@NonNull IBinder activityToken,
+    private @NonNull Resources getOrCreateResourcesForActivityLocked(@NonNull IBinder activityToken,
             @NonNull ClassLoader classLoader, @NonNull ResourcesImpl impl) {
         final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(
                 activityToken);
@@ -393,7 +393,7 @@
      * Gets an existing Resources object if the class loader and ResourcesImpl are the same,
      * otherwise creates a new Resources object.
      */
-    private Resources getOrCreateResourcesLocked(@NonNull ClassLoader classLoader,
+    private @NonNull Resources getOrCreateResourcesLocked(@NonNull ClassLoader classLoader,
             @NonNull ResourcesImpl impl) {
         // Find an existing Resources that has this ResourcesImpl set.
         final int refCount = mResourceReferences.size();
@@ -441,7 +441,7 @@
      *                    {@link ClassLoader#getSystemClassLoader()} is used.
      * @return a Resources object from which to access resources.
      */
-    public Resources createBaseActivityResources(@NonNull IBinder activityToken,
+    public @NonNull Resources createBaseActivityResources(@NonNull IBinder activityToken,
             @Nullable String resDir,
             @Nullable String[] splitResDirs,
             @Nullable String[] overlayDirs,
@@ -495,7 +495,7 @@
      *         {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)}
      *         is called.
      */
-    private Resources getOrCreateResources(@Nullable IBinder activityToken,
+    private @NonNull Resources getOrCreateResources(@Nullable IBinder activityToken,
             @NonNull ResourcesKey key, @NonNull ClassLoader classLoader) {
         synchronized (this) {
             if (DEBUG) {
@@ -603,7 +603,7 @@
      * {@link ClassLoader#getSystemClassLoader()} is used.
      * @return a Resources object from which to access resources.
      */
-    public Resources getResources(@Nullable IBinder activityToken,
+    public @NonNull Resources getResources(@Nullable IBinder activityToken,
             @Nullable String resDir,
             @Nullable String[] splitResDirs,
             @Nullable String[] overlayDirs,
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 30da03c..bc79f41 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -29,7 +29,9 @@
 import android.text.TextPaint;
 import android.text.TextUtils;
 import android.util.Printer;
-
+import android.text.BidiFormatter;
+import android.text.TextPaint;
+import android.text.Html;
 import java.text.Collator;
 import java.util.Comparator;
 
@@ -44,7 +46,6 @@
  */
 public class PackageItemInfo {
     private static final float MAX_LABEL_SIZE_PX = 500f;
-
     /**
      * Public name of this item. From the "android:name" attribute.
      */
@@ -145,7 +146,7 @@
         }
         return packageName;
     }
-
+ 
     /**
      * Same as {@link #loadLabel(PackageManager)} with the addition that
      * the returned label is safe for being presented in the UI since it
diff --git a/core/java/android/security/net/config/ManifestConfigSource.java b/core/java/android/security/net/config/ManifestConfigSource.java
index d59b5e3..92bddb7 100644
--- a/core/java/android/security/net/config/ManifestConfigSource.java
+++ b/core/java/android/security/net/config/ManifestConfigSource.java
@@ -29,13 +29,19 @@
 
     private final Object mLock = new Object();
     private final Context mContext;
-    private final ApplicationInfo mInfo;
+    private final int mApplicationInfoFlags;
+    private final int mTargetSdkVersion;
+    private final int mConfigResourceId;
 
     private ConfigSource mConfigSource;
 
-    public ManifestConfigSource(Context context, ApplicationInfo info) {
+    public ManifestConfigSource(Context context) {
         mContext = context;
-        mInfo = info;
+        // Cache values because ApplicationInfo is mutable and apps do modify it :(
+        ApplicationInfo info = context.getApplicationInfo();
+        mApplicationInfoFlags = info.flags;
+        mTargetSdkVersion = info.targetSdkVersion;
+        mConfigResourceId = info.networkSecurityConfigRes;
     }
 
     @Override
@@ -53,29 +59,24 @@
             if (mConfigSource != null) {
                 return mConfigSource;
             }
-            int targetSdkVersion = mInfo.targetSdkVersion;
-            int configResourceId = 0;
-            if (mInfo != null) {
-                configResourceId = mInfo.networkSecurityConfigRes;
-            }
 
             ConfigSource source;
-            if (configResourceId != 0) {
-                boolean debugBuild = (mInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+            if (mConfigResourceId != 0) {
+                boolean debugBuild = (mApplicationInfoFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
                 if (DBG) {
                     Log.d(LOG_TAG, "Using Network Security Config from resource "
-                            + mContext.getResources().getResourceEntryName(configResourceId)
+                            + mContext.getResources().getResourceEntryName(mConfigResourceId)
                             + " debugBuild: " + debugBuild);
                 }
-                source = new XmlConfigSource(mContext, configResourceId, debugBuild,
-                        targetSdkVersion);
+                source = new XmlConfigSource(mContext, mConfigResourceId, debugBuild,
+                        mTargetSdkVersion);
             } else {
                 if (DBG) {
                     Log.d(LOG_TAG, "No Network Security Config specified, using platform default");
                 }
                 boolean usesCleartextTraffic =
-                        (mInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0;
-                source = new DefaultConfigSource(usesCleartextTraffic, targetSdkVersion);
+                        (mApplicationInfoFlags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0;
+                source = new DefaultConfigSource(usesCleartextTraffic, mTargetSdkVersion);
             }
             mConfigSource = source;
             return mConfigSource;
diff --git a/core/java/android/security/net/config/NetworkSecurityConfigProvider.java b/core/java/android/security/net/config/NetworkSecurityConfigProvider.java
index 4c51cc3..0f66873 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfigProvider.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfigProvider.java
@@ -17,7 +17,6 @@
 package android.security.net.config;
 
 import android.content.Context;
-import android.content.pm.ApplicationInfo;
 import java.security.Security;
 import java.security.Provider;
 
@@ -33,8 +32,8 @@
         put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
     }
 
-    public static void install(Context context, ApplicationInfo info) {
-        ApplicationConfig config = new ApplicationConfig(new ManifestConfigSource(context, info));
+    public static void install(Context context) {
+        ApplicationConfig config = new ApplicationConfig(new ManifestConfigSource(context));
         ApplicationConfig.setDefaultInstance(config);
         int pos = Security.insertProviderAt(new NetworkSecurityConfigProvider(), 1);
         if (pos != 1) {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index b4131b4..415e70c 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -51,6 +51,7 @@
 
     private static native void nativeSetLayer(long nativeObject, int zorder);
     private static native void nativeSetPosition(long nativeObject, float x, float y);
+    private static native void nativeSetPositionAppliesWithResize(long nativeObject);
     private static native void nativeSetSize(long nativeObject, int w, int h);
     private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
     private static native void nativeSetAlpha(long nativeObject, float alpha);
@@ -407,6 +408,16 @@
         nativeSetPosition(mNativeObject, x, y);
     }
 
+    /**
+     * If the size changes in this transaction, position updates specified
+     * in this transaction will not complete until a buffer of the new size
+     * arrives.
+     */
+    public void setPositionAppliesWithResize() {
+        checkNotReleased();
+        nativeSetPositionAppliesWithResize(mNativeObject);
+    }
+
     public void setSize(int w, int h) {
         checkNotReleased();
         nativeSetSize(mNativeObject, w, h);
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
index 5d3043c..c828d11 100644
--- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
@@ -84,7 +84,8 @@
                     powerMaUs = 0;
                 }
 
-                if (callback != null) {
+                // Only report if there is a callback and if this is not the first read.
+                if (callback != null && mLastTimeReadUs != 0) {
                     long userTimeDeltaUs = userTimeUs;
                     long systemTimeDeltaUs = systemTimeUs;
                     long powerDeltaMaUs = powerMaUs;
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index a9ed9dc..ff75677 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -248,6 +248,15 @@
     }
 }
 
+static void nativeSetPositionAppliesWithResize(JNIEnv* env, jclass clazz,
+        jlong nativeObject) {
+    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    status_t err = ctrl->setPositionAppliesWithResize();
+    if (err < 0 && err != NO_INIT) {
+        doThrowIAE(env);
+    }
+}
+
 static void nativeSetSize(JNIEnv* env, jclass clazz, jlong nativeObject, jint w, jint h) {
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     status_t err = ctrl->setSize(w, h);
@@ -658,6 +667,8 @@
             (void*)nativeSetLayer },
     {"nativeSetPosition", "(JFF)V",
             (void*)nativeSetPosition },
+    {"nativeSetPositionAppliesWithResize", "(J)V",
+            (void*)nativeSetPositionAppliesWithResize },
     {"nativeSetSize", "(JII)V",
             (void*)nativeSetSize },
     {"nativeSetTransparentRegionHint", "(JLandroid/graphics/Region;)V",
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index aa84ed0..17712b0 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -860,32 +860,32 @@
     </plurals>
     <string name="now_string_shortest" msgid="8912796667087856402">"indi"</string>
     <plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>dəq</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>dəq</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>d</item>
     </plurals>
     <plurals name="duration_hours_shortest" formatted="false" msgid="3552182110578602356">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>saat</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>saat</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>st</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>st</item>
     </plurals>
     <plurals name="duration_days_shortest" formatted="false" msgid="5213655532597081640">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>gün</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>gün</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>g</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>g</item>
     </plurals>
     <plurals name="duration_years_shortest" formatted="false" msgid="7848711145196397042">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>il</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>il</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>i</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>i</item>
     </plurals>
     <plurals name="duration_minutes_shortest_future" formatted="false" msgid="3277614521231489951">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>dəqiqədə</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>dəqiqədə</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>d-də</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>d-də</item>
     </plurals>
     <plurals name="duration_hours_shortest_future" formatted="false" msgid="2152452368397489370">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>saata</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>saata</item>
+      <item quantity="other"> <xliff:g id="COUNT_1">%d</xliff:g>s-da</item>
+      <item quantity="one"> <xliff:g id="COUNT_0">%d</xliff:g>s-da</item>
     </plurals>
     <plurals name="duration_days_shortest_future" formatted="false" msgid="8088331502820295701">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>gündə</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>gündə</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>g-də</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>g-də</item>
     </plurals>
     <plurals name="duration_years_shortest_future" formatted="false" msgid="2317006667145250301">
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>ildə</item>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 92541f2..616d2b8 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -860,20 +860,20 @@
     </plurals>
     <string name="now_string_shortest" msgid="8912796667087856402">"jetzt"</string>
     <plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> min</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> min</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> min</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> min</item>
     </plurals>
     <plurals name="duration_hours_shortest" formatted="false" msgid="3552182110578602356">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> h</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> h</item>
     </plurals>
     <plurals name="duration_days_shortest" formatted="false" msgid="5213655532597081640">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> d</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> d</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> T.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> T.</item>
     </plurals>
     <plurals name="duration_years_shortest" formatted="false" msgid="7848711145196397042">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> a</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> J.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> J.</item>
     </plurals>
     <plurals name="duration_minutes_shortest_future" formatted="false" msgid="3277614521231489951">
       <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> min</item>
@@ -884,12 +884,12 @@
       <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> h</item>
     </plurals>
     <plurals name="duration_days_shortest_future" formatted="false" msgid="8088331502820295701">
-      <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> d</item>
-      <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> d</item>
+      <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> T.</item>
+      <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> T.</item>
     </plurals>
     <plurals name="duration_years_shortest_future" formatted="false" msgid="2317006667145250301">
-      <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> a</item>
-      <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> a</item>
+      <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> J.</item>
+      <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> J.</item>
     </plurals>
     <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
       <item quantity="other">vor <xliff:g id="COUNT_1">%d</xliff:g> Minuten</item>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 393b8ff..2f76a33 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -868,12 +868,12 @@
       <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> h</item>
     </plurals>
     <plurals name="duration_days_shortest" formatted="false" msgid="5213655532597081640">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> días</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> día</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> d</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> d</item>
     </plurals>
     <plurals name="duration_years_shortest" formatted="false" msgid="7848711145196397042">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> años</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> año</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> a</item>
     </plurals>
     <plurals name="duration_minutes_shortest_future" formatted="false" msgid="3277614521231489951">
       <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> min</item>
@@ -884,8 +884,8 @@
       <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> h</item>
     </plurals>
     <plurals name="duration_days_shortest_future" formatted="false" msgid="8088331502820295701">
-      <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> días</item>
-      <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> día</item>
+      <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> d</item>
+      <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> d</item>
     </plurals>
     <plurals name="duration_years_shortest_future" formatted="false" msgid="2317006667145250301">
       <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> años</item>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 0626546..fcccc55 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -860,8 +860,8 @@
     </plurals>
     <string name="now_string_shortest" msgid="8912796667087856402">"agora"</string>
     <plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> min</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> min</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> m</item>
     </plurals>
     <plurals name="duration_hours_shortest" formatted="false" msgid="3552182110578602356">
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
@@ -876,8 +876,8 @@
       <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> a</item>
     </plurals>
     <plurals name="duration_minutes_shortest_future" formatted="false" msgid="3277614521231489951">
-      <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> min</item>
-      <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> min</item>
+      <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> m</item>
+      <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> m</item>
     </plurals>
     <plurals name="duration_hours_shortest_future" formatted="false" msgid="2152452368397489370">
       <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> h</item>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 993cd7e..ee89493 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -21,7 +21,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="byteShort" msgid="8340973892742019101">"Բ"</string>
-    <string name="kilobyteShort" msgid="5973789783504771878">"ԿԲ"</string>
+    <string name="kilobyteShort" msgid="5973789783504771878">"կԲ"</string>
     <string name="megabyteShort" msgid="6355851576770428922">"ՄԲ"</string>
     <string name="gigabyteShort" msgid="3259882455212193214">"ԳԲ"</string>
     <string name="terabyteShort" msgid="231613018159186962">"ՏԲ"</string>
@@ -973,7 +973,7 @@
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Խմբագրել հետևյալով՝ %1$s"</string>
     <string name="whichEditApplicationLabel" msgid="7183524181625290300">"Փոփոխել"</string>
     <string name="whichSendApplication" msgid="6902512414057341668">"Կիսվել"</string>
-    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Տարածել ըստ %1$s"</string>
+    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Կիսվել %1$s-ի միջոցով"</string>
     <string name="whichSendApplicationLabel" msgid="4579076294675975354">"Տրամադրել"</string>
     <string name="whichSendToApplication" msgid="8272422260066642057">"Ուղարկել այս հավելվածով"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"Ուղարկել %1$s հավելվածով"</string>
@@ -995,7 +995,7 @@
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածի աշխատանքը շարունակաբար ընդհատվում է"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը շարունակաբար ընդհատվում է"</string>
     <string name="aerr_restart" msgid="7581308074153624475">"Կրկին բացել հավելվածը"</string>
-    <string name="aerr_report" msgid="5371800241488400617">"Ուղարկել կարծիք"</string>
+    <string name="aerr_report" msgid="5371800241488400617">"Կարծիք հայտնել"</string>
     <string name="aerr_close" msgid="2991640326563991340">"Փակել"</string>
     <string name="aerr_mute" msgid="1974781923723235953">"Անջատել ձայնը մինչև սարքի վերագործարկումը"</string>
     <string name="aerr_wait" msgid="3199956902437040261">"Սպասել"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index ee3c606..860ff12 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -253,7 +253,7 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"åpne bilder, medieinnhold og filer på enheten din"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
-    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"spill inn lyd"</string>
+    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ta opp lyd"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"ta bilder og ta opp video"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 12f2ba7..d9156b5 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -243,23 +243,23 @@
     <string name="user_owner_label" msgid="1119010402169916617">"ਨਿੱਜੀ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="managed_profile_label" msgid="5289992269827577857">"ਕੰਮ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"ਸੰਪਰਕ"</string>
-    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਨੂੰ ਐਕਸੈਸ ਕਰੋ"</string>
+    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"ਟਿਕਾਣਾ"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"ਇਸ ਡੀਵਾਈਸ ਦੇ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਤੱਕ ਪਹੁੰਚੋ"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"ਇਸ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ਕੈਲੰਡਰ"</string>
-    <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ਆਪਣੇ ਕੈਲੰਡਰ ਦੀ ਐਕਸੈਸ ਕਰੋ"</string>
+    <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
-    <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦਿਖਾਓ"</string>
+    <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS ਸੁਨੇਹੇ ਭੇਜਣ ਅਤੇ ਦੇਖਣ"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"ਸਟੋਰੇਜ"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"ਆਪਣੀ ਡੀਵਾਈਸ ’ਤੇ ਫੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਫਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣ"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"ਆਪਣੀ ਡੀਵਾਈਸ ’ਤੇ ਫੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਫਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"ਮਾਈਕ੍ਰੋਫੋਨ"</string>
-    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ਔਡੀਓ ਰਿਕਾਰਡ ਕਰੋ"</string>
+    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ਔਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"ਕੈਮਰਾ"</string>
-    <string name="permgroupdesc_camera" msgid="3250611594678347720">"ਤਸਵੀਰਾਂ ਖਿੱਚੋ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰੋ"</string>
+    <string name="permgroupdesc_camera" msgid="3250611594678347720">"ਤਸਵੀਰਾਂ ਲੈਣ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"ਫੋਨ"</string>
-    <string name="permgroupdesc_phone" msgid="6234224354060641055">"ਫ਼ੋਨ ਕਾਲਾਂ ਕਰੋ ਅਤੇ ਉਹਨਾਂ ਨੂੰ ਪ੍ਰਬੰਧਿਤ ਕਰੋ"</string>
+    <string name="permgroupdesc_phone" msgid="6234224354060641055">"ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"ਸਰੀਰ ਸੰਵੇਦਕ"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ਆਪਣੇ ਮਹੱਤਵਪੂਰਣ ਲੱਛਣਾਂ ਬਾਰੇ ਸੰਵੇਦਕ ਡੈਟਾ ਤੱਕ ਪਹੁੰਚ"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ਆਪਣੇ ਸਰੀਰ ਦੇ ਅਹਿਮ ਚਿੰਨ੍ਹਾਂ ਬਾਰੇ ਸੰਵੇਦਕ ਡੈਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਇੱਕ ਵਿੰਡੋ ਦੀ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਇੰਟਰੈਕਟ ਕਰ ਰਹੇ ਹੋ।"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ਐਕਸਪਲੋਰ ਬਾਇ ਟਚ ਚਾਲੂ ਕਰੋ"</string>
@@ -292,7 +292,7 @@
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਵੱਲੋਂ ਪ੍ਰਾਪਤ ਕੀਤੇ ਸੈਲ ਪ੍ਰਸਾਰਨ ਸੁਨੇਹੇ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸੈਲ ਪ੍ਰਸਾਰਨ ਚਿਤਾਵਨੀਆਂ ਤੁਹਾਨੂੰ ਐਮਰਜੈਂਸੀ ਸਥਿਤੀਆਂ ਦੀ ਚਿਤਾਵਨੀ ਦੇਣ ਲਈ ਕੁਝ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਤੇ ਪ੍ਰਦਾਨ ਕੀਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ। ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦੇ ਪ੍ਰਦਰਸ਼ਨ ਜਾਂ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾ ਸਕਦੇ ਹਨ ਜਦੋਂ ਇੱਕ ਐਮਰਜੈਂਸੀ ਸੈਲ ਪ੍ਰਸਾਰਨ ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ਸਬਸਕ੍ਰਾਈਬ ਕੀਤੇ ਫੀਡਸ ਪੜ੍ਹੋ"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ਐਪ ਨੂੰ ਵਰਤਮਾਨ ਵਿੱਚ ਸਿੰਕ ਕੀਤੇ ਫੀਡਸ ਬਾਰੇ ਵੇਰਵੇ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
-    <string name="permlab_sendSms" msgid="7544599214260982981">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦਿਖਾਓ"</string>
+    <string name="permlab_sendSms" msgid="7544599214260982981">"SMS ਸੁਨੇਹੇ ਭੇਜਣ ਅਤੇ ਦੇਖਣ"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"ਐਪ ਨੂੰ SMS ਸੁਨੇਹੇ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦੇ ਸਿੱਟੇ ਵਜੋਂ ਅਕਲਪਿਤ ਖ਼ਰਚੇ ਪੈ ਸਕਦੇ ਹਨ। ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੀ ਪੁਸ਼ਟੀ ਤੋਂ ਬਿਨਾਂ ਸੁਨੇਹੇ ਭੇਜ ਕੇ ਤੁਹਾਨੂੰ ਖ਼ਰਚੇ ਪਾ ਸਕਦੇ ਹਨ।"</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"ਤੁਹਾਡੇ ਟੈਕਸਟ ਸੁਨੇਹੇ (SMS ਜਾਂ MMS) ਪੜ੍ਹੋ"</string>
     <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਜਾਂ SIM ਕਾਰਡ ਤੇ ਸਟੋਰ ਕੀਤੇ SMS ਸੁਨੇਹੇ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਸਾਰੇ SMS ਸੁਨੇਹੇ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਸਮੱਗਰੀ ਜਾਂ ਗੁਪਤਤਾ ਤੇ ਧਿਆਨ ਦਿੱਤੇ ਬਿਨਾਂ।"</string>
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index f287f51..ae858fe 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -843,6 +843,8 @@
   to: http://tools.android.com/tech-docs/test-recorder
 - from: /r/studio-ui/export-licenses.html
   to: http://tools.android.com/tech-docs/new-build-system/license
+- from: /r/studio-ui/experimental-to-stable-gradle.html
+  to: http://tools.android.com/tech-docs/new-build-system/gradle-experimental/experimental-to-stable-gradle
 - from: /reference/org/apache/http/...
   to: /about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client
 - from: /shareables/...
diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd
index 1335790..4d93c83 100644
--- a/docs/html/guide/practices/screens_support.jd
+++ b/docs/html/guide/practices/screens_support.jd
@@ -677,7 +677,7 @@
   <li>48x48 (1.0x baseline) for medium-density</li>
   <li>72x72 (1.5x) for high-density</li>
   <li>96x96 (2.0x) for extra-high-density</li>
-  <li>180x180 (3.0x) for extra-extra-high-density</li>
+  <li>144x144 (3.0x) for extra-extra-high-density</li>
   <li>192x192 (4.0x) for extra-extra-extra-high-density (launcher icon only; see
     <a href="#xxxhdpi-note">note</a> above)</li>
 </ul>
diff --git a/docs/html/topic/libraries/support-library/features.jd b/docs/html/topic/libraries/support-library/features.jd
index d9616d9..584bef8 100755
--- a/docs/html/topic/libraries/support-library/features.jd
+++ b/docs/html/topic/libraries/support-library/features.jd
@@ -619,7 +619,7 @@
 <a href="{@docRoot}reference/android/support/customtabs/CustomTabsService.html">Custom Tabs
 Service</a>
 and
-<a href="{@docRoot}reference/android/support/customtabs/CustomTabsSCallback.html">Custom Tabs
+<a href="{@docRoot}reference/android/support/customtabs/CustomTabsCallback.html">Custom Tabs
 Callback</a>.  </p>
 
 
diff --git a/docs/html/topic/libraries/testing-support-library/index.jd b/docs/html/topic/libraries/testing-support-library/index.jd
index 8b23f73..941f5c3 100644
--- a/docs/html/topic/libraries/testing-support-library/index.jd
+++ b/docs/html/topic/libraries/testing-support-library/index.jd
@@ -523,7 +523,7 @@
 mDevice = UiDevice.getInstance(getInstrumentation());
 
 // Perform a short press on the HOME button
-mDevice().pressHome();
+mDevice.pressHome();
 
 // Bring up the default launcher by searching for
 // a UI component that matches the content-description for the launcher button
diff --git a/docs/html/training/appbar/setting-up.jd b/docs/html/training/appbar/setting-up.jd
index cc963c6..cf564d0 100644
--- a/docs/html/training/appbar/setting-up.jd
+++ b/docs/html/training/appbar/setting-up.jd
@@ -68,7 +68,7 @@
 as your activity's app bar:
 
 <ol>
-  <li>Add the the
+  <li>Add the
   <a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7
   appcompat</a> support library to your project, as described in <a href=
   "{@docRoot}tools/support-library/setup.html">Support Library Setup</a>.
diff --git a/docs/html/training/auto/audio/index.jd b/docs/html/training/auto/audio/index.jd
index 9144900..aa20e3a 100644
--- a/docs/html/training/auto/audio/index.jd
+++ b/docs/html/training/auto/audio/index.jd
@@ -20,6 +20,7 @@
       <li><a href="#overview">Provide Audio Services</a></li>
       <li><a href="#config_manifest">Configure Your Manifest</a></li>
       <li><a href="#isconnected">Determine if Your App is Connected</a></li>
+      <li><a href="#alarm">Handle Alarms</a></li>
       <li><a href="#implement_browser">Build a Browser Service</a></li>
       <li><a href="#implement_callback">Implement Play Controls</a></li>
       <li><a href="#support_voice">Support Voice Actions</a></li>
@@ -239,6 +240,44 @@
 registerReceiver(receiver, filter);
 </pre>
 
+<h2 id="alarm">Handle Alarms</h2>
+<p>
+To prevent user distraction, Android Auto media apps must not start playing audio
+ through the car speakers unless a user consciously starts playback (such as
+ when the user presses play in your app). Even a user-scheduled alarm from the
+ media app must not start playing music through the car speakers.
+ If your media app has an alarm feature, the app should determine if the phone
+ is in
+<a href="{@docRoot}reference/android/content/res/Configuration.html#UI_MODE_TYPE_CAR">car mode</a>
+before playing any audio. Your app can do this by calling
+<a href="{@docRoot}reference/android/app/UiModeManager.html">UiModeManager.getCurrentModeType()</a>,
+ which checks whether the device is running in car mode.
+</p>
+
+<p>
+If the device is in car mode, media apps that support alarms must do one of the
+following things:
+
+<ul>
+<li>Disable the alarm.</li>
+<li>Play the alarm over
+<a href="{@docRoot}reference/android/media/AudioManager.html">STREAM_ALARM</a>,
+ and provide a UI on the phone screen to disable the alarm.</li>
+</ul>
+
+The following code snippet checks whether an app is running in car mode:
+<pre>
+ public static boolean isCarUiMode(Context c) {
+      UiModeManager uiModeManager = (UiModeManager) c.getSystemService(Context.UI_MODE_SERVICE);
+      if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
+            LogHelper.d(TAG, "Running in Car mode");
+            return true;
+      } else {
+          LogHelper.d(TAG, "Running on a non-Car mode");
+          return false;
+        }
+  }
+</pre>
 
 <h2 id="implement_browser">Build a Browser Service</h2>
 
diff --git a/docs/html/training/testing/performance.jd b/docs/html/training/testing/performance.jd
index 8592c0f..0c0ab7f 100644
--- a/docs/html/training/testing/performance.jd
+++ b/docs/html/training/testing/performance.jd
@@ -437,15 +437,25 @@
 </p>
 
 <ul>
-  <li>Rendering Performance 101
+  <li>
+    <a class="external-link" href="https://www.youtube.com/watch?v=HXQhu6qfTVU">
+      Rendering Performance 101</a>
   </li>
-  <li>Why 60fps?
+  <li>
+    <a class="external-link" href="https://www.youtube.com/watch?v=CaMTIgxCSqU">
+      Why 60fps?</a>
   </li>
-  <li>Android UI and the GPU
+  <li>
+    <a class="external-link" href="https://www.youtube.com/watch?v=WH9AFhgwmDw">
+      Android, UI, and the GPU</a>
   </li>
-  <li>Invalidations Layouts and performance
+  <li>
+    <a class="external-link" href="https://www.youtube.com/watch?v=we6poP0kw6E">
+      Invalidations, Layouts, and Performance</a>
   </li>
-  <li>Analyzing UI Performance with Systrace
+  <li>
+    <a href="{@docRoot}studio/profile/systrace.html">
+      Analyzing UI Performance with Systrace</a>
   </li>
 </ul>
 
diff --git a/packages/PrintRecommendationService/res/values/strings.xml b/packages/PrintRecommendationService/res/values/strings.xml
index 348fcac..b6c45b7 100644
--- a/packages/PrintRecommendationService/res/values/strings.xml
+++ b/packages/PrintRecommendationService/res/values/strings.xml
@@ -26,6 +26,6 @@
     <string name="plugin_vendor_samsung">Samsung</string>
     <string name="plugin_vendor_epson">Epson</string>
     <string name="plugin_vendor_konica_minolta">Konica Minolta</string>
-    <string name="plugin_vendor_fuji">Fuji</string>
+    <string name="plugin_vendor_fuji_xerox">Fuji Xerox</string>
     <string name="plugin_vendor_morpia">Mopria</string>
 </resources>
diff --git a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
index 52889ce..703cf6f 100644
--- a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
+++ b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
@@ -60,7 +60,7 @@
     </vendor>
 
     <vendor>
-        <name>@string/plugin_vendor_fuji</name>
+        <name>@string/plugin_vendor_fuji_xerox</name>
         <package>jp.co.fujixerox.prt.PrintUtil.PCL</package>
         <mdns-names>
             <mdns-name>FUJI XEROX</mdns-name>
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/MDnsUtils.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/MDnsUtils.java
index 7a2d0d8..b0da08b 100755
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/MDnsUtils.java
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/MDnsUtils.java
@@ -39,8 +39,10 @@
         String usbMfg = getString(attributes.get(ATTRIBUTE__USB_MFG));
         String usbMdl = getString(attributes.get(ATTRIBUTE__USB_MDL));
         String mfg = getString(attributes.get(ATTRIBUTE__MFG));
-        return containsVendor(product, vendorValues) || containsVendor(ty, vendorValues) || containsVendor(usbMfg, vendorValues) || containsVendor(mfg, vendorValues) && !(containsString(ty, EXCLUDE_FUJI) || containsString(product, EXCLUDE_FUJI) || containsString(usbMdl, EXCLUDE_FUJI));
-
+        return (containsVendor(product, vendorValues) || containsVendor(ty, vendorValues) ||
+                containsVendor(usbMfg, vendorValues) || containsVendor(mfg, vendorValues)) &&
+                !(containsString(ty, EXCLUDE_FUJI) || containsString(product, EXCLUDE_FUJI) ||
+                        containsString(usbMdl, EXCLUDE_FUJI));
     }
 
     public static String getVendor(NsdServiceInfo networkDevice) {
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 08dbb01..2cd6813 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -242,7 +242,7 @@
     <string name="transition_animation_scale_title" msgid="387527540523595875">"Scale ng transition animation"</string>
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"Scale ng tagal ng animator"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"I-simulate, ika-2 display"</string>
-    <string name="debug_applications_category" msgid="4206913653849771549">"Apps"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"Mga App"</string>
     <string name="immediately_destroy_activities" msgid="1579659389568133959">"Huwag magtago ng mga aktibidad"</string>
     <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"Sirain ang bawat aktibidad sa sandaling iwan ito ng user"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"Limitasyon ng proseso sa background"</string>
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index 2db97a6..0c8cc9b 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -43,7 +43,7 @@
             android:ellipsize="start"
             android:inputType="textShortMessage|textAutoCorrect|textCapSentences"
             android:textIsSelectable="true"
-            android:imeOptions="actionSend|flagNoExtractUi" />
+            android:imeOptions="actionNone|flagNoExtractUi" />
 
     <FrameLayout
             android:layout_width="wrap_content"
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index cf96457..71bd798 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -109,18 +109,18 @@
         if (mListening) {
             if (mPosition != position) {
                 // Clear out the last pages from listening.
-                mPages.get(mPosition).setListening(false);
+                setPageListening(mPosition, false);
                 if (mOffPage) {
-                    mPages.get(mPosition + 1).setListening(false);
+                    setPageListening(mPosition + 1, false);
                 }
                 // Set the new pages to listening
-                mPages.get(position).setListening(true);
+                setPageListening(position, true);
                 if (offPage) {
-                    mPages.get(position + 1).setListening(true);
+                    setPageListening(position + 1, true);
                 }
             } else if (mOffPage != offPage) {
                 // Whether we are showing position + 1 has changed.
-                mPages.get(mPosition + 1).setListening(offPage);
+                setPageListening(mPosition + 1, offPage);
             }
         }
         // Save the current state.
@@ -128,6 +128,11 @@
         mOffPage = offPage;
     }
 
+    private void setPageListening(int position, boolean listening) {
+        if (position >= mPages.size()) return;
+        mPages.get(position).setListening(listening);
+    }
+
     @Override
     public boolean hasOverlappingRendering() {
         return false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index 8d6e17e..d5fb8f2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -178,6 +178,7 @@
     private void updateQsState() {
         boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling || mHeaderAnimating;
         mQSPanel.setExpanded(mQsExpanded);
+        mQSDetail.setExpanded(mQsExpanded);
         mHeader.setVisibility((mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
                 ? View.VISIBLE
                 : View.INVISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 0cf7e479..a40e5b7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -31,6 +31,7 @@
 import android.widget.LinearLayout;
 import android.widget.Switch;
 import android.widget.TextView;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
@@ -64,6 +65,9 @@
     private boolean mFullyExpanded;
     private View mQsDetailHeaderBack;
     private BaseStatusBarHeader mHeader;
+    private boolean mTriggeredExpand;
+    private int mOpenX;
+    private int mOpenY;
 
     public QSDetail(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
@@ -112,6 +116,7 @@
     public void setQsPanel(QSPanel panel, BaseStatusBarHeader header) {
         mQsPanel = panel;
         mHeader = header;
+        mHeader.setCallback(mQsPanelCallback);
         mQsPanel.setCallback(mQsPanelCallback);
     }
 
@@ -126,6 +131,12 @@
         mFullyExpanded = fullyExpanded;
     }
 
+    public void setExpanded(boolean qsExpanded) {
+        if (!qsExpanded) {
+            mTriggeredExpand = false;
+        }
+    }
+
     private void updateDetailText() {
         mDetailDoneButton.setText(R.string.quick_settings_done);
         mDetailSettingsButton.setText(R.string.quick_settings_more_settings);
@@ -161,6 +172,22 @@
                     }
                 });
             }
+            if (!mFullyExpanded) {
+                mTriggeredExpand = true;
+                mHost.animateToggleQSExpansion();
+            } else {
+                mTriggeredExpand = false;
+            }
+            mOpenX = x;
+            mOpenY = y;
+        } else {
+            // Ensure we collapse into the same point we opened from.
+            x = mOpenX;
+            y = mOpenY;
+            if (mTriggeredExpand) {
+                mHost.animateToggleQSExpansion();
+                mTriggeredExpand = false;
+            }
         }
 
         boolean visibleDiff = (mDetailAdapter != null) != (adapter != null);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 6945176..2c874e5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -23,6 +23,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
@@ -56,7 +57,7 @@
 
     private int mPanelPaddingBottom;
     private int mBrightnessPaddingTop;
-    private boolean mExpanded;
+    protected boolean mExpanded;
     protected boolean mListening;
 
     private Callback mCallback;
@@ -70,7 +71,6 @@
 
     private QSCustomizer mCustomizePanel;
     private Record mDetailRecord;
-    private boolean mTriggeredExpand;
 
     public QSPanel(Context context) {
         this(context, null);
@@ -221,7 +221,6 @@
         }
         MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, mExpanded);
         if (!mExpanded) {
-            mTriggeredExpand = false;
             closeDetail();
         } else {
             logTiles();
@@ -279,6 +278,7 @@
     public void setTiles(Collection<QSTile<?>> tiles, boolean collapsedView) {
         for (TileRecord record : mRecords) {
             mTileLayout.removeTile(record);
+            record.tile.removeCallback(record.callback);
         }
         mRecords.clear();
         for (QSTile<?> tile : tiles) {
@@ -294,6 +294,10 @@
         return new QSTileView(mContext, tile.createTileView(mContext), collapsedView);
     }
 
+    protected boolean shouldShowDetail() {
+        return mExpanded;
+    }
+
     protected void addTile(final QSTile<?> tile, boolean collapsedView) {
         final TileRecord r = new TileRecord();
         r.tile = tile;
@@ -306,7 +310,11 @@
 
             @Override
             public void onShowDetail(boolean show) {
-                QSPanel.this.showDetail(show, r);
+                // Both the collapsed and full QS panels get this callback, this check determines
+                // which one should handle showing the detail.
+                if (shouldShowDetail()) {
+                    QSPanel.this.showDetail(show, r);
+                }
             }
 
             @Override
@@ -330,6 +338,7 @@
             }
         };
         r.tile.addCallback(callback);
+        r.callback = callback;
         final View.OnClickListener click = new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -390,17 +399,6 @@
     }
 
     protected void handleShowDetail(Record r, boolean show) {
-        if (show) {
-            if (!mExpanded) {
-                mTriggeredExpand = true;
-                mHost.animateToggleQSExpansion();
-            } else {
-                mTriggeredExpand = false;
-            }
-        } else if (mTriggeredExpand) {
-            mHost.animateToggleQSExpansion();
-            mTriggeredExpand = false;
-        }
         if (r instanceof TileRecord) {
             handleShowDetailTile((TileRecord) r, show);
         } else {
@@ -520,6 +518,7 @@
         public QSTile<?> tile;
         public QSTileBaseView tileView;
         public boolean scanState;
+        public QSTile.Callback callback;
     }
 
     public interface Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 8d9f23f..974de08 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -161,6 +161,10 @@
         mHandler.obtainMessage(H.ADD_CALLBACK, callback).sendToTarget();
     }
 
+    public void removeCallback(Callback callback) {
+        mHandler.obtainMessage(H.REMOVE_CALLBACK, callback).sendToTarget();
+    }
+
     public void removeCallbacks() {
         mHandler.sendEmptyMessage(H.REMOVE_CALLBACKS);
     }
@@ -224,6 +228,10 @@
         handleRefreshState(null);
     }
 
+    private void handleRemoveCallback(Callback callback) {
+        mCallbacks.remove(callback);
+    }
+
     private void handleRemoveCallbacks() {
         mCallbacks.clear();
     }
@@ -334,7 +342,8 @@
         private static final int DESTROY = 10;
         private static final int CLEAR_STATE = 11;
         private static final int REMOVE_CALLBACKS = 12;
-        private static final int SET_LISTENING = 13;
+        private static final int REMOVE_CALLBACK = 13;
+        private static final int SET_LISTENING = 14;
 
         private H(Looper looper) {
             super(looper);
@@ -350,6 +359,9 @@
                 } else if (msg.what == REMOVE_CALLBACKS) {
                     name = "handleRemoveCallbacks";
                     handleRemoveCallbacks();
+                } else if (msg.what == REMOVE_CALLBACK) {
+                    name = "handleRemoveCallback";
+                    handleRemoveCallback((QSTile.Callback) msg.obj);
                 } else if (msg.what == CLICK) {
                     name = "handleClick";
                     if (mState.disabledByPolicy) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index b28d0f2..c984abe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -77,6 +77,11 @@
     }
 
     @Override
+    protected boolean shouldShowDetail() {
+        return !mExpanded;
+    }
+
+    @Override
     protected void drawTile(TileRecord r, State state) {
         if (state instanceof SignalState) {
             State copy = r.tile.newTileState();
@@ -90,11 +95,6 @@
     }
 
     @Override
-    protected void showDetail(boolean show, Record r) {
-        // Do nothing, will be handled by the QSPanel.
-    }
-
-    @Override
     protected QSTileBaseView createTileView(QSTile<?> tile, boolean collapsedView) {
         return new QSTileBaseView(mContext, tile.createTileView(mContext), collapsedView);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 7b372ec..691e599 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -31,6 +31,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.RippleDrawable;
 import android.os.CountDownTimer;
 import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
@@ -460,6 +461,7 @@
         mDismissButton.setContentDescription(t.dismissDescription);
         mDismissButton.setOnClickListener(this);
         mDismissButton.setClickable(false);
+        ((RippleDrawable) mDismissButton.getBackground()).setForceSoftware(true);
 
         // When freeform workspaces are enabled, then update the move-task button depending on the
         // current task
@@ -477,6 +479,7 @@
             }
             mMoveTaskButton.setOnClickListener(this);
             mMoveTaskButton.setClickable(false);
+            ((RippleDrawable) mMoveTaskButton.getBackground()).setForceSoftware(true);
         }
 
         if (Recents.getDebugFlags().isFastToggleRecentsEnabled()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BaseStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BaseStatusBarHeader.java
index 6e1c862..79eef43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BaseStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BaseStatusBarHeader.java
@@ -20,6 +20,7 @@
 import android.util.AttributeSet;
 import android.widget.RelativeLayout;
 import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QSPanel.Callback;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl;
 import com.android.systemui.statusbar.policy.NextAlarmController;
@@ -44,4 +45,5 @@
     public abstract void setBatteryController(BatteryController batteryController);
     public abstract void setNextAlarmController(NextAlarmController nextAlarmController);
     public abstract void setUserInfoController(UserInfoController userInfoController);
+    public abstract void setCallback(Callback qsPanelCallback);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index 8360544a..e091d6dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -38,6 +38,7 @@
 import com.android.systemui.R;
 import com.android.systemui.qs.QSAnimator;
 import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QSPanel.Callback;
 import com.android.systemui.qs.QuickQSPanel;
 import com.android.systemui.qs.TouchAnimator;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -222,6 +223,7 @@
     @Override
     public void setExpanded(boolean expanded) {
         mExpanded = expanded;
+        mHeaderQsPanel.setExpanded(expanded);
         updateEverything();
     }
 
@@ -393,6 +395,11 @@
     }
 
     @Override
+    public void setCallback(Callback qsPanelCallback) {
+        mHeaderQsPanel.setCallback(qsPanelCallback);
+    }
+
+    @Override
     public void setEmergencyCallsOnly(boolean show) {
         boolean changed = show != mShowEmergencyCallsOnly;
         if (changed) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index a051973..72eafd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -44,6 +44,7 @@
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QSPanel.Callback;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.QSTile.DetailAdapter;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -511,6 +512,10 @@
     }
 
     @Override
+    public void setCallback(Callback qsPanelCallback) {
+    }
+
+    @Override
     public void onClick(View v) {
         if (v == mSettingsButton) {
             if (mSettingsButton.isTunerClick()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index d5f1707..7c391fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -873,7 +873,8 @@
             ExpandableNotificationRow row = (ExpandableNotificationRow) child;
             ExpandableNotificationRow parent = row.getNotificationParent();
             if (parent != null && parent.areChildrenExpanded()
-                    && (mGearExposedView == parent
+                    && (parent.areGutsExposed()
+                        || mGearExposedView == parent
                         || (parent.getNotificationChildren().size() == 1
                                 && parent.isClearable()))) {
                 // In this case the group is expanded and showing the gear for the
@@ -961,6 +962,7 @@
     public boolean canChildBeExpanded(View v) {
         return v instanceof ExpandableNotificationRow
                 && ((ExpandableNotificationRow) v).isExpandable()
+                && !((ExpandableNotificationRow) v).areGutsExposed()
                 && (mIsExpanded || !((ExpandableNotificationRow) v).isPinned());
     }
 
@@ -2097,7 +2099,9 @@
         final ExpandableView firstChild = getFirstChildNotGone();
         int firstChildMinHeight = firstChild != null
                 ? firstChild.getIntrinsicHeight()
-                : mCollapsedSize;
+                : mEmptyShadeView != null
+                        ? mEmptyShadeView.getMinHeight()
+                        : mCollapsedSize;
         if (mOwnScrollY > 0) {
             firstChildMinHeight = Math.max(firstChildMinHeight - mOwnScrollY, mCollapsedSize);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 5d26988..c8c7d3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -171,6 +171,12 @@
     }
 
     public static boolean canChildBeDismissed(View v) {
+        if (v instanceof ExpandableNotificationRow) {
+            ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+            if (row.areGutsExposed()) {
+                return false;
+            }
+        }
         final View veto = v.findViewById(R.id.veto);
         return (veto != null && veto.getVisibility() != View.GONE);
     }
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 3eadb5c..9154b8e 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -222,7 +222,7 @@
                             } catch (RemoteException e) {
                                 Slog.e(TAG,"Unable to call onBrEdrDown", e);
                             } finally {
-                                mBluetoothLock.readLock().lock();
+                                mBluetoothLock.readLock().unlock();
                             }
                         } else if (st == BluetoothAdapter.STATE_ON){
                             // disable without persisting the setting
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 32aeea8..2d6b5ef8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -267,6 +267,7 @@
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
 import static android.content.pm.PackageManager.GET_PROVIDERS;
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
@@ -7820,7 +7821,7 @@
         return ActivityManager.APP_START_MODE_NORMAL;
     }
 
-    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
+    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
         ProviderInfo pi = null;
         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
         if (cpr != null) {
@@ -7828,7 +7829,8 @@
         } else {
             try {
                 pi = AppGlobals.getPackageManager().resolveContentProvider(
-                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
+                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
+                        userHandle);
             } catch (RemoteException ex) {
             }
         }
@@ -7951,7 +7953,8 @@
         }
 
         final String authority = grantUri.uri.getAuthority();
-        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
+        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
+                MATCH_DEBUG_TRIAGED_MISSING);
         if (pi == null) {
             Slog.w(TAG, "No content provider found for permission check: " +
                     grantUri.uri.toSafeString());
@@ -8078,7 +8081,8 @@
                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
 
         final String authority = grantUri.uri.getAuthority();
-        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
+        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
+                MATCH_DEBUG_TRIAGED_MISSING);
         if (pi == null) {
             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
             return;
@@ -8293,7 +8297,8 @@
 
         final IPackageManager pm = AppGlobals.getPackageManager();
         final String authority = grantUri.uri.getAuthority();
-        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
+        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
+                MATCH_DEBUG_TRIAGED_MISSING);
         if (pi == null) {
             Slog.w(TAG, "No content provider found for permission revoke: "
                     + grantUri.toSafeString());
@@ -8390,7 +8395,8 @@
             }
 
             final String authority = uri.getAuthority();
-            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
+            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
+                    MATCH_DEBUG_TRIAGED_MISSING);
             if (pi == null) {
                 Slog.w(TAG, "No content provider found for permission revoke: "
                         + uri.toSafeString());
@@ -8624,8 +8630,11 @@
                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
 
                         // Sanity check that provider still belongs to source package
+                        // Both direct boot aware and unaware packages are fine as we
+                        // will do filtering at query time to avoid multiple parsing.
                         final ProviderInfo pi = getProviderInfoLocked(
-                                uri.getAuthority(), sourceUserId);
+                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
+                                        | MATCH_DIRECT_BOOT_UNAWARE);
                         if (pi != null && sourcePkg.equals(pi.packageName)) {
                             int targetUid = -1;
                             try {
@@ -8804,8 +8813,30 @@
                 if (perms == null) {
                     Slog.w(TAG, "No permission grants found for " + packageName);
                 } else {
+                    final int userId = UserHandle.getUserId(callingUid);
+                    Set<String> existingAuthorities = null;
+
                     for (UriPermission perm : perms.values()) {
                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
+                            // Is this provider available in the current boot state? If the user
+                            // is not running and unlocked we check if the provider package exists.
+                            if (!mUserController.isUserRunningLocked(userId,
+                                    ActivityManager.FLAG_AND_UNLOCKED)) {
+                                String authority = perm.uri.uri.getAuthority();
+                                if (existingAuthorities == null
+                                        || !existingAuthorities.contains(authority)) {
+                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
+                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
+                                    if (providerInfo != null) {
+                                        if (existingAuthorities == null) {
+                                            existingAuthorities = new ArraySet<>();
+                                        }
+                                        existingAuthorities.add(authority);
+                                    } else {
+                                        continue;
+                                    }
+                                }
+                            }
                             result.add(perm.buildPersistedPublicApiObject());
                         }
                     }
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 142426d..cc556c7 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -96,7 +96,7 @@
 
     private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
     private static final int MAX_FAILED_ATTEMPTS = 5;
-    private static final long CANCEL_TIMEOUT_LIMIT = 300; // max wait for onCancel() from HAL,in ms
+    private static final long CANCEL_TIMEOUT_LIMIT = 3000; // max wait for onCancel() from HAL,in ms
     private final String mKeyguardPackage;
     private int mCurrentUserId = UserHandle.USER_CURRENT;
     private final FingerprintUtils mFingerprintUtils = FingerprintUtils.getInstance();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 27ca62af..87141b4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7520,9 +7520,11 @@
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
         }
-        /* Only the shell or the app user should be able to dump profiles. */
+        /* Only the shell, root, or the app user should be able to dump profiles. */
         int callingUid = Binder.getCallingUid();
-        if (callingUid != Process.SHELL_UID && callingUid != pkg.applicationInfo.uid) {
+        if (callingUid != Process.SHELL_UID &&
+            callingUid != Process.ROOT_UID &&
+            callingUid != pkg.applicationInfo.uid) {
             throw new SecurityException("dumpProfiles");
         }
 
@@ -7530,16 +7532,7 @@
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
             final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
             try {
-                final File codeFile = new File(pkg.applicationInfo.getCodePath());
-                List<String> allCodePaths = Collections.EMPTY_LIST;
-                if (codeFile != null && codeFile.exists()) {
-                    try {
-                        final PackageLite codePkg = PackageParser.parsePackageLite(codeFile, 0);
-                        allCodePaths = codePkg.getAllCodePaths();
-                    } catch (PackageParserException e) {
-                        // Well, we tried.
-                    }
-                }
+                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
                 String gid = Integer.toString(sharedGid);
                 String codePaths = TextUtils.join(";", allCodePaths);
                 mInstaller.dumpProfiles(gid, packageName, codePaths);
@@ -8620,7 +8613,11 @@
             // We don't expect installation to fail beyond this point
 
             if (pkgSetting.pkg != null) {
-                maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg, user);
+                // Note that |user| might be null during the initial boot scan. If a codePath
+                // for an app has changed during a boot scan, it's due to an app update that's
+                // part of the system partition and marker changes must be applied to all users.
+                maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg,
+                    (user != null) ? user : UserHandle.ALL);
             }
 
             // Add the new setting to mSettings
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 3f4c1d5..a882607 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5346,7 +5346,13 @@
         // If this isn't coming from the system then don't allow disabling the lockscreen
         // to bypass security.
         if (Binder.getCallingUid() != Process.SYSTEM_UID && isKeyguardSecure()) {
-            Log.d(TAG_WM, "current mode is SecurityMode, ignore hide keyguard");
+            Log.d(TAG_WM, "current mode is SecurityMode, ignore disableKeyguard");
+            return;
+        }
+
+        // If this isn't coming from the current user, ignore it.
+        if (Binder.getCallingUserHandle().getIdentifier() != mCurrentUserId) {
+            Log.d(TAG_WM, "non-current user, ignore disableKeyguard");
             return;
         }
 
@@ -5661,6 +5667,11 @@
             mAppTransition.setCurrentUser(newUserId);
             mPolicy.setCurrentUserLw(newUserId);
 
+            // If keyguard was disabled, re-enable it
+            // TODO: Keep track of keyguardEnabled state per user and use here...
+            // e.g. enabled = mKeyguardDisableHandler.getEnabledStateForUser(newUserId);
+            mPolicy.enableKeyguard(true);
+
             // Hide windows that should not be seen by the new user.
             final int numDisplays = mDisplayContents.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
@@ -10022,6 +10033,7 @@
         }
     }
 
+    @Override
     public void createWallpaperInputConsumer(InputChannel inputChannel) {
         synchronized (mWindowMap) {
             mWallpaperInputConsumer = new InputConsumerImpl(this, "wallpaper input", inputChannel);
@@ -10030,6 +10042,7 @@
         }
     }
 
+    @Override
     public void removeWallpaperInputConsumer() {
         synchronized (mWindowMap) {
             if (mWallpaperInputConsumer != null) {
@@ -11125,6 +11138,7 @@
         }
     }
 
+    @Override
     public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
             throws RemoteException {
         if (!checkCallingPermission(Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS,
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3b4c3cf..881fc10 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -230,6 +230,14 @@
 
     boolean mForceScaleUntilResize;
 
+    // WindowState.mHScale and WindowState.mVScale contain the
+    // scale according to client specified layout parameters (e.g.
+    // one layout size, with another surface size, creates such scaling).
+    // Here we track an additional scaling factor used to follow stack
+    // scaling (as in the case of the Pinned stack animation).
+    float mExtraHScale = (float) 1.0;
+    float mExtraVScale = (float) 1.0;
+
     private final Rect mTmpSize = new Rect();
 
     WindowStateAnimator(final WindowState win) {
@@ -1306,7 +1314,6 @@
     }
 
     private int resolveStackClip() {
-
         // App animation overrides window animation stack clip mode.
         if (mAppAnimator != null && mAppAnimator.animation != null) {
             return mAppAnimator.getStackClip();
@@ -1397,8 +1404,8 @@
         mTmpSize.set(w.mShownPosition.x, w.mShownPosition.y, 0, 0);
         calculateSurfaceBounds(w, w.getAttrs());
 
-        float extraHScale = (float) 1.0;
-        float extraVScale = (float) 1.0;
+        mExtraHScale = (float) 1.0;
+        mExtraVScale = (float) 1.0;
 
         // Once relayout has been called at least once, we need to make sure
         // we only resize the client surface during calls to relayout. For
@@ -1412,6 +1419,9 @@
         // aren't observing known issues here outside of PiP resizing. (Typically
         // the other windows that use -1 are PopupWindows which aren't likely
         // to be rendering while we resize).
+
+        boolean wasForceScaled = mForceScaleUntilResize;
+
         if (!w.inPinnedWorkspace() || (!w.mRelayoutCalled || w.mInRelayout)) {
             mSurfaceResized = mSurfaceController.setSizeInTransaction(
                     mTmpSize.width(), mTmpSize.height(), recoveringMemory);
@@ -1420,34 +1430,39 @@
         }
         mForceScaleUntilResize = mForceScaleUntilResize && !mSurfaceResized;
 
-
         calculateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect);
+
+        float surfaceWidth = mSurfaceController.getWidth();
+        float surfaceHeight = mSurfaceController.getHeight();
+
         if ((task != null && task.mStack.getForceScaleToCrop()) || mForceScaleUntilResize) {
             int hInsets = w.getAttrs().surfaceInsets.left + w.getAttrs().surfaceInsets.right;
             int vInsets = w.getAttrs().surfaceInsets.top + w.getAttrs().surfaceInsets.bottom;
-            float surfaceWidth = mSurfaceController.getWidth();
-            float surfaceHeight = mSurfaceController.getHeight();
+            if (!mForceScaleUntilResize) {
+                mSurfaceController.forceScaleableInTransaction(true);
+            }
             // We want to calculate the scaling based on the content area, not based on
             // the entire surface, so that we scale in sync with windows that don't have insets.
-            extraHScale = (mTmpClipRect.width() - hInsets) / (float)(surfaceWidth - hInsets);
-            extraVScale = (mTmpClipRect.height() - vInsets) / (float)(surfaceHeight - vInsets);
+            mExtraHScale = (mTmpClipRect.width() - hInsets) / (float)(surfaceWidth - hInsets);
+            mExtraVScale = (mTmpClipRect.height() - vInsets) / (float)(surfaceHeight - vInsets);
 
             // In the case of ForceScaleToCrop we scale entire tasks together,
             // and so we need to scale our offsets relative to the task bounds
             // or parent and child windows would fall out of alignment.
-            int posX = (int) (mTmpSize.left - w.mAttrs.x * (1 - extraHScale));
-            int posY = (int) (mTmpSize.top - w.mAttrs.y * (1 - extraVScale));
+            int posX = (int) (mTmpSize.left - w.mAttrs.x * (1 - mExtraHScale));
+            int posY = (int) (mTmpSize.top - w.mAttrs.y * (1 - mExtraVScale));
             // Imagine we are scaling down. As we scale the buffer down, we decrease the
             // distance between the surface top left, and the start of the surface contents
             // (previously it was surfaceInsets.left pixels in screen space but now it
-            // will be surfaceInsets.left*extraHScale). This means in order to keep the
+            // will be surfaceInsets.left*mExtraHScale). This means in order to keep the
             // non inset content at the same position, we have to shift the whole window
             // forward. Likewise for scaling up, we've increased this distance, and we need
             // to shift by a negative number to compensate.
-            posX += w.getAttrs().surfaceInsets.left * (1 - extraHScale);
-            posY += w.getAttrs().surfaceInsets.top * (1 - extraVScale);
+            posX += w.getAttrs().surfaceInsets.left * (1 - mExtraHScale);
+            posY += w.getAttrs().surfaceInsets.top * (1 - mExtraVScale);
 
-            mSurfaceController.setPositionInTransaction(posX, posY, recoveringMemory);
+            mSurfaceController.setPositionInTransaction((float)Math.floor(posX),
+                    (float)Math.floor(posY), recoveringMemory);
 
             // Since we are scaled to fit in our previously desired crop, we can now
             // expose the whole window in buffer space, and not risk extending
@@ -1459,7 +1474,7 @@
             // We need to ensure for each surface, that we disable transformation matrix
             // scaling in the same transaction which we resize the surface in.
             // As we are in SCALING_MODE_SCALE_TO_WINDOW, SurfaceFlinger will
-            // then take over the scaling until the new buffer arrives, and things 
+            // then take over the scaling until the new buffer arrives, and things
             // will be seamless.
             mForceScaleUntilResize = true;
         } else {
@@ -1467,12 +1482,28 @@
                     recoveringMemory);
         }
 
+        // If we are ending the scaling mode. We switch to SCALING_MODE_FREEZE
+        // to prevent further updates until buffer latch. Normally position
+        // would continue to apply immediately. But we need a different position
+        // before and after resize (since we have scaled the shadows, as discussed
+        // above).
+        if (wasForceScaled && !mForceScaleUntilResize) {
+            mSurfaceController.setPositionAppliesWithResizeInTransaction(true);
+            mSurfaceController.forceScaleableInTransaction(false);
+        }
+        if (w.inPinnedWorkspace()) {
+            mTmpClipRect.set(0, 0, -1, -1);
+            task.mStack.getDimBounds(mTmpFinalClipRect);
+            mTmpFinalClipRect.inset(-w.mAttrs.surfaceInsets.left, -w.mAttrs.surfaceInsets.top,
+                    -w.mAttrs.surfaceInsets.right, -w.mAttrs.surfaceInsets.bottom);
+        }
+
         updateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect, recoveringMemory);
 
-        mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * extraHScale,
-                mDtDx * w.mVScale * extraVScale,
-                mDsDy * w.mHScale * extraHScale,
-                mDtDy * w.mVScale * extraVScale, recoveringMemory);
+        mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * mExtraHScale,
+                mDtDx * w.mVScale * mExtraVScale,
+                mDsDy * w.mHScale * mExtraHScale,
+                mDtDy * w.mVScale * mExtraVScale, recoveringMemory);
 
         if (mSurfaceResized) {
             mReportSurfaceResized = true;
@@ -1558,8 +1589,10 @@
 
             boolean prepared =
                 mSurfaceController.prepareToShowInTransaction(mShownAlpha, mAnimLayer,
-                        mDsDx * w.mHScale, mDtDx * w.mVScale,
-                        mDsDy * w.mHScale, mDtDy * w.mVScale,
+                        mDsDx * w.mHScale * mExtraHScale,
+                        mDtDx * w.mVScale * mExtraVScale,
+                        mDsDy * w.mHScale * mExtraHScale,
+                        mDtDy * w.mVScale * mExtraVScale,
                         recoveringMemory);
 
             if (prepared && mLastHidden && mDrawState == HAS_DRAWN) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 9646a49..c30da14 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -176,7 +176,7 @@
         if (SHOW_TRANSACTIONS) logSurface(
                 "CROP " + clipRect.toShortString(), null);
         try {
-            if (clipRect.width() > 0 && clipRect.height() > 0) {
+            if (clipRect.width() != 0 && clipRect.height() != 0) {
                 mSurfaceControl.setWindowCrop(clipRect);
                 mHiddenForCrop = false;
                 updateVisibility();
@@ -236,6 +236,10 @@
         }
     }
 
+    void setPositionAppliesWithResizeInTransaction(boolean recoveringMemory) {
+        mSurfaceControl.setPositionAppliesWithResize();
+    }
+
     void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy,
             boolean recoveringMemory) {
         try {
@@ -554,6 +558,13 @@
         }
 
         @Override
+        public void setPositionAppliesWithResize() {
+            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPositionAppliesWithResize(): OLD: "
+                    + this + ". Called by" + Debug.getCallers(9));
+            super.setPositionAppliesWithResize();
+        }
+
+        @Override
         public void setSize(int w, int h) {
             if (w != mSize.x || h != mSize.y) {
                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"