Merge "Add hibernation NPE check and unhibernate only if hibernating" into sc-v2-dev

This commit is contained in:
Kevin Han
2021-12-04 00:43:54 +00:00
committed by Android (Google) Code Review
2 changed files with 38 additions and 9 deletions

View File

@@ -24299,24 +24299,24 @@ public class PackageManagerService extends IPackageManager.Stub
} }
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */, enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
true /* checkShell */, "stop package"); true /* checkShell */, "stop package");
boolean shouldUnhibernate = false;
// writer // writer
synchronized (mLock) { synchronized (mLock) {
final PackageSetting ps = mSettings.getPackageLPr(packageName); final PackageSetting ps = mSettings.getPackageLPr(packageName);
if (ps != null && ps.getStopped(userId) && !stopped) {
shouldUnhibernate = true;
}
if (!shouldFilterApplicationLocked(ps, callingUid, userId) if (!shouldFilterApplicationLocked(ps, callingUid, userId)
&& mSettings.setPackageStoppedStateLPw(this, packageName, stopped, userId)) { && mSettings.setPackageStoppedStateLPw(this, packageName, stopped, userId)) {
scheduleWritePackageRestrictionsLocked(userId); scheduleWritePackageRestrictionsLocked(userId);
} }
} }
if (shouldUnhibernate) { // If this would cause the app to leave force-stop, then also make sure to unhibernate the
// app if needed.
if (!stopped) {
mHandler.post(() -> { mHandler.post(() -> {
AppHibernationManagerInternal ah = AppHibernationManagerInternal ah =
mInjector.getLocalService(AppHibernationManagerInternal.class); mInjector.getLocalService(AppHibernationManagerInternal.class);
if (ah != null && ah.isHibernatingForUser(packageName, userId)) {
ah.setHibernatingForUser(packageName, userId, false); ah.setHibernatingForUser(packageName, userId, false);
ah.setHibernatingGlobally(packageName, false); ah.setHibernatingGlobally(packageName, false);
}
}); });
} }
} }

View File

@@ -29,6 +29,7 @@ import com.android.server.apphibernation.AppHibernationManagerInternal
import com.android.server.apphibernation.AppHibernationService import com.android.server.apphibernation.AppHibernationService
import com.android.server.extendedtestutils.wheneverStatic import com.android.server.extendedtestutils.wheneverStatic
import com.android.server.testutils.whenever import com.android.server.testutils.whenever
import org.junit.Assert
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Before import org.junit.Before
@@ -100,8 +101,11 @@ class PackageManagerServiceHibernationTests {
rule.system().dataAppDirectory) rule.system().dataAppDirectory)
val pm = createPackageManagerService() val pm = createPackageManagerService()
rule.system().validateFinalState() rule.system().validateFinalState()
val ps = pm.getPackageSetting(TEST_PACKAGE_NAME)
ps!!.setStopped(true, TEST_USER_ID) TestableLooper.get(this).processAllMessages()
whenever(appHibernationManager.isHibernatingForUser(TEST_PACKAGE_NAME, TEST_USER_ID))
.thenReturn(true)
pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID) pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID)
@@ -111,6 +115,31 @@ class PackageManagerServiceHibernationTests {
verify(appHibernationManager).setHibernatingGlobally(TEST_PACKAGE_NAME, false) verify(appHibernationManager).setHibernatingGlobally(TEST_PACKAGE_NAME, false)
} }
@Test
fun testExitForceStop_nonExistingAppHibernationManager_doesNotThrowException() {
whenever(rule.mocks().injector.getLocalService(AppHibernationManagerInternal::class.java))
.thenReturn(null)
rule.system().stageScanExistingPackage(
TEST_PACKAGE_NAME,
1L,
rule.system().dataAppDirectory)
val pm = createPackageManagerService()
rule.system().validateFinalState()
TestableLooper.get(this).processAllMessages()
whenever(appHibernationManager.isHibernatingForUser(TEST_PACKAGE_NAME, TEST_USER_ID))
.thenReturn(true)
try {
pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID)
TestableLooper.get(this).processAllMessages()
} catch (e: Exception) {
Assert.fail("Method throws exception when AppHibernationManager is not ready.\n$e")
}
}
@Test @Test
fun testGetOptimizablePackages_ExcludesGloballyHibernatingPackages() { fun testGetOptimizablePackages_ExcludesGloballyHibernatingPackages() {
rule.system().stageScanExistingPackage( rule.system().stageScanExistingPackage(