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:
@@ -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)) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user