Merge "Fixes for ending PiP animation." into nyc-dev
diff --git a/api/system-current.txt b/api/system-current.txt
index 938755c..4ca3e56 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8883,7 +8883,6 @@
     field public static final java.lang.String ACTION_INPUT_METHOD_CHANGED = "android.intent.action.INPUT_METHOD_CHANGED";
     field public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT";
     field public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
-    field public static final java.lang.String ACTION_INSTALL_EPHEMERAL_PACKAGE = "android.intent.action.INSTALL_EPHEMERAL_PACKAGE";
     field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
     field public static final java.lang.String ACTION_INTENT_FILTER_NEEDS_VERIFICATION = "android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION";
     field public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
@@ -8941,7 +8940,6 @@
     field public static final java.lang.String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK";
     field public static final java.lang.String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
     field public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT";
-    field public static final java.lang.String ACTION_RESOLVE_EPHEMERAL_PACKAGE = "android.intent.action.RESOLVE_EPHEMERAL_PACKAGE";
     field public static final java.lang.String ACTION_REVIEW_PERMISSIONS = "android.intent.action.REVIEW_PERMISSIONS";
     field public static final java.lang.String ACTION_RUN = "android.intent.action.RUN";
     field public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
@@ -9037,8 +9035,6 @@
     field public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; // 0x0
     field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
     field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
-    field public static final java.lang.String EXTRA_EPHEMERAL_FAILURE = "android.intent.extra.EPHEMERAL_FAILURE";
-    field public static final java.lang.String EXTRA_EPHEMERAL_SUCCESS = "android.intent.extra.EPHEMERAL_SUCCESS";
     field public static final java.lang.String EXTRA_EXCLUDE_COMPONENTS = "android.intent.extra.EXCLUDE_COMPONENTS";
     field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
     field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 1381ddb..31fe390 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2378,6 +2378,8 @@
         public int displayId;
         public int userId;
         public boolean visible;
