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

Commit 0cf87344 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor for pending dispatched ClientTransaction cleanup" into main

parents 4a999fae 09f22a63
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -1113,11 +1113,11 @@ class ActivityClientController extends IActivityClientController.Stub {
                    false /* fromClient */);
        }

        try {
        final EnterPipRequestedItem item = new EnterPipRequestedItem(r.token);
            mService.getLifecycleManager().scheduleTransactionItem(r.app.getThread(), item);
            return true;
        } catch (Exception e) {
        try {
            return mService.getLifecycleManager().scheduleTransactionItem(r.app.getThread(), item);
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            Slog.w(TAG, "Failed to send enter pip requested item: "
                    + r.intent.getComponent(), e);
            return false;
@@ -1129,10 +1129,11 @@ class ActivityClientController extends IActivityClientController.Stub {
     */
    void onPictureInPictureUiStateChanged(@NonNull ActivityRecord r,
            PictureInPictureUiState pipState) {
        try {
        final PipStateTransactionItem item = new PipStateTransactionItem(r.token, pipState);
        try {
            mService.getLifecycleManager().scheduleTransactionItem(r.app.getThread(), item);
        } catch (Exception e) {
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            Slog.w(TAG, "Failed to send pip state transaction item: "
                    + r.intent.getComponent(), e);
        }
+127 −87
Original line number Diff line number Diff line
@@ -253,6 +253,7 @@ import android.annotation.Size;
import android.app.Activity;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityOptions;
import android.app.IApplicationThread;
import android.app.IScreenCaptureObserver;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
@@ -1351,15 +1352,16 @@ final class ActivityRecord extends WindowToken {
                    this, displayId);
            return;
        }
        try {
        ProtoLog.v(WM_DEBUG_SWITCH, "Reporting activity moved to "
                        + "display, activityRecord=%s, displayId=%d, config=%s", this, displayId,
                config);

        final MoveToDisplayItem item =
                new MoveToDisplayItem(token, displayId, config, activityWindowInfo);
        try {
            mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            // If process died, whatever.
        }
    }
@@ -1371,14 +1373,15 @@ final class ActivityRecord extends WindowToken {
                    + "update - client not running, activityRecord=%s", this);
            return;
        }
        try {
        ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending new config to %s, "
                + "config: %s", this, config);

        final ActivityConfigurationChangeItem item =
                new ActivityConfigurationChangeItem(token, config, activityWindowInfo);
        try {
            mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            // If process died, whatever.
        }
    }
@@ -1393,19 +1396,18 @@ final class ActivityRecord extends WindowToken {
        if (onTop) {
            app.addToPendingTop();
        }
        try {
        ProtoLog.v(WM_DEBUG_STATES, "Sending position change to %s, onTop: %b",
                this, onTop);

            final TopResumedActivityChangeItem item =
                    new TopResumedActivityChangeItem(token, onTop);
            mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
        final TopResumedActivityChangeItem item = new TopResumedActivityChangeItem(token, onTop);
        try {
            return mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            // If process died, whatever.
            Slog.w(TAG, "Failed to send top-resumed=" + onTop + " to " + this, e);
            return false;
        }
        return true;
    }

    void updateMultiWindowMode() {
@@ -2604,14 +2606,21 @@ final class ActivityRecord extends WindowToken {
            removeStartingWindow();
            return;
        }
        try {
        mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT;
        final TransferSplashScreenViewStateItem item =
                new TransferSplashScreenViewStateItem(token, parcelable, windowAnimationLeash);
            mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
            scheduleTransferSplashScreenTimeout();
        } catch (Exception e) {
        boolean isSuccessful;
        try {
            isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
                    app.getThread(), item);
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            Slog.w(TAG, "onCopySplashScreenComplete fail: " + this);
            isSuccessful = false;
        }
        if (isSuccessful) {
            scheduleTransferSplashScreenTimeout();
        } else {
            mStartingWindow.cancelAnimation();
            parcelable.clearIfNeeded();
            mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_FINISH;
@@ -3957,11 +3966,23 @@ final class ActivityRecord extends WindowToken {

            boolean skipDestroy = false;

            try {
            if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + this);
            boolean isSuccessful;
            final IApplicationThread client = app.getThread();
            if (client == null) {
                Slog.w(TAG_WM, "Failed to schedule DestroyActivityItem because client is inactive");
                isSuccessful = false;
            } else {
                final DestroyActivityItem item = new DestroyActivityItem(token, finishing);
                mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
            } catch (Exception e) {
                try {
                    isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
                            client, item);
                } catch (RemoteException e) {
                    // TODO(b/323801078): remove Exception when cleanup
                    isSuccessful = false;
                }
            }
            if (!isSuccessful) {
                // We can just ignore exceptions here...  if the process has crashed, our death
                // notification will clean things up.
                if (finishing) {
@@ -4884,13 +4905,17 @@ final class ActivityRecord extends WindowToken {
        }

        if (isState(RESUMED) && attachedToProcess()) {
            try {
            final ArrayList<ResultInfo> list = new ArrayList<>();
            list.add(new ResultInfo(resultWho, requestCode, resultCode, data, callerToken));
            final ActivityResultItem item = new ActivityResultItem(token, list);
                mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
            try {
                final boolean isSuccessful = mAtmService.getLifecycleManager()
                        .scheduleTransactionItem(app.getThread(), item);
                if (isSuccessful) {
                    return;
            } catch (Exception e) {
                }
            } catch (RemoteException e) {
                // TODO(b/323801078): remove Exception when cleanup
                Slog.w(TAG, "Exception thrown sending result to " + this, e);
            }
        }
@@ -4917,6 +4942,7 @@ final class ActivityRecord extends WindowToken {
                            app.getThread(), activityResultItem);
                }
            } catch (RemoteException e) {
                // TODO(b/323801078): remove Exception when cleanup
                Slog.w(TAG, "Exception thrown sending result to " + this, e);
            }
            // We return here to ensure that result for media projection setup is not stored as a
@@ -4989,7 +5015,6 @@ final class ActivityRecord extends WindowToken {
        }
        final ReferrerIntent rintent = new ReferrerIntent(intent, getFilteredReferrer(referrer),
                callerToken);
        boolean unsent = true;
        final boolean isTopActivityWhileSleeping = isSleeping() && isTopRunningActivity();

        // We want to immediately deliver the intent to the activity if:
@@ -4998,26 +5023,27 @@ final class ActivityRecord extends WindowToken {
        // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
        if ((mState == RESUMED || mState == PAUSED || isTopActivityWhileSleeping)
                && attachedToProcess()) {
            try {
                ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
            final ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
            ar.add(rintent);
            // Making sure the client state is RESUMED after transaction completed and doing
            // so only if activity is currently RESUMED. Otherwise, client may have extra
            // life-cycle calls to RESUMED (and PAUSED later).
                final NewIntentItem item =
                        new NewIntentItem(token, ar, mState == RESUMED /* resume */);
                mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
                unsent = false;
            final NewIntentItem item = new NewIntentItem(token, ar, mState == RESUMED /* resume */);
            try {
                final boolean isSuccessful = mAtmService.getLifecycleManager()
                        .scheduleTransactionItem(app.getThread(), item);
                if (isSuccessful) {
                    return;
                }
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
            } catch (NullPointerException e) {
                // TODO(b/323801078): remove Exception when cleanup
                Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
            }
        }
        if (unsent) {

        // Didn't send.
        addNewIntentLocked(rintent);
    }
    }

    void updateOptionsLocked(ActivityOptions options) {
        if (options != null) {
@@ -6044,11 +6070,12 @@ final class ActivityRecord extends WindowToken {
            setState(PAUSING, "makeActiveIfNeeded");
            EventLogTags.writeWmPauseActivity(mUserId, System.identityHashCode(this),
                    shortComponentName, "userLeaving=false", "make-active");
            try {
            final PauseActivityItem item = new PauseActivityItem(token, finishing,
                    false /* userLeaving */, false /* dontReport */, mAutoEnteringPip);
            try {
                mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
            } catch (Exception e) {
            } catch (RemoteException e) {
                // TODO(b/323801078): remove Exception when cleanup
                Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
            }
        } else if (shouldStartActivity()) {
@@ -6057,10 +6084,11 @@ final class ActivityRecord extends WindowToken {
            }
            setState(STARTED, "makeActiveIfNeeded");

            final StartActivityItem item = new StartActivityItem(token, takeSceneTransitionInfo());
            try {
                mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
                        new StartActivityItem(token, takeSceneTransitionInfo()));
            } catch (Exception e) {
                mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
            } catch (RemoteException e) {
                // TODO(b/323801078): remove Exception when cleanup
                Slog.w(TAG, "Exception thrown sending start: " + intent.getComponent(), e);
            }
            // The activity may be waiting for stop, but that is no longer appropriate if we are
@@ -6343,7 +6371,6 @@ final class ActivityRecord extends WindowToken {
            return;
        }
        resumeKeyDispatchingLocked();
        try {
        ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPING: %s (stop requested)", this);

        setState(STOPPING, "stopIfPossible");
@@ -6352,14 +6379,21 @@ final class ActivityRecord extends WindowToken {
        }
        EventLogTags.writeWmStopActivity(
                mUserId, System.identityHashCode(this), shortComponentName);
            mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
                    new StopActivityItem(token));

            mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT);
        } catch (Exception e) {
        final StopActivityItem item = new StopActivityItem(token);
        boolean isSuccessful;
        try {
            isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
                    app.getThread(), item);
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            // Maybe just ignore exceptions here...  if the process has crashed, our death
            // notification will clean things up.
            Slog.w(TAG, "Exception thrown during pause", e);
            isSuccessful = false;
        }
        if (isSuccessful) {
            mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT);
        } else {
            // Just in case, assume it to be stopped.
            mAppStopped = true;
            mStoppedTime = SystemClock.uptimeMillis();
@@ -8926,7 +8960,6 @@ final class ActivityRecord extends WindowToken {
                    task.mTaskId, shortComponentName, Integer.toHexString(configChangeFlags));
        }

        try {
        ProtoLog.i(WM_DEBUG_STATES, "Moving to %s Relaunching %s callers=%s" ,
                (andResume ? "RESUMED" : "PAUSED"), this, Debug.getCallers(6));
        final ClientTransactionItem callbackItem = new ActivityRelaunchItem(token,
@@ -8941,14 +8974,20 @@ final class ActivityRecord extends WindowToken {
        } else {
            lifecycleItem = new PauseActivityItem(token);
        }
            mAtmService.getLifecycleManager().scheduleTransactionItems(
        boolean isSuccessful;
        try {
            isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItems(
                    app.getThread(), callbackItem, lifecycleItem);
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            Slog.w(TAG, "Failed to relaunch " + this + ": " + e);
            isSuccessful = false;
        }
        if (isSuccessful) {
            startRelaunching();
            // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
            // request resume if this activity is currently resumed, which implies we aren't
            // sleeping.
        } catch (RemoteException e) {
            Slog.w(TAG, "Failed to relaunch " + this + ": " + e);
        }

        if (andResume) {
@@ -9028,10 +9067,11 @@ final class ActivityRecord extends WindowToken {
    private void scheduleStopForRestartProcess() {
        // The process will be killed until the activity reports stopped with saved state (see
        // {@link ActivityTaskManagerService.activityStopped}).
        final StopActivityItem item = new StopActivityItem(token);
        try {
            mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
                    new StopActivityItem(token));
            mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            Slog.w(TAG, "Exception thrown during restart " + this, e);
        }
        mTaskSupervisor.scheduleRestartTimeout(this);
+9 −4
Original line number Diff line number Diff line
@@ -88,17 +88,22 @@ class ActivityRefresher {
                new RefreshCallbackItem(activity.token, cycleThroughStop ? ON_STOP : ON_PAUSE);
        final ResumeActivityItem resumeActivityItem = new ResumeActivityItem(
                activity.token, /* isForward */ false, /* shouldSendCompatFakeFocus */ false);
        boolean isSuccessful;
        try {
            activity.mAtmService.getLifecycleManager().scheduleTransactionItems(
            isSuccessful = activity.mAtmService.getLifecycleManager().scheduleTransactionItems(
                    activity.app.getThread(), refreshCallbackItem, resumeActivityItem);
        } catch (RemoteException e) {
            isSuccessful = false;
        }
        if (isSuccessful) {
            mHandler.postDelayed(() -> {
                synchronized (mWmService.mGlobalLock) {
                    onActivityRefreshed(activity);
                }
            }, REFRESH_CALLBACK_TIMEOUT_MS);
        } catch (RemoteException e) {
            activity.mAppCompatController.getCameraOverrides()
                    .setIsRefreshRequested(false);
        } else {
            activity.mAppCompatController.getCameraOverrides().setIsRefreshRequested(false);

        }
    }

+102 −59
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.DisplayMetrics;
@@ -1751,7 +1752,6 @@ class TaskFragment extends WindowContainer<WindowContainer> {
                }
            }

            try {
            final IApplicationThread appThread = next.app.getThread();
            // Deliver all pending results.
            final ArrayList<ResultInfo> a = next.results;
@@ -1762,14 +1762,38 @@ class TaskFragment extends WindowContainer<WindowContainer> {
                        Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a);
                    }
                    final ActivityResultItem item = new ActivityResultItem(next.token, a);
                        mAtmService.getLifecycleManager().scheduleTransactionItem(appThread, item);
                    boolean isSuccessful;
                    try {
                        isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
                                appThread, item);
                    } catch (RemoteException e) {
                        // TODO(b/323801078): remove Exception when cleanup
                        isSuccessful = false;
                    }
                    if (!isSuccessful) {
                        onResumeTopActivityRemoteFailure(lastState, next, lastResumedActivity,
                                lastFocusedRootTask);
                        return true;
                    }
                }
            }

            if (next.newIntents != null) {
                final NewIntentItem item =
                        new NewIntentItem(next.token, next.newIntents, true /* resume */);
                    mAtmService.getLifecycleManager().scheduleTransactionItem(appThread, item);
                boolean isSuccessful;
                try {
                    isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
                            appThread, item);
                } catch (RemoteException e) {
                    // TODO(b/323801078): remove Exception when cleanup
                    isSuccessful = false;
                }
                if (!isSuccessful) {
                    onResumeTopActivityRemoteFailure(lastState, next, lastResumedActivity,
                            lastFocusedRootTask);
                    return true;
                }
            }

            // Well the app will no longer be stopped.
@@ -1786,32 +1810,22 @@ class TaskFragment extends WindowContainer<WindowContainer> {
            final ResumeActivityItem resumeActivityItem = new ResumeActivityItem(
                    next.token, topProcessState, dc.isNextTransitionForward(),
                    next.shouldSendCompatFakeFocus());
                mAtmService.getLifecycleManager().scheduleTransactionItem(
            boolean isSuccessful;
            try {
                isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
                        appThread, resumeActivityItem);

                ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Resumed %s", next);
            } catch (Exception e) {
                // Whoops, need to restart this activity!
                ProtoLog.v(WM_DEBUG_STATES, "Resume failed; resetting state to %s: "
                        + "%s", lastState, next);
                next.setState(lastState, "resumeTopActivityInnerLocked");

                // lastResumedActivity being non-null implies there is a lastStack present.
                if (lastResumedActivity != null) {
                    lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
                }

                Slog.i(TAG, "Restarting because process died: " + next);
                if (!next.hasBeenLaunched) {
                    next.hasBeenLaunched = true;
                } else if (SHOW_APP_STARTING_PREVIEW && lastFocusedRootTask != null
                        && lastFocusedRootTask.isTopRootTaskInDisplayArea()) {
                    next.showStartingWindow(false /* taskSwitch */);
            } catch (RemoteException e) {
                // TODO(b/323801078): remove Exception when cleanup
                isSuccessful = false;
            }
                mTaskSupervisor.startSpecificActivity(next, true, false);
            if (!isSuccessful) {
                onResumeTopActivityRemoteFailure(lastState, next, lastResumedActivity,
                        lastFocusedRootTask);
                return true;
            }

            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Resumed %s", next);

            next.completeResumeLocked();
        } else {
            // Whoops, need to restart this activity!
@@ -1830,6 +1844,29 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        return true;
    }

    /** Likely app process has been killed. Needs to restart this activity. */
    private void onResumeTopActivityRemoteFailure(@NonNull ActivityRecord.State lastState,
            @NonNull ActivityRecord next, @Nullable ActivityRecord lastResumedActivity,
            @Nullable Task lastFocusedRootTask) {
        ProtoLog.v(WM_DEBUG_STATES, "Resume failed; resetting state to %s: "
                + "%s", lastState, next);
        next.setState(lastState, "resumeTopActivityInnerLocked");

        // lastResumedActivity being non-null implies there is a lastStack present.
        if (lastResumedActivity != null) {
            lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
        }

        Slog.i(TAG, "Restarting because process died: " + next);
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else if (SHOW_APP_STARTING_PREVIEW && lastFocusedRootTask != null
                && lastFocusedRootTask.isTopRootTaskInDisplayArea()) {
            next.showStartingWindow(false /* taskSwitch */);
        }
        mTaskSupervisor.startSpecificActivity(next, true, false);
    }

    boolean shouldSleepOrShutDownActivities() {
        return shouldSleepActivities() || mAtmService.mShuttingDown;
    }
@@ -2034,17 +2071,23 @@ class TaskFragment extends WindowContainer<WindowContainer> {
    void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
            boolean pauseImmediately, boolean autoEnteringPip, String reason) {
        ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
        try {
        prev.mPauseSchedulePendingForPip = false;
        EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                prev.shortComponentName, "userLeaving=" + userLeaving, reason);

        final PauseActivityItem item = new PauseActivityItem(prev.token, prev.finishing,
                userLeaving, pauseImmediately, autoEnteringPip);
            mAtmService.getLifecycleManager().scheduleTransactionItem(prev.app.getThread(), item);
        } catch (Exception e) {
        boolean isSuccessful;
        try {
            isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
                    prev.app.getThread(), item);
        } catch (RemoteException e) {
            // TODO(b/323801078): remove Exception when cleanup
            // Ignore exception, if process died other code will cleanup.
            Slog.w(TAG, "Exception thrown during pause", e);
            isSuccessful = false;
        }
        if (!isSuccessful) {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mTaskSupervisor.mNoHistoryActivities.remove(prev);