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

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

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I962b632c5ca389109cb8381af4812529bc24797a
This commit is contained in:
Treehugger Robot
2021-02-04 04:32:12 +00:00
committed by Automerger Merge Worker
2 changed files with 40 additions and 65 deletions

View File

@@ -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");
if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
Slog.w(TAG, "Attempt to set hibernation state for a stopped or nonexistent user "
+ userId);
return;
}
synchronized (mLock) {
if (!mUserStates.contains(userId)) {
throw new IllegalArgumentException("No user associated with user id " + userId);
}
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)) {

View File

@@ -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) {