Merge "Send boot complete broadcast when unhibernated" into sc-dev

This commit is contained in:
Kevin Han
2021-04-22 06:46:39 +00:00
committed by Android (Google) Code Review
2 changed files with 66 additions and 0 deletions

View File

@@ -16,6 +16,7 @@
package com.android.server.apphibernation;
import static android.app.AppOpsManager.OP_NONE;
import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.Intent.EXTRA_REMOVED_FOR_ALL_USERS;
@@ -25,8 +26,10 @@ import static android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION;
import static com.android.server.apphibernation.AppHibernationConstants.KEY_APP_HIBERNATION_ENABLED;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.IActivityManager;
@@ -366,6 +369,49 @@ public final class AppHibernationService extends SystemService {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "unhibernatePackage");
pkgState.hibernated = false;
pkgState.lastUnhibernatedMs = System.currentTimeMillis();
// Deliver LOCKED_BOOT_COMPLETE AND BOOT_COMPLETE broadcast so app can re-register
// their alarms/jobs/etc.
try {
Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
.setPackage(packageName);
final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
mIActivityManager.broadcastIntentWithFeature(
null /* caller */,
null /* callingFeatureId */,
lockedBcIntent,
null /* resolvedType */,
null /* resultTo */,
Activity.RESULT_OK,
null /* resultData */,
null /* resultExtras */,
requiredPermissions,
null /* excludedPermissions */,
OP_NONE,
null /* bOptions */,
false /* serialized */,
false /* sticky */,
userId);
Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
mIActivityManager.broadcastIntentWithFeature(
null /* caller */,
null /* callingFeatureId */,
bcIntent,
null /* resolvedType */,
null /* resultTo */,
Activity.RESULT_OK,
null /* resultData */,
null /* resultExtras */,
requiredPermissions,
null /* excludedPermissions */,
OP_NONE,
null /* bOptions */,
false /* serialized */,
false /* sticky */,
userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}

View File

@@ -30,6 +30,7 @@ import static org.mockito.ArgumentMatchers.intThat;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.IActivityManager;
@@ -264,6 +265,25 @@ public final class AppHibernationServiceTest {
assertFalse(mAppHibernationService.isHibernatingGlobally(PACKAGE_NAME_1));
}
@Test
public void testUnhibernatingPackageForUserSendsBootCompleteBroadcast()
throws RemoteException {
// GIVEN a hibernating package for a user
mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_1, true);
// WHEN we unhibernate the package
mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_1, false);
// THEN we send the boot complete broadcasts
ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mIActivityManager, times(2)).broadcastIntentWithFeature(any(), any(),
intentArgumentCaptor.capture(), any(), any(), anyInt(), any(), any(), any(), any(),
anyInt(), any(), anyBoolean(), anyBoolean(), eq(USER_ID_1));
List<Intent> capturedIntents = intentArgumentCaptor.getAllValues();
assertEquals(capturedIntents.get(0).getAction(), Intent.ACTION_LOCKED_BOOT_COMPLETED);
assertEquals(capturedIntents.get(1).getAction(), Intent.ACTION_BOOT_COMPLETED);
}
/**
* Add a mock user with one package.
*/