Merge "Add a new(Empty) system service for AppFunctions project" into main
diff --git a/apct-tests/perftests/multiuser/Android.bp b/apct-tests/perftests/multiuser/Android.bp
index 856dba3..9eea712 100644
--- a/apct-tests/perftests/multiuser/Android.bp
+++ b/apct-tests/perftests/multiuser/Android.bp
@@ -45,3 +45,8 @@
         "trace_configs/trace_config_multi_user.textproto",
     ],
 }
+
+prebuilt_etc {
+    name: "trace_config_multi_user.textproto",
+    src: ":multi_user_trace_config",
+}
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index b0ab11f..1fab3cf 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -171,6 +171,17 @@
                     "include-filter": "android.content.pm.cts.PackageManagerShellCommandMultiUserTest"
                 }
             ]
+        },
+        {
+            "name":"CtsPackageInstallerCUJTestCases",
+            "options":[
+                {
+                    "exclude-annotation":"androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation":"org.junit.Ignore"
+                }
+            ]
         }
     ]
 }
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index a6ae948..adbc598 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -61,16 +61,6 @@
 
 flag {
     namespace: "windowing_sdk"
-    name: "fix_pip_restore_to_overlay"
-    description: "Restore exit-pip activity back to ActivityEmbedding overlay"
-    bug: "297887697"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
-    namespace: "windowing_sdk"
     name: "activity_embedding_animation_customization_flag"
     description: "Whether the animation customization feature for AE is enabled"
     bug: "293658614"
@@ -128,3 +118,11 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    namespace: "windowing_sdk"
+    name: "ae_back_stack_restore"
+    description: "Allow the ActivityEmbedding back stack to be restored after process restarted"
+    bug: "289875940"
+    is_fixed_read_only: true
+}
diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
index 69d1cb3..7bfb800 100644
--- a/core/java/com/android/internal/jank/Cuj.java
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -210,8 +210,16 @@
      */
     public static final int CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE = 116;
 
+    /**
+     * Track interaction of exiting desktop mode on closing the last window.
+     *
+     * <p>Tracking starts when the last window is closed and finishes when the animation to exit
+     * desktop mode ends.
+     */
+    public static final int CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE = 117;
+
     // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
-    @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE;
+    @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE;
 
     /** @hide */
     @IntDef({
@@ -319,7 +327,8 @@
             CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_OPEN,
             CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE,
             CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH,
-            CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE
+            CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE,
+            CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {}
@@ -438,6 +447,7 @@
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE;
     }
 
     private Cuj() {
@@ -666,6 +676,8 @@
                 return "LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH";
             case CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE:
                 return "DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE";
+            case CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE:
+                return "DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE";
         }
         return "UNKNOWN";
     }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 25e7107..26d180c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -695,12 +695,8 @@
                         break;
                     case TYPE_ACTIVITY_REPARENTED_TO_TASK:
                         final IBinder candidateAssociatedActToken, lastOverlayToken;
