diff options
author | Kevin Han <kevhan@google.com> | 2021-03-20 01:37:29 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-03-20 01:37:29 +0000 |
commit | 4dfa5f8db4dfe13591c76c1526277c8a2ef08a8d (patch) | |
tree | 66dc4388da1367ee59fe828cb37df8c84f6d1e04 /services | |
parent | 64e333a2501c191a50bd14eb3bfbae0f9b3ebddb (diff) | |
parent | f0df72a9c7268c2bde7443dfde708ab895e2bf30 (diff) |
Merge changes from topic "app_hibernation_permission"
* changes:
Add API to get hibernating packages
Add MANAGE_APP_HIBERNATION permission
Diffstat (limited to 'services')
2 files changed, 70 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java index 968cf5f1df91..b3373d0bb536 100644 --- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java +++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java @@ -173,7 +173,9 @@ public final class AppHibernationService extends SystemService { if (!checkHibernationEnabled("isHibernatingForUser")) { return false; } - + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_APP_HIBERNATION, + "Caller does not have MANAGE_APP_HIBERNATION permission."); userId = handleIncomingUser(userId, "isHibernating"); if (!mUserManager.isUserUnlockingOrUnlocked(userId)) { Slog.e(TAG, "Attempt to get hibernation state of stopped or nonexistent user " @@ -202,6 +204,9 @@ public final class AppHibernationService extends SystemService { if (!checkHibernationEnabled("isHibernatingGlobally")) { return false; } + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_APP_HIBERNATION, + "Caller does not have MANAGE_APP_HIBERNATION permission."); synchronized (mLock) { GlobalLevelState state = mGlobalHibernationStates.get(packageName); if (state == null) { @@ -223,6 +228,9 @@ public final class AppHibernationService extends SystemService { if (!checkHibernationEnabled("setHibernatingForUser")) { return; } + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_APP_HIBERNATION, + "Caller does not have MANAGE_APP_HIBERNATION permission."); userId = handleIncomingUser(userId, "setHibernating"); if (!mUserManager.isUserUnlockingOrUnlocked(userId)) { Slog.w(TAG, "Attempt to set hibernation state for a stopped or nonexistent user " @@ -263,6 +271,9 @@ public final class AppHibernationService extends SystemService { if (!checkHibernationEnabled("setHibernatingGlobally")) { return; } + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_APP_HIBERNATION, + "Caller does not have MANAGE_APP_HIBERNATION permission."); synchronized (mLock) { GlobalLevelState state = mGlobalHibernationStates.get(packageName); if (state == null) { @@ -282,6 +293,35 @@ public final class AppHibernationService extends SystemService { } /** + * Get the hibernating packages for the given user. This is equivalent to the list of + * packages for the user that return true for {@link #isHibernatingForUser}. + */ + @NonNull List<String> getHibernatingPackagesForUser(int userId) { + ArrayList<String> hibernatingPackages = new ArrayList<>(); + if (!checkHibernationEnabled("getHibernatingPackagesForUser")) { + return hibernatingPackages; + } + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_APP_HIBERNATION, + "Caller does not have MANAGE_APP_HIBERNATION permission."); + userId = handleIncomingUser(userId, "getHibernatingPackagesForUser"); + if (!mUserManager.isUserUnlockingOrUnlocked(userId)) { + Slog.w(TAG, "Attempt to get hibernating packages for a stopped or nonexistent user " + + userId); + return hibernatingPackages; + } + synchronized (mLock) { + Map<String, UserLevelState> userStates = mUserStates.get(userId); + for (UserLevelState state : userStates.values()) { + if (state.hibernated) { + hibernatingPackages.add(state.packageName); + } + } + return hibernatingPackages; + } + } + + /** * Put an app into hibernation for a given user, allowing user-level optimizations to occur. * * @param pkgState package hibernation state @@ -608,6 +648,11 @@ public final class AppHibernationService extends SystemService { } @Override + public List<String> getHibernatingPackagesForUser(int userId) { + return mService.getHibernatingPackagesForUser(userId); + } + + @Override public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) { diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java index 1c9683803857..1b8ab2175458 100644 --- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java @@ -18,6 +18,7 @@ package com.android.server.apphibernation; import static android.content.pm.PackageManager.MATCH_ANY_USER; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.AdditionalAnswers.returnsArgAt; import static org.mockito.ArgumentMatchers.any; @@ -67,6 +68,7 @@ public final class AppHibernationServiceTest { private static final String PACKAGE_SCHEME = "package"; private static final String PACKAGE_NAME_1 = "package1"; private static final String PACKAGE_NAME_2 = "package2"; + private static final String PACKAGE_NAME_3 = "package3"; private static final int USER_ID_1 = 1; private static final int USER_ID_2 = 2; @@ -107,6 +109,8 @@ public final class AppHibernationServiceTest { List<PackageInfo> packages = new ArrayList<>(); packages.add(makePackageInfo(PACKAGE_NAME_1)); + packages.add(makePackageInfo(PACKAGE_NAME_2)); + packages.add(makePackageInfo(PACKAGE_NAME_3)); doReturn(new ParceledListSlice<>(packages)).when(mIPackageManager).getInstalledPackages( intThat(arg -> (arg & MATCH_ANY_USER) != 0), anyInt()); mAppHibernationService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); @@ -179,6 +183,26 @@ public final class AppHibernationServiceTest { assertTrue(mAppHibernationService.isHibernatingGlobally(PACKAGE_NAME_1)); } + @Test + public void testGetHibernatingPackagesForUser_returnsCorrectPackages() throws RemoteException { + // GIVEN an unlocked user with all packages installed + UserInfo userInfo = + addUser(USER_ID_2, new String[]{PACKAGE_NAME_1, PACKAGE_NAME_2, PACKAGE_NAME_3}); + mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo)); + doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_2); + + // WHEN packages are hibernated for the user + mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_2, true); + mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_2, USER_ID_2, true); + + // THEN the hibernating packages returned matches + List<String> hibernatingPackages = + mAppHibernationService.getHibernatingPackagesForUser(USER_ID_2); + assertEquals(2, hibernatingPackages.size()); + assertTrue(hibernatingPackages.contains(PACKAGE_NAME_1)); + assertTrue(hibernatingPackages.contains(PACKAGE_NAME_2)); + } + /** * Add a mock user with one package. */ |