+        // Index of the stack in the display's stack list, can be used for comparison of stack order
+        public int position;
 
         @Override
         public int describeContents() {
@@ -2405,6 +2407,7 @@
             dest.writeInt(displayId);
             dest.writeInt(userId);
             dest.writeInt(visible ? 1 : 0);
+            dest.writeInt(position);
             if (topActivity != null) {
                 dest.writeInt(1);
                 topActivity.writeToParcel(dest, 0);
@@ -2434,6 +2437,7 @@
             displayId = source.readInt();
             userId = source.readInt();
             visible = source.readInt() > 0;
+            position = source.readInt();
             if (source.readInt() > 0) {
                 topActivity = ComponentName.readFromParcel(source);
             }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 47abd2b..9118f01 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1481,7 +1481,6 @@
      *
      * @hide
      */
-    @SystemApi
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_INSTALL_EPHEMERAL_PACKAGE
             = "android.intent.action.INSTALL_EPHEMERAL_PACKAGE";
@@ -1495,7 +1494,6 @@
      *
      * @hide
      */
-    @SystemApi
     @SdkConstant(SdkConstantType.SERVICE_ACTION)
     public static final String ACTION_RESOLVE_EPHEMERAL_PACKAGE
             = "android.intent.action.RESOLVE_EPHEMERAL_PACKAGE";
@@ -3764,14 +3762,12 @@
      * A {@link IntentSender} to start after ephemeral installation success.
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_EPHEMERAL_SUCCESS = "android.intent.extra.EPHEMERAL_SUCCESS";
 
     /**
      * A {@link IntentSender} to start after ephemeral installation failure.
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_EPHEMERAL_FAILURE = "android.intent.extra.EPHEMERAL_FAILURE";
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 15bc279..64f83a9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -371,11 +371,19 @@
         try {
             ActivityManager.StackInfo stackInfo = mIam.getStackInfo(
                     ActivityManager.StackId.HOME_STACK_ID);
+            ActivityManager.StackInfo fullscreenStackInfo = mIam.getStackInfo(
+                    ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID);
             ComponentName topActivity = stackInfo.topActivity;
-            if (isHomeStackVisible != null) {
-                isHomeStackVisible.value = stackInfo.visible;
+            boolean homeStackVisibleNotOccluded = stackInfo.visible;
+            if (fullscreenStackInfo != null) {
+                boolean isFullscreenStackOccludingHome = fullscreenStackInfo.visible &&
+                        fullscreenStackInfo.position > stackInfo.position;
+                homeStackVisibleNotOccluded &= !isFullscreenStackOccludingHome;
             }
-            return (stackInfo.visible && topActivity != null
+            if (isHomeStackVisible != null) {
+                isHomeStackVisible.value = homeStackVisibleNotOccluded;
+            }
+            return (homeStackVisibleNotOccluded && topActivity != null
                     && topActivity.getPackageName().equals(RecentsImpl.RECENTS_PACKAGE)
                     && (topActivity.getClassName().equals(RecentsImpl.RECENTS_ACTIVITY)
                         || topActivity.getClassName().equals(RecentsTvImpl.RECENTS_TV_ACTIVITY)));
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 0baca9e..ded9aa8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -123,7 +123,6 @@
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -3406,12 +3405,16 @@
     }
 
     private StackInfo getStackInfoLocked(ActivityStack stack) {
+        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
         StackInfo info = new StackInfo();
         mWindowManager.getStackBounds(stack.mStackId, info.bounds);
         info.displayId = Display.DEFAULT_DISPLAY;
         info.stackId = stack.mStackId;
         info.userId = stack.mCurrentUser;
         info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE;
+        info.position = display != null
+                ? display.mStacks.indexOf(stack)
+                : 0;
 
         ArrayList<TaskRecord> tasks = stack.getAllTasks();
         final int numTasks = tasks.size();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 488645d..35bcaa9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17550,21 +17550,26 @@
                 throw new IllegalArgumentException(
                         "Unknown component: " + packageName + "/" + className);
             }
-            // Don't allow other apps to disable an active profile owner
-            if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
-                final DevicePolicyManagerInternal dpmi = LocalServices
-                        .getService(DevicePolicyManagerInternal.class);
-                if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
-                    throw new SecurityException("Cannot disable a device owner or a profile owner");
-                }
-            }
-            // Allow root and verify that userId is not being specified by a different user
-            if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
+        }
+
+        // Limit who can change which apps
+        if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
+            // Don't allow apps that don't have permission to modify other apps
+            if (!allowedByPermission) {
                 throw new SecurityException(
                         "Permission Denial: attempt to change component state from pid="
                         + Binder.getCallingPid()
                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
             }
+            // Don't allow changing profile and device owners. Calling into DPMS, so no locking.
+            final DevicePolicyManagerInternal dpmi = LocalServices
+                    .getService(DevicePolicyManagerInternal.class);
+            if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
+                throw new SecurityException("Cannot disable a device owner or a profile owner");
+            }
+        }
+
+        synchronized (mPackages) {
             if (uid == Process.SHELL_UID) {
                 // Shell can only change whole packages between ENABLED and DISABLED_USER states
                 int oldState = pkgSetting.getEnabled(userId);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c3f2367..2570954 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2115,14 +2115,16 @@
         mWasVisibleBeforeClientHidden = false;
     }
 
-    void clearAnimatingWithSavedSurface() {
+    boolean clearAnimatingWithSavedSurface() {
         if (mAnimatingWithSavedSurface) {
             // App has drawn something to its windows, we're no longer animating with
             // the saved surfaces.
             if (DEBUG_ANIM) Slog.d(TAG,
                     "clearAnimatingWithSavedSurface(): win=" + this);
             mAnimatingWithSavedSurface = false;
+            return true;
         }
+        return false;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c92d325..54c4214 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -587,7 +587,7 @@
                     + drawStateToString());
         }
 
-        mWin.clearAnimatingWithSavedSurface();
+        boolean layoutNeeded = mWin.clearAnimatingWithSavedSurface();
 
         if (mDrawState == DRAW_PENDING) {
             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
@@ -597,10 +597,10 @@
                 Slog.v(TAG, "Draw state now committed in " + mWin);
             }
             mDrawState = COMMIT_DRAW_PENDING;
-            return true;
+            layoutNeeded = true;
         }
 
-        return false;
+        return layoutNeeded;
     }
 
     // This must be called while inside a transaction.
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 4cab7f0..fc7d741 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -1367,12 +1367,14 @@
 
     /** {@hide} */
     protected void removeConnection(Connection connection) {
-        String id = mIdByConnection.get(connection);
         connection.unsetConnectionService(this);
         connection.removeConnectionListener(mConnectionListener);
-        mConnectionById.remove(mIdByConnection.get(connection));
-        mIdByConnection.remove(connection);
-        mAdapter.removeCall(id);
+        String id = mIdByConnection.get(connection);
+        if (id != null) {
+            mConnectionById.remove(id);
+            mIdByConnection.remove(connection);
+            mAdapter.removeCall(id);
+        }
     }
 
     private String addConferenceInternal(Conference conference) {