Listening to package broadcast on all users

When a package is added or removed on a secondary user, the broadcast
was not being processed, leading to inconsistent state, like lingering
defunt alarms and stale exact alarm candidates.

Also reordered some switch-case statements for better readability.

Test: atest FrameworksMockingServicesTests:com.android.server.alarm

Bug: 218868406
Change-Id: I1f1b9a5b8f63d6564c9e121bee7d6d6d697b471d
This commit is contained in:
Suprabh Shukla
2022-03-10 18:28:23 -08:00
parent 2a1f77d19c
commit 6c9df302ae
2 changed files with 18 additions and 16 deletions

View File

@@ -4891,13 +4891,15 @@ public class AlarmManagerService extends SystemService {
filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
filter.addDataScheme(IntentFilter.SCHEME_PACKAGE); filter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
getContext().registerReceiver(this, filter); getContext().registerReceiverForAllUsers(this, filter,
/* broadcastPermission */ null, /* scheduler */ null);
// Register for events related to sdcard installation. // Register for events related to sdcard installation.
IntentFilter sdFilter = new IntentFilter(); IntentFilter sdFilter = new IntentFilter();
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
sdFilter.addAction(Intent.ACTION_USER_STOPPED); sdFilter.addAction(Intent.ACTION_USER_STOPPED);
sdFilter.addAction(Intent.ACTION_UID_REMOVED); sdFilter.addAction(Intent.ACTION_UID_REMOVED);
getContext().registerReceiver(this, sdFilter); getContext().registerReceiverForAllUsers(this, sdFilter,
/* broadcastPermission */ null, /* scheduler */ null);
} }
@Override @Override
@@ -4915,9 +4917,6 @@ public class AlarmManagerService extends SystemService {
} }
} }
return; return;
case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
break;
case Intent.ACTION_USER_STOPPED: case Intent.ACTION_USER_STOPPED:
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
if (userHandle >= 0) { if (userHandle >= 0) {
@@ -4932,6 +4931,18 @@ public class AlarmManagerService extends SystemService {
mRemovalHistory.delete(uid); mRemovalHistory.delete(uid);
mLastOpScheduleExactAlarm.delete(uid); mLastOpScheduleExactAlarm.delete(uid);
return; return;
case Intent.ACTION_PACKAGE_ADDED:
if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
final String packageUpdated = intent.getData().getSchemeSpecificPart();
mHandler.obtainMessage(
AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1,
packageUpdated).sendToTarget();
}
mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES);
return;
case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
break;
case Intent.ACTION_PACKAGE_REMOVED: case Intent.ACTION_PACKAGE_REMOVED:
if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
// This package is being updated; don't kill its alarms. // This package is being updated; don't kill its alarms.
@@ -4950,15 +4961,6 @@ public class AlarmManagerService extends SystemService {
} }
} }
break; break;
case Intent.ACTION_PACKAGE_ADDED:
if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
final String packageUpdated = intent.getData().getSchemeSpecificPart();
mHandler.obtainMessage(
AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1,
packageUpdated).sendToTarget();
}
mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES);
return;
} }
if (pkgList != null && (pkgList.length > 0)) { if (pkgList != null && (pkgList.length > 0)) {
for (String pkg : pkgList) { for (String pkg : pkgList) {

View File

@@ -494,9 +494,9 @@ public class AlarmManagerServiceTest {
final ArgumentCaptor<AlarmManagerService.UninstallReceiver> packageReceiverCaptor = final ArgumentCaptor<AlarmManagerService.UninstallReceiver> packageReceiverCaptor =
ArgumentCaptor.forClass(AlarmManagerService.UninstallReceiver.class); ArgumentCaptor.forClass(AlarmManagerService.UninstallReceiver.class);
verify(mMockContext).registerReceiver(packageReceiverCaptor.capture(), verify(mMockContext).registerReceiverForAllUsers(packageReceiverCaptor.capture(),
argThat((filter) -> filter.hasAction(Intent.ACTION_PACKAGE_ADDED) argThat((filter) -> filter.hasAction(Intent.ACTION_PACKAGE_ADDED)
&& filter.hasAction(Intent.ACTION_PACKAGE_REMOVED))); && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)), isNull(), isNull());
mPackageChangesReceiver = packageReceiverCaptor.getValue(); mPackageChangesReceiver = packageReceiverCaptor.getValue();
assertEquals(mService.mExactAlarmCandidates, Collections.emptySet()); assertEquals(mService.mExactAlarmCandidates, Collections.emptySet());