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

Commit b89c0389 authored by Adam Bookatz's avatar Adam Bookatz
Browse files

Prepare Overlays for MainUser earlier

Headless System User Mode (HSUM) creates and switches to the MainUser
immediately in the initial bootup. This requires that the MainUser's
overlays be ready before launching SetupWizard (SUW).

We therefore monitor for when the user is created, and once it is, we
immediately start updating its overlays, so that they can be ready
early.

Bug: 283904547
Test: Manually confirmed that SUW had theming on HSUM device
Change-Id: Ia3339e6a39bc5d641644cfa6a2a723dd0c067d6f
parent fad849bc
Loading
Loading
Loading
Loading
+38 −1
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
import com.android.server.pm.KnownPackages;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerService;
import com.android.server.pm.pkg.PackageState;

@@ -287,6 +288,9 @@ public final class OverlayManagerService extends SystemService {
            getContext().registerReceiverAsUser(new UserReceiver(), UserHandle.ALL,
                    userFilter, null, null);

            UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
            umi.addUserLifecycleListener(new UserLifecycleListener());

            restoreSettings();

            // Wipe all shell overlays on boot, to recover from a potentially broken device
@@ -337,6 +341,7 @@ public final class OverlayManagerService extends SystemService {
        if (newUserId == mPrevStartedUserId) {
            return;
        }
        Slog.i(TAG, "Updating overlays for starting user " + newUserId);
        try {
            traceBegin(TRACE_TAG_RRO, "OMS#onStartUser " + newUserId);
            // ensure overlays in the settings are up-to-date, and propagate
@@ -533,14 +538,46 @@ public final class OverlayManagerService extends SystemService {
        }
    }

    /**
     * Indicates that the given user is of great importance so that when it is created, we quickly
     * update its overlays by using a Listener mechanism rather than a Broadcast mechanism. This
     * is especially important for {@link UserManager#isHeadlessSystemUserMode() HSUM}'s MainUser,
     * which is created and switched-to immediately on first boot.
     */
    private static boolean isHighPriorityUserCreation(UserInfo user) {
        // TODO: Consider extending this to all created users (guarded behind a flag in that case).
        return user != null && user.isMain();
    }

    private final class UserLifecycleListener implements UserManagerInternal.UserLifecycleListener {
        @Override
        public void onUserCreated(UserInfo user, Object token) {
            if (isHighPriorityUserCreation(user)) {
                final int userId = user.id;
                try {
                    Slog.i(TAG, "Updating overlays for onUserCreated " + userId);
                    traceBegin(TRACE_TAG_RRO, "OMS#onUserCreated " + userId);
                    synchronized (mLock) {
                        updatePackageManagerLocked(mImpl.updateOverlaysForUser(userId));
                    }
                } finally {
                    traceEnd(TRACE_TAG_RRO);
                }
            }
        }
    }

    private final class UserReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
            switch (intent.getAction()) {
                case ACTION_USER_ADDED:
                    if (userId != UserHandle.USER_NULL) {
                    UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
                    UserInfo userInfo = umi.getUserInfo(userId);
                    if (userId != UserHandle.USER_NULL && !isHighPriorityUserCreation(userInfo)) {
                        try {
                            Slog.i(TAG, "Updating overlays for added user " + userId);
                            traceBegin(TRACE_TAG_RRO, "OMS ACTION_USER_ADDED");
                            synchronized (mLock) {
                                updatePackageManagerLocked(mImpl.updateOverlaysForUser(userId));