Merge "Unhibernate when an app is no longer force-stopped." into sc-dev

This commit is contained in:
Kevin Han
2021-03-08 20:04:09 +00:00
committed by Android (Google) Code Review
4 changed files with 95 additions and 11 deletions

View File

@@ -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);
}
/**

View File

@@ -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;
@@ -23405,15 +23406,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

View File

@@ -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("", ""),

View File

@@ -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)
}
}