Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5af95b5 authored by Chilun Huang's avatar Chilun Huang Committed by Chilun
Browse files

Revert "Revert "Introduce ActivityTransactionItem and reduce null checks""

This reverts commit fd2be2c1.

Reason for revert: Reland the CL

This class is used for activity-targeting item to inherit,
which encapsulate null checks of activity client record.
This patch also change signature of ClientTransactionHandler#handle*
and reduces null checks.

In addition, add some null pointer checks after getActivityClient().
Also fix a typo in performStopActivityInner() and
performDestroyActivity().

Bug: 127877792
Bug: 164982975
Test: atest frameworks/base/core/tests/coretests/src/android/app/servertransaction
Test: atest ActivityThreadTest ActivityThreadClientTest
Test: atest TransactionExecutorTests#testActivityItemNullRecordThrowsException
Test: atest TransactionExecutorTests#testActivityItemExecute
Test: atest CtsAppTestCases:LocalActivityManagerTest
Change-Id: Ida612f1c8af7ecd7a04e69ade461403b8711508a
parent 48e000d7
Loading
Loading
Loading
Loading
+190 −260
Original line number Diff line number Diff line
@@ -614,7 +614,7 @@ public final class ActivityThread extends ClientTransactionHandler {
                    throw new IllegalStateException(
                            "Received config update for non-existing activity");
                }
                activity.mMainThread.handleActivityConfigurationChanged(token, overrideConfig,
                activity.mMainThread.handleActivityConfigurationChanged(this, overrideConfig,
                        newDisplayId);
            };
        }
@@ -3475,13 +3475,9 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void handleStartActivity(IBinder token, PendingTransactionActions pendingActions) {
        final ActivityClientRecord r = mActivities.get(token);
    public void handleStartActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        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.");
        }
