Merge "Fix a crash happening on a context menu."
diff --git a/core/java/android/service/quicksettings/IQSService.aidl b/core/java/android/service/quicksettings/IQSService.aidl
index bf96357..d03ff93 100644
--- a/core/java/android/service/quicksettings/IQSService.aidl
+++ b/core/java/android/service/quicksettings/IQSService.aidl
@@ -23,16 +23,16 @@
  * @hide
  */
 interface IQSService {
-    Tile getTile(in ComponentName component);
-    void updateQsTile(in Tile tile);
-    void updateStatusIcon(in Tile tile, in Icon icon,
+    Tile getTile(in IBinder tile);
+    void updateQsTile(in Tile tile, in IBinder service);
+    void updateStatusIcon(in IBinder tile, in Icon icon,
             String contentDescription);
-    void onShowDialog(in Tile tile);
-    void onStartActivity(in Tile tile);
+    void onShowDialog(in IBinder tile);
+    void onStartActivity(in IBinder tile);
     boolean isLocked();
     boolean isSecure();
-    void startUnlockAndRun(in Tile tile);
+    void startUnlockAndRun(in IBinder tile);
 
-    void onDialogHidden(in Tile tile);
-    void onStartSuccessful(in Tile tile);
+    void onDialogHidden(in IBinder tile);
+    void onStartSuccessful(in IBinder tile);
 }
diff --git a/core/java/android/service/quicksettings/Tile.java b/core/java/android/service/quicksettings/Tile.java
index 3d7d53e..4b81a72 100644
--- a/core/java/android/service/quicksettings/Tile.java
+++ b/core/java/android/service/quicksettings/Tile.java
@@ -15,8 +15,8 @@
  */
 package android.service.quicksettings;
 
-import android.content.ComponentName;
 import android.graphics.drawable.Icon;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -59,7 +59,7 @@
      */
     public static final int STATE_ACTIVE = 2;
 
-    private ComponentName mComponentName;
+    private IBinder mToken;
     private Icon mIcon;
     private CharSequence mLabel;
     private CharSequence mContentDescription;
@@ -78,29 +78,15 @@
     /**
      * @hide
      */
-    public Tile(ComponentName componentName) {
-        mComponentName = componentName;
+    public Tile() {
     }
 
     /**
      * @hide
      */
-    public void setService(IQSService service) {
+    public void setService(IQSService service, IBinder stub) {
         mService = service;
-    }
-
-    /**
-     * @hide
-     */
-    public ComponentName getComponentName() {
-        return mComponentName;
-    }
-
-    /**
-     * @hide
-     */
-    public IQSService getQsService() {
-        return mService;
+        mToken = stub;
     }
 
     /**
@@ -193,7 +179,7 @@
      */
     public void updateTile() {
         try {
-            mService.updateQsTile(this);
+            mService.updateQsTile(this, mToken);
         } catch (RemoteException e) {
             Log.e(TAG, "Couldn't update tile");
         }
@@ -201,12 +187,6 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        if (mComponentName != null) {
-            dest.writeByte((byte) 1);
-            mComponentName.writeToParcel(dest, flags);
-        } else {
-            dest.writeByte((byte) 0);
-        }
         if (mIcon != null) {
             dest.writeByte((byte) 1);
             mIcon.writeToParcel(dest, flags);
@@ -220,11 +200,6 @@
 
     private void readFromParcel(Parcel source) {
         if (source.readByte() != 0) {
-            mComponentName = ComponentName.CREATOR.createFromParcel(source);
-        } else {
-            mComponentName = null;
-        }
-        if (source.readByte() != 0) {
             mIcon = Icon.CREATOR.createFromParcel(source);
         } else {
             mIcon = null;
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 50411ab..887f4b6 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -123,6 +123,11 @@
     /**
      * @hide
      */
+    public static final String EXTRA_TOKEN = "token";
+
+    /**
+     * @hide
+     */
     public static final String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
 
     private final H mHandler = new H(Looper.getMainLooper());
@@ -132,6 +137,7 @@
     private IBinder mToken;
     private IQSService mService;
     private Runnable mUnlockRunnable;
+    private IBinder mTileToken;
 
     @Override
     public void onDestroy() {
@@ -197,7 +203,7 @@
     public final void setStatusIcon(Icon icon, String contentDescription) {
         if (mService != null) {
             try {
-                mService.updateStatusIcon(mTile, icon, contentDescription);
+                mService.updateStatusIcon(mTileToken, icon, contentDescription);
             } catch (RemoteException e) {
             }
         }
@@ -224,14 +230,14 @@
             @Override
             public void onViewDetachedFromWindow(View v) {
                 try {
-                    mService.onDialogHidden(getQsTile());
+                    mService.onDialogHidden(mTileToken);
                 } catch (RemoteException e) {
                 }
             }
         });
         dialog.show();
         try {
-            mService.onShowDialog(mTile);
+            mService.onShowDialog(mTileToken);
         } catch (RemoteException e) {
         }
     }
@@ -246,7 +252,7 @@
     public final void unlockAndRun(Runnable runnable) {
         mUnlockRunnable = runnable;
         try {
-            mService.startUnlockAndRun(mTile);
+            mService.startUnlockAndRun(mTileToken);
         } catch (RemoteException e) {
         }
     }
@@ -292,7 +298,7 @@
     public final void startActivityAndCollapse(Intent intent) {
         startActivity(intent);
         try {
-            mService.onStartActivity(mTile);
+            mService.onStartActivity(mTileToken);
         } catch (RemoteException e) {
         }
     }
@@ -311,14 +317,14 @@
     @Override
     public IBinder onBind(Intent intent) {
         mService = IQSService.Stub.asInterface(intent.getIBinderExtra(EXTRA_SERVICE));
+        mTileToken = intent.getIBinderExtra(EXTRA_TOKEN);
         try {
-            ComponentName component = intent.getParcelableExtra(EXTRA_COMPONENT);
-            mTile = mService.getTile(component);
+            mTile = mService.getTile(mTileToken);
         } catch (RemoteException e) {
             throw new RuntimeException("Unable to reach IQSService", e);
         }
         if (mTile != null) {
-            mTile.setService(mService);
+            mTile.setService(mService, mTileToken);
             mHandler.sendEmptyMessage(H.MSG_START_SUCCESS);
         }
         return new IQSTileService.Stub() {
@@ -403,7 +409,7 @@
                     break;
                 case MSG_START_SUCCESS:
                     try {
-                        mService.onStartSuccessful(mTile);
+                        mService.onStartSuccessful(mTileToken);
                     } catch (RemoteException e) {
                     }
                     break;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e700570..495b032 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5502,6 +5502,15 @@
         if (mView != null && mAdded) {
             final int what = event.mAction;
 
+            // Cache the drag description when the operation starts, then fill it in
+            // on subsequent calls as a convenience
+            if (what == DragEvent.ACTION_DRAG_STARTED) {
+                mCurrentDragView = null;    // Start the current-recipient tracking
+                mDragDescription = event.mClipDescription;
+            } else {
+                event.mClipDescription = mDragDescription;
+            }
+
             if (what == DragEvent.ACTION_DRAG_EXITED) {
                 // A direct EXITED event means that the window manager knows we've just crossed
                 // a window boundary, so the current drag target within this one must have
@@ -5509,15 +5518,6 @@
                 // for now.
                 mView.dispatchDragEvent(event);
             } else {
-                // Cache the drag description when the operation starts, then fill it in
-                // on subsequent calls as a convenience
-                if (what == DragEvent.ACTION_DRAG_STARTED) {
-                    mCurrentDragView = null;    // Start the current-recipient tracking
-                    mDragDescription = event.mClipDescription;
-                } else {
-                    event.mClipDescription = mDragDescription;
-                }
-
                 // For events with a [screen] location, translate into window coordinates
                 if ((what == DragEvent.ACTION_DRAG_LOCATION) || (what == DragEvent.ACTION_DROP)) {
                     mDragPoint.set(event.mX, event.mY);
diff --git a/core/tests/coretests/src/android/app/ApplicationErrorReportTest.java b/core/tests/coretests/src/android/app/ApplicationErrorReportTest.java
new file mode 100644
index 0000000..19a390a
--- /dev/null
+++ b/core/tests/coretests/src/android/app/ApplicationErrorReportTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.app.ApplicationErrorReport.CrashInfo;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ApplicationErrorReportTest {
+
+    @Test
+    public void testHugeStacktraceLeadsToReasonableReport() {
+        Throwable deepStackTrace = deepStackTrace();
+        CrashInfo crashInfo = new CrashInfo(deepStackTrace);
+
+        assertTrue("stack trace is longer than 50'000 characters",
+                crashInfo.stackTrace.length() < 50000);
+    }
+
+    @Test
+    public void testHugeExceptionMessageLeadsToReasonableReport() {
+        StringBuilder msg = new StringBuilder();
+        for (int i = 0; i < 1000000; i++) {
+            msg.append('x');
+        }
+
+        CrashInfo crashInfo = new CrashInfo(new Throwable(msg.toString()));
+
+        assertTrue("message is longer than 50'000 characters",
+                crashInfo.exceptionMessage.length() < 50000);
+    }
+
+    @Test
+    public void testTruncationKeepsStartAndEndIntact() {
+        StringBuilder msg = new StringBuilder("start");
+        for (int i = 0; i < 1000000; i++) {
+            msg.append('x');
+        }
+        msg.append("end");
+
+        CrashInfo crashInfo = new CrashInfo(new Throwable(msg.toString()));
+
+        String exceptionMessage = crashInfo.exceptionMessage;
+        assertEquals("start", exceptionMessage.substring(0, "start".length()));
+        assertEquals("end", exceptionMessage.substring(exceptionMessage.length() - "end".length()));
+    }
+
+    /**
+     * @return a Throwable with a very long stack trace.
+     */
+    private Throwable deepStackTrace() {
+        return stackTraceGenerator__aaaaaaaaa_aaaaaaaaa_aaaaaaaaa_aaaaaaaaa_aaaaaaaaa(1000);
+    }
+
+    private Throwable stackTraceGenerator__aaaaaaaaa_aaaaaaaaa_aaaaaaaaa_aaaaaaaaa_aaaaaaaaa(
+            int d) {
+        if (d > 0) {
+            return stackTraceGenerator__aaaaaaaaa_aaaaaaaaa_aaaaaaaaa_aaaaaaaaa_aaaaaaaaa(d - 1);
+        } else {
+            return new Throwable("here");
+        }
+    }
+}
diff --git a/docs/html/preview/api-overview.jd b/docs/html/preview/api-overview.jd
index 3373fc4..90b4e39 100644
--- a/docs/html/preview/api-overview.jd
+++ b/docs/html/preview/api-overview.jd
@@ -755,6 +755,20 @@
   on the device.
 </p>
 
+<p class="note">
+  <strong>Note: </strong>Only a small number of devices running Android N
+  support hardware-level key attestation; all other devices running Android N
+  use software-level key attestation instead. Before you verify the properties
+  of a device's hardware-backed keys in a production-level environment, you
+  should make sure that the device supports hardware-level key attestation. To
+  do so, you should check that the attestation certificate chain contains a root
+  certificate that is signed by the Google attestation root key and that the
+  <code>attestationSecurityLevel</code> element within the <a
+  href="{@docRoot}preview/features/key-attestation.html#certificate_schema_keydescription">key
+  description</a> data structure is set to the TrustedEnvironment security
+  level.
+</p>
+
 <p>
   For more information, see the
   <a href="{@docRoot}preview/features/key-attestation.html">Key Attestation</a>
diff --git a/docs/html/preview/features/key-attestation.jd b/docs/html/preview/features/key-attestation.jd
index 98b8340..5be6dfa 100644
--- a/docs/html/preview/features/key-attestation.jd
+++ b/docs/html/preview/features/key-attestation.jd
@@ -21,6 +21,19 @@
   interpret the schema of the attestation certificate's extension data.
 </p>
 
+<p class="note">
+  <strong>Note: </strong>Only a small number of devices running Android N
+  support hardware-level key attestation; all other devices running Android N
+  use software-level key attestation instead. Before you verify the properties
+  of a device's hardware-backed keys in a production-level environment, you
+  should make sure that the device supports hardware-level key attestation. To
+  do so, you should check that the attestation certificate chain contains a root
+  certificate that is signed by the Google attestation root key and that the
+  <code>attestationSecurityLevel</code> element within the <a
+  href="#certificate_schema_keydescription">key description</a> data structure
+  is set to the TrustedEnvironment security level.
+</p>
+
 <h2 id="verifying">
   Retrieving and Verifying a Hardware-backed Key Pair
 </h2>
@@ -227,8 +240,8 @@
       level</a> of the attestation.
     </p>
 
-    <p class="note">
-      <strong>Note:</strong> Although it is possible to attest keys that are
+    <p class="caution">
+      <strong>Warning:</strong> Although it is possible to attest keys that are
       stored in the Android system&mdash;that is, if the
       <code>attestationSecurity</code> value is set to Software&mdash;you
       cannot trust these attestations if the Android system becomes compromised.
diff --git a/docs/html/wear/preview/_book.yaml b/docs/html/wear/preview/_book.yaml
index 3bea2fd..a231fb5 100644
--- a/docs/html/wear/preview/_book.yaml
+++ b/docs/html/wear/preview/_book.yaml
@@ -30,5 +30,8 @@
 - title: License Agreement
   path: /wear/preview/license.html
 
+- title: Behavior Changes
+  path: /wear/preview/behavior-changes.html
+
 - title: Support and Release Notes
   path: /wear/preview/support.html
diff --git a/docs/html/wear/preview/behavior-changes.jd b/docs/html/wear/preview/behavior-changes.jd
new file mode 100644
index 0000000..0214622
--- /dev/null
+++ b/docs/html/wear/preview/behavior-changes.jd
@@ -0,0 +1,63 @@
+page.title=Behavior Changes
+meta.keywords="preview", "wear"
+page.tags="preview", "developer preview"
+
+@jd:body
+
+<p>
+  Along with new features, Android Wear 2.0 includes a variety of behavior
+  changes. This document highlights some of the key changes to
+  account for in your apps.
+</p>
+
+<p>
+  If you have previously published an app for Android Wear, be aware that
+  your app might be affected by these changes in the platform.
+</p>
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+
+<ul>
+  <li><a href="#activity-dismissal">Activity Dismissal</a></li>
+</ul>
+
+</div>
+</div>
+
+<h2 id="activity-dismissal">Activity Dismissal</h2>
+
+<p>
+  Starting in <a href="{@docRoot}wear/preview/index.html">Android Wear 2.0</a>,
+  users dismiss apps and activities by using
+  the power (stem) button on the watch.
+  Long-pressing to dismiss an app is no longer suggested.
+  Additionally, developers should not implement the
+  long-press for dismissing
+  <a href="{@docRoot}training/wearables/ui/exit.html">full screen</a>
+  activities (panning or immersive activities such as Google Maps).
+</p>
+
+<p>
+  In Android Wear 2.0, the power button of the watch is used
+  to navigate back in the
+  <a href="{@docRoot}guide/components/tasks-and-back-stack.html">back stack</a>,
+  including for full-screen panning activities.
+  Before Android Wear 2.0, the <code>DismissOverlayView</code> class was
+  used to implement the long-press for a user to dismiss an app.
+  (The <code>DismissOverlayView</code> class was added to a layout
+  for full-screen drawing and to draw over the other views.)
+  Developers should test the power button for going back
+  between an app's activities and for exiting an app.
+</p>
+
+<p>
+  Additionally, swipe for exiting an app or activity is not available.
+  Developers can consider how their user interfaces
+  can be enhanced with swipe-left and swipe-right,
+  in a way similar to the functionality described for
+  <a href="{@docRoot}wear/preview/features/ui-nav-actions.html">navigation
+  drawers</a>.
+</p>
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 9481c46..f413184 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -25,6 +25,7 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.net.Uri;
+import android.os.Build;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Process;
@@ -192,7 +193,8 @@
      * </ul>
      *
      * @deprecated Use {@link #ACTION_KEYCHAIN_CHANGED}, {@link #ACTION_STORAGE_CHANGED} or
-     * {@link #ACTION_KEY_ACCESS_CHANGED}.
+     * {@link #ACTION_KEY_ACCESS_CHANGED}. Apps that target a version higher than
+     * {@link Build.VERSION_CODES#N_MR1} will not receive this broadcast.
      */
     public static final String ACTION_STORAGE_CHANGED = "android.security.STORAGE_CHANGED";
 
diff --git a/packages/DocumentsUI/res/values-ldrtl/config.xml b/packages/DocumentsUI/res/values-ldrtl/config.xml
deleted file mode 100644
index 22f8131..0000000
--- a/packages/DocumentsUI/res/values-ldrtl/config.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <bool name="list_divider_inset_left">false</bool>
-</resources>
diff --git a/packages/DocumentsUI/res/values/config.xml b/packages/DocumentsUI/res/values/config.xml
index f0cab08..f883164 100644
--- a/packages/DocumentsUI/res/values/config.xml
+++ b/packages/DocumentsUI/res/values/config.xml
@@ -21,9 +21,6 @@
     <!-- Intentionally unset. Vendors should set this in an overlay. -->
     <string name="trusted_quick_viewer_package" translatable="false"></string>
 
-    <!-- overridden for RTL langs -->
-    <bool name="list_divider_inset_left">true</bool>
-
     <!-- Flags setup as productivity oriented in which case Downloads app will be presented
              as Files app. Including showing of the Documents and "advanced" roots. -->
     <bool name="productivity_device">false</bool>
diff --git a/packages/Keyguard/Android.mk b/packages/Keyguard/Android.mk
index 9083212..f9e2686 100644
--- a/packages/Keyguard/Android.mk
+++ b/packages/Keyguard/Android.mk
@@ -16,6 +16,8 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_USE_AAPT2 := true
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files)
 
 LOCAL_MODULE := Keyguard
@@ -30,6 +32,8 @@
 
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
+LOCAL_JAR_EXCLUDE_FILES := none
+
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 #include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/Keyguard/test/Android.mk b/packages/Keyguard/test/Android.mk
index 15059c6..54224b7 100644
--- a/packages/Keyguard/test/Android.mk
+++ b/packages/Keyguard/test/Android.mk
@@ -16,6 +16,8 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_USE_AAPT2 := true
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := KeyguardTest
diff --git a/packages/Keyguard/test/SampleTrustAgent/Android.mk b/packages/Keyguard/test/SampleTrustAgent/Android.mk
index 2a18ee1..6ffb018 100644
--- a/packages/Keyguard/test/SampleTrustAgent/Android.mk
+++ b/packages/Keyguard/test/SampleTrustAgent/Android.mk
@@ -16,6 +16,8 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_USE_AAPT2 := true
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := SampleTrustAgent
@@ -27,6 +29,6 @@
 
 # LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+LOCAL_STATIC_ANDROID_LIBRARIES := android-support-v4
 
 include $(BUILD_PACKAGE)
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 548ddf8..e049079 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -169,7 +169,7 @@
      * Determine whether a package is a "system package", in which case certain things (like
      * disabling notifications or disabling the package altogether) should be disallowed.
      */
-    public static boolean isSystemPackage(PackageManager pm, PackageInfo pkg) {
+    public static boolean isSystemPackage(Resources resources, PackageManager pm, PackageInfo pkg) {
         if (sSystemSignature == null) {
             sSystemSignature = new Signature[]{ getSystemSignature(pm) };
         }
@@ -187,7 +187,8 @@
                 || pkg.packageName.equals(sPermissionControllerPackageName)
                 || pkg.packageName.equals(sServicesSystemSharedLibPackageName)
                 || pkg.packageName.equals(sSharedSystemSharedLibPackageName)
-                || pkg.packageName.equals(PrintManager.PRINT_SPOOLER_PACKAGE_NAME);
+                || pkg.packageName.equals(PrintManager.PRINT_SPOOLER_PACKAGE_NAME)
+                || isDeviceProvisioningPackage(resources, pkg.packageName);
     }
 
     private static Signature getFirstSignature(PackageInfo pkg) {
@@ -205,4 +206,14 @@
         }
         return null;
     }
+
+    /**
+     * Returns {@code true} if the supplied package is the device provisioning app. Otherwise,
+     * returns {@code false}.
+     */
+    public static boolean isDeviceProvisioningPackage(Resources resources, String packageName) {
+        String deviceProvisioningPackage = resources.getString(
+                com.android.internal.R.string.config_deviceProvisioningPackage);
+        return deviceProvisioningPackage != null && deviceProvisioningPackage.equals(packageName);
+    }
 }
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 6d8b9f6..258c82e 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -16,17 +16,21 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_USE_AAPT2 := true
+
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-Iaidl-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := \
+LOCAL_STATIC_ANDROID_LIBRARIES := \
     Keyguard \
     android-support-v7-recyclerview \
     android-support-v7-preference \
     android-support-v7-appcompat \
     android-support-v14-preference \
-    android-support-v17-leanback \
+    android-support-v17-leanback
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
     framework-protos \
     SystemUI-proto-tags
 
@@ -39,19 +43,6 @@
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
-LOCAL_RESOURCE_DIR := \
-    frameworks/base/packages/Keyguard/res \
-    $(LOCAL_PATH)/res \
-    frameworks/support/v7/preference/res \
-    frameworks/support/v14/preference/res \
-    frameworks/support/v7/appcompat/res \
-    frameworks/support/v7/recyclerview/res \
-    frameworks/support/v17/leanback/res
-
-LOCAL_AAPT_FLAGS := --auto-add-overlay \
-    --extra-packages com.android.keyguard:android.support.v7.recyclerview:android.support.v7.preference:android.support.v14.preference:android.support.v7.appcompat \
-    --extra-packages android.support.v17.leanback
-
 ifneq ($(SYSTEM_UI_INCREMENTAL_BUILDS),)
     LOCAL_PROGUARD_ENABLED := disabled
     LOCAL_JACK_ENABLED := incremental
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 46e6b9b..14944d5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -67,6 +67,8 @@
     private boolean mTriggeredExpand;
     private int mOpenX;
     private int mOpenY;
+    private boolean mAnimating;
+    private boolean mSwitchState;
 
     public QSDetail(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
@@ -212,6 +214,7 @@
 
     protected void animateDetailVisibleDiff(int x, int y, boolean visibleDiff, AnimatorListener listener) {
         if (visibleDiff) {
+            mAnimating = true;
             if (mFullyExpanded || mDetailAdapter != null) {
                 setAlpha(1);
                 mClipper.animateCircularClip(x, y, mDetailAdapter != null, listener);
@@ -243,7 +246,7 @@
             mQsDetailHeader.setClickable(false);
         } else {
             mQsDetailHeaderSwitch.setVisibility(VISIBLE);
-            mQsDetailHeaderSwitch.setChecked(toggleState);
+            handleToggleStateChanged(toggleState);
             mQsDetailHeader.setClickable(true);
             mQsDetailHeader.setOnClickListener(new OnClickListener() {
                 @Override
@@ -257,6 +260,10 @@
     }
 
     private void handleToggleStateChanged(boolean state) {
+        mSwitchState = state;
+        if (mAnimating) {
+            return;
+        }
         mQsDetailHeaderSwitch.setChecked(state);
     }
 
@@ -273,6 +280,10 @@
         }
     }
 
+    private void checkPendingAnimations() {
+        handleToggleStateChanged(mSwitchState);
+    }
+
     protected QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
         @Override
         public void onToggleStateChanged(final boolean state) {
@@ -310,6 +321,8 @@
             // If we have been cancelled, remove the listener so that onAnimationEnd doesn't get
             // called, this will avoid accidentally turning off the grid when we don't want to.
             animation.removeListener(this);
+            mAnimating = false;
+            checkPendingAnimations();
         };
 
         @Override
@@ -319,6 +332,8 @@
                 mQsPanel.setGridContentVisibility(false);
                 mHeader.setVisibility(View.INVISIBLE);
             }
+            mAnimating = false;
+            checkPendingAnimations();
         }
     };
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 569a567..b36221d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -71,7 +71,7 @@
         super(host);
         mWindowManager = WindowManagerGlobal.getWindowManagerService();
         mComponent = ComponentName.unflattenFromString(action);
-        mTile = new Tile(mComponent);
+        mTile = new Tile();
         setTileIcon();
         mServiceManager = host.getTileServices().getTileWrapper(this);
         mService = mServiceManager.getTileService();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
index 407453c..451e1f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
@@ -94,4 +94,8 @@
             return false;
         }
     }
+
+    public IQSTileService getService() {
+        return mService;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 79f9de6..681005c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -26,6 +26,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ServiceInfo;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -37,6 +38,7 @@
 import android.support.annotation.VisibleForTesting;
 import android.util.ArraySet;
 import android.util.Log;
+
 import libcore.util.Objects;
 
 import java.util.Set;
@@ -67,6 +69,7 @@
     private final Handler mHandler;
     private final Intent mIntent;
     private final UserHandle mUser;
+    private final IBinder mToken = new Binder();
 
     private Set<Integer> mQueuedMessages = new ArraySet<>();
     private QSTileServiceWrapper mWrapper;
@@ -88,7 +91,7 @@
         mHandler = handler;
         mIntent = intent;
         mIntent.putExtra(TileService.EXTRA_SERVICE, service.asBinder());
-        mIntent.putExtra(TileService.EXTRA_COMPONENT, intent.getComponent());
+        mIntent.putExtra(TileService.EXTRA_TOKEN, mToken);
         mUser = user;
         if (DEBUG) Log.d(TAG, "Creating " + mIntent + " " + mUser);
     }
@@ -396,6 +399,10 @@
         handleDeath();
     }
 
+    public IBinder getToken() {
+        return mToken;
+    }
+
     public interface TileChangeListener {
         void onTileChanged(ComponentName tile);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
index 3d030f9..f3e4d60 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -25,6 +25,7 @@
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.UserHandle;
 import android.service.quicksettings.IQSTileService;
 import android.service.quicksettings.Tile;
@@ -32,6 +33,7 @@
 import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 
+import com.android.systemui.qs.customize.TileQueryHelper.TileStateListener;
 import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener;
 
 import java.util.List;
@@ -106,6 +108,10 @@
         return mStateManager;
     }
 
+    public IBinder getToken() {
+        return mStateManager.getToken();
+    }
+
     public void setBindRequested(boolean bindRequested) {
         if (mBindRequested == bindRequested) return;
         mBindRequested = bindRequested;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 6f0bed2..575f198 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -25,10 +25,12 @@
 import android.graphics.drawable.Icon;
 import android.os.Binder;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.quicksettings.IQSService;
+import android.service.quicksettings.IQSTileService;
 import android.service.quicksettings.Tile;
 import android.service.quicksettings.TileService;
 import android.util.ArrayMap;
@@ -52,6 +54,7 @@
 
     private final ArrayMap<CustomTile, TileServiceManager> mServices = new ArrayMap<>();
     private final ArrayMap<ComponentName, CustomTile> mTiles = new ArrayMap<>();
+    private final ArrayMap<IBinder, CustomTile> mTokenMap = new ArrayMap<>();
     private final Context mContext;
     private final Handler mHandler;
     private final Handler mMainHandler;
@@ -82,6 +85,7 @@
         synchronized (mServices) {
             mServices.put(tile, service);
             mTiles.put(component, tile);
+            mTokenMap.put(service.getToken(), tile);
         }
         return service;
     }
@@ -95,6 +99,7 @@
             service.setBindAllowed(false);
             service.handleDestroy();
             mServices.remove(tile);
+            mTokenMap.remove(service.getToken());
             mTiles.remove(tile.getComponent());
             final String slot = tile.getComponent().getClassName();
             mMainHandler.post(new Runnable() {
@@ -138,8 +143,9 @@
         }
     }
 
-    private void verifyCaller(String packageName) {
+    private void verifyCaller(CustomTile tile) {
         try {
+            String packageName = tile.getComponent().getPackageName();
             int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
                     Binder.getCallingUserHandle().getIdentifier());
             if (Binder.getCallingUid() != uid) {
@@ -170,10 +176,9 @@
     }
 
     @Override
-    public void updateQsTile(Tile tile) {
-        ComponentName componentName = tile.getComponentName();
-        verifyCaller(componentName.getPackageName());
-        CustomTile customTile = getTileForComponent(componentName);
+    public void updateQsTile(Tile tile, IBinder token) {
+        CustomTile customTile = getTileForToken(token);
+        verifyCaller(customTile);
         if (customTile != null) {
             synchronized (mServices) {
                 final TileServiceManager tileServiceManager = mServices.get(customTile);
@@ -186,10 +191,9 @@
     }
 
     @Override
-    public void onStartSuccessful(Tile tile) {
-        ComponentName componentName = tile.getComponentName();
-        verifyCaller(componentName.getPackageName());
-        CustomTile customTile = getTileForComponent(componentName);
+    public void onStartSuccessful(IBinder token) {
+        CustomTile customTile = getTileForToken(token);
+        verifyCaller(customTile);
         if (customTile != null) {
             synchronized (mServices) {
                 final TileServiceManager tileServiceManager = mServices.get(customTile);
@@ -200,10 +204,9 @@
     }
 
     @Override
-    public void onShowDialog(Tile tile) {
-        ComponentName componentName = tile.getComponentName();
-        verifyCaller(componentName.getPackageName());
-        CustomTile customTile = getTileForComponent(componentName);
+    public void onShowDialog(IBinder token) {
+        CustomTile customTile = getTileForToken(token);
+        verifyCaller(customTile);
         if (customTile != null) {
             customTile.onDialogShown();
             mHost.collapsePanels();
@@ -212,10 +215,9 @@
     }
 
     @Override
-    public void onDialogHidden(Tile tile) {
-        ComponentName componentName = tile.getComponentName();
-        verifyCaller(componentName.getPackageName());
-        CustomTile customTile = getTileForComponent(componentName);
+    public void onDialogHidden(IBinder token) {
+        CustomTile customTile = getTileForToken(token);
+        verifyCaller(customTile);
         if (customTile != null) {
             mServices.get(customTile).setShowingDialog(false);
             customTile.onDialogHidden();
@@ -223,23 +225,22 @@
     }
 
     @Override
-    public void onStartActivity(Tile tile) {
-        ComponentName componentName = tile.getComponentName();
-        verifyCaller(componentName.getPackageName());
-        CustomTile customTile = getTileForComponent(componentName);
+    public void onStartActivity(IBinder token) {
+        CustomTile customTile = getTileForToken(token);
+        verifyCaller(customTile);
         if (customTile != null) {
             mHost.collapsePanels();
         }
     }
 
     @Override
-    public void updateStatusIcon(Tile tile, Icon icon, String contentDescription) {
-        final ComponentName componentName = tile.getComponentName();
-        String packageName = componentName.getPackageName();
-        verifyCaller(packageName);
-        CustomTile customTile = getTileForComponent(componentName);
+    public void updateStatusIcon(IBinder token, Icon icon, String contentDescription) {
+        CustomTile customTile = getTileForToken(token);
+        verifyCaller(customTile);
         if (customTile != null) {
             try {
+                ComponentName componentName = customTile.getComponent();
+                String packageName = componentName.getPackageName();
                 UserHandle userHandle = getCallingUserHandle();
                 PackageInfo info = mContext.getPackageManager().getPackageInfoAsUser(packageName, 0,
                         userHandle.getIdentifier());
@@ -263,9 +264,9 @@
     }
 
     @Override
-    public Tile getTile(ComponentName componentName) {
-        verifyCaller(componentName.getPackageName());
-        CustomTile customTile = getTileForComponent(componentName);
+    public Tile getTile(IBinder token) {
+        CustomTile customTile = getTileForToken(token);
+        verifyCaller(customTile);
         if (customTile != null) {
             return customTile.getQsTile();
         }
@@ -273,10 +274,9 @@
     }
 
     @Override
-    public void startUnlockAndRun(Tile tile) {
-        ComponentName componentName = tile.getComponentName();
-        verifyCaller(componentName.getPackageName());
-        CustomTile customTile = getTileForComponent(componentName);
+    public void startUnlockAndRun(IBinder token) {
+        CustomTile customTile = getTileForToken(token);
+        verifyCaller(customTile);
         if (customTile != null) {
             customTile.startUnlockAndRun();
         }
@@ -294,6 +294,12 @@
         return keyguardMonitor.isSecure() && keyguardMonitor.isShowing();
     }
 
+    private CustomTile getTileForToken(IBinder token) {
+        synchronized (mServices) {
+            return mTokenMap.get(token);
+        }
+    }
+
     private CustomTile getTileForComponent(ComponentName component) {
         synchronized (mServices) {
             return mTiles.get(component);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index f892a24..68f594b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -90,11 +90,11 @@
             mHost.startActivityDismissingKeyguard(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
             return;
         }
+        showDetail(true);
         if (!mState.value) {
             mState.value = true;
             mController.setBluetoothEnabled(true);
         }
-        showDetail(true);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 04cb553..91821ba 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -122,9 +122,9 @@
         if (mState.value) {
             mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
         } else {
+            showDetail(true);
             int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
             mController.setZen(zen, null, TAG);
-            showDetail(true);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 8910864..4c023d2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -116,11 +116,11 @@
             mHost.startActivityDismissingKeyguard(new Intent(Settings.ACTION_WIFI_SETTINGS));
             return;
         }
+        showDetail(true);
         if (!mState.value) {
             mController.setWifiEnabled(true);
             mState.value = true;
         }
-        showDetail(true);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index b66a4fb..c497cfd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -186,7 +186,7 @@
         try {
             final PackageInfo info =
                     pm.getPackageInfo(sbn.getPackageName(), PackageManager.GET_SIGNATURES);
-            systemApp = Utils.isSystemPackage(pm, info);
+            systemApp = Utils.isSystemPackage(getResources(), pm, info);
         } catch (PackageManager.NameNotFoundException e) {
             // unlikely.
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 15e235d..405ccd6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -400,7 +400,7 @@
                 ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
                 Intent intent = new Intent().setComponent(component);
                 TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
-                        mContext, mServices, new Tile(component), intent,
+                        mContext, mServices, new Tile(), intent,
                         new UserHandle(ActivityManager.getCurrentUser()));
                 lifecycleManager.onStopListening();
                 lifecycleManager.onTileRemoved();
@@ -414,7 +414,7 @@
                 ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
                 Intent intent = new Intent().setComponent(component);
                 TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
-                        mContext, mServices, new Tile(component), intent,
+                        mContext, mServices, new Tile(), intent,
                         new UserHandle(ActivityManager.getCurrentUser()));
                 lifecycleManager.onTileAdded();
                 lifecycleManager.flushMessagesAndUnbind();
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 6c39e35..2020abb 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -15,6 +15,7 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_USE_AAPT2 := true
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_JACK_FLAGS := --multi-dex native
@@ -23,37 +24,31 @@
 LOCAL_PROTOC_FLAGS := -I$(LOCAL_PATH)/..
 LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
 
-LOCAL_AAPT_FLAGS := --auto-add-overlay \
-    --extra-packages com.android.systemui:com.android.keyguard:android.support.v14.preference:android.support.v7.preference:android.support.v7.appcompat:android.support.v7.recyclerview \
-    --extra-packages android.support.v17.leanback
+LOCAL_PACKAGE_NAME := SystemUITests
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     $(call all-Iaidl-files-under, src) \
     $(call all-java-files-under, ../src)
 
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res \
-    frameworks/support/v7/preference/res \
-    frameworks/support/v14/preference/res \
-    frameworks/support/v7/appcompat/res \
-    frameworks/support/v7/recyclerview/res \
-    frameworks/support/v17/leanback/res \
     frameworks/base/packages/SystemUI/res \
-    frameworks/base/packages/Keyguard/res
 
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common android.car
-
-LOCAL_PACKAGE_NAME := SystemUITests
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    mockito-target \
+LOCAL_STATIC_ANDROID_LIBRARIES := \
     Keyguard \
     android-support-v7-recyclerview \
     android-support-v7-preference \
     android-support-v7-appcompat \
     android-support-v14-preference \
-    android-support-v17-leanback \
+    android-support-v17-leanback
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    mockito-target \
     SystemUI-proto-tags
 
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common android.car
+
+LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui
+
 # sign this with platform cert, so this test is allowed to inject key events into
 # UI it doesn't own. This is necessary to allow screenshots to be taken
 LOCAL_CERTIFICATE := platform
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
index c93377a..7703c58 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
@@ -58,7 +58,7 @@
         mHandler = new Handler(mThread.getLooper());
         ComponentName component = new ComponentName(mContext, FakeTileService.class);
         mStateManager = new TileLifecycleManager(mHandler, getContext(),
-                Mockito.mock(IQSService.class), new Tile(component),
+                Mockito.mock(IQSService.class), new Tile(),
                 new Intent().setComponent(component),
                 new UserHandle(UserHandle.myUserId()));
         mCallbacks.clear();
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index d10080b..497eac9 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -5501,11 +5501,11 @@
 
                         // If the policy is satisfied, go ahead and set up to pipe the
                         // data to the agent.
-                        if (DEBUG && okay && mAgent != null) {
+                        if (MORE_DEBUG && okay && mAgent != null) {
                             Slog.i(TAG, "Reusing existing agent instance");
                         }
                         if (okay && mAgent == null) {
-                            if (DEBUG) Slog.d(TAG, "Need to launch agent for " + pkg);
+                            if (MORE_DEBUG) Slog.d(TAG, "Need to launch agent for " + pkg);
 
                             try {
                                 mTargetApp = mPackageManager.getApplicationInfo(pkg, 0);
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 5fefd4c..7d20931 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -403,107 +403,6 @@
 
         publishLocalService(VrManagerInternal.class, new LocalService());
         publishBinderService(VR_MANAGER_BINDER_SERVICE, mVrManager.asBinder());
-
-        // If there are no VR packages installed on the device, then disable VR
-        // components, otherwise, enable them.
-        setEnabledStatusOfVrComponents();
-    }
-
-    private void setEnabledStatusOfVrComponents() {
-        ArraySet<ComponentName> vrComponents = SystemConfig.getInstance().getDefaultVrComponents();
-        if (vrComponents == null) {
-           return;
-        }
-
-        // We only want to enable VR components if there is a VR package installed on the device.
-        // The VR components themselves do not quality as a VR package, so exclude them.
-        ArraySet<String> vrComponentPackageNames = new ArraySet<>();
-        for (ComponentName componentName : vrComponents) {
-            vrComponentPackageNames.add(componentName.getPackageName());
-        }
-
-        // Check to see if there are any packages on the device, other than the VR component
-        // packages.
-        PackageManager pm = mContext.getPackageManager();
-        List<PackageInfo> packageInfos = pm.getInstalledPackages(
-                PackageManager.GET_CONFIGURATIONS);
-        boolean vrModeIsUsed = false;
-        for (PackageInfo packageInfo : packageInfos) {
-            if (packageInfo != null && packageInfo.packageName != null &&
-                    pm.getApplicationEnabledSetting(packageInfo.packageName) ==
-                            PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
-                vrModeIsUsed = enableVrComponentsIfVrModeUsed(pm, packageInfo,
-                        vrComponentPackageNames, vrComponents);
-                if (vrModeIsUsed) {
-                    break;
-                }
-            }
-        }
-
-        if (!vrModeIsUsed) {
-            Slog.i(TAG, "No VR packages found, disabling VR components");
-            setVrComponentsEnabledOrDisabled(vrComponents, false);
-
-            // Register to receive an intent when a new package is installed, in case that package
-            // requires VR components.
-            IntentFilter intentFilter = new IntentFilter();
-            intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
-            intentFilter.addDataScheme("package");
-            mContext.registerReceiver(new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    PackageManager pm = context.getPackageManager();
-                    final String packageName = intent.getData().getSchemeSpecificPart();
-                    if (packageName != null) {
-                        try {
-                            PackageInfo packageInfo = pm.getPackageInfo(packageName,
-                                    PackageManager.GET_CONFIGURATIONS);
-                            enableVrComponentsIfVrModeUsed(pm, packageInfo,
-                                    vrComponentPackageNames, vrComponents);
-                        } catch (NameNotFoundException e) {
-                        }
-                    }
-                };
-            }, intentFilter);
-        }
-    }
-
-    private void setVrComponentsEnabledOrDisabled(ArraySet<ComponentName> vrComponents,
-            boolean enabled) {
-        int state = enabled ?
-                PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
-        PackageManager pm = mContext.getPackageManager();
-        for (ComponentName componentName : vrComponents) {
-            try {
-                // Note that we must first check for the existance of the package before trying
-                // to set its enabled state.  This is to prevent PackageManager from throwing
-                // an excepton if the package is not found (not just a NameNotFoundException
-                // exception).
-                PackageInfo packageInfo = pm.getPackageInfo(componentName.getPackageName(),
-                        PackageManager.GET_CONFIGURATIONS);
-                pm.setApplicationEnabledSetting(componentName.getPackageName(), state , 0);
-            } catch (NameNotFoundException e) {
-            }
-        }
-    }
-
-    private boolean enableVrComponentsIfVrModeUsed(PackageManager pm, PackageInfo packageInfo,
-            ArraySet<String> vrComponentPackageNames, ArraySet<ComponentName> vrComponents) {
-        boolean isVrComponent = vrComponents != null &&
-                vrComponentPackageNames.contains(packageInfo.packageName);
-        if (packageInfo != null && packageInfo.reqFeatures != null && !isVrComponent) {
-            for (FeatureInfo featureInfo : packageInfo.reqFeatures) {
-                if (featureInfo.name != null &&
-                    (featureInfo.name.equals(PackageManager.FEATURE_VR_MODE) ||
-                     featureInfo.name.equals(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE))) {
-                    Slog.i(TAG, "VR package found, enabling VR components");
-                    setVrComponentsEnabledOrDisabled(vrComponents, true);
-                    return true;
-                }
-            }
-        }
-        return false;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index eed751f..409cf1b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2913,9 +2913,23 @@
                     }
                     result |= RELAYOUT_RES_SURFACE_CHANGED;
                 }
+                final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
+                if (viewVisibility == View.VISIBLE && surfaceController != null) {
+                    // We already told the client to go invisible, but the message may not be
+                    // handled yet, or it might want to draw a last frame. If we already have a
+                    // surface, let the client use that, but don't create new surface at this point.
+                    surfaceController.getSurface(outSurface);
+                } else {
+                    if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
 
-                outSurface.release();
-                if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
+                    try {
+                        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
+                                + win.mAttrs.getTitle());
+                        outSurface.release();
+                    } finally {
+                        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+                    }
+                }
             }
 
             if (focusMayChange) {
@@ -3050,6 +3064,7 @@
         } else {
             // For some reason there isn't a surface.  Clear the
             // caller's object so they see the same state.
+            Slog.w(TAG_WM, "Failed to create surface control for " + win);
             outSurface.release();
         }
         return result;