diff options
| author | 2025-03-03 04:49:52 -0800 | |
|---|---|---|
| committer | 2025-03-03 04:49:52 -0800 | |
| commit | 0cf87344f29e46a199e09bb1e869b1bc88d54105 (patch) | |
| tree | 3ea86eae2b4a3c9650546d993f42b078b34a22ca | |
| parent | 4a999fae18d64b8f7a6c61077d5eedb4bd326253 (diff) | |
| parent | 09f22a63a4449530e64e9d6065124e15357de52c (diff) | |
Merge "Refactor for pending dispatched ClientTransaction cleanup" into main
4 files changed, 245 insertions, 156 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index 463a830c9e68..7da4beb95114 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -1113,11 +1113,11 @@ class ActivityClientController extends IActivityClientController.Stub { false /* fromClient */); } + final EnterPipRequestedItem item = new EnterPipRequestedItem(r.token); try { - final EnterPipRequestedItem item = new EnterPipRequestedItem(r.token); - mService.getLifecycleManager().scheduleTransactionItem(r.app.getThread(), item); - return true; - } catch (Exception e) { + 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) { + final PipStateTransactionItem item = new PipStateTransactionItem(r.token, pipState); try { - final PipStateTransactionItem item = new PipStateTransactionItem(r.token, pipState); 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); } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index d452d76db18d..7ddfe06491f8 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -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); + 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); + 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); + ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending new config to %s, " + + "config: %s", this, config); - final ActivityConfigurationChangeItem item = - new ActivityConfigurationChangeItem(token, config, activityWindowInfo); + 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); + 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; } + mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT; + final TransferSplashScreenViewStateItem item = + new TransferSplashScreenViewStateItem(token, parcelable, windowAnimationLeash); + boolean isSuccessful; 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) { + 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); + 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()) { + final ArrayList<ResultInfo> list = new ArrayList<>(); + list.add(new ResultInfo(resultWho, requestCode, resultCode, data, callerToken)); + final ActivityResultItem item = new ActivityResultItem(token, list); 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); - return; - } catch (Exception e) { + final boolean isSuccessful = mAtmService.getLifecycleManager() + .scheduleTransactionItem(app.getThread(), item); + if (isSuccessful) { + return; + } + } 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,25 +5023,26 @@ 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()) { + 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 */); try { - 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 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) { - addNewIntentLocked(rintent); - } + + // Didn't send. + addNewIntentLocked(rintent); } void updateOptionsLocked(ActivityOptions options) { @@ -6044,11 +6070,12 @@ final class ActivityRecord extends WindowToken { setState(PAUSING, "makeActiveIfNeeded"); EventLogTags.writeWmPauseActivity(mUserId, System.identityHashCode(this), shortComponentName, "userLeaving=false", "make-active"); + final PauseActivityItem item = new PauseActivityItem(token, finishing, + false /* userLeaving */, false /* dontReport */, mAutoEnteringPip); try { - final PauseActivityItem item = new PauseActivityItem(token, finishing, - false /* userLeaving */, false /* dontReport */, mAutoEnteringPip); 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,23 +6371,29 @@ final class ActivityRecord extends WindowToken { return; } resumeKeyDispatchingLocked(); - try { - ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPING: %s (stop requested)", this); + ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPING: %s (stop requested)", this); - setState(STOPPING, "stopIfPossible"); - if (DEBUG_VISIBILITY) { - Slog.v(TAG_VISIBILITY, "Stopping:" + this); - } - EventLogTags.writeWmStopActivity( - mUserId, System.identityHashCode(this), shortComponentName); - mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), - new StopActivityItem(token)); - - mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT); - } catch (Exception e) { + setState(STOPPING, "stopIfPossible"); + if (DEBUG_VISIBILITY) { + Slog.v(TAG_VISIBILITY, "Stopping:" + this); + } + EventLogTags.writeWmStopActivity( + mUserId, System.identityHashCode(this), shortComponentName); + 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,29 +8960,34 @@ final class ActivityRecord extends WindowToken { task.mTaskId, shortComponentName, Integer.toHexString(configChangeFlags)); } + 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, + pendingResults, pendingNewIntents, configChangeFlags, + new MergedConfiguration(getProcessGlobalConfiguration(), + getMergedOverrideConfiguration()), + preserveWindow, getActivityWindowInfo()); + final ActivityLifecycleItem lifecycleItem; + if (andResume) { + lifecycleItem = new ResumeActivityItem(token, isTransitionForward(), + shouldSendCompatFakeFocus()); + } else { + lifecycleItem = new PauseActivityItem(token); + } + boolean isSuccessful; 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, - pendingResults, pendingNewIntents, configChangeFlags, - new MergedConfiguration(getProcessGlobalConfiguration(), - getMergedOverrideConfiguration()), - preserveWindow, getActivityWindowInfo()); - final ActivityLifecycleItem lifecycleItem; - if (andResume) { - lifecycleItem = new ResumeActivityItem(token, isTransitionForward(), - shouldSendCompatFakeFocus()); - } else { - lifecycleItem = new PauseActivityItem(token); - } - mAtmService.getLifecycleManager().scheduleTransactionItems( + 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); diff --git a/services/core/java/com/android/server/wm/ActivityRefresher.java b/services/core/java/com/android/server/wm/ActivityRefresher.java index 25e38b307b5e..8fe603cad46b 100644 --- a/services/core/java/com/android/server/wm/ActivityRefresher.java +++ b/services/core/java/com/android/server/wm/ActivityRefresher.java @@ -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); + } } diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index f95698a5b0bd..5183c6b57f15 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -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,67 +1752,80 @@ class TaskFragment extends WindowContainer<WindowContainer> { } } - try { - final IApplicationThread appThread = next.app.getThread(); - // Deliver all pending results. - final ArrayList<ResultInfo> a = next.results; - if (a != null) { - final int size = a.size(); - if (!next.finishing && size > 0) { - if (DEBUG_RESULTS) { - Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a); - } - final ActivityResultItem item = new ActivityResultItem(next.token, a); - mAtmService.getLifecycleManager().scheduleTransactionItem(appThread, item); + final IApplicationThread appThread = next.app.getThread(); + // Deliver all pending results. + final ArrayList<ResultInfo> a = next.results; + if (a != null) { + final int size = a.size(); + if (!next.finishing && size > 0) { + if (DEBUG_RESULTS) { + Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a); + } + final ActivityResultItem item = new ActivityResultItem(next.token, a); + 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); + if (next.newIntents != null) { + final NewIntentItem item = + new NewIntentItem(next.token, next.newIntents, true /* resume */); + 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. - // Clear app token stopped state in window manager if needed. - next.notifyAppResumed(); - - EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next), - next.getTask().mTaskId, next.shortComponentName); - - mAtmService.getAppWarningsLocked().onResumeActivity(next); - final int topProcessState = mAtmService.mTopProcessState; - next.app.setPendingUiCleanAndForceProcessStateUpTo(topProcessState); - next.abortAndClearOptionsAnimation(); - final ResumeActivityItem resumeActivityItem = new ResumeActivityItem( - next.token, topProcessState, dc.isNextTransitionForward(), - next.shouldSendCompatFakeFocus()); - 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"); + // Well the app will no longer be stopped. + // Clear app token stopped state in window manager if needed. + next.notifyAppResumed(); - // lastResumedActivity being non-null implies there is a lastStack present. - if (lastResumedActivity != null) { - lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked"); - } + EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next), + next.getTask().mTaskId, next.shortComponentName); - 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); + mAtmService.getAppWarningsLocked().onResumeActivity(next); + final int topProcessState = mAtmService.mTopProcessState; + next.app.setPendingUiCleanAndForceProcessStateUpTo(topProcessState); + next.abortAndClearOptionsAnimation(); + final ResumeActivityItem resumeActivityItem = new ResumeActivityItem( + next.token, topProcessState, dc.isNextTransitionForward(), + next.shouldSendCompatFakeFocus()); + boolean isSuccessful; + try { + isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem( + appThread, resumeActivityItem); + } catch (RemoteException e) { + // TODO(b/323801078): remove Exception when cleanup + isSuccessful = 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); + 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); + boolean isSuccessful; 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) { + 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); |