Merge "Update NotificationIconAreaController"
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 267b818..d67b986 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -614,7 +614,7 @@
                     throw new IllegalStateException(
                             "Received config update for non-existing activity");
                 }
-                activity.mMainThread.handleActivityConfigurationChanged(this, overrideConfig,
+                activity.mMainThread.handleActivityConfigurationChanged(token, overrideConfig,
                         newDisplayId);
             };
         }
@@ -3475,9 +3475,13 @@
     }
 
     @Override
-    public void handleStartActivity(ActivityClientRecord r,
-            PendingTransactionActions pendingActions) {
+    public void handleStartActivity(IBinder token, PendingTransactionActions pendingActions) {
+        final ActivityClientRecord r = mActivities.get(token);
         final Activity activity = r.activity;
+        if (r.activity == null) {
+            // TODO(lifecycler): What do we do in this case?
+            return;
+        }
         if (!r.stopped) {
             throw new IllegalStateException("Can't start activity that is not stopped.");
         }
@@ -3683,7 +3687,12 @@
     }
 
     @Override
-    public void handleNewIntent(ActivityClientRecord r, List<ReferrerIntent> intents) {
+    public void handleNewIntent(IBinder token, List<ReferrerIntent> intents) {
+        final ActivityClientRecord r = mActivities.get(token);
+        if (r == null) {
+            return;
+        }
+
         checkAndBlockForNetworkAccess();
         deliverNewIntents(r, intents);
     }
@@ -3872,7 +3881,13 @@
     }
 
     @Override
-    public void handlePictureInPictureRequested(ActivityClientRecord r) {
+    public void handlePictureInPictureRequested(IBinder token) {
+        final ActivityClientRecord r = mActivities.get(token);
+        if (r == null) {
+            Log.w(TAG, "Activity to request PIP to no longer exists");
+            return;
+        }
+
         final boolean receivedByApp = r.activity.onPictureInPictureRequested();
         if (!receivedByApp) {
             // Previous recommendation was for apps to enter picture-in-picture in
@@ -4402,21 +4417,22 @@
 
     /**
      * Resume the activity.
-     * @param r Target activity record.
+     * @param token Target activity token.
      * @param finalStateRequest Flag indicating if this is part of final state resolution for a
      *                          transaction.
      * @param reason Reason for performing the action.
      *
-     * @return {@code true} that was resumed, {@code false} otherwise.
+     * @return The {@link ActivityClientRecord} that was resumed, {@code null} otherwise.
      */
     @VisibleForTesting
-    public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
+    public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
             String reason) {
+        final ActivityClientRecord r = mActivities.get(token);
         if (localLOGV) {
             Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
         }
-        if (r.activity.mFinished) {
-            return false;
+        if (r == null || r.activity.mFinished) {
+            return null;
         }
         if (r.getLifecycleState() == ON_RESUME) {
             if (!finalStateRequest) {
@@ -4430,7 +4446,7 @@
                 // handle two resume requests for the final state. For cases other than this
                 // one, we don't expect it to happen.
             }
-            return false;
+            return null;
         }
         if (finalStateRequest) {
             r.hideForNow = false;
@@ -4461,7 +4477,7 @@
                         + r.intent.getComponent().toShortString() + ": " + e.toString(), e);
             }
         }
-        return true;
+        return r;
     }
 
     static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
@@ -4482,19 +4498,20 @@
     }
 
     @Override
-    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
-            boolean isForward, String reason) {
+    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
+            String reason) {
         // If we are getting ready to gc after going to the background, well
         // we are back active so skip it.
         unscheduleGcIdler();
         mSomeActivitiesChanged = true;
 
         // TODO Push resumeArgs into the activity for consideration
-        // skip below steps for double-resume and r.mFinish = true case.
-        if (!performResumeActivity(r, finalStateRequest, reason)) {
+        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
+        if (r == null) {
+            // We didn't actually resume the activity, so skipping any follow-up actions.
             return;
         }
-        if (mActivitiesToBeDestroyed.containsKey(r.token)) {
+        if (mActivitiesToBeDestroyed.containsKey(token)) {
             // Although the activity is resumed, it is going to be destroyed. So the following
             // UI operations are unnecessary and also prevents exception because its token may
             // be gone that window manager cannot recognize it. All necessary cleanup actions
@@ -4612,8 +4629,13 @@
 
 
     @Override
-    public void handleTopResumedActivityChanged(ActivityClientRecord r, boolean onTop,
-            String reason) {
+    public void handleTopResumedActivityChanged(IBinder token, boolean onTop, String reason) {
+        ActivityClientRecord r = mActivities.get(token);
+        if (r == null || r.activity == null) {
+            Slog.w(TAG, "Not found target activity to report position change for token: " + token);
+            return;
+        }
+
         if (DEBUG_ORDER) {
             Slog.d(TAG, "Received position change to top: " + onTop + " for activity: " + r);
         }
@@ -4646,20 +4668,23 @@
     }
 
     @Override
-    public void handlePauseActivity(ActivityClientRecord r, boolean finished, boolean userLeaving,
+    public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
             int configChanges, PendingTransactionActions pendingActions, String reason) {
-        if (userLeaving) {
-            performUserLeavingActivity(r);
-        }
+        ActivityClientRecord r = mActivities.get(token);
+        if (r != null) {
+            if (userLeaving) {
+                performUserLeavingActivity(r);
+            }
 
-        r.activity.mConfigChangeFlags |= configChanges;
-        performPauseActivity(r, finished, reason, pendingActions);
+            r.activity.mConfigChangeFlags |= configChanges;
+            performPauseActivity(r, finished, reason, pendingActions);
 
-        // Make sure any pending writes are now committed.
-        if (r.isPreHoneycomb()) {
-            QueuedWork.waitToFinish();
+            // Make sure any pending writes are now committed.
+            if (r.isPreHoneycomb()) {
+                QueuedWork.waitToFinish();
+            }
+            mSomeActivitiesChanged = true;
         }
-        mSomeActivitiesChanged = true;
     }
 
     final void performUserLeavingActivity(ActivityClientRecord r) {
@@ -4756,11 +4781,8 @@
         r.setState(ON_PAUSE);
     }
 
-    // TODO(b/127877792): Make LocalActivityManager call performStopActivityInner. We cannot do this
-    // since it's a high usage hidden API.
     /** Called from {@link LocalActivityManager}. */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 127877792,
-            publicAlternatives = "{@code N/A}")
+    @UnsupportedAppUsage
     final void performStopActivity(IBinder token, boolean saveState, String reason) {
         ActivityClientRecord r = mActivities.get(token);
         performStopActivityInner(r, null /* stopInfo */, saveState, false /* finalStateRequest */,
@@ -4801,37 +4823,39 @@
     private void performStopActivityInner(ActivityClientRecord r, StopInfo info,
             boolean saveState, boolean finalStateRequest, String reason) {
         if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
-        if (r.stopped) {
-            if (r.activity.mFinished) {
-                // If we are finishing, we won't call onResume() in certain
-                // cases.  So here we likewise don't want to call onStop()
-                // if the activity isn't resumed.
-                return;
+        if (r != null) {
+            if (r.stopped) {
+                if (r.activity.mFinished) {
+                    // If we are finishing, we won't call onResume() in certain
+                    // cases.  So here we likewise don't want to call onStop()
+                    // if the activity isn't resumed.
+                    return;
+                }
+                if (!finalStateRequest) {
+                    final RuntimeException e = new RuntimeException(
+                            "Performing stop of activity that is already stopped: "
+                                    + r.intent.getComponent().toShortString());
+                    Slog.e(TAG, e.getMessage(), e);
+                    Slog.e(TAG, r.getStateString());
+                }
             }
-            if (!finalStateRequest) {
-                final RuntimeException e = new RuntimeException(
-                        "Performing stop of activity that is already stopped: "
-                                + r.intent.getComponent().toShortString());
-                Slog.e(TAG, e.getMessage(), e);
-                Slog.e(TAG, r.getStateString());
-            }
-        }
 
-        // One must first be paused before stopped...
-        performPauseActivityIfNeeded(r, reason);
+            // One must first be paused before stopped...
+            performPauseActivityIfNeeded(r, reason);
 
-        if (info != null) {
-            try {
-                // First create a thumbnail for the activity...
-                // For now, don't create the thumbnail here; we are
-                // doing that by doing a screen snapshot.
-                info.setDescription(r.activity.onCreateDescription());
-            } catch (Exception e) {
-                if (!mInstrumentation.onException(r.activity, e)) {
-                    throw new RuntimeException(
-                            "Unable to save state of activity "
-                            + r.intent.getComponent().toShortString()
-                            + ": " + e.toString(), e);
+            if (info != null) {
+                try {
+                    // First create a thumbnail for the activity...
+                    // For now, don't create the thumbnail here; we are
+                    // doing that by doing a screen snapshot.
+                    info.setDescription(r.activity.onCreateDescription());
+                } catch (Exception e) {
+                    if (!mInstrumentation.onException(r.activity, e)) {
+                        throw new RuntimeException(
+                                "Unable to save state of activity "
+                                + r.intent.getComponent().toShortString()
+                                + ": " + e.toString(), e);
+                    }
                 }
             }
 
@@ -4903,8 +4927,9 @@
     }
 
     @Override
-    public void handleStopActivity(ActivityClientRecord r, int configChanges,
+    public void handleStopActivity(IBinder token, int configChanges,
             PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
+        final ActivityClientRecord r = mActivities.get(token);
         r.activity.mConfigChangeFlags |= configChanges;
 
         final StopInfo stopInfo = new StopInfo();
@@ -4940,7 +4965,8 @@
     }
 
     @Override
-    public void performRestartActivity(ActivityClientRecord r, boolean start) {
+    public void performRestartActivity(IBinder token, boolean start) {
+        ActivityClientRecord r = mActivities.get(token);
         if (r.stopped) {
             r.activity.performRestart(start, "performRestartActivity");
             if (start) {
@@ -5027,101 +5053,107 @@
     }
 
     @Override
-    public void handleSendResult(ActivityClientRecord r, List<ResultInfo> results, String reason) {
+    public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) {
+        ActivityClientRecord r = mActivities.get(token);
         if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
-        final boolean resumed = !r.paused;
-        if (!r.activity.mFinished && r.activity.mDecor != null
-                && r.hideForNow && resumed) {
-            // We had hidden the activity because it started another
-            // one...  we have gotten a result back and we are not
-            // paused, so make sure our window is visible.
-            updateVisibility(r, true);
+        if (r != null) {
+            final boolean resumed = !r.paused;
+            if (!r.activity.mFinished && r.activity.mDecor != null
+                    && r.hideForNow && resumed) {
+                // We had hidden the activity because it started another
+                // one...  we have gotten a result back and we are not
+                // paused, so make sure our window is visible.
+                updateVisibility(r, true);
+            }
+            if (resumed) {
+                try {
+                    // Now we are idle.
+                    r.activity.mCalled = false;
+                    mInstrumentation.callActivityOnPause(r.activity);
+                    if (!r.activity.mCalled) {
+                        throw new SuperNotCalledException(
+                            "Activity " + r.intent.getComponent().toShortString()
+                            + " did not call through to super.onPause()");
+                    }
+                } catch (SuperNotCalledException e) {
+                    throw e;
+                } catch (Exception e) {
+                    if (!mInstrumentation.onException(r.activity, e)) {
+                        throw new RuntimeException(
+                                "Unable to pause activity "
+                                + r.intent.getComponent().toShortString()
+                                + ": " + e.toString(), e);
+                    }
+                }
+            }
+            checkAndBlockForNetworkAccess();
+            deliverResults(r, results, reason);
+            if (resumed) {
+                r.activity.performResume(false, reason);
+            }
         }
-        if (resumed) {
+    }
+
+    /** Core implementation of activity destroy call. */
+    ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
+            int configChanges, boolean getNonConfigInstance, String reason) {
+        ActivityClientRecord r = mActivities.get(token);
+        Class<? extends Activity> activityClass = null;
+        if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
+        if (r != null) {
+            activityClass = r.activity.getClass();
+            r.activity.mConfigChangeFlags |= configChanges;
+            if (finishing) {
+                r.activity.mFinished = true;
+            }
+
+            performPauseActivityIfNeeded(r, "destroy");
+
+            if (!r.stopped) {
+                callActivityOnStop(r, false /* saveState */, "destroy");
+            }
+            if (getNonConfigInstance) {
+                try {
+                    r.lastNonConfigurationInstances
+                            = r.activity.retainNonConfigurationInstances();
+                } catch (Exception e) {
+                    if (!mInstrumentation.onException(r.activity, e)) {
+                        throw new RuntimeException(
+                                "Unable to retain activity "
+                                + r.intent.getComponent().toShortString()
+                                + ": " + e.toString(), e);
+                    }
+                }
+            }
             try {
-                // Now we are idle.
                 r.activity.mCalled = false;
-                mInstrumentation.callActivityOnPause(r.activity);
+                mInstrumentation.callActivityOnDestroy(r.activity);
                 if (!r.activity.mCalled) {
                     throw new SuperNotCalledException(
-                        "Activity " + r.intent.getComponent().toShortString()
-                        + " did not call through to super.onPause()");
+                        "Activity " + safeToComponentShortString(r.intent) +
+                        " did not call through to super.onDestroy()");
+                }
+                if (r.window != null) {
+                    r.window.closeAllPanels();
                 }
             } catch (SuperNotCalledException e) {
                 throw e;
             } catch (Exception e) {
                 if (!mInstrumentation.onException(r.activity, e)) {
                     throw new RuntimeException(
-                            "Unable to pause activity "
-                            + r.intent.getComponent().toShortString()
-                            + ": " + e.toString(), e);
-                }
-            }
-        }
-        checkAndBlockForNetworkAccess();
-        deliverResults(r, results, reason);
-        if (resumed) {
-            r.activity.performResume(false, reason);
-        }
-    }
-
-    /** Core implementation of activity destroy call. */
-    ActivityClientRecord performDestroyActivity(ActivityClientRecord r, boolean finishing,
-            int configChanges, boolean getNonConfigInstance, String reason) {
-        Class<? extends Activity> activityClass = null;
-        if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
-        activityClass = r.activity.getClass();
-        r.activity.mConfigChangeFlags |= configChanges;
-        if (finishing) {
-            r.activity.mFinished = true;
-        }
-
-        performPauseActivityIfNeeded(r, "destroy");
-
-        if (!r.stopped) {
-            callActivityOnStop(r, false /* saveState */, "destroy");
-        }
-        if (getNonConfigInstance) {
-            try {
-                r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
-            } catch (Exception e) {
-                if (!mInstrumentation.onException(r.activity, e)) {
-                    throw new RuntimeException(
-                            "Unable to retain activity "
-                            + r.intent.getComponent().toShortString()
+                            "Unable to destroy activity " + safeToComponentShortString(r.intent)
                             + ": " + e.toString(), e);
                 }
             }
             r.setState(ON_DESTROY);
             mLastReportedWindowingMode.remove(r.activity.getActivityToken());
         }
-        try {
-            r.activity.mCalled = false;
-            mInstrumentation.callActivityOnDestroy(r.activity);
-            if (!r.activity.mCalled) {
-                throw new SuperNotCalledException(
-                    "Activity " + safeToComponentShortString(r.intent)
-                            + " did not call through to super.onDestroy()");
-            }
-            if (r.window != null) {
-                r.window.closeAllPanels();
-            }
-        } catch (SuperNotCalledException e) {
-            throw e;
-        } catch (Exception e) {
-            if (!mInstrumentation.onException(r.activity, e)) {
-                throw new RuntimeException(
-                        "Unable to destroy activity " + safeToComponentShortString(r.intent)
-                        + ": " + e.toString(), e);
-            }
-        }
-        r.setState(ON_DESTROY);
         schedulePurgeIdler();
         // updatePendingActivityConfiguration() reads from mActivities to update
         // ActivityClientRecord which runs in a different thread. Protect modifications to
         // mActivities to avoid race.
         synchronized (mResourcesManager) {
-            mActivities.remove(r.token);
+            mActivities.remove(token);
         }
         StrictMode.decrementExpectedActivityCount(activityClass);
         return r;
@@ -5138,67 +5170,70 @@
     }
 
     @Override
-    public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
+    public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
             boolean getNonConfigInstance, String reason) {
-        r = performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
-        cleanUpPendingRemoveWindows(r, finishing);
-        WindowManager wm = r.activity.getWindowManager();
-        View v = r.activity.mDecor;
-        if (v != null) {
-            if (r.activity.mVisibleFromServer) {
-                mNumVisibleActivities--;
-            }
-            IBinder wtoken = v.getWindowToken();
-            if (r.activity.mWindowAdded) {
-                if (r.mPreserveWindow) {
-                    // Hold off on removing this until the new activity's
-                    // window is being added.
-                    r.mPendingRemoveWindow = r.window;
-                    r.mPendingRemoveWindowManager = wm;
-                    // We can only keep the part of the view hierarchy that we control,
-                    // everything else must be removed, because it might not be able to
-                    // behave properly when activity is relaunching.
-                    r.window.clearContentView();
-                } else {
-                    wm.removeViewImmediate(v);
+        ActivityClientRecord r = performDestroyActivity(token, finishing,
+                configChanges, getNonConfigInstance, reason);
+        if (r != null) {
+            cleanUpPendingRemoveWindows(r, finishing);
+            WindowManager wm = r.activity.getWindowManager();
+            View v = r.activity.mDecor;
+            if (v != null) {
+                if (r.activity.mVisibleFromServer) {
+                    mNumVisibleActivities--;
                 }
+                IBinder wtoken = v.getWindowToken();
+                if (r.activity.mWindowAdded) {
+                    if (r.mPreserveWindow) {
+                        // Hold off on removing this until the new activity's
+                        // window is being added.
+                        r.mPendingRemoveWindow = r.window;
+                        r.mPendingRemoveWindowManager = wm;
+                        // We can only keep the part of the view hierarchy that we control,
+                        // everything else must be removed, because it might not be able to
+                        // behave properly when activity is relaunching.
+                        r.window.clearContentView();
+                    } else {
+                        wm.removeViewImmediate(v);
+                    }
+                }
+                if (wtoken != null && r.mPendingRemoveWindow == null) {
+                    WindowManagerGlobal.getInstance().closeAll(wtoken,
+                            r.activity.getClass().getName(), "Activity");
+                } else if (r.mPendingRemoveWindow != null) {
+                    // We're preserving only one window, others should be closed so app views
+                    // will be detached before the final tear down. It should be done now because
+                    // some components (e.g. WebView) rely on detach callbacks to perform receiver
+                    // unregister and other cleanup.
+                    WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
+                            r.activity.getClass().getName(), "Activity");
+                }
+                r.activity.mDecor = null;
             }
-            if (wtoken != null && r.mPendingRemoveWindow == null) {
-                WindowManagerGlobal.getInstance().closeAll(wtoken,
-                        r.activity.getClass().getName(), "Activity");
-            } else if (r.mPendingRemoveWindow != null) {
-                // We're preserving only one window, others should be closed so app views
-                // will be detached before the final tear down. It should be done now because
-                // some components (e.g. WebView) rely on detach callbacks to perform receiver
-                // unregister and other cleanup.
-                WindowManagerGlobal.getInstance().closeAllExceptView(r.token, v,
+            if (r.mPendingRemoveWindow == null) {
+                // If we are delaying the removal of the activity window, then
+                // we can't clean up all windows here.  Note that we can't do
+                // so later either, which means any windows that aren't closed
+                // by the app will leak.  Well we try to warning them a lot
+                // about leaking windows, because that is a bug, so if they are
+                // using this recreate facility then they get to live with leaks.
+                WindowManagerGlobal.getInstance().closeAll(token,
                         r.activity.getClass().getName(), "Activity");
             }
-            r.activity.mDecor = null;
-        }
-        if (r.mPendingRemoveWindow == null) {
-            // If we are delaying the removal of the activity window, then
-            // we can't clean up all windows here.  Note that we can't do
-            // so later either, which means any windows that aren't closed
-            // by the app will leak.  Well we try to warning them a lot
-            // about leaking windows, because that is a bug, so if they are
-            // using this recreate facility then they get to live with leaks.
-            WindowManagerGlobal.getInstance().closeAll(r.token,
-                    r.activity.getClass().getName(), "Activity");
-        }
 
-        // Mocked out contexts won't be participating in the normal
-        // process lifecycle, but if we're running with a proper
-        // ApplicationContext we need to have it tear down things
-        // cleanly.
-        Context c = r.activity.getBaseContext();
-        if (c instanceof ContextImpl) {
-            ((ContextImpl) c).scheduleFinalCleanup(
-                    r.activity.getClass().getName(), "Activity");
+            // Mocked out contexts won't be participating in the normal
+            // process lifecycle, but if we're running with a proper
+            // ApplicationContext we need to have it tear down things
+            // cleanly.
+            Context c = r.activity.getBaseContext();
+            if (c instanceof ContextImpl) {
+                ((ContextImpl) c).scheduleFinalCleanup(
+                        r.activity.getClass().getName(), "Activity");
+            }
         }
         if (finishing) {
             try {
-                ActivityTaskManager.getService().activityDestroyed(r.token);
+                ActivityTaskManager.getService().activityDestroyed(token);
             } catch (RemoteException ex) {
                 throw ex.rethrowFromSystemServer();
             }
@@ -5421,7 +5456,7 @@
             callActivityOnStop(r, true /* saveState */, reason);
         }
 
-        handleDestroyActivity(r, false, configChanges, true, reason);
+        handleDestroyActivity(r.token, false, configChanges, true, reason);
 
         r.activity = null;
         r.window = null;
@@ -5449,10 +5484,12 @@
     }
 
     @Override
-    public void reportRelaunch(ActivityClientRecord r, PendingTransactionActions pendingActions) {
+    public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) {
         try {
-            ActivityTaskManager.getService().activityRelaunched(r.token);
-            if (pendingActions.shouldReportRelaunchToWindowManager() && r.window != null) {
+            ActivityTaskManager.getService().activityRelaunched(token);
+            final ActivityClientRecord r = mActivities.get(token);
+            if (pendingActions.shouldReportRelaunchToWindowManager() && r != null
+                    && r.window != null) {
                 r.window.reportActivityRelaunched();
             }
         } catch (RemoteException e) {
@@ -5611,7 +5648,13 @@
      */
     private Configuration performActivityConfigurationChanged(Activity activity,
             Configuration newConfig, Configuration amOverrideConfig, int displayId) {
+        if (activity == null) {
+            throw new IllegalArgumentException("No activity provided.");
+        }
         final IBinder activityToken = activity.getActivityToken();
+        if (activityToken == null) {
+            throw new IllegalArgumentException("Activity token not set. Is the activity attached?");
+        }
 
         final boolean movedToDifferentDisplay = isDifferentDisplay(activity, displayId);
         boolean shouldReportChange = false;
@@ -5911,8 +5954,20 @@
      * processing any configurations older than {@code overrideConfig}.
      */
     @Override
-    public void updatePendingActivityConfiguration(ActivityClientRecord r,
+    public void updatePendingActivityConfiguration(IBinder activityToken,
             Configuration overrideConfig) {
+        final ActivityClientRecord r;
+        synchronized (mResourcesManager) {
+            r = mActivities.get(activityToken);
+        }
+
+        if (r == null) {
+            if (DEBUG_CONFIGURATION) {
+                Slog.w(TAG, "Not found target activity to update its pending config.");
+            }
+            return;
+        }
+
         synchronized (r) {
             if (r.mPendingOverrideConfig != null
                     && !r.mPendingOverrideConfig.isOtherSeqNewer(overrideConfig)) {
@@ -5932,14 +5987,21 @@
      * if {@link #updatePendingActivityConfiguration(IBinder, Configuration)} has been called with
      * a newer config than {@code overrideConfig}.
      *
-     * @param r Target activity record.
+     * @param activityToken Target activity token.
      * @param overrideConfig Activity override config.
      * @param displayId Id of the display where activity was moved to, -1 if there was no move and
      *                  value didn't change.
      */
     @Override
-    public void handleActivityConfigurationChanged(ActivityClientRecord r,
+    public void handleActivityConfigurationChanged(IBinder activityToken,
             @NonNull Configuration overrideConfig, int displayId) {
+        ActivityClientRecord r = mActivities.get(activityToken);
+        // Check input params.
+        if (r == null || r.activity == null) {
+            if (DEBUG_CONFIGURATION) Slog.w(TAG, "Not found target activity to report to: " + r);
+            return;
+        }
+
         synchronized (r) {
             if (overrideConfig.isOtherSeqNewer(r.mPendingOverrideConfig)) {
                 if (DEBUG_CONFIGURATION) {
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index ac50676..2df756e 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -15,8 +15,6 @@
  */
 package android.app;
 
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.ClientTransactionItem;
 import android.app.servertransaction.PendingTransactionActions;
@@ -91,38 +89,37 @@
     public abstract Map<IBinder, ClientTransactionItem> getActivitiesToBeDestroyed();
 
     /** Destroy the activity. */
-    public abstract void handleDestroyActivity(@NonNull ActivityClientRecord r, boolean finishing,
-            int configChanges, boolean getNonConfigInstance, String reason);
+    public abstract void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
+            boolean getNonConfigInstance, String reason);
 
     /** Pause the activity. */
-    public abstract void handlePauseActivity(@NonNull ActivityClientRecord r, boolean finished,
-            boolean userLeaving, int configChanges, PendingTransactionActions pendingActions,
-            String reason);
+    public abstract void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
+            int configChanges, PendingTransactionActions pendingActions, String reason);
 
     /**
      * Resume the activity.
-     * @param r Target activity record.
+     * @param token Target activity token.
      * @param finalStateRequest Flag indicating if this call is handling final lifecycle state
      *                          request for a transaction.
      * @param isForward Flag indicating if next transition is forward.
      * @param reason Reason for performing this operation.
      */
-    public abstract void handleResumeActivity(@NonNull ActivityClientRecord r,
-            boolean finalStateRequest, boolean isForward, String reason);
+    public abstract void handleResumeActivity(IBinder token, boolean finalStateRequest,
+            boolean isForward, String reason);
 
     /**
      * Notify the activity about top resumed state change.
-     * @param r Target activity record.
+     * @param token Target activity token.
      * @param isTopResumedActivity Current state of the activity, {@code true} if it's the
      *                             topmost resumed activity in the system, {@code false} otherwise.
      * @param reason Reason for performing this operation.
      */
-    public abstract void handleTopResumedActivityChanged(@NonNull ActivityClientRecord r,
+    public abstract void handleTopResumedActivityChanged(IBinder token,
             boolean isTopResumedActivity, String reason);
 
     /**
      * Stop the activity.
-     * @param r Target activity record.
+     * @param token Target activity token.
      * @param configChanges Activity configuration changes.
      * @param pendingActions Pending actions to be used on this or later stages of activity
      *                       transaction.
@@ -130,40 +127,38 @@
      *                          request for a transaction.
      * @param reason Reason for performing this operation.
      */
-    public abstract void handleStopActivity(@NonNull ActivityClientRecord r, int configChanges,
+    public abstract void handleStopActivity(IBinder token, int configChanges,
             PendingTransactionActions pendingActions, boolean finalStateRequest, String reason);
 
     /** Report that activity was stopped to server. */
     public abstract void reportStop(PendingTransactionActions pendingActions);
 
     /** Restart the activity after it was stopped. */
-    public abstract void performRestartActivity(@NonNull ActivityClientRecord r, boolean start);
+    public abstract void performRestartActivity(IBinder token, boolean start);
 
     /** Set pending activity configuration in case it will be updated by other transaction item. */
-    public abstract void updatePendingActivityConfiguration(@NonNull ActivityClientRecord r,
+    public abstract void updatePendingActivityConfiguration(IBinder activityToken,
             Configuration overrideConfig);
 
     /** Deliver activity (override) configuration change. */
-    public abstract void handleActivityConfigurationChanged(@NonNull ActivityClientRecord r,
+    public abstract void handleActivityConfigurationChanged(IBinder activityToken,
             Configuration overrideConfig, int displayId);
 
     /** Deliver result from another activity. */
-    public abstract void handleSendResult(
-            @NonNull ActivityClientRecord r, List<ResultInfo> results, String reason);
+    public abstract void handleSendResult(IBinder token, List<ResultInfo> results, String reason);
 
     /** Deliver new intent. */
-    public abstract void handleNewIntent(
-            @NonNull ActivityClientRecord r, List<ReferrerIntent> intents);
+    public abstract void handleNewIntent(IBinder token, List<ReferrerIntent> intents);
 
     /** Request that an activity enter picture-in-picture. */
-    public abstract void handlePictureInPictureRequested(@NonNull ActivityClientRecord r);
+    public abstract void handlePictureInPictureRequested(IBinder token);
 
     /** Perform activity launch. */
-    public abstract Activity handleLaunchActivity(@NonNull ActivityClientRecord r,
+    public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
             PendingTransactionActions pendingActions, Intent customIntent);
 
     /** Perform activity start. */
-    public abstract void handleStartActivity(@NonNull ActivityClientRecord r,
+    public abstract void handleStartActivity(IBinder token,
             PendingTransactionActions pendingActions);
 
     /** Get package info. */
@@ -181,7 +176,7 @@
      * Get {@link android.app.ActivityThread.ActivityClientRecord} instance that corresponds to the
      * provided token.
      */
-    public abstract ActivityClientRecord getActivityClient(IBinder token);
+    public abstract ActivityThread.ActivityClientRecord getActivityClient(IBinder token);
 
     /**
      * Prepare activity relaunch to update internal bookkeeping. This is used to track multiple
@@ -196,7 +191,7 @@
      * @return An initialized instance of {@link ActivityThread.ActivityClientRecord} to use during
      *         relaunch, or {@code null} if relaunch cancelled.
      */
-    public abstract ActivityClientRecord prepareRelaunchActivity(IBinder token,
+    public abstract ActivityThread.ActivityClientRecord prepareRelaunchActivity(IBinder token,
             List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
             int configChanges, MergedConfiguration config, boolean preserveWindow);
 
@@ -205,15 +200,14 @@
      * @param r Activity client record prepared for relaunch.
      * @param pendingActions Pending actions to be used on later stages of activity transaction.
      * */
-    public abstract void handleRelaunchActivity(@NonNull ActivityClientRecord r,
+    public abstract void handleRelaunchActivity(ActivityThread.ActivityClientRecord r,
             PendingTransactionActions pendingActions);
 
     /**
      * Report that relaunch request was handled.
-     * @param r Target activity record.
+     * @param token Target activity token.
      * @param pendingActions Pending actions initialized on earlier stages of activity transaction.
      *                       Used to check if we should report relaunch to WM.
      * */
-    public abstract void reportRelaunch(@NonNull ActivityClientRecord r,
-            PendingTransactionActions pendingActions);
+    public abstract void reportRelaunch(IBinder token, PendingTransactionActions pendingActions);
 }
diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java
index d61c5d5..7cdf85e 100644
--- a/core/java/android/app/LocalActivityManager.java
+++ b/core/java/android/app/LocalActivityManager.java
@@ -49,7 +49,6 @@
     private static final String TAG = "LocalActivityManager";
     private static final boolean localLOGV = false;
 
-    // TODO(b/127877792): try to remove this and use {@code ActivityClientRecord} instead.
     // Internal token for an Activity being managed by LocalActivityManager.
     private static class LocalActivityRecord extends Binder {
         LocalActivityRecord(String _id, Intent _intent) {
@@ -137,7 +136,7 @@
             // startActivity() has not yet been called, so nothing to do.
             return;
         }
-
+        
         if (r.curState == INITIALIZING) {
             // Get the lastNonConfigurationInstance for the activity
             HashMap<String, Object> lastNonConfigurationInstances =
@@ -178,13 +177,12 @@
                 pendingActions = null;
             }
 
-            mActivityThread.handleStartActivity(clientRecord, pendingActions);
+            mActivityThread.handleStartActivity(r, pendingActions);
             r.curState = STARTED;
             
             if (desiredState == RESUMED) {
                 if (localLOGV) Log.v(TAG, r.id + ": resuming");
-                mActivityThread.performResumeActivity(clientRecord, true,
-                        "moveToState-INITIALIZING");
+                mActivityThread.performResumeActivity(r, true, "moveToState-INITIALIZING");
                 r.curState = RESUMED;
             }
             
@@ -196,21 +194,18 @@
             // group's state catches up.
             return;
         }
-
-        final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
-
+        
         switch (r.curState) {
             case CREATED:
                 if (desiredState == STARTED) {
                     if (localLOGV) Log.v(TAG, r.id + ": restarting");
-                    mActivityThread.performRestartActivity(clientRecord, true /* start */);
+                    mActivityThread.performRestartActivity(r, true /* start */);
                     r.curState = STARTED;
                 }
                 if (desiredState == RESUMED) {
                     if (localLOGV) Log.v(TAG, r.id + ": restarting and resuming");
-                    mActivityThread.performRestartActivity(clientRecord, true /* start */);
-                    mActivityThread.performResumeActivity(clientRecord, true,
-                            "moveToState-CREATED");
+                    mActivityThread.performRestartActivity(r, true /* start */);
+                    mActivityThread.performResumeActivity(r, true, "moveToState-CREATED");
                     r.curState = RESUMED;
                 }
                 return;
@@ -219,8 +214,7 @@
                 if (desiredState == RESUMED) {
                     // Need to resume it...
                     if (localLOGV) Log.v(TAG, r.id + ": resuming");
-                    mActivityThread.performResumeActivity(clientRecord, true,
-                            "moveToState-STARTED");
+                    mActivityThread.performResumeActivity(r, true, "moveToState-STARTED");
                     r.instanceState = null;
                     r.curState = RESUMED;
                 }
@@ -358,8 +352,7 @@
                     ArrayList<ReferrerIntent> intents = new ArrayList<>(1);
                     intents.add(new ReferrerIntent(intent, mParent.getPackageName()));
                     if (localLOGV) Log.v(TAG, r.id + ": new intent");
-                    final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
-                    mActivityThread.handleNewIntent(clientRecord, intents);
+                    mActivityThread.handleNewIntent(r, intents);
                     r.intent = intent;
                     moveToState(r, mCurState);
                     if (mSingleMode) {
@@ -406,8 +399,7 @@
             performPause(r, finish);
         }
         if (localLOGV) Log.v(TAG, r.id + ": destroying");
-        final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
-        mActivityThread.performDestroyActivity(clientRecord, finish, 0 /* configChanges */,
+        mActivityThread.performDestroyActivity(r, finish, 0 /* configChanges */,
                 false /* getNonConfigInstance */, "LocalActivityManager::performDestroy");
         r.activity = null;
         r.window = null;
@@ -672,8 +664,7 @@
         for (int i=0; i<N; i++) {
             LocalActivityRecord r = mActivityArray.get(i);
             if (localLOGV) Log.v(TAG, r.id + ": destroying");
-            final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
-            mActivityThread.performDestroyActivity(clientRecord, finishing, 0 /* configChanges */,
+            mActivityThread.performDestroyActivity(r, finishing, 0 /* configChanges */,
                     false /* getNonConfigInstance */, "LocalActivityManager::dispatchDestroy");
         }
         mActivities.clear();
diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
index 8a4bee9..8b52242 100644
--- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
@@ -20,7 +20,6 @@
 import static android.view.Display.INVALID_DISPLAY;
 
 import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.content.res.Configuration;
 import android.os.IBinder;
@@ -33,24 +32,23 @@
  * Activity configuration changed callback.
  * @hide
  */
-public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
+public class ActivityConfigurationChangeItem extends ClientTransactionItem {
 
     private Configuration mConfiguration;
 
     @Override
     public void preExecute(android.app.ClientTransactionHandler client, IBinder token) {
-        final ActivityClientRecord r = getActivityClientRecord(client, token);
         // Notify the client of an upcoming change in the token configuration. This ensures that
         // batches of config change items only process the newest configuration.
-        client.updatePendingActivityConfiguration(r, mConfiguration);
+        client.updatePendingActivityConfiguration(token, mConfiguration);
     }
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         // TODO(lifecycler): detect if PIP or multi-window mode changed and report it here.
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
-        client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY);
+        client.handleActivityConfigurationChanged(token, mConfiguration, INVALID_DISPLAY);
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
@@ -95,7 +93,7 @@
         mConfiguration = in.readTypedObject(Configuration.CREATOR);
     }
 
-    public static final @NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
+    public static final @android.annotation.NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
             new Creator<ActivityConfigurationChangeItem>() {
         public ActivityConfigurationChangeItem createFromParcel(Parcel in) {
             return new ActivityConfigurationChangeItem(in);
diff --git a/core/java/android/app/servertransaction/ActivityLifecycleItem.java b/core/java/android/app/servertransaction/ActivityLifecycleItem.java
index cadb660..c9193a9 100644
--- a/core/java/android/app/servertransaction/ActivityLifecycleItem.java
+++ b/core/java/android/app/servertransaction/ActivityLifecycleItem.java
@@ -25,7 +25,7 @@
  * Request for lifecycle state that an activity should reach.
  * @hide
  */
-public abstract class ActivityLifecycleItem extends ActivityTransactionItem {
+public abstract class ActivityLifecycleItem extends ClientTransactionItem {
 
     @IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
             UNDEFINED,
diff --git a/core/java/android/app/servertransaction/ActivityRelaunchItem.java b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
index 87ea3f8..9844de7 100644
--- a/core/java/android/app/servertransaction/ActivityRelaunchItem.java
+++ b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
@@ -18,8 +18,7 @@
 
 import static android.app.ActivityThread.DEBUG_ORDER;
 
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
+import android.app.ActivityThread;
 import android.app.ClientTransactionHandler;
 import android.app.ResultInfo;
 import android.os.IBinder;
@@ -37,7 +36,7 @@
  * Activity relaunch callback.
  * @hide
  */
-public class ActivityRelaunchItem extends ActivityTransactionItem {
+public class ActivityRelaunchItem extends ClientTransactionItem {
 
     private static final String TAG = "ActivityRelaunchItem";
 
@@ -51,7 +50,7 @@
      * A record that was properly configured for relaunch. Execution will be cancelled if not
      * initialized after {@link #preExecute(ClientTransactionHandler, IBinder)}.
      */
-    private ActivityClientRecord mActivityClientRecord;
+    private ActivityThread.ActivityClientRecord mActivityClientRecord;
 
     @Override
     public void preExecute(ClientTransactionHandler client, IBinder token) {
@@ -60,7 +59,7 @@
     }
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         if (mActivityClientRecord == null) {
             if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled");
@@ -74,8 +73,7 @@
     @Override
     public void postExecute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
-        final ActivityClientRecord r = getActivityClientRecord(client, token);
-        client.reportRelaunch(r, pendingActions);
+        client.reportRelaunch(token, pendingActions);
     }
 
     // ObjectPoolItem implementation
@@ -132,16 +130,16 @@
         mPreserveWindow = in.readBoolean();
     }
 
-    public static final @NonNull Creator<ActivityRelaunchItem> CREATOR =
+    public static final @android.annotation.NonNull Creator<ActivityRelaunchItem> CREATOR =
             new Creator<ActivityRelaunchItem>() {
-        public ActivityRelaunchItem createFromParcel(Parcel in) {
-            return new ActivityRelaunchItem(in);
-        }
+                public ActivityRelaunchItem createFromParcel(Parcel in) {
+                    return new ActivityRelaunchItem(in);
+                }
 
-        public ActivityRelaunchItem[] newArray(int size) {
-            return new ActivityRelaunchItem[size];
-        }
-    };
+                public ActivityRelaunchItem[] newArray(int size) {
+                    return new ActivityRelaunchItem[size];
+                }
+            };
 
     @Override
     public boolean equals(Object o) {
diff --git a/core/java/android/app/servertransaction/ActivityResultItem.java b/core/java/android/app/servertransaction/ActivityResultItem.java
index 47096a8..4e743cac 100644
--- a/core/java/android/app/servertransaction/ActivityResultItem.java
+++ b/core/java/android/app/servertransaction/ActivityResultItem.java
@@ -18,11 +18,10 @@
 
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.app.ResultInfo;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Trace;
@@ -34,7 +33,7 @@
  * Activity result delivery callback.
  * @hide
  */
-public class ActivityResultItem extends ActivityTransactionItem {
+public class ActivityResultItem extends ClientTransactionItem {
 
     @UnsupportedAppUsage
     private List<ResultInfo> mResultInfoList;
@@ -46,10 +45,10 @@
     }*/
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
-        client.handleSendResult(r, mResultInfoList, "ACTIVITY_RESULT");
+        client.handleSendResult(token, mResultInfoList, "ACTIVITY_RESULT");
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
@@ -89,7 +88,7 @@
         mResultInfoList = in.createTypedArrayList(ResultInfo.CREATOR);
     }
 
-    public static final @NonNull Parcelable.Creator<ActivityResultItem> CREATOR =
+    public static final @android.annotation.NonNull Parcelable.Creator<ActivityResultItem> CREATOR =
             new Parcelable.Creator<ActivityResultItem>() {
         public ActivityResultItem createFromParcel(Parcel in) {
             return new ActivityResultItem(in);
diff --git a/core/java/android/app/servertransaction/ActivityTransactionItem.java b/core/java/android/app/servertransaction/ActivityTransactionItem.java
deleted file mode 100644
index f7d7e9d..0000000
--- a/core/java/android/app/servertransaction/ActivityTransactionItem.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2020 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.servertransaction;
-
-import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
-
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
-import android.app.ClientTransactionHandler;
-import android.os.IBinder;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * An activity-targeting callback message to a client that can be scheduled and executed.
- * It also provides nullity-free version of
- * {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)} for child class
- * to inherit.
- *
- * @see ClientTransaction
- * @see ClientTransactionItem
- * @see com.android.server.wm.ClientLifecycleManager
- * @hide
- */
-public abstract class ActivityTransactionItem extends ClientTransactionItem {
-    @Override
-    public final void execute(ClientTransactionHandler client, IBinder token,
-            PendingTransactionActions pendingActions) {
-        final ActivityClientRecord r = getActivityClientRecord(client, token);
-
-        execute(client, r, pendingActions);
-    }
-
-    /**
-     * Like {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)},
-     * but take non-null {@link ActivityClientRecord} as a parameter.
-     */
-    @VisibleForTesting(visibility = PACKAGE)
-    public abstract void execute(@NonNull ClientTransactionHandler client,
-            @NonNull ActivityClientRecord r, PendingTransactionActions pendingActions);
-
-    @NonNull ActivityClientRecord getActivityClientRecord(
-            @NonNull ClientTransactionHandler client, IBinder token) {
-        final ActivityClientRecord r = client.getActivityClient(token);
-        if (r == null) {
-            throw new IllegalArgumentException("Activity client record must not be null to execute "
-                    + "transaction item");
-        }
-        if (client.getActivity(token) == null) {
-            throw new IllegalArgumentException("Activity must not be null to execute "
-                    + "transaction item");
-        }
-        return r;
-    }
-}
diff --git a/core/java/android/app/servertransaction/DestroyActivityItem.java b/core/java/android/app/servertransaction/DestroyActivityItem.java
index 1611369..3ee7614 100644
--- a/core/java/android/app/servertransaction/DestroyActivityItem.java
+++ b/core/java/android/app/servertransaction/DestroyActivityItem.java
@@ -18,8 +18,6 @@
 
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -40,10 +38,10 @@
     }
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
-        client.handleDestroyActivity(r, mFinished, mConfigChanges,
+        client.handleDestroyActivity(token, mFinished, mConfigChanges,
                 false /* getNonConfigInstance */, "DestroyActivityItem");
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
@@ -94,7 +92,7 @@
         mConfigChanges = in.readInt();
     }
 
-    public static final @NonNull Creator<DestroyActivityItem> CREATOR =
+    public static final @android.annotation.NonNull Creator<DestroyActivityItem> CREATOR =
             new Creator<DestroyActivityItem>() {
         public DestroyActivityItem createFromParcel(Parcel in) {
             return new DestroyActivityItem(in);
diff --git a/core/java/android/app/servertransaction/EnterPipRequestedItem.java b/core/java/android/app/servertransaction/EnterPipRequestedItem.java
index b7e81a5..b2a1276 100644
--- a/core/java/android/app/servertransaction/EnterPipRequestedItem.java
+++ b/core/java/android/app/servertransaction/EnterPipRequestedItem.java
@@ -16,20 +16,20 @@
 
 package android.app.servertransaction;
 
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
+import android.os.IBinder;
 import android.os.Parcel;
 
 /**
  * Request an activity to enter picture-in-picture mode.
  * @hide
  */
-public final class EnterPipRequestedItem extends ActivityTransactionItem {
+public final class EnterPipRequestedItem extends ClientTransactionItem {
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
-        client.handlePictureInPictureRequested(r);
+        client.handlePictureInPictureRequested(token);
     }
 
     // ObjectPoolItem implementation
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 77457af..2e7b626 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -18,7 +18,6 @@
 
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
-import android.annotation.NonNull;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.app.ProfilerInfo;
@@ -164,7 +163,7 @@
                 in.readTypedObject(FixedRotationAdjustments.CREATOR));
     }
 
-    public static final @NonNull Creator<LaunchActivityItem> CREATOR =
+    public static final @android.annotation.NonNull Creator<LaunchActivityItem> CREATOR =
             new Creator<LaunchActivityItem>() {
         public LaunchActivityItem createFromParcel(Parcel in) {
             return new LaunchActivityItem(in);
diff --git a/core/java/android/app/servertransaction/MoveToDisplayItem.java b/core/java/android/app/servertransaction/MoveToDisplayItem.java
index 32de53f..9a457a3 100644
--- a/core/java/android/app/servertransaction/MoveToDisplayItem.java
+++ b/core/java/android/app/servertransaction/MoveToDisplayItem.java
@@ -19,7 +19,6 @@
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
 import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.content.res.Configuration;
 import android.os.IBinder;
@@ -32,24 +31,23 @@
  * Activity move to a different display message.
  * @hide
  */
-public class MoveToDisplayItem extends ActivityTransactionItem {
+public class MoveToDisplayItem extends ClientTransactionItem {
 
     private int mTargetDisplayId;
     private Configuration mConfiguration;
 
     @Override
     public void preExecute(ClientTransactionHandler client, IBinder token) {
-        final ActivityClientRecord r = getActivityClientRecord(client, token);
         // Notify the client of an upcoming change in the token configuration. This ensures that
         // batches of config change items only process the newest configuration.
-        client.updatePendingActivityConfiguration(r, mConfiguration);
+        client.updatePendingActivityConfiguration(token, mConfiguration);
     }
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityMovedToDisplay");
-        client.handleActivityConfigurationChanged(r, mConfiguration, mTargetDisplayId);
+        client.handleActivityConfigurationChanged(token, mConfiguration, mTargetDisplayId);
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
@@ -98,8 +96,7 @@
         mConfiguration = in.readTypedObject(Configuration.CREATOR);
     }
 
-    public static final @NonNull Creator<MoveToDisplayItem> CREATOR =
-            new Creator<MoveToDisplayItem>() {
+    public static final @android.annotation.NonNull Creator<MoveToDisplayItem> CREATOR = new Creator<MoveToDisplayItem>() {
         public MoveToDisplayItem createFromParcel(Parcel in) {
             return new MoveToDisplayItem(in);
         }
diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java
index b4e2a7b..6a4996d 100644
--- a/core/java/android/app/servertransaction/NewIntentItem.java
+++ b/core/java/android/app/servertransaction/NewIntentItem.java
@@ -19,10 +19,9 @@
 import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
 import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
 
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Trace;
@@ -36,7 +35,7 @@
  * New intent message.
  * @hide
  */
-public class NewIntentItem extends ActivityTransactionItem {
+public class NewIntentItem extends ClientTransactionItem {
 
     @UnsupportedAppUsage
     private List<ReferrerIntent> mIntents;
@@ -48,10 +47,10 @@
     }
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
-        client.handleNewIntent(r, mIntents);
+        client.handleNewIntent(token, mIntents);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
@@ -95,7 +94,7 @@
         mIntents = in.createTypedArrayList(ReferrerIntent.CREATOR);
     }
 
-    public static final @NonNull Parcelable.Creator<NewIntentItem> CREATOR =
+    public static final @android.annotation.NonNull Parcelable.Creator<NewIntentItem> CREATOR =
             new Parcelable.Creator<NewIntentItem>() {
         public NewIntentItem createFromParcel(Parcel in) {
             return new NewIntentItem(in);
diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java
index cb154e9..f65c843 100644
--- a/core/java/android/app/servertransaction/PauseActivityItem.java
+++ b/core/java/android/app/servertransaction/PauseActivityItem.java
@@ -18,9 +18,8 @@
 
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
-import android.annotation.NonNull;
+import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -41,10 +40,10 @@
     private boolean mDontReport;
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
-        client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, pendingActions,
+        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
                 "PAUSE_ACTIVITY_ITEM");
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
@@ -131,7 +130,7 @@
         mDontReport = in.readBoolean();
     }
 
-    public static final @NonNull Creator<PauseActivityItem> CREATOR =
+    public static final @android.annotation.NonNull Creator<PauseActivityItem> CREATOR =
             new Creator<PauseActivityItem>() {
         public PauseActivityItem createFromParcel(Parcel in) {
             return new PauseActivityItem(in);
diff --git a/core/java/android/app/servertransaction/ResumeActivityItem.java b/core/java/android/app/servertransaction/ResumeActivityItem.java
index d2a156c..905076b 100644
--- a/core/java/android/app/servertransaction/ResumeActivityItem.java
+++ b/core/java/android/app/servertransaction/ResumeActivityItem.java
@@ -18,10 +18,8 @@
 
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
-import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -48,10 +46,10 @@
     }
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
-        client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
+        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                 "RESUME_ACTIVITY");
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
@@ -130,7 +128,7 @@
         mIsForward = in.readBoolean();
     }
 
-    public static final @NonNull Creator<ResumeActivityItem> CREATOR =
+    public static final @android.annotation.NonNull Creator<ResumeActivityItem> CREATOR =
             new Creator<ResumeActivityItem>() {
         public ResumeActivityItem createFromParcel(Parcel in) {
             return new ResumeActivityItem(in);
diff --git a/core/java/android/app/servertransaction/StartActivityItem.java b/core/java/android/app/servertransaction/StartActivityItem.java
index ae0bd24..4fbe02b 100644
--- a/core/java/android/app/servertransaction/StartActivityItem.java
+++ b/core/java/android/app/servertransaction/StartActivityItem.java
@@ -18,9 +18,8 @@
 
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Trace;
 
@@ -33,10 +32,10 @@
     private static final String TAG = "StartActivityItem";
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "startActivityItem");
-        client.handleStartActivity(r, pendingActions);
+        client.handleStartActivity(token, pendingActions);
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
@@ -80,7 +79,7 @@
         // Empty
     }
 
-    public static final @NonNull Creator<StartActivityItem> CREATOR =
+    public static final @android.annotation.NonNull Creator<StartActivityItem> CREATOR =
             new Creator<StartActivityItem>() {
                 public StartActivityItem createFromParcel(Parcel in) {
                     return new StartActivityItem(in);
diff --git a/core/java/android/app/servertransaction/StopActivityItem.java b/core/java/android/app/servertransaction/StopActivityItem.java
index 7708104..8668bd4 100644
--- a/core/java/android/app/servertransaction/StopActivityItem.java
+++ b/core/java/android/app/servertransaction/StopActivityItem.java
@@ -18,8 +18,6 @@
 
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -36,10 +34,10 @@
     private int mConfigChanges;
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
-        client.handleStopActivity(r, mConfigChanges, pendingActions,
+        client.handleStopActivity(token, mConfigChanges, pendingActions,
                 true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
@@ -95,7 +93,7 @@
         mConfigChanges = in.readInt();
     }
 
-    public static final @NonNull Creator<StopActivityItem> CREATOR =
+    public static final @android.annotation.NonNull Creator<StopActivityItem> CREATOR =
             new Creator<StopActivityItem>() {
         public StopActivityItem createFromParcel(Parcel in) {
             return new StopActivityItem(in);
diff --git a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
index 345c1dd..c7e4c36 100644
--- a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
+++ b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
@@ -17,9 +17,7 @@
 
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
-import android.annotation.NonNull;
 import android.app.ActivityTaskManager;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -30,15 +28,15 @@
  * Top resumed activity changed callback.
  * @hide
  */
-public class TopResumedActivityChangeItem extends ActivityTransactionItem {
+public class TopResumedActivityChangeItem extends ClientTransactionItem {
 
     private boolean mOnTop;
 
     @Override
-    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+    public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "topResumedActivityChangeItem");
-        client.handleTopResumedActivityChanged(r, mOnTop, "topResumedActivityChangeItem");
+        client.handleTopResumedActivityChanged(token, mOnTop, "topResumedActivityChangeItem");
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
@@ -99,16 +97,16 @@
         mOnTop = in.readBoolean();
     }
 
-    public static final @NonNull Creator<TopResumedActivityChangeItem> CREATOR =
+    public static final @android.annotation.NonNull Creator<TopResumedActivityChangeItem> CREATOR =
             new Creator<TopResumedActivityChangeItem>() {
-        public TopResumedActivityChangeItem createFromParcel(Parcel in) {
-            return new TopResumedActivityChangeItem(in);
-        }
+                public TopResumedActivityChangeItem createFromParcel(Parcel in) {
+                    return new TopResumedActivityChangeItem(in);
+                }
 
-        public TopResumedActivityChangeItem[] newArray(int size) {
-            return new TopResumedActivityChangeItem[size];
-        }
-    };
+                public TopResumedActivityChangeItem[] newArray(int size) {
+                    return new TopResumedActivityChangeItem[size];
+                }
+            };
 
     @Override
     public boolean equals(Object o) {
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 3dcf2cb..17fcda5 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -218,29 +218,29 @@
                             null /* customIntent */);
                     break;
                 case ON_START:
-                    mTransactionHandler.handleStartActivity(r, mPendingActions);
+                    mTransactionHandler.handleStartActivity(r.token, mPendingActions);
                     break;
                 case ON_RESUME:
-                    mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
+                    mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                             r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                     break;
                 case ON_PAUSE:
-                    mTransactionHandler.handlePauseActivity(r, false /* finished */,
+                    mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                             false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                             "LIFECYCLER_PAUSE_ACTIVITY");
                     break;
                 case ON_STOP:
-                    mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
+                    mTransactionHandler.handleStopActivity(r.token, 0 /* configChanges */,
                             mPendingActions, false /* finalStateRequest */,
                             "LIFECYCLER_STOP_ACTIVITY");
                     break;
                 case ON_DESTROY:
-                    mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
+                    mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                             0 /* configChanges */, false /* getNonConfigInstance */,
                             "performLifecycleSequence. cycling to:" + path.get(size - 1));
                     break;
                 case ON_RESTART:
-                    mTransactionHandler.performRestartActivity(r, false /* start */);
+                    mTransactionHandler.performRestartActivity(r.token, false /* start */);
                     break;
                 default:
                     throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 896a534..000e870 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -25,14 +25,14 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
 
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityThread;
-import android.app.ActivityThread.ActivityClientRecord;
 import android.app.IApplicationThread;
 import android.app.PictureInPictureParams;
 import android.app.ResourcesManager;
@@ -114,12 +114,11 @@
         final ActivityThread activityThread = activity.getActivityThread();
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             activityThread.executeTransaction(newResumeTransaction(activity));
-            final ActivityClientRecord r = getActivityClientRecord(activity);
-            assertFalse(activityThread.performResumeActivity(r, true /* finalStateRequest */,
-                    "test"));
+            assertNull(activityThread.performResumeActivity(activity.getActivityToken(),
+                    true /* finalStateRequest */, "test"));
 
-            assertFalse(activityThread.performResumeActivity(r, false /* finalStateRequest */,
-                    "test"));
+            assertNull(activityThread.performResumeActivity(activity.getActivityToken(),
+                    false /* finalStateRequest */, "test"));
         });
     }
 
@@ -245,18 +244,20 @@
             newerConfig.orientation = orientation == ORIENTATION_LANDSCAPE
                     ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
             newerConfig.seq = seq + 2;
-            final ActivityClientRecord r = getActivityClientRecord(activity);
-            activityThread.updatePendingActivityConfiguration(r, newerConfig);
+            activityThread.updatePendingActivityConfiguration(activity.getActivityToken(),
+                    newerConfig);
 
             final Configuration olderConfig = new Configuration();
             olderConfig.orientation = orientation;
             olderConfig.seq = seq + 1;
 
-            activityThread.handleActivityConfigurationChanged(r, olderConfig, INVALID_DISPLAY);
+            activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
+                    olderConfig, INVALID_DISPLAY);
             assertEquals(numOfConfig, activity.mNumOfConfigChanges);
             assertEquals(olderConfig.orientation, activity.mConfig.orientation);
 
-            activityThread.handleActivityConfigurationChanged(r, newerConfig, INVALID_DISPLAY);
+            activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
+                    newerConfig, INVALID_DISPLAY);
             assertEquals(numOfConfig + 1, activity.mNumOfConfigChanges);
             assertEquals(newerConfig.orientation, activity.mConfig.orientation);
         });
@@ -273,7 +274,7 @@
             config.seq = BASE_SEQ;
             config.orientation = ORIENTATION_PORTRAIT;
 
-            activityThread.handleActivityConfigurationChanged(getActivityClientRecord(activity),
+            activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
                     config, INVALID_DISPLAY);
         });
 
@@ -334,8 +335,8 @@
             config.seq = BASE_SEQ;
             config.orientation = ORIENTATION_PORTRAIT;
 
-            final ActivityClientRecord r = getActivityClientRecord(activity);
-            activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
+            activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
+                    config, INVALID_DISPLAY);
         });
 
         final int numOfConfig = activity.mNumOfConfigChanges;
@@ -512,10 +513,9 @@
         startIntent.putExtra(TestActivity.PIP_REQUESTED_OVERRIDE_ENTER, true);
         final TestActivity activity = mActivityTestRule.launchActivity(startIntent);
         final ActivityThread activityThread = activity.getActivityThread();
-        final ActivityClientRecord r = getActivityClientRecord(activity);
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            activityThread.handlePictureInPictureRequested(r);
+            activityThread.handlePictureInPictureRequested(activity.getActivityToken());
         });
 
         assertTrue(activity.pipRequested());
@@ -528,10 +528,9 @@
         startIntent.putExtra(TestActivity.PIP_REQUESTED_OVERRIDE_SKIP, true);
         final TestActivity activity = mActivityTestRule.launchActivity(startIntent);
         final ActivityThread activityThread = activity.getActivityThread();
-        final ActivityClientRecord r = getActivityClientRecord(activity);
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            activityThread.handlePictureInPictureRequested(r);
+            activityThread.handlePictureInPictureRequested(activity.getActivityToken());
         });
 
         assertTrue(activity.pipRequested());
@@ -542,10 +541,9 @@
     public void testHandlePictureInPictureRequested_notOverridden() {
         final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
         final ActivityThread activityThread = activity.getActivityThread();
-        final ActivityClientRecord r = getActivityClientRecord(activity);
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            activityThread.handlePictureInPictureRequested(r);
+            activityThread.handlePictureInPictureRequested(activity.getActivityToken());
         });
 
         assertTrue(activity.pipRequested());
@@ -554,9 +552,8 @@
     }
 
     /**
-     * Calls {@link ActivityThread#handleActivityConfigurationChanged(ActivityClientRecord,
-     * Configuration, int)} to try to push activity configuration to the activity for the given
-     * sequence number.
+     * Calls {@link ActivityThread#handleActivityConfigurationChanged(IBinder, Configuration, int)}
+     * to try to push activity configuration to the activity for the given sequence number.
      * <p>
      * It uses orientation to push the configuration and it tries a different orientation if the
      * first attempt doesn't make through, to rule out the possibility that the previous
@@ -569,13 +566,13 @@
      */
     private int applyConfigurationChange(TestActivity activity, int seq) {
         final ActivityThread activityThread = activity.getActivityThread();
-        final ActivityClientRecord r = getActivityClientRecord(activity);
 
         final int numOfConfig = activity.mNumOfConfigChanges;
         Configuration config = new Configuration();
         config.orientation = ORIENTATION_PORTRAIT;
         config.seq = seq;
-        activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
+        activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config,
+                INVALID_DISPLAY);
 
         if (activity.mNumOfConfigChanges > numOfConfig) {
             return config.seq;
@@ -584,17 +581,12 @@
         config = new Configuration();
         config.orientation = ORIENTATION_LANDSCAPE;
         config.seq = seq + 1;
-        activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
+        activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config,
+                INVALID_DISPLAY);
 
         return config.seq;
     }
 
-    private static ActivityClientRecord getActivityClientRecord(Activity activity) {
-        final ActivityThread thread = activity.getActivityThread();
-        final IBinder token = activity.getActivityToken();
-        return thread.getActivityClient(token);
-    }
-
     private static ClientTransaction newRelaunchResumeTransaction(Activity activity) {
         final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null,
                 null, 0, new MergedConfiguration(), false /* preserveWindow */);
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index 6a0105c..3c32c71 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -32,12 +32,11 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.Activity;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
@@ -226,7 +225,6 @@
         when(callback2.getPostExecutionState()).thenReturn(UNDEFINED);
         ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
         IBinder token = mock(IBinder.class);
-        when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
 
         ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
                 token /* activityToken */);
@@ -238,9 +236,9 @@
         mExecutor.execute(transaction);
 
         InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, stateRequest);
-        inOrder.verify(callback1).execute(eq(mTransactionHandler), eq(token), any());
-        inOrder.verify(callback2).execute(eq(mTransactionHandler), eq(token), any());
-        inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
+        inOrder.verify(callback1, times(1)).execute(eq(mTransactionHandler), eq(token), any());
+        inOrder.verify(callback2, times(1)).execute(eq(mTransactionHandler), eq(token), any());
+        inOrder.verify(stateRequest, times(1)).execute(eq(mTransactionHandler), eq(token), any());
     }
 
     @Test
@@ -275,7 +273,7 @@
 
         // The launch transaction should not be executed because its token is in the
         // to-be-destroyed container.
-        verify(launchItem, never()).execute(any(), any(), any());
+        verify(launchItem, times(0)).execute(any(), any(), any());
 
         // After the destroy transaction has been executed, the token should be removed.
         mExecutor.execute(destroyTransaction);
@@ -284,8 +282,6 @@
 
     @Test
     public void testActivityResultRequiredStateResolution() {
-        when(mTransactionHandler.getActivity(any())).thenReturn(mock(Activity.class));
-
         PostExecItem postExecItem = new PostExecItem(ON_RESUME);
 
         IBinder token = mock(IBinder.class);
@@ -296,12 +292,12 @@
         // Verify resolution that should get to onPause
         mClientRecord.setState(ON_RESUME);
         mExecutor.executeCallbacks(transaction);
-        verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_PAUSE), eq(transaction));
+        verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_PAUSE), eq(transaction));
 
         // Verify resolution that should get to onStart
         mClientRecord.setState(ON_STOP);
         mExecutor.executeCallbacks(transaction);
-        verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_START), eq(transaction));
+        verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_START), eq(transaction));
     }
 
     @Test
@@ -437,38 +433,6 @@
                 mExecutorHelper.getClosestPreExecutionState(mClientRecord, ON_RESUME));
     }
 
-    @Test(expected = IllegalArgumentException.class)
-    public void testActivityItemNullRecordThrowsException() {
-        final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
-        when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
-        final IBinder token = mock(IBinder.class);
-        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
-                token /* activityToken */);
-        transaction.addCallback(activityItem);
-        when(mTransactionHandler.getActivityClient(token)).thenReturn(null);
-
-        mExecutor.executeCallbacks(transaction);
-    }
-
-    @Test
-    public void testActivityItemExecute() {
-        final IBinder token = mock(IBinder.class);
-        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
-                token /* activityToken */);
-        final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
-        when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
-        transaction.addCallback(activityItem);
-        final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
-        transaction.setLifecycleStateRequest(stateRequest);
-        when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
-
-        mExecutor.execute(transaction);
-
-        final InOrder inOrder = inOrder(activityItem, stateRequest);
-        inOrder.verify(activityItem).execute(eq(mTransactionHandler), eq(mClientRecord), any());
-        inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
-    }
-
     private static int[] shuffledArray(int[] inputArray) {
         final List<Integer> list = Arrays.stream(inputArray).boxed().collect(Collectors.toList());
         Collections.shuffle(list);
@@ -525,13 +489,13 @@
 
         public static final Parcelable.Creator<StubItem> CREATOR =
                 new Parcelable.Creator<StubItem>() {
-            public StubItem createFromParcel(Parcel in) {
-                return new StubItem(in);
-            }
+                    public StubItem createFromParcel(Parcel in) {
+                        return new StubItem(in);
+                    }
 
-            public StubItem[] newArray(int size) {
-                return new StubItem[size];
-            }
-        };
+                    public StubItem[] newArray(int size) {
+                        return new StubItem[size];
+                    }
+                };
     }
 }
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 3f2d0f1..1cdc75a 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -176,27 +176,27 @@
         }
 
         private void startActivity(ActivityClientRecord r) {
-            mThread.handleStartActivity(r, null /* pendingActions */);
+            mThread.handleStartActivity(r.token, null /* pendingActions */);
         }
 
         private void resumeActivity(ActivityClientRecord r) {
-            mThread.handleResumeActivity(r, true /* finalStateRequest */,
+            mThread.handleResumeActivity(r.token, true /* finalStateRequest */,
                     true /* isForward */, "test");
         }
 
         private void pauseActivity(ActivityClientRecord r) {
-            mThread.handlePauseActivity(r, false /* finished */,
+            mThread.handlePauseActivity(r.token, false /* finished */,
                     false /* userLeaving */, 0 /* configChanges */, null /* pendingActions */,
                     "test");
         }
 
         private void stopActivity(ActivityClientRecord r) {
-            mThread.handleStopActivity(r, 0 /* configChanges */,
+            mThread.handleStopActivity(r.token, 0 /* configChanges */,
                     new PendingTransactionActions(), false /* finalStateRequest */, "test");
         }
 
         private void destroyActivity(ActivityClientRecord r) {
-            mThread.handleDestroyActivity(r, true /* finishing */, 0 /* configChanges */,
+            mThread.handleDestroyActivity(r.token, true /* finishing */, 0 /* configChanges */,
                     false /* getNonConfigInstance */, "test");
         }
 
diff --git a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
index 46396e3..4b3534b 100644
--- a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
@@ -32,6 +32,7 @@
         android:gravity="center">
         <ImageView
             android:id="@+id/screenshot_action_chip_icon"
+            android:tint="@*android:color/accent_device_default"
             android:layout_width="@dimen/screenshot_action_chip_icon_size"
             android:layout_height="@dimen/screenshot_action_chip_icon_size"
             android:layout_marginStart="@dimen/screenshot_action_chip_padding_start"
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
index b5209bb..a488702 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
@@ -65,10 +65,10 @@
     }
 
     void setIcon(Icon icon, boolean tint) {
-        if (tint) {
-            icon.setTint(mIconColor);
-        }
         mIcon.setImageIcon(icon);
+        if (!tint) {
+            mIcon.setImageTintList(null);
+        }
     }
 
     void setText(CharSequence text) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
index 118cffc..ca8f79d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
@@ -44,11 +44,11 @@
     fun addPlayingThenRemote() {
         val playerIsPlaying = mock(MediaControlPanel::class.java)
         whenever(playerIsPlaying.isPlaying).thenReturn(true)
-        val dataIsPlaying = createMediaData(LOCAL, !RESUMPTION)
+        val dataIsPlaying = createMediaData("app1", LOCAL, !RESUMPTION)
 
         val playerIsRemote = mock(MediaControlPanel::class.java)
         whenever(playerIsRemote.isPlaying).thenReturn(false)
-        val dataIsRemote = createMediaData(!LOCAL, !RESUMPTION)
+        val dataIsRemote = createMediaData("app2", !LOCAL, !RESUMPTION)
 
         MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying)
         MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote)
@@ -62,11 +62,11 @@
     fun switchPlayersPlaying() {
         val playerIsPlaying1 = mock(MediaControlPanel::class.java)
         whenever(playerIsPlaying1.isPlaying).thenReturn(true)
-        val dataIsPlaying1 = createMediaData(LOCAL, !RESUMPTION)
+        val dataIsPlaying1 = createMediaData("app1", LOCAL, !RESUMPTION)
 
         val playerIsPlaying2 = mock(MediaControlPanel::class.java)
         whenever(playerIsPlaying2.isPlaying).thenReturn(false)
-        val dataIsPlaying2 = createMediaData(LOCAL, !RESUMPTION)
+        val dataIsPlaying2 = createMediaData("app2", LOCAL, !RESUMPTION)
 
         MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1)
         MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2)
@@ -86,23 +86,23 @@
     fun fullOrderTest() {
         val playerIsPlaying = mock(MediaControlPanel::class.java)
         whenever(playerIsPlaying.isPlaying).thenReturn(true)
-        val dataIsPlaying = createMediaData(LOCAL, !RESUMPTION)
+        val dataIsPlaying = createMediaData("app1", LOCAL, !RESUMPTION)
 
         val playerIsPlayingAndRemote = mock(MediaControlPanel::class.java)
         whenever(playerIsPlayingAndRemote.isPlaying).thenReturn(true)
-        val dataIsPlayingAndRemote = createMediaData(!LOCAL, !RESUMPTION)
+        val dataIsPlayingAndRemote = createMediaData("app2", !LOCAL, !RESUMPTION)
 
         val playerIsStoppedAndLocal = mock(MediaControlPanel::class.java)
         whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false)
-        val dataIsStoppedAndLocal = createMediaData(LOCAL, !RESUMPTION)
+        val dataIsStoppedAndLocal = createMediaData("app3", LOCAL, !RESUMPTION)
 
         val playerIsStoppedAndRemote = mock(MediaControlPanel::class.java)
         whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false)
-        val dataIsStoppedAndRemote = createMediaData(!LOCAL, !RESUMPTION)
+        val dataIsStoppedAndRemote = createMediaData("app4", !LOCAL, !RESUMPTION)
 
         val playerCanResume = mock(MediaControlPanel::class.java)
         whenever(playerCanResume.isPlaying).thenReturn(false)
-        val dataCanResume = createMediaData(LOCAL, RESUMPTION)
+        val dataCanResume = createMediaData("app5", LOCAL, RESUMPTION)
 
         MediaPlayerData.addMediaPlayer("3", dataIsStoppedAndLocal, playerIsStoppedAndLocal)
         MediaPlayerData.addMediaPlayer("5", dataIsStoppedAndRemote, playerIsStoppedAndRemote)
@@ -116,7 +116,7 @@
             playerIsStoppedAndLocal, playerCanResume, playerIsStoppedAndRemote).inOrder()
     }
 
-    private fun createMediaData(isLocalSession: Boolean, resumption: Boolean) =
-        MediaData(0, false, 0, null, null, null, null, null, emptyList(), emptyList<Int>(), "",
+    private fun createMediaData(app: String, isLocalSession: Boolean, resumption: Boolean) =
+        MediaData(0, false, 0, app, null, null, null, null, emptyList(), emptyList<Int>(), "",
             null, null, null, true, null, isLocalSession, resumption, null, false)
 }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 8204b36..403f225 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -251,6 +251,7 @@
 import com.android.server.AttributeCache;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.SystemServiceManager;
 import com.android.server.UiThread;
 import com.android.server.Watchdog;