-                        if (Flags.fixPipRestoreToOverlay()) {
-                            candidateAssociatedActToken = change.getOtherActivityToken();
-                            lastOverlayToken = change.getTaskFragmentToken();
-                        } else {
-                            candidateAssociatedActToken = lastOverlayToken = null;
-                        }
+                        candidateAssociatedActToken = change.getOtherActivityToken();
+                        lastOverlayToken = change.getTaskFragmentToken();
                         onActivityReparentedToTask(
                                 wct,
                                 taskId,
@@ -1023,10 +1019,6 @@
     @Nullable
     OverlayContainerRestoreParams getOverlayContainerRestoreParams(
             @Nullable IBinder associatedActivityToken, @Nullable IBinder overlayToken) {
-        if (!Flags.fixPipRestoreToOverlay()) {
-            return null;
-        }
-
         if (associatedActivityToken == null || overlayToken == null) {
             return null;
         }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index d0e2c99..ee3e6f3 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -36,7 +36,6 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.window.flags.Flags;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -257,7 +256,7 @@
         mPendingAppearedIntent = pendingAppearedIntent;
 
         // Save the information necessary for restoring the overlay when needed.
-        if (Flags.fixPipRestoreToOverlay() && overlayTag != null && pendingAppearedIntent != null
+        if (overlayTag != null && pendingAppearedIntent != null
                 && associatedActivity != null && !associatedActivity.isFinishing()) {
             final IBinder associatedActivityToken = associatedActivity.getActivityToken();
             final OverlayContainerRestoreParams params = new OverlayContainerRestoreParams(mToken,
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 475475b..90eeb58 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -874,8 +874,6 @@
 
     @Test
     public void testOnActivityReparentedToTask_overlayRestoration() {
-        mSetFlagRule.enableFlags(Flags.FLAG_FIX_PIP_RESTORE_TO_OVERLAY);
-
         // Prepares and mock the data necessary for the test.
         final IBinder activityToken = mActivity.getActivityToken();
         final Intent intent = new Intent();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 7275c64..1242287 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -95,6 +95,7 @@
 
 import java.io.PrintWriter;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Predicate;
 
 /**
  * Controls the window animation run when a user initiates a back gesture.
@@ -1209,7 +1210,7 @@
             }
 
             if (info.getType() != WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION
-                    && !isGestureBackTransition(info)) {
+                    && isNotGestureBackTransition(info)) {
                 return false;
             }
 
@@ -1364,7 +1365,7 @@
             // try to handle unexpected transition
             mergePendingTransitions(info);
 
-            if (!isGestureBackTransition(info) || shouldCancelAnimation(info)
+            if (isNotGestureBackTransition(info) || shouldCancelAnimation(info)
                     || !mCloseTransitionRequested) {
                 if (mPrepareOpenTransition != null) {
                     applyFinishOpenTransition();
@@ -1395,8 +1396,8 @@
 
         // Cancel close animation if something happen unexpected, let another handler to handle
         private boolean shouldCancelAnimation(@NonNull TransitionInfo info) {
-            final boolean noCloseAllowed =
-                    info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION;
+            final boolean noCloseAllowed = !mCloseTransitionRequested
+                    && info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION;
             boolean unableToHandle = false;
             boolean filterTargets = false;
             for (int i = info.getChanges().size() - 1; i >= 0; --i) {
@@ -1455,7 +1456,11 @@
             if (info.getType() != WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION) {
                 return false;
             }
-
+            // Must have open target, must not have close target.
+            if (hasAnimationInMode(info, TransitionUtil::isClosingMode)
+                    || !hasAnimationInMode(info, TransitionUtil::isOpeningMode)) {
+                return false;
+            }
             SurfaceControl openingLeash = null;
             if (mApps != null) {
                 for (int i = mApps.length - 1; i >= 0; --i) {
@@ -1482,17 +1487,6 @@
             return true;
         }
 
-        private boolean isGestureBackTransition(@NonNull TransitionInfo info) {
-            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
-                final TransitionInfo.Change c = info.getChanges().get(i);
-                if (c.hasFlags(FLAG_BACK_GESTURE_ANIMATED)
-                        && (TransitionUtil.isOpeningMode(c.getMode())
-                        || TransitionUtil.isClosingMode(c.getMode()))) {
-                    return true;
-                }
-            }
-            return false;
-        }
         /**
          * Check whether this transition is triggered from back gesture commitment.
          * Reparent the transition targets to animation leashes, so the animation won't be broken.
@@ -1501,10 +1495,18 @@
                 @NonNull SurfaceControl.Transaction st,
                 @NonNull SurfaceControl.Transaction ft,
                 @NonNull Transitions.TransitionFinishCallback finishCallback) {
-            if (info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION
-                    || !mCloseTransitionRequested) {
+            if (!mCloseTransitionRequested) {
                 return false;
             }
+            // must have close target
+            if (!hasAnimationInMode(info, TransitionUtil::isClosingMode)) {
+                return false;
+            }
+            if (mApps == null) {
+                // animation is done
+                applyAndFinish(st, ft, finishCallback);
+                return true;
+            }
             SurfaceControl openingLeash = null;
             SurfaceControl closingLeash = null;
             for (int i = mApps.length - 1; i >= 0; --i) {
@@ -1522,6 +1524,7 @@
                         final Point offset = c.getEndRelOffset();
                         st.setPosition(c.getLeash(), offset.x, offset.y);
                         st.reparent(c.getLeash(), openingLeash);
+                        st.setAlpha(c.getLeash(), 1.0f);
                     } else if (TransitionUtil.isClosingMode(c.getMode())) {
                         st.reparent(c.getLeash(), closingLeash);
                     }
@@ -1592,6 +1595,21 @@
         }
     }
 
+    private static boolean isNotGestureBackTransition(@NonNull TransitionInfo info) {
+        return !hasAnimationInMode(info, TransitionUtil::isOpenOrCloseMode);
+    }
+
+    private static boolean hasAnimationInMode(@NonNull TransitionInfo info,
+            Predicate<Integer> mode) {
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            final TransitionInfo.Change c = info.getChanges().get(i);
+            if (c.hasFlags(FLAG_BACK_GESTURE_ANIMATED) && mode.test(c.getMode())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private static ComponentName findComponentName(TransitionInfo.Change change) {
         final ComponentName componentName = change.getActivityComponent();
         if (componentName != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index efa1031..f002d89 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -1601,6 +1601,11 @@
                 getResources().getColor(android.R.color.system_neutral1_1000)));
         mManageMenuScrim.setBackgroundDrawable(new ColorDrawable(
                 getResources().getColor(android.R.color.system_neutral1_1000)));
+        if (mShowingManage) {
+            // the manage menu location depends on the manage button location which may need a
+            // layout pass, so post this to the looper
+            post(() -> showManageMenu(true));
+        }
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
index 73aa7ce..a6ed3b8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
@@ -22,6 +22,7 @@
 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
 import android.content.Context
 import android.os.IBinder
+import android.os.Trace
 import android.util.SparseArray
 import android.view.SurfaceControl
 import android.view.WindowManager
@@ -51,6 +52,8 @@
 import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.transition.Transitions
 
+const val VISIBLE_TASKS_COUNTER_NAME = "DESKTOP_MODE_VISIBLE_TASKS"
+
 /**
  * A [Transitions.TransitionObserver] that observes transitions and the proposed changes to log
  * appropriate desktop mode session log events. This observes transitions related to desktop mode
@@ -292,8 +295,14 @@
             val previousTaskInfo = preTransitionVisibleFreeformTasks[taskId]
             when {
                 // new tasks added
-                previousTaskInfo == null ->
+                previousTaskInfo == null -> {
                     desktopModeEventLogger.logTaskAdded(sessionId, currentTaskUpdate)
+                    Trace.setCounter(
+                        Trace.TRACE_TAG_WINDOW_MANAGER,
+                        VISIBLE_TASKS_COUNTER_NAME,
+                        postTransitionVisibleFreeformTasks.size().toLong()
+                    )
+                }
                 // old tasks that were resized or repositioned
                 // TODO(b/347935387): Log changes only once they are stable.
                 buildTaskUpdateForTask(previousTaskInfo) != currentTaskUpdate ->
@@ -305,6 +314,11 @@
         preTransitionVisibleFreeformTasks.forEach { taskId, taskInfo ->
             if (!postTransitionVisibleFreeformTasks.containsKey(taskId)) {
                 desktopModeEventLogger.logTaskRemoved(sessionId, buildTaskUpdateForTask(taskInfo))
+                Trace.setCounter(
+                    Trace.TRACE_TAG_WINDOW_MANAGER,
+                    VISIBLE_TASKS_COUNTER_NAME,
+                    postTransitionVisibleFreeformTasks.size().toLong()
+                )
             }
         }
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
index a5e0550..3ffc9d7 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
@@ -21,6 +21,7 @@
 import android.tools.flicker.legacy.FlickerBuilder
 import android.tools.flicker.legacy.LegacyFlickerTest
 import android.tools.traces.component.ComponentNameMatcher
+import com.android.wm.shell.Flags
 import com.android.wm.shell.flicker.pip.common.ClosePipTransition
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -60,7 +61,7 @@
             val pipCenterY = pipRegion.centerY()
             val displayCenterX = device.displayWidth / 2
             val barComponent =
-                if (flicker.scenario.isTablet) {
+                if (flicker.scenario.isTablet || Flags.enableTaskbarOnPhones()) {
                     ComponentNameMatcher.TASK_BAR
                 } else {
                     ComponentNameMatcher.NAV_BAR
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt
index 4465a16..acaf021 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt
@@ -28,12 +28,16 @@
 import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import com.android.server.wm.flicker.taskBarLayerIsVisibleAtStartAndEnd
 import com.android.server.wm.flicker.taskBarWindowIsAlwaysVisible
+import com.android.wm.shell.Flags
 import org.junit.Assume
 import org.junit.Test
 
 interface ICommonAssertions {
     val flicker: LegacyFlickerTest
 
+    val usesTaskbar: Boolean
+        get() = flicker.scenario.isTablet || Flags.enableTaskbarOnPhones()
+
     /** Checks that all parts of the screen are covered during the transition */
     @Presubmit @Test fun entireScreenCovered() = flicker.entireScreenCovered()
 
@@ -43,7 +47,7 @@
     @Presubmit
     @Test
     fun navBarLayerIsVisibleAtStartAndEnd() {
-        Assume.assumeFalse(flicker.scenario.isTablet)
+        Assume.assumeFalse(usesTaskbar)
         flicker.navBarLayerIsVisibleAtStartAndEnd()
     }
 
@@ -54,7 +58,7 @@
     @Presubmit
     @Test
     fun navBarLayerPositionAtStartAndEnd() {
-        Assume.assumeFalse(flicker.scenario.isTablet)
+        Assume.assumeFalse(usesTaskbar)
         flicker.navBarLayerPositionAtStartAndEnd()
     }
 
@@ -66,7 +70,7 @@
     @Presubmit
     @Test
     fun navBarWindowIsAlwaysVisible() {
-        Assume.assumeFalse(flicker.scenario.isTablet)
+        Assume.assumeFalse(usesTaskbar)
         flicker.navBarWindowIsAlwaysVisible()
     }
 
@@ -76,7 +80,7 @@
     @Presubmit
     @Test
     fun taskBarLayerIsVisibleAtStartAndEnd() {
-        Assume.assumeTrue(flicker.scenario.isTablet)
+        Assume.assumeTrue(usesTaskbar)
         flicker.taskBarLayerIsVisibleAtStartAndEnd()
     }
 
@@ -88,7 +92,7 @@
     @Presubmit
     @Test
     fun taskBarWindowIsAlwaysVisible() {
-        Assume.assumeTrue(flicker.scenario.isTablet)
+        Assume.assumeTrue(usesTaskbar)
         flicker.taskBarWindowIsAlwaysVisible()
     }
 
diff --git a/packages/PackageInstaller/TEST_MAPPING b/packages/PackageInstaller/TEST_MAPPING
index b3fb1e7..ff83610 100644
--- a/packages/PackageInstaller/TEST_MAPPING
+++ b/packages/PackageInstaller/TEST_MAPPING
@@ -28,6 +28,17 @@
     },
     {
       "name": "CtsIntentSignatureTestCases"
+    },
+    {
+      "name": "CtsPackageInstallerCUJTestCases",
+      "options":[
+          {
+              "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+              "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
     }
   ]
 }
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 98e3e24..22b4d5d 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -686,6 +686,9 @@
                     (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
             final boolean fullApp =
                     (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
+            final boolean isPackageDeviceAdmin = mPm.isPackageDeviceAdmin(packageName, userId);
+            final boolean isProtectedPackage = mPm.mProtectedPackages != null
+                    && mPm.mProtectedPackages.isPackageStateProtected(userId, packageName);
 
             // writer
             synchronized (mPm.mLock) {
@@ -694,7 +697,8 @@
                 if (pkgSetting == null || pkgSetting.getPkg() == null) {
                     return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender);
                 }
-                if (instantApp && (pkgSetting.isSystem() || pkgSetting.isUpdatedSystemApp())) {
+                if (instantApp && (pkgSetting.isSystem() || pkgSetting.isUpdatedSystemApp()
+                        || isPackageDeviceAdmin || isProtectedPackage)) {
                     return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender);
                 }
                 if (!snapshot.canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index c40608d..c95d88e 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -163,6 +163,22 @@
     },
     {
       "name": "CtsUpdateOwnershipEnforcementTestCases"
+    },
+    {
+      "name": "CtsPackageInstallerCUJTestCases",
+      "file_patterns": [
+        "core/java/.*Install.*",
+        "services/core/.*Install.*",
+        "services/core/java/com/android/server/pm/.*"
+      ],
+      "options":[
+          {
+              "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+              "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
     }
   ],
   "imports": [
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 561ff7d..7212d37 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -407,8 +407,7 @@
                 change.setTaskFragmentToken(lastParentTfToken);
             }
             // Only pass the activity token to the client if it belongs to the same process.
-            if (Flags.fixPipRestoreToOverlay() && nextFillTaskActivity != null
-                    && nextFillTaskActivity.getPid() == mOrganizerPid) {
+            if (nextFillTaskActivity != null && nextFillTaskActivity.getPid() == mOrganizerPid) {
                 change.setOtherActivityToken(nextFillTaskActivity.token);
             }
             return change;