summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/apphibernation/AppHibernationService.java13
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java11
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt1
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt81
4 files changed, 95 insertions, 11 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..2c0a5891c4b9 100644
--- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
@@ -314,17 +314,8 @@ public final class AppHibernationService extends SystemService {
private void unhibernatePackageForUser(@NonNull String packageName, int userId,
UserLevelState pkgState) {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "unhibernatePackage");
- final long caller = Binder.clearCallingIdentity();
- try {
- mIPackageManager.setPackageStoppedState(packageName, false, userId);
- pkgState.hibernated = false;
- } catch (RemoteException e) {
- throw new IllegalStateException(
- "Failed to unhibernate due to manager not being available", e);
- } finally {
- Binder.restoreCallingIdentity(caller);
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
- }
+ pkgState.hibernated = false;
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7da53b50d927..50668d59175b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -367,6 +367,7 @@ import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.SystemServerInitThreadPool;
import com.android.server.Watchdog;
+import com.android.server.apphibernation.AppHibernationManagerInternal;
import com.android.server.compat.CompatChange;
import com.android.server.compat.PlatformCompat;
import com.android.server.net.NetworkPolicyManagerInternal;
@@ -23400,15 +23401,25 @@ public class PackageManagerService extends IPackageManager.Stub
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
true /* checkShell */, "stop package");
+ boolean shouldUnhibernate = false;
// writer
synchronized (mLock) {
final PackageSetting ps = mSettings.getPackageLPr(packageName);
+ if (ps.getStopped(userId) && !stopped) {
+ shouldUnhibernate = true;
+ }
if (!shouldFilterApplicationLocked(ps, callingUid, userId)
&& mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
allowedByPermission, callingUid, userId)) {
scheduleWritePackageRestrictionsLocked(userId);
}
}
+ if (shouldUnhibernate) {
+ AppHibernationManagerInternal ah =
+ mInjector.getLocalService(AppHibernationManagerInternal.class);
+ ah.setHibernatingForUser(packageName, userId, false);
+ ah.setHibernatingGlobally(packageName, false);
+ }
}
@Override
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 6e27b3a8166c..e853fd341ae5 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -287,6 +287,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
whenever(mocks.settings.internalVersion).thenReturn(DEFAULT_VERSION_INFO)
whenever(mocks.settings.keySetManagerService).thenReturn(mocks.keySetManagerService)
whenever(mocks.settings.keySetManagerService).thenReturn(mocks.keySetManagerService)
+ whenever(mocks.settings.snapshot()).thenReturn(mocks.settings)
whenever(mocks.packageAbiHelper.derivePackageAbi(
any(AndroidPackage::class.java), anyBoolean(), nullable(), any(File::class.java))) {
android.util.Pair(PackageAbiHelper.Abis("", ""),
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
new file mode 100644
index 000000000000..a0e208f662e3
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm
+
+import android.os.Build
+import com.android.server.apphibernation.AppHibernationManagerInternal
+import com.android.server.testutils.whenever
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(JUnit4::class)
+class PackageManagerServiceHibernationTests {
+
+ companion object {
+ val TEST_PACKAGE_NAME = "test.package"
+ val TEST_USER_ID = 0
+ }
+
+ @Rule
+ @JvmField
+ val rule = MockSystemRule()
+
+ @Mock
+ lateinit var appHibernationManager: AppHibernationManagerInternal
+
+ @Before
+ @Throws(Exception::class)
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ rule.system().stageNominalSystemState()
+ whenever(rule.mocks().injector.getLocalService(AppHibernationManagerInternal::class.java))
+ .thenReturn(appHibernationManager)
+ }
+
+ @Test
+ fun testExitForceStopExitsHibernation() {
+ rule.system().stageScanExistingPackage(
+ TEST_PACKAGE_NAME,
+ 1L,
+ rule.system().dataAppDirectory)
+ val pm = createPackageManagerService()
+ rule.system().validateFinalState()
+ val ps = pm.getPackageSetting(TEST_PACKAGE_NAME)
+ ps!!.setStopped(true, TEST_USER_ID)
+
+ pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID)
+ verify(appHibernationManager).setHibernatingForUser(TEST_PACKAGE_NAME, TEST_USER_ID, false)
+ verify(appHibernationManager).setHibernatingGlobally(TEST_PACKAGE_NAME, false)
+ }
+
+ private fun createPackageManagerService(): PackageManagerService {
+ return PackageManagerService(rule.mocks().injector,
+ false /*coreOnly*/,
+ false /*factoryTest*/,
+ MockSystem.DEFAULT_VERSION_INFO.fingerprint,
+ false /*isEngBuild*/,
+ false /*isUserDebugBuild*/,
+ Build.VERSION_CODES.CUR_DEVELOPMENT,
+ Build.VERSION.INCREMENTAL)
+ }
+}