Fix Launcher crash while handling top resumed state
The process of current top resumed activity was killed. Before getting the callbacks from binder death recipient, the process was being restarted while bringing up other non-UI components - such as sending broadcast. Since the top resumed activity was not being updated, ATM had to schedule to the client for dropping the top resumed state after process bound. So, exceptions thrown because it was illegal to drop the top resumed state for a fresh client. Check if necessary to update top resumed activity whenever the stack resumed activity changes. Bug: 128837461 Test: run emulator for 10 times Test: atest ActivityLifecycleTopResumedStateTests Test: atest ActivityLifecycleKeyguardTests Test: atest ActivityLifecycleTests Change-Id: Iefde9bbe5ae50f3a241235faa505a2e58ed681ee
This commit is contained in:
@@ -693,13 +693,13 @@ final class ActivityRecord extends ConfigurationContainer {
|
||||
}
|
||||
}
|
||||
|
||||
void scheduleTopResumedActivityChanged(boolean onTop) {
|
||||
boolean scheduleTopResumedActivityChanged(boolean onTop) {
|
||||
if (!attachedToProcess()) {
|
||||
if (DEBUG_STATES) {
|
||||
Slog.w(TAG, "Can't report activity position update - client not running"
|
||||
+ ", activityRecord=" + this);
|
||||
}
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (DEBUG_STATES) {
|
||||
@@ -710,7 +710,9 @@ final class ActivityRecord extends ConfigurationContainer {
|
||||
TopResumedActivityChangeItem.obtain(onTop));
|
||||
} catch (RemoteException e) {
|
||||
// If process died, whatever.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void updateMultiWindowMode() {
|
||||
@@ -3408,7 +3410,6 @@ final class ActivityRecord extends ConfigurationContainer {
|
||||
transaction.addCallback(callbackItem);
|
||||
transaction.setLifecycleStateRequest(lifecycleItem);
|
||||
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
|
||||
mStackSupervisor.updateTopResumedActivityIfNeeded();
|
||||
// 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.
|
||||
|
||||
@@ -1500,7 +1500,6 @@ class ActivityStack extends ConfigurationContainer {
|
||||
+ " callers=" + Debug.getCallers(5));
|
||||
r.setState(RESUMED, "minimalResumeActivityLocked");
|
||||
r.completeResumeLocked();
|
||||
mStackSupervisor.updateTopResumedActivityIfNeeded();
|
||||
if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
|
||||
"Launch completed; removing icicle of " + r.icicle);
|
||||
}
|
||||
@@ -2571,7 +2570,6 @@ class ActivityStack extends ConfigurationContainer {
|
||||
// Protect against recursion.
|
||||
mInResumeTopActivity = true;
|
||||
result = resumeTopActivityInnerLocked(prev, options);
|
||||
mStackSupervisor.updateTopResumedActivityIfNeeded();
|
||||
|
||||
// When resuming the top activity, it may be necessary to pause the top activity (for
|
||||
// example, returning to the lock screen. We suppress the normal pause logic in
|
||||
@@ -2606,6 +2604,7 @@ class ActivityStack extends ConfigurationContainer {
|
||||
if (DEBUG_STACK) Slog.d(TAG_STACK, "setResumedActivity stack:" + this + " + from: "
|
||||
+ mResumedActivity + " to:" + r + " reason:" + reason);
|
||||
mResumedActivity = r;
|
||||
mStackSupervisor.updateTopResumedActivityIfNeeded();
|
||||
}
|
||||
|
||||
@GuardedBy("mService")
|
||||
|
||||
@@ -853,7 +853,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
|
||||
|
||||
// Schedule transaction.
|
||||
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
|
||||
updateTopResumedActivityIfNeeded();
|
||||
|
||||
if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
|
||||
&& mService.mHasHeavyWeightFeature) {
|
||||
@@ -2321,8 +2320,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
|
||||
// mTopResumedActivityWaitingForPrev == true at this point would mean that an activity
|
||||
// before the prevTopActivity one hasn't reported back yet. So server never sent the top
|
||||
// resumed state change message to prevTopActivity.
|
||||
if (prevActivityReceivedTopState) {
|
||||
prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */);
|
||||
if (prevActivityReceivedTopState
|
||||
&& prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */)) {
|
||||
scheduleTopResumedStateLossTimeout(prevTopActivity);
|
||||
mTopResumedActivityWaitingForPrev = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user