Fixed booting logic on ActivityTaskSupervisor.activityIdleInternal()

It was clearing the list of users being switched when the device is
"booting", which could be a problem on systems running on headless
mode: if the method was called by a non-null record (like the
FallBackHome) before it was called by null, the non-system user would
never finish switching.

Test: manual verification # on automotive and phones

Fixes: 190854171
Bug: 203885241

Change-Id: I4c589fd618b104689434bf918ebb48a64cef30e4
This commit is contained in:
Felipe Leme
2021-10-26 17:03:02 -07:00
parent e1f6054225
commit 1a6d740c4c
3 changed files with 22 additions and 6 deletions

View File

@@ -4932,6 +4932,8 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public void bootAnimationComplete() {
if (DEBUG_ALL) Slog.d(TAG, "bootAnimationComplete: Callers=" + Debug.getCallers(4));
final boolean callFinishBooting;
synchronized (this) {
callFinishBooting = mCallFinishBooting;
@@ -7765,7 +7767,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// On Automotive, at this point the system user has already been started and unlocked,
// and some of the tasks we do here have already been done. So skip those in that case.
// TODO(b/132262830): this workdound shouldn't be necessary once we move the
// TODO(b/132262830, b/203885241): this workdound shouldn't be necessary once we move the
// headless-user start logic to UserManager-land
final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;

View File

@@ -145,4 +145,11 @@ public final class UserState {
proto.write(UserStateProto.SWITCHING, switching);
proto.end(token);
}
@Override
public String toString() {
return "[UserState: id=" + mHandle.getIdentifier() + ", state=" + stateToString(state)
+ ", lastState=" + stateToString(lastState) + ", switching=" + switching
+ ", tokenProvided=" + tokenProvided + "]";
}
}

View File

@@ -147,6 +147,7 @@ import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.UserState;
import com.android.server.utils.Slogf;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
import java.io.FileDescriptor;
@@ -1322,8 +1323,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// us, we can now deliver.
r.idle = true;
//Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
// Check if able to finish booting when device is booting and all resumed activities
// are idle.
if ((mService.isBooting() && mRootWindowContainer.allResumedActivitiesIdle())
@@ -1356,14 +1355,21 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// Atomically retrieve all of the other things to do.
processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
if (DEBUG_IDLE) {
Slogf.i(TAG, "activityIdleInternal(): r=%s, booting=%b, mStartingUsers=%s", r, booting,
mStartingUsers);
}
if (!mStartingUsers.isEmpty()) {
final ArrayList<UserState> startingUsers = new ArrayList<>(mStartingUsers);
mStartingUsers.clear();
if (!booting) {
// TODO(b/190854171): remove the isHeadlessSystemUserMode() check on master
if (!booting || UserManager.isHeadlessSystemUserMode()) {
// Complete user switch.
for (int i = 0; i < startingUsers.size(); i++) {
mService.mAmInternal.finishUserSwitch(startingUsers.get(i));
UserState userState = startingUsers.get(i);
Slogf.i(TAG, "finishing switch of user %d", userState.mHandle.getIdentifier());
mService.mAmInternal.finishUserSwitch(userState);
}
}
}
@@ -2012,6 +2018,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
final void scheduleIdle() {
if (!mHandler.hasMessages(IDLE_NOW_MSG)) {
if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdle: Callers=" + Debug.getCallers(4));
mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}
}