diff options
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) + } +} |