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

Commit f6e6e686 authored by Momoko Hattori's avatar Momoko Hattori
Browse files

Fix getPreviousForegroundUser() after boot on HSUM with boot user switch

In commit c21b1cb6 we fixed
UserManagerService.LifeCycle#onUserStarting so that the last foreground
time for the system user 0 can be updated when interactive HSUM devices
boot as well. However, on HSUM devices, HsumBootUserInitializer triggers
user switch to the boot user after the system user is started, which
causes getPreviousForegroundUser() to always return 0 right after boot
even when the perceived previous foreground user isn't 0, like as in the
following case:
  1. The device's current user is X (not 0)
  2. The device reboots.
  3. The device's current user is Y (not 0 or X), but
     getPreviousForegroundUser() returns 0 instead of X
To fix the behavior, avoid updating the last foreground time of system
user 0 on HSUM devices, and update it later in
HsumBootUserInitializer#switchToBootUser(), at which point the boot user
should have been finalized.

This change also modifies the import as requested by preupload check.

Bug: 418780738
Bug: 412630247
Test: `atest android.host.multiuser.UserManagerHostTest` passes on auto
    and desktop
Flag: EXEMPT bug fix

Change-Id: Ic5fa226400a56b0a41b4fd1015bcc4305f7566e9
parent 2e195e44
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -370,6 +370,12 @@ public final class HsumBootUserInitializer {


    private void switchToBootUser(@UserIdInt int bootUserId) {
    private void switchToBootUser(@UserIdInt int bootUserId) {
        Slogf.i(TAG, "Switching to boot user %d", bootUserId);
        Slogf.i(TAG, "Switching to boot user %d", bootUserId);
        if (bootUserId == UserHandle.USER_SYSTEM) {
            // System user is already the foreground user, so onUserSwitching() will not be called
            // for the system user to record the last entered foreground time. Therefore explicitly
            // set the time now.
            mUms.setLastEnteredForegroundTimeToNow(bootUserId);
        }
        final boolean started = mAms.startUserInForegroundWithListener(bootUserId,
        final boolean started = mAms.startUserInForegroundWithListener(bootUserId,
                /* unlockListener= */ null);
                /* unlockListener= */ null);
        if (!started) {
        if (!started) {
+26 −11
Original line number Original line Diff line number Diff line
@@ -189,16 +189,6 @@ import com.android.server.utils.Slogf;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;


import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import libcore.io.IoUtils;
import libcore.io.IoUtils;


import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParser;
@@ -215,11 +205,19 @@ import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collections;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.LinkedList;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Objects;
import java.util.Optional;
import java.util.Optional;
import java.util.Set;
import java.util.Set;
@@ -1029,7 +1027,12 @@ public class UserManagerService extends IUserManager.Stub {
                if (user != null) {
                if (user != null) {
                    user.startRealtime = SystemClock.elapsedRealtime();
                    user.startRealtime = SystemClock.elapsedRealtime();
                    if (targetUser.getUserIdentifier() == UserHandle.USER_SYSTEM
                    if (targetUser.getUserIdentifier() == UserHandle.USER_SYSTEM
                            && user.info.supportsSwitchTo()) {
                            && user.info.isFull()) {
                        // On interactive HSUM devices (where the system user is not a full user but
                        // can be in foreground), the last entered foreground time for the system
                        // user will be set later in HsumBootUserInitializer only when it is the
                        // boot user. This is because we don't know yet if the system user will be
                        // the boot user (e.g., setBootUser could be called later).
                        mUms.setLastEnteredForegroundTimeToNow(user);
                        mUms.setLastEnteredForegroundTimeToNow(user);
                    }
                    }
                }
                }
@@ -7877,6 +7880,18 @@ public class UserManagerService extends IUserManager.Stub {
                        || someUserHasSeedAccountNoChecks(accountName, accountType));
                        || someUserHasSeedAccountNoChecks(accountName, accountType));
    }
    }


    /**
     * Sets the last entered foreground time to the current time for the given user.
     */
    public void setLastEnteredForegroundTimeToNow(@UserIdInt int userId) {
        UserData userData = getUserDataNoChecks(userId);
        if (userData == null) {
            Slog.w(LOG_TAG, "setLastEnteredForegroundTimeToNow: unknown user #" + userId);
            return;
        }
        setLastEnteredForegroundTimeToNow(userData);
    }

    private void setLastEnteredForegroundTimeToNow(@NonNull UserData userData) {
    private void setLastEnteredForegroundTimeToNow(@NonNull UserData userData) {
        userData.mLastEnteredForegroundTimeMillis = System.currentTimeMillis();
        userData.mLastEnteredForegroundTimeMillis = System.currentTimeMillis();
        scheduleWriteUser(userData.info.id);
        scheduleWriteUser(userData.info.id);