Merge changes from topic "app_hibernation_permission" am: 4dfa5f8db4
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1624868 Change-Id: I55b8dc7dfa171b5d11098320445932ef2f91bcbf
This commit is contained in:
@@ -1422,6 +1422,7 @@ package android.app.usage {
|
||||
package android.apphibernation {
|
||||
|
||||
public final class AppHibernationManager {
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public java.util.List<java.lang.String> getHibernatingPackagesForUser();
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public boolean isHibernatingForUser(@NonNull String);
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public boolean isHibernatingGlobally(@NonNull String);
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public void setHibernatingForUser(@NonNull String, boolean);
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class provides an API surface for system apps to manipulate the app hibernation
|
||||
* state of a package for the user provided in the context.
|
||||
@@ -111,4 +113,20 @@ public final class AppHibernationManager {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hibernating packages for the user. This is equivalent to the list of packages for
|
||||
* the user that return true for {@link #isHibernatingForUser}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(value = android.Manifest.permission.MANAGE_APP_HIBERNATION)
|
||||
public @NonNull List<String> getHibernatingPackagesForUser() {
|
||||
try {
|
||||
return mIAppHibernationService.getHibernatingPackagesForUser(mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,4 +25,5 @@ interface IAppHibernationService {
|
||||
void setHibernatingForUser(String packageName, int userId, boolean isHibernating);
|
||||
boolean isHibernatingGlobally(String packageName);
|
||||
void setHibernatingGlobally(String packageName, boolean isHibernating);
|
||||
List<String> getHibernatingPackagesForUser(int userId);
|
||||
}
|
||||
@@ -292,6 +292,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.
|
||||
*
|
||||
@@ -618,6 +647,11 @@ public final class AppHibernationService extends SystemService {
|
||||
return mService.isHibernatingGlobally(packageName);
|
||||
}
|
||||
|
||||
@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,
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user