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

Commit 71452ce2 authored by Annie Meng's avatar Annie Meng
Browse files

[Multi-User] Unregister stopped users in BMS

Adds a handler for system service callbacks when a user is stopped. This
currently only unregisters the user in bookkeeping but will be used in
the future for cleanup work such as cancelling scheduled jobs, etc.

Bug: 120212806
Test: 1) atest RunBackupFrameworksServicesRoboTests
2) atest TrampolineTest
3) Enable multi user + register user -> service started for user; stop
user -> user is unregistered

Change-Id: Ic712da646f961b9bb02c7d77d964a13345eca7ec
parent 49ba9fee
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -124,6 +124,10 @@ public class BackupManagerService {
        }
        }
    }
    }


    // ---------------------------------------------
    // USER LIFECYCLE CALLBACKS
    // ---------------------------------------------

    /**
    /**
     * Starts the backup service for user {@code userId} by creating a new instance of {@link
     * Starts the backup service for user {@code userId} by creating a new instance of {@link
     * UserBackupManagerService} and registering it with this service.
     * UserBackupManagerService} and registering it with this service.
@@ -153,6 +157,12 @@ public class BackupManagerService {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
    }


    /** Stops the backup service for user {@code userId} when the user is stopped. */
    @VisibleForTesting
    protected void stopServiceForUser(int userId) {
        mServiceUsers.remove(userId);
    }

    SparseArray<UserBackupManagerService> getServiceUsers() {
    SparseArray<UserBackupManagerService> getServiceUsers() {
        return mServiceUsers;
        return mServiceUsers;
    }
    }
@@ -820,5 +830,10 @@ public class BackupManagerService {
            }
            }
            sInstance.unlockUser(userId);
            sInstance.unlockUser(userId);
        }
        }

        @Override
        public void onStopUser(int userId) {
            sInstance.stopUser(userId);
        }
    }
    }
}
}
+20 −0
Original line number Original line Diff line number Diff line
@@ -197,6 +197,26 @@ public class Trampoline extends IBackupManager.Stub {
        }
        }
    }
    }


    /**
     * Called from {@link BackupManagerService.Lifecycle} when a user {@code userId} is stopped.
     * Offloads work onto the handler thread {@link #mHandlerThread} to keep stopping time low.
     */
    void stopUser(int userId) {
        if (userId != UserHandle.USER_SYSTEM && !isMultiUserEnabled()) {
            Slog.i(TAG, "Multi-user disabled, cannot stop service for user: " + userId);
            return;
        }

        postToHandler(
                () -> {
                    BackupManagerService service = mService;
                    if (service != null) {
                        Slog.i(TAG, "Stopping service for user: " + userId);
                        service.stopServiceForUser(userId);
                    }
                });
    }

    /**
    /**
     * Only privileged callers should be changing the backup state. This method only acts on {@link
     * Only privileged callers should be changing the backup state. This method only acts on {@link
     * UserHandle#USER_SYSTEM} and is a no-op if passed non-system users. Deactivating backup in the
     * UserHandle#USER_SYSTEM} and is a no-op if passed non-system users. Deactivating backup in the
+26 −0
Original line number Original line Diff line number Diff line
@@ -175,6 +175,32 @@ public class BackupManagerServiceTest {
        assertThat(serviceUsers.get(mUserOneId)).isEqualTo(mUserOneService);
        assertThat(serviceUsers.get(mUserOneId)).isEqualTo(mUserOneService);
    }
    }


    /** Test that the service unregisters users when stopped. */
    @Test
    public void testStopServiceForUser_forRegisteredUser_unregistersCorrectUser() throws Exception {
        BackupManagerService backupManagerService =
                createServiceAndRegisterUser(mUserOneId, mUserOneService);
        backupManagerService.startServiceForUser(mUserTwoId, mUserTwoService);

        backupManagerService.stopServiceForUser(mUserOneId);

        SparseArray<UserBackupManagerService> serviceUsers = backupManagerService.getServiceUsers();
        assertThat(serviceUsers.size()).isEqualTo(1);
        assertThat(serviceUsers.get(mUserOneId)).isNull();
        assertThat(serviceUsers.get(mUserTwoId)).isEqualTo(mUserTwoService);
    }

    /** Test that the service unregisters users when stopped. */
    @Test
    public void testStopServiceForUser_forUnknownUser_doesNothing() throws Exception {
        BackupManagerService backupManagerService = createService();

        backupManagerService.stopServiceForUser(mUserOneId);

        SparseArray<UserBackupManagerService> serviceUsers = backupManagerService.getServiceUsers();
        assertThat(serviceUsers.size()).isEqualTo(0);
    }

    /**
    /**
     * Test that the backup services throws a {@link SecurityException} if the caller does not have
     * Test that the backup services throws a {@link SecurityException} if the caller does not have
     * INTERACT_ACROSS_USERS_FULL permission and passes a different user id.
     * INTERACT_ACROSS_USERS_FULL permission and passes a different user id.
+30 −0
Original line number Original line Diff line number Diff line
@@ -162,6 +162,36 @@ public class TrampolineTest {
        verify(mBackupManagerServiceMock).startServiceForUser(10);
        verify(mBackupManagerServiceMock).startServiceForUser(10);
    }
    }


    @Test
    public void stopUser_whenMultiUserSettingDisabled_callsBackupManagerServiceForSystemUser() {
        Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 0);
        mTrampoline.initializeService();

        mTrampoline.stopUser(UserHandle.USER_SYSTEM);

        verify(mBackupManagerServiceMock).stopServiceForUser(UserHandle.USER_SYSTEM);
    }

    @Test
    public void stopUser_whenMultiUserSettingDisabled_isIgnoredForNonSystemUser() {
        Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 0);
        mTrampoline.initializeService();

        mTrampoline.stopUser(10);

        verify(mBackupManagerServiceMock, never()).stopServiceForUser(10);
    }

    @Test
    public void stopUser_whenMultiUserSettingEnabled_callsBackupManagerServiceForNonSystemUser() {
        Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 1);
        mTrampoline.initializeService();

        mTrampoline.stopUser(10);

        verify(mBackupManagerServiceMock).stopServiceForUser(10);
    }

    @Test
    @Test
    public void initializeService_successfullyInitializesBackupService() {
    public void initializeService_successfullyInitializesBackupService() {
        mTrampoline.initializeService();
        mTrampoline.initializeService();