@@ -3687,12 +3683,7 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void handleNewIntent(IBinder token, List<ReferrerIntent> intents) {
        final ActivityClientRecord r = mActivities.get(token);
        if (r == null) {
            return;
        }

    public void handleNewIntent(ActivityClientRecord r, List<ReferrerIntent> intents) {
        checkAndBlockForNetworkAccess();
        deliverNewIntents(r, intents);
    }
@@ -3881,13 +3872,7 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    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;
        }

    public void handlePictureInPictureRequested(ActivityClientRecord r) {
        final boolean receivedByApp = r.activity.onPictureInPictureRequested();
        if (!receivedByApp) {
            // Previous recommendation was for apps to enter picture-in-picture in
@@ -4417,22 +4402,21 @@ public final class ActivityThread extends ClientTransactionHandler {

    /**
     * Resume the activity.
     * @param token Target activity token.
     * @param r Target activity record.
     * @param finalStateRequest Flag indicating if this is part of final state resolution for a
     *                          transaction.
     * @param reason Reason for performing the action.
     *
     * @return The {@link ActivityClientRecord} that was resumed, {@code null} otherwise.
     * @return {@code true} that was resumed, {@code false} otherwise.
     */
    @VisibleForTesting
    public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
    public boolean performResumeActivity(ActivityClientRecord r, 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 == null || r.activity.mFinished) {
            return null;
        if (r.activity.mFinished) {
            return false;
        }
        if (r.getLifecycleState() == ON_RESUME) {
            if (!finalStateRequest) {
@@ -4446,7 +4430,7 @@ public final class ActivityThread extends ClientTransactionHandler {
                // handle two resume requests for the final state. For cases other than this
                // one, we don't expect it to happen.
            }
            return null;
            return false;
        }
        if (finalStateRequest) {
            r.hideForNow = false;
@@ -4477,7 +4461,7 @@ public final class ActivityThread extends ClientTransactionHandler {
                        + r.intent.getComponent().toShortString() + ": " + e.toString(), e);
            }
        }
        return r;
        return true;
    }

    static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
@@ -4498,20 +4482,19 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
    public void handleResumeActivity(ActivityClientRecord r, 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
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        if (r == null) {
            // We didn't actually resume the activity, so skipping any follow-up actions.
        // skip below steps for double-resume and r.mFinish = true case.
        if (!performResumeActivity(r, finalStateRequest, reason)) {
            return;
        }
        if (mActivitiesToBeDestroyed.containsKey(token)) {
        if (mActivitiesToBeDestroyed.containsKey(r.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
@@ -4629,13 +4612,8 @@ public final class ActivityThread extends ClientTransactionHandler {


    @Override
    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;
        }

    public void handleTopResumedActivityChanged(ActivityClientRecord r, boolean onTop,
            String reason) {
        if (DEBUG_ORDER) {
            Slog.d(TAG, "Received position change to top: " + onTop + " for activity: " + r);
        }
@@ -4668,10 +4646,8 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
    public void handlePauseActivity(ActivityClientRecord r, boolean finished, boolean userLeaving,
            int configChanges, PendingTransactionActions pendingActions, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }
@@ -4685,7 +4661,6 @@ public final class ActivityThread extends ClientTransactionHandler {
        }
        mSomeActivitiesChanged = true;
    }
    }

    final void performUserLeavingActivity(ActivityClientRecord r) {
        mInstrumentation.callActivityOnPictureInPictureRequested(r.activity);
@@ -4781,8 +4756,11 @@ public final class ActivityThread extends ClientTransactionHandler {
        r.setState(ON_PAUSE);
    }

    // TODO(b/127877792): Make LocalActivityManager call performStopActivityInner. We cannot remove
    // this since it's a high usage hidden API.
    /** Called from {@link LocalActivityManager}. */
    @UnsupportedAppUsage
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 127877792,
            publicAlternatives = "{@code N/A}")
    final void performStopActivity(IBinder token, boolean saveState, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        performStopActivityInner(r, null /* stopInfo */, saveState, false /* finalStateRequest */,
@@ -4823,7 +4801,6 @@ public final class ActivityThread extends ClientTransactionHandler {
    private void performStopActivityInner(ActivityClientRecord r, StopInfo info,
            boolean saveState, boolean finalStateRequest, String reason) {
        if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
        if (r != null) {
        if (r.stopped) {
            if (r.activity.mFinished) {
                // If we are finishing, we won't call onResume() in certain
@@ -4861,7 +4838,6 @@ public final class ActivityThread extends ClientTransactionHandler {

        callActivityOnStop(r, saveState, reason);
    }
    }

    /**
     * Calls {@link Activity#onStop()} and {@link Activity#onSaveInstanceState(Bundle)}, and updates
@@ -4927,9 +4903,8 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void handleStopActivity(IBinder token, int configChanges,
    public void handleStopActivity(ActivityClientRecord r, int configChanges,
            PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
        final ActivityClientRecord r = mActivities.get(token);
        r.activity.mConfigChangeFlags |= configChanges;

        final StopInfo stopInfo = new StopInfo();
@@ -4965,8 +4940,7 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void performRestartActivity(IBinder token, boolean start) {
        ActivityClientRecord r = mActivities.get(token);
    public void performRestartActivity(ActivityClientRecord r, boolean start) {
        if (r.stopped) {
            r.activity.performRestart(start, "performRestartActivity");
            if (start) {
@@ -5053,10 +5027,8 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) {
        ActivityClientRecord r = mActivities.get(token);
    public void handleSendResult(ActivityClientRecord r, List<ResultInfo> results, String reason) {
        if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
        if (r != null) {
        final boolean resumed = !r.paused;
        if (!r.activity.mFinished && r.activity.mDecor != null
                && r.hideForNow && resumed) {
@@ -5092,15 +5064,12 @@ public final class ActivityThread extends ClientTransactionHandler {
            r.activity.performResume(false, reason);
        }
    }
    }

    /** Core implementation of activity destroy call. */
    ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
    void performDestroyActivity(ActivityClientRecord r, 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) {
@@ -5114,14 +5083,11 @@ public final class ActivityThread extends ClientTransactionHandler {
        }
        if (getNonConfigInstance) {
            try {
                    r.lastNonConfigurationInstances
                            = r.activity.retainNonConfigurationInstances();
                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);
                    throw new RuntimeException("Unable to retain activity "
                            + r.intent.getComponent().toShortString() + ": " + e.toString(), e);
                }
            }
        }
@@ -5129,9 +5095,8 @@ public final class ActivityThread extends ClientTransactionHandler {
            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()");
                throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                        + " did not call through to super.onDestroy()");
            }
            if (r.window != null) {
                r.window.closeAllPanels();
@@ -5140,23 +5105,20 @@ public final class ActivityThread extends ClientTransactionHandler {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                            "Unable to destroy activity " + safeToComponentShortString(r.intent)
                            + ": " + e.toString(), e);
                throw new RuntimeException("Unable to destroy activity "
                        + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
            }
        }
        r.setState(ON_DESTROY);
        mLastReportedWindowingMode.remove(r.activity.getActivityToken());
        }
        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(token);
            mActivities.remove(r.token);
        }
        StrictMode.decrementExpectedActivityCount(activityClass);
        return r;
    }

    private static String safeToComponentShortString(Intent intent) {
@@ -5170,11 +5132,9 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
    public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
            boolean getNonConfigInstance, String reason) {
        ActivityClientRecord r = performDestroyActivity(token, finishing,
                configChanges, getNonConfigInstance, reason);
        if (r != null) {
        performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
        cleanUpPendingRemoveWindows(r, finishing);
        WindowManager wm = r.activity.getWindowManager();
        View v = r.activity.mDecor;
@@ -5185,8 +5145,7 @@ public final class ActivityThread extends ClientTransactionHandler {
            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.
                    // 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,
@@ -5205,7 +5164,7 @@ public final class ActivityThread extends ClientTransactionHandler {
                // 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,
                WindowManagerGlobal.getInstance().closeAllExceptView(r.token, v,
                        r.activity.getClass().getName(), "Activity");
            }
            r.activity.mDecor = null;
@@ -5217,7 +5176,7 @@ public final class ActivityThread extends ClientTransactionHandler {
            // 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,
            WindowManagerGlobal.getInstance().closeAll(r.token,
                    r.activity.getClass().getName(), "Activity");
        }

@@ -5227,13 +5186,11 @@ public final class ActivityThread extends ClientTransactionHandler {
        // cleanly.
        Context c = r.activity.getBaseContext();
        if (c instanceof ContextImpl) {
                ((ContextImpl) c).scheduleFinalCleanup(
                        r.activity.getClass().getName(), "Activity");
            }
            ((ContextImpl) c).scheduleFinalCleanup(r.activity.getClass().getName(), "Activity");
        }
        if (finishing) {
            try {
                ActivityTaskManager.getService().activityDestroyed(token);
                ActivityTaskManager.getService().activityDestroyed(r.token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
@@ -5455,7 +5412,7 @@ public final class ActivityThread extends ClientTransactionHandler {
            callActivityOnStop(r, true /* saveState */, reason);
        }

        handleDestroyActivity(r.token, false, configChanges, true, reason);
        handleDestroyActivity(r, false, configChanges, true, reason);

        r.activity = null;
        r.window = null;
@@ -5483,12 +5440,10 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) {
    public void reportRelaunch(ActivityClientRecord r, PendingTransactionActions pendingActions) {
        try {
            ActivityTaskManager.getService().activityRelaunched(token);
            final ActivityClientRecord r = mActivities.get(token);
            if (pendingActions.shouldReportRelaunchToWindowManager() && r != null
                    && r.window != null) {
            ActivityTaskManager.getService().activityRelaunched(r.token);
            if (pendingActions.shouldReportRelaunchToWindowManager() && r.window != null) {
                r.window.reportActivityRelaunched();
            }
        } catch (RemoteException e) {
@@ -5647,13 +5602,7 @@ public final class ActivityThread extends ClientTransactionHandler {
     */
    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?");
        }

        // WindowConfiguration differences aren't considered as public, check it separately.
        // multi-window / pip mode changes, if any, should be sent before the configuration
@@ -5952,20 +5901,8 @@ public final class ActivityThread extends ClientTransactionHandler {
     * processing any configurations older than {@code overrideConfig}.
     */
    @Override
    public void updatePendingActivityConfiguration(IBinder activityToken,
    public void updatePendingActivityConfiguration(ActivityClientRecord r,
            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)) {
@@ -5985,21 +5922,14 @@ public final class ActivityThread extends ClientTransactionHandler {
     * if {@link #updatePendingActivityConfiguration(IBinder, Configuration)} has been called with
     * a newer config than {@code overrideConfig}.
     *
     * @param activityToken Target activity token.
     * @param r Target activity record.
     * @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(IBinder activityToken,
    public void handleActivityConfigurationChanged(ActivityClientRecord r,
            @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) {
+30 −24

File changed.

Preview size limit exceeded, changes collapsed.

+31 −12
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ public class LocalActivityManager {
    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) {
@@ -177,12 +178,13 @@ public class LocalActivityManager {
                pendingActions = null;
            }

            mActivityThread.handleStartActivity(r, pendingActions);
            mActivityThread.handleStartActivity(clientRecord, pendingActions);
            r.curState = STARTED;
            
            if (desiredState == RESUMED) {
                if (localLOGV) Log.v(TAG, r.id + ": resuming");
                mActivityThread.performResumeActivity(r, true, "moveToState-INITIALIZING");
                mActivityThread.performResumeActivity(clientRecord, true,
                        "moveToState-INITIALIZING");
                r.curState = RESUMED;
            }
            
@@ -195,17 +197,24 @@ public class LocalActivityManager {
            return;
        }

        final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
        if (clientRecord == null) {
            Log.w(TAG, "Can't get activity record for " + r.id);
            return;
        }

        switch (r.curState) {
            case CREATED:
                if (desiredState == STARTED) {
                    if (localLOGV) Log.v(TAG, r.id + ": restarting");
                    mActivityThread.performRestartActivity(r, true /* start */);
                    mActivityThread.performRestartActivity(clientRecord, true /* start */);
                    r.curState = STARTED;
                }
                if (desiredState == RESUMED) {
                    if (localLOGV) Log.v(TAG, r.id + ": restarting and resuming");
                    mActivityThread.performRestartActivity(r, true /* start */);
                    mActivityThread.performResumeActivity(r, true, "moveToState-CREATED");
                    mActivityThread.performRestartActivity(clientRecord, true /* start */);
                    mActivityThread.performResumeActivity(clientRecord, true,
                            "moveToState-CREATED");
                    r.curState = RESUMED;
                }
                return;
@@ -214,7 +223,8 @@ public class LocalActivityManager {
                if (desiredState == RESUMED) {
                    // Need to resume it...
                    if (localLOGV) Log.v(TAG, r.id + ": resuming");
                    mActivityThread.performResumeActivity(r, true, "moveToState-STARTED");
                    mActivityThread.performResumeActivity(clientRecord, true,
                            "moveToState-STARTED");
                    r.instanceState = null;
                    r.curState = RESUMED;
                }
@@ -352,7 +362,8 @@ public class LocalActivityManager {
                    ArrayList<ReferrerIntent> intents = new ArrayList<>(1);
                    intents.add(new ReferrerIntent(intent, mParent.getPackageName()));
                    if (localLOGV) Log.v(TAG, r.id + ": new intent");
                    mActivityThread.handleNewIntent(r, intents);
                    final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
                    mActivityThread.handleNewIntent(clientRecord, intents);
                    r.intent = intent;
                    moveToState(r, mCurState);
                    if (mSingleMode) {
@@ -399,8 +410,11 @@ public class LocalActivityManager {
            performPause(r, finish);
        }
        if (localLOGV) Log.v(TAG, r.id + ": destroying");
        mActivityThread.performDestroyActivity(r, finish, 0 /* configChanges */,
        final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
        if (clientRecord != null) {
            mActivityThread.performDestroyActivity(clientRecord, finish, 0 /* configChanges */,
                    false /* getNonConfigInstance */, "LocalActivityManager::performDestroy");
        }
        r.activity = null;
        r.window = null;
        if (finish) {
@@ -664,7 +678,12 @@ public class LocalActivityManager {
        for (int i=0; i<N; i++) {
            LocalActivityRecord r = mActivityArray.get(i);
            if (localLOGV) Log.v(TAG, r.id + ": destroying");
            mActivityThread.performDestroyActivity(r, finishing, 0 /* configChanges */,
            final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
            if (clientRecord == null) {
                if (localLOGV) Log.v(TAG, r.id + ": no corresponding record");
                continue;
            }
            mActivityThread.performDestroyActivity(clientRecord, finishing, 0 /* configChanges */,
                    false /* getNonConfigInstance */, "LocalActivityManager::dispatchDestroy");
        }
        mActivities.clear();
+7 −5
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
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;
@@ -32,23 +33,24 @@ import java.util.Objects;
 * Activity configuration changed callback.
 * @hide
 */
public class ActivityConfigurationChangeItem extends ClientTransactionItem {
public class ActivityConfigurationChangeItem extends ActivityTransactionItem {

    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(token, mConfiguration);
        client.updatePendingActivityConfiguration(r, mConfiguration);
    }

    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            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(token, mConfiguration, INVALID_DISPLAY);
        client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

@@ -93,7 +95,7 @@ public class ActivityConfigurationChangeItem extends ClientTransactionItem {
        mConfiguration = in.readTypedObject(Configuration.CREATOR);
    }

    public static final @android.annotation.NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
    public static final @NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
            new Creator<ActivityConfigurationChangeItem>() {
        public ActivityConfigurationChangeItem createFromParcel(Parcel in) {
            return new ActivityConfigurationChangeItem(in);
+1 −1

File changed.

Preview size limit exceeded, changes collapsed.

Loading