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

Commit 7fe1787b authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add/remove user state based off user unlocking" am: 85797196 am: 6b55ff44

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1566902

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I962b632c5ca389109cb8381af4812529bc24797a
parents fad38049 6b55ff44
Loading
Loading
Loading
Loading
+20 −38
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@ package com.android.server.apphibernation;

import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.Intent.ACTION_USER_ADDED;
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.EXTRA_REMOVED_FOR_ALL_USERS;
import static android.content.Intent.EXTRA_REPLACING;
import static android.content.pm.PackageManager.MATCH_ALL;
@@ -36,7 +34,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -48,6 +45,7 @@ import android.os.UserManager;
import android.provider.DeviceConfig;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
@@ -107,11 +105,6 @@ public final class AppHibernationService extends SystemService {
        final Context userAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ACTION_USER_ADDED);
        intentFilter.addAction(ACTION_USER_REMOVED);
        userAllContext.registerReceiver(mBroadcastReceiver, intentFilter);

        intentFilter = new IntentFilter();
        intentFilter.addAction(ACTION_PACKAGE_ADDED);
        intentFilter.addAction(ACTION_PACKAGE_REMOVED);
        intentFilter.addDataScheme("package");
@@ -123,19 +116,6 @@ public final class AppHibernationService extends SystemService {
        publishBinderService(Context.APP_HIBERNATION_SERVICE, mServiceStub);
    }

    @Override
    public void onBootPhase(int phase) {
        if (phase == PHASE_BOOT_COMPLETED) {
            synchronized (mLock) {
                final List<UserInfo> users = mUserManager.getUsers();
                // TODO: Pull from persistent disk storage. For now, just make from scratch.
                for (UserInfo user : users) {
                    addUserPackageStatesL(user.id);
                }
            }
        }
    }

    /**
     * Whether a package is hibernating for a given user.
     *
@@ -145,11 +125,13 @@ public final class AppHibernationService extends SystemService {
     */
    boolean isHibernatingForUser(String packageName, int userId) {
        userId = handleIncomingUser(userId, "isHibernating");
        if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
            Slog.e(TAG, "Attempt to get hibernation state of stopped or nonexistent user "
                    + userId);
            return false;
        }
        synchronized (mLock) {
            final Map<String, UserPackageState> packageStates = mUserStates.get(userId);
            if (packageStates == null) {
                throw new IllegalArgumentException("No user associated with user id " + userId);
            }
            final UserPackageState pkgState = packageStates.get(packageName);
            if (pkgState == null) {
                throw new IllegalArgumentException(
@@ -181,10 +163,12 @@ public final class AppHibernationService extends SystemService {
     */
    void setHibernatingForUser(String packageName, int userId, boolean isHibernating) {
        userId = handleIncomingUser(userId, "setHibernating");
        synchronized (mLock) {
            if (!mUserStates.contains(userId)) {
                throw new IllegalArgumentException("No user associated with user id " + userId);
        if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
            Slog.w(TAG, "Attempt to set hibernation state for a stopped or nonexistent user "
                    + userId);
            return;
        }
        synchronized (mLock) {
            Map<String, UserPackageState> packageStates = mUserStates.get(userId);
            UserPackageState pkgState = packageStates.get(packageName);
            if (pkgState == null) {
@@ -310,15 +294,19 @@ public final class AppHibernationService extends SystemService {
        mUserStates.put(userId, packages);
    }

    private void onUserAdded(int userId) {
    @Override
    public void onUserUnlocking(@NonNull TargetUser user) {
        // TODO: Pull from persistent disk storage. For now, just make from scratch.
        synchronized (mLock) {
            addUserPackageStatesL(userId);
            addUserPackageStatesL(user.getUserIdentifier());
        }
    }

    private void onUserRemoved(int userId) {
    @Override
    public void onUserStopping(@NonNull TargetUser user) {
        synchronized (mLock) {
            mUserStates.remove(userId);
            // TODO: Flush to disk when persistence is implemented
            mUserStates.remove(user.getUserIdentifier());
        }
    }

@@ -395,7 +383,7 @@ public final class AppHibernationService extends SystemService {
        }
    }

    // Broadcast receiver for user and package add/removal events
    // Broadcast receiver for package add/removal events
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
@@ -405,12 +393,6 @@ public final class AppHibernationService extends SystemService {
            }

            final String action = intent.getAction();
            if (ACTION_USER_ADDED.equals(action)) {
                onUserAdded(userId);
            }
            if (ACTION_USER_REMOVED.equals(action)) {
                onUserRemoved(userId);
            }
            if (ACTION_PACKAGE_ADDED.equals(action) || ACTION_PACKAGE_REMOVED.equals(action)) {
                final String packageName = intent.getData().getSchemeSpecificPart();
                if (intent.getBooleanExtra(EXTRA_REPLACING, false)) {
+20 −27
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.mockito.internal.verification.VerificationModeFactory.times;

import android.app.IActivityManager;
import android.content.BroadcastReceiver;
@@ -87,7 +86,7 @@ public final class AppHibernationServiceTest {
        mAppHibernationService = new AppHibernationService(mContext, mIPackageManager,
                mIActivityManager, mUserManager);

        verify(mContext, times(2)).registerReceiver(mReceiverCaptor.capture(), any());
        verify(mContext).registerReceiver(mReceiverCaptor.capture(), any());
        mBroadcastReceiver = mReceiverCaptor.getValue();

        doReturn(mUserInfos).when(mUserManager).getUsers();
@@ -95,12 +94,13 @@ public final class AppHibernationServiceTest {
        doAnswer(returnsArgAt(2)).when(mIActivityManager).handleIncomingUser(anyInt(), anyInt(),
                anyInt(), anyBoolean(), anyBoolean(), any(), any());

        addUser(USER_ID_1);
        mAppHibernationService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
        UserInfo userInfo = addUser(USER_ID_1);
        mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo));
        doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_1);
    }

    @Test
    public void testSetHibernatingForUser_packageIsHibernating() throws RemoteException {
    public void testSetHibernatingForUser_packageIsHibernating() {
        // WHEN we hibernate a package for a user
        mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_1, true);

@@ -109,8 +109,7 @@ public final class AppHibernationServiceTest {
    }

    @Test
    public void testSetHibernatingForUser_newPackageAdded_packageIsHibernating()
            throws RemoteException {
    public void testSetHibernatingForUser_newPackageAdded_packageIsHibernating() {
        // WHEN a new package is added and it is hibernated
        Intent intent = new Intent(Intent.ACTION_PACKAGE_ADDED,
                Uri.fromParts(PACKAGE_SCHEME, PACKAGE_NAME_2, null /* fragment */));
@@ -124,17 +123,12 @@ public final class AppHibernationServiceTest {
    }

    @Test
    public void testSetHibernatingForUser_newUserAdded_packageIsHibernating()
    public void testSetHibernatingForUser_newUserUnlocked_packageIsHibernating()
            throws RemoteException {
        // WHEN a new user is added and a package from the user is hibernated
        List<PackageInfo> userPackages = new ArrayList<>();
        userPackages.add(makePackageInfo(PACKAGE_NAME_1));
        doReturn(new ParceledListSlice<>(userPackages)).when(mIPackageManager)
                .getInstalledPackages(anyInt(), eq(USER_ID_2));
        Intent intent = new Intent(Intent.ACTION_USER_ADDED);
        intent.putExtra(Intent.EXTRA_USER_HANDLE, USER_ID_2);
        mBroadcastReceiver.onReceive(mContext, intent);

        UserInfo user2 = addUser(USER_ID_2);
        mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(user2));
        doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_2);
        mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_2, true);

        // THEN the new user's package is hibernated
@@ -142,8 +136,7 @@ public final class AppHibernationServiceTest {
    }

    @Test
    public void testIsHibernatingForUser_packageReplaced_stillReturnsHibernating()
            throws RemoteException {
    public void testIsHibernatingForUser_packageReplaced_stillReturnsHibernating() {
        // GIVEN a package is currently hibernated
        mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_1, true);

@@ -159,7 +152,7 @@ public final class AppHibernationServiceTest {
    }

    @Test
    public void testSetHibernatingGlobally_packageIsHibernatingGlobally() throws RemoteException {
    public void testSetHibernatingGlobally_packageIsHibernatingGlobally() {
        // WHEN we hibernate a package
        mAppHibernationService.setHibernatingGlobally(PACKAGE_NAME_1, true);

@@ -168,25 +161,25 @@ public final class AppHibernationServiceTest {
    }

    /**
     * Add a mock user with one package. Must be called before
     * {@link AppHibernationService#onBootPhase(int)} to work properly.
     * Add a mock user with one package.
     */
    private void addUser(int userId) throws RemoteException {
        addUser(userId, new String[]{PACKAGE_NAME_1});
    private UserInfo addUser(int userId) throws RemoteException {
        return addUser(userId, new String[]{PACKAGE_NAME_1});
    }

    /**
     * Add a mock user with the packages specified. Must be called before
     * {@link AppHibernationService#onBootPhase(int)} to work properly
     * Add a mock user with the packages specified.
     */
    private void addUser(int userId, String[] packageNames) throws RemoteException {
        mUserInfos.add(new UserInfo(userId, "user_" + userId, 0 /* flags */));
    private UserInfo addUser(int userId, String[] packageNames) throws RemoteException {
        UserInfo userInfo = new UserInfo(userId, "user_" + userId, 0 /* flags */);
        mUserInfos.add(userInfo);
        List<PackageInfo> userPackages = new ArrayList<>();
        for (String pkgName : packageNames) {
            userPackages.add(makePackageInfo(pkgName));
        }
        doReturn(new ParceledListSlice<>(userPackages)).when(mIPackageManager)
                .getInstalledPackages(anyInt(), eq(userId));
        return userInfo;
    }

    private static PackageInfo makePackageInfo(String packageName) {