summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/Intent.java36
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java294
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java7
4 files changed, 241 insertions, 97 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 71cd6f1ec49c..39933a9ee7b4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2569,6 +2569,32 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
/**
+ * Broadcast Action: An existing application package has been removed from
+ * the device. The data contains the name of the package and the visibility
+ * allow list. The package that is being removed does <em>not</em> receive
+ * this Intent.
+ * <ul>
+ * <li> {@link #EXTRA_UID} containing the integer uid previously assigned
+ * to the package.
+ * <li> {@link #EXTRA_DATA_REMOVED} is set to true if the entire
+ * application -- data and code -- is being removed.
+ * <li> {@link #EXTRA_REPLACING} is set to true if this will be followed
+ * by an {@link #ACTION_PACKAGE_ADDED} broadcast for the same package.
+ * <li> {@link #EXTRA_USER_INITIATED} containing boolean field to signal
+ * that the application was removed with the user-initiated action.
+ * <li> {@link #EXTRA_VISIBILITY_ALLOW_LIST} containing an int array to
+ * indicate the visibility allow list.
+ * </ul>
+ *
+ * <p class="note">This is a protected intent that can only be sent
+ * by the system.
+ *
+ * @hide This broadcast is used internally by the system.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_PACKAGE_REMOVED_INTERNAL =
+ "android.intent.action.PACKAGE_REMOVED_INTERNAL";
+ /**
* Broadcast Action: An existing application package has been completely
* removed from the device. The data contains the name of the package.
* This is like {@link #ACTION_PACKAGE_REMOVED}, but only set when
@@ -6122,6 +6148,16 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final String EXTRA_LOCUS_ID = "android.intent.extra.LOCUS_ID";
+ /**
+ * Used as an int array extra field in
+ * {@link android.content.Intent#ACTION_PACKAGE_REMOVED_INTERNAL}
+ * intents to indicate that visibility allow list of this removed package.
+ *
+ * @hide
+ */
+ public static final String EXTRA_VISIBILITY_ALLOW_LIST =
+ "android.intent.extra.VISIBILITY_ALLOW_LIST";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Intent flags (see mFlags variable).
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0e1f6de86ac7..47d810b19517 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -40,6 +40,7 @@
<protected-broadcast android:name="android.intent.action.PACKAGE_REPLACED" />
<protected-broadcast android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<protected-broadcast android:name="android.intent.action.PACKAGE_REMOVED" />
+ <protected-broadcast android:name="android.intent.action.PACKAGE_REMOVED_INTERNAL" />
<protected-broadcast android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
<protected-broadcast android:name="android.intent.action.PACKAGE_CHANGED" />
<protected-broadcast android:name="android.intent.action.PACKAGE_FULLY_LOADED" />
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index edd43af9f5b9..47d16295e6a7 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -37,9 +37,11 @@ import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.LocusId;
import android.content.pm.ActivityInfo;
@@ -95,6 +97,7 @@ import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.wm.ActivityTaskManagerInternal;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -146,10 +149,13 @@ public class LauncherAppsService extends SystemService {
private final ActivityManagerInternal mActivityManagerInternal;
private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
private final ShortcutServiceInternal mShortcutServiceInternal;
+ private final PackageManagerInternal mPackageManagerInternal;
private final PackageCallbackList<IOnAppsChangedListener> mListeners
= new PackageCallbackList<IOnAppsChangedListener>();
private final DevicePolicyManager mDpm;
+ private final PackageRemovedListener mPackageRemovedListener =
+ new PackageRemovedListener();
private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
@GuardedBy("mListeners")
@@ -175,6 +181,8 @@ public class LauncherAppsService extends SystemService {
LocalServices.getService(ActivityTaskManagerInternal.class));
mShortcutServiceInternal = Objects.requireNonNull(
LocalServices.getService(ShortcutServiceInternal.class));
+ mPackageManagerInternal = Objects.requireNonNull(
+ LocalServices.getService(PackageManagerInternal.class));
mShortcutServiceInternal.addListener(mPackageMonitor);
mShortcutChangeHandler = new ShortcutChangeHandler(mUserManagerInternal);
mShortcutServiceInternal.addShortcutChangeCallback(mShortcutChangeHandler);
@@ -294,6 +302,11 @@ public class LauncherAppsService extends SystemService {
*/
private void startWatchingPackageBroadcasts() {
if (!mIsWatchingPackageBroadcasts) {
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED_INTERNAL);
+ filter.addDataScheme("package");
+ mContext.registerReceiverAsUser(mPackageRemovedListener, UserHandle.ALL, filter,
+ /* broadcastPermission= */ null, mCallbackHandler);
mPackageMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler);
mIsWatchingPackageBroadcasts = true;
}
@@ -307,6 +320,7 @@ public class LauncherAppsService extends SystemService {
Log.d(TAG, "Stopped watching for packages");
}
if (mIsWatchingPackageBroadcasts) {
+ mContext.unregisterReceiver(mPackageRemovedListener);
mPackageMonitor.unregister();
mIsWatchingPackageBroadcasts = false;
}
@@ -395,9 +409,8 @@ public class LauncherAppsService extends SystemService {
if (!canAccessProfile(user.getIdentifier(), "cannot get shouldHideFromSuggestions")) {
return false;
}
- final PackageManagerInternal pmi = LocalServices.getService(
- PackageManagerInternal.class);
- int flags = pmi.getDistractingPackageRestrictions(packageName, user.getIdentifier());
+ final int flags = mPackageManagerInternal.getDistractingPackageRestrictions(packageName,
+ user.getIdentifier());
return (flags & PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS) != 0;
}
@@ -433,16 +446,14 @@ public class LauncherAppsService extends SystemService {
final ArrayList<LauncherActivityInfoInternal> result = new ArrayList<>(
launcherActivities.getList());
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
if (packageName != null) {
// If this hidden app should not be shown, return the original list.
// Otherwise, inject hidden activity that forwards user to app details page.
if (result.size() > 0) {
return launcherActivities;
}
- ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName, /*flags*/ 0,
- callingUid, user.getIdentifier());
+ final ApplicationInfo appInfo = mPackageManagerInternal.getApplicationInfo(
+ packageName, /* flags= */ 0, callingUid, user.getIdentifier());
if (shouldShowSyntheticActivity(user, appInfo)) {
LauncherActivityInfoInternal info = getHiddenAppActivityInfo(packageName,
callingUid, user);
@@ -456,8 +467,9 @@ public class LauncherAppsService extends SystemService {
for (LauncherActivityInfoInternal info : result) {
visiblePackages.add(info.getActivityInfo().packageName);
}
- List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(0,
- user.getIdentifier(), callingUid);
+ final List<ApplicationInfo> installedPackages =
+ mPackageManagerInternal.getInstalledApplications(/* flags= */ 0,
+ user.getIdentifier(), callingUid);
for (ApplicationInfo applicationInfo : installedPackages) {
if (!visiblePackages.contains(applicationInfo.packageName)) {
if (!shouldShowSyntheticActivity(user, applicationInfo)) {
@@ -483,9 +495,7 @@ public class LauncherAppsService extends SystemService {
if (isManagedProfileAdmin(user, appInfo.packageName)) {
return false;
}
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
- final AndroidPackage pkg = pmInt.getPackage(appInfo.packageName);
+ final AndroidPackage pkg = mPackageManagerInternal.getPackage(appInfo.packageName);
if (pkg == null) {
// Should not happen, but we shouldn't be failing if it does
return false;
@@ -501,13 +511,11 @@ public class LauncherAppsService extends SystemService {
}
private boolean hasDefaultEnableLauncherActivity(@NonNull String packageName) {
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
final Intent matchIntent = new Intent(Intent.ACTION_MAIN);
matchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
matchIntent.setPackage(packageName);
- final List<ResolveInfo> infoList = pmInt.queryIntentActivities(matchIntent,
- matchIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
+ final List<ResolveInfo> infoList = mPackageManagerInternal.queryIntentActivities(
+ matchIntent, matchIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
PackageManager.MATCH_DISABLED_COMPONENTS, Binder.getCallingUid(),
getCallingUserId());
final int size = infoList.size();
@@ -548,9 +556,7 @@ public class LauncherAppsService extends SystemService {
final int callingUid = injectBinderCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
- final ActivityInfo activityInfo = pmInt.getActivityInfo(component,
+ final ActivityInfo activityInfo = mPackageManagerInternal.getActivityInfo(component,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
callingUid, user.getIdentifier());
@@ -561,8 +567,9 @@ public class LauncherAppsService extends SystemService {
// should not happen
return null;
}
- final IncrementalStatesInfo incrementalStatesInfo = pmInt.getIncrementalStatesInfo(
- component.getPackageName(), callingUid, user.getIdentifier());
+ final IncrementalStatesInfo incrementalStatesInfo =
+ mPackageManagerInternal.getIncrementalStatesInfo(component.getPackageName(),
+ callingUid, user.getIdentifier());
if (incrementalStatesInfo == null) {
// package does not exist; should not happen
return null;
@@ -598,9 +605,7 @@ public class LauncherAppsService extends SystemService {
private List<LauncherActivityInfoInternal> queryIntentLauncherActivities(
Intent intent, int callingUid, UserHandle user) {
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
- List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
+ final List<ResolveInfo> apps = mPackageManagerInternal.queryIntentActivities(intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
@@ -614,8 +619,9 @@ public class LauncherAppsService extends SystemService {
// should not happen
continue;
}
- final IncrementalStatesInfo incrementalStatesInfo = pmInt.getIncrementalStatesInfo(
- packageName, callingUid, user.getIdentifier());
+ final IncrementalStatesInfo incrementalStatesInfo =
+ mPackageManagerInternal.getIncrementalStatesInfo(packageName, callingUid,
+ user.getIdentifier());
if (incrementalStatesInfo == null) {
// package doesn't exist any more; should not happen
continue;
@@ -639,15 +645,14 @@ public class LauncherAppsService extends SystemService {
final int callingUid = injectBinderCallingUid();
final long identity = Binder.clearCallingIdentity();
try {
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
Intent packageIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT)
.setPackage(component.getPackageName());
- List<ResolveInfo> apps = pmInt.queryIntentActivities(packageIntent,
- packageIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- callingUid, user.getIdentifier());
+ List<ResolveInfo> apps =
+ mPackageManagerInternal.queryIntentActivities(packageIntent,
+ packageIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+ callingUid, user.getIdentifier());
// ensure that the component is present in the list
if (!apps.stream().anyMatch(
ri -> component.getClassName().equals(ri.activityInfo.name))) {
@@ -712,9 +717,7 @@ public class LauncherAppsService extends SystemService {
final int callingUid = injectBinderCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
- PackageInfo info = pmInt.getPackageInfo(packageName,
+ final PackageInfo info = mPackageManagerInternal.getPackageInfo(packageName,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
callingUid, user.getIdentifier());
@@ -730,9 +733,8 @@ public class LauncherAppsService extends SystemService {
if (!canAccessProfile(user.getIdentifier(), "Cannot get launcher extras")) {
return null;
}
- final PackageManagerInternal pmi =
- LocalServices.getService(PackageManagerInternal.class);
- return pmi.getSuspendedPackageLauncherExtras(packageName, user.getIdentifier());
+ return mPackageManagerInternal.getSuspendedPackageLauncherExtras(packageName,
+ user.getIdentifier());
}
@Override
@@ -746,10 +748,8 @@ public class LauncherAppsService extends SystemService {
final int callingUid = injectBinderCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
- ApplicationInfo info = pmInt.getApplicationInfo(packageName, flags,
- callingUid, user.getIdentifier());
+ final ApplicationInfo info = mPackageManagerInternal.getApplicationInfo(packageName,
+ flags, callingUid, user.getIdentifier());
return info;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -1043,11 +1043,9 @@ public class LauncherAppsService extends SystemService {
return false;
}
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
final int callingUid = injectBinderCallingUid();
- final int state = pmInt.getComponentEnabledSetting(component, callingUid,
- user.getIdentifier());
+ final int state = mPackageManagerInternal.getComponentEnabledSetting(component,
+ callingUid, user.getIdentifier());
switch (state) {
case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
break; // Need to check the manifest's enabled state.
@@ -1061,7 +1059,7 @@ public class LauncherAppsService extends SystemService {
final long ident = Binder.clearCallingIdentity();
try {
- ActivityInfo info = pmInt.getActivityInfo(component,
+ final ActivityInfo info = mPackageManagerInternal.getActivityInfo(component,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
callingUid, user.getIdentifier());
@@ -1160,12 +1158,11 @@ public class LauncherAppsService extends SystemService {
final int callingUid = injectBinderCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
// Check that the component actually has Intent.CATEGORY_LAUCNCHER
// as calling startActivityAsUser ignores the category and just
// resolves based on the component if present.
- List<ResolveInfo> apps = pmInt.queryIntentActivities(launchIntent,
+ final List<ResolveInfo> apps = mPackageManagerInternal.queryIntentActivities(
+ launchIntent,
launchIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
@@ -1229,6 +1226,31 @@ public class LauncherAppsService extends SystemService {
user.getIdentifier(), debugMsg, false);
}
+ /** Returns whether or not the result to the listener should be filtered. */
+ private boolean isPackageVisibleToListener(String packageName, BroadcastCookie cookie) {
+ return !mPackageManagerInternal.filterAppAccess(packageName, cookie.callingUid,
+ cookie.user.getIdentifier());
+ }
+
+ /** Returns whether or not the given UID is in allow list */
+ private static boolean isCallingUidAllowed(int[] allowList, int callingUid) {
+ if (allowList == null) {
+ return true;
+ }
+ return Arrays.binarySearch(allowList, callingUid) > -1;
+ }
+
+ private String[] getFilteredPackageNames(String[] packageNames, BroadcastCookie cookie) {
+ final List<String> filteredPackageNames = new ArrayList<>();
+ for (String packageName : packageNames) {
+ if (!isPackageVisibleToListener(packageName, cookie)) {
+ continue;
+ }
+ filteredPackageNames.add(packageName);
+ }
+ return filteredPackageNames.toArray(new String[filteredPackageNames.size()]);
+ }
+
private int toShortcutsCacheFlags(int cacheFlags) {
int ret = 0;
if (cacheFlags == FLAG_CACHE_NOTIFICATION_SHORTCUTS) {
@@ -1253,19 +1275,17 @@ public class LauncherAppsService extends SystemService {
* loaded, register loading progress listener.
*/
void registerLoadingProgressForIncrementalApps() {
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
final List<UserHandle> users = mUm.getUserProfiles();
if (users == null) {
return;
}
for (UserHandle user : users) {
- pmInt.forEachInstalledPackage(pkg -> {
+ mPackageManagerInternal.forEachInstalledPackage(pkg -> {
final String packageName = pkg.getPackageName();
- if (pmInt.getIncrementalStatesInfo(packageName, Process.myUid(),
- user.getIdentifier()).isLoading()) {
- pmInt.registerInstalledLoadingProgressCallback(packageName,
- new PackageLoadingProgressCallback(packageName, user),
+ if (mPackageManagerInternal.getIncrementalStatesInfo(packageName,
+ Process.myUid(), user.getIdentifier()).isLoading()) {
+ mPackageManagerInternal.registerInstalledLoadingProgressCallback(
+ packageName, new PackageLoadingProgressCallback(packageName, user),
user.getIdentifier());
}
}, user.getIdentifier());
@@ -1398,6 +1418,59 @@ public class LauncherAppsService extends SystemService {
}
}
+ private class PackageRemovedListener extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL);
+ if (userId == UserHandle.USER_NULL) {
+ Slog.w(TAG, "Intent broadcast does not contain user handle: " + intent);
+ return;
+ }
+ final String action = intent.getAction();
+ // Handle onPackageRemoved.
+ if (Intent.ACTION_PACKAGE_REMOVED_INTERNAL.equals(action)) {
+ final String packageName = getPackageName(intent);
+ final int[] allowList =
+ intent.getIntArrayExtra(Intent.EXTRA_VISIBILITY_ALLOW_LIST);
+ // If {@link #EXTRA_REPLACING} is true, that will be onPackageChanged case.
+ if (packageName != null && !intent.getBooleanExtra(
+ Intent.EXTRA_REPLACING, /* defaultValue= */ false)) {
+ final UserHandle user = new UserHandle(userId);
+ final int n = mListeners.beginBroadcast();
+ try {
+ for (int i = 0; i < n; i++) {
+ final IOnAppsChangedListener listener =
+ mListeners.getBroadcastItem(i);
+ final BroadcastCookie cookie =
+ (BroadcastCookie) mListeners.getBroadcastCookie(i);
+ if (!isEnabledProfileOf(cookie.user, user, "onPackageRemoved")) {
+ continue;
+ }
+ if (!isCallingUidAllowed(allowList, cookie.callingUid)) {
+ continue;
+ }
+ try {
+ listener.onPackageRemoved(user, packageName);
+ } catch (RemoteException re) {
+ Slog.d(TAG, "Callback failed ", re);
+ }
+ }
+ } finally {
+ mListeners.finishBroadcast();
+ }
+ }
+ }
+ }
+
+ private String getPackageName(Intent intent) {
+ final Uri uri = intent.getData();
+ final String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
+ return pkg;
+ }
+ }
+
private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
// TODO Simplify with lambdas.
@@ -1410,7 +1483,12 @@ public class LauncherAppsService extends SystemService {
for (int i = 0; i < n; i++) {
IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
- if (!isEnabledProfileOf(cookie.user, user, "onPackageAdded")) continue;
+ if (!isEnabledProfileOf(cookie.user, user, "onPackageAdded")) {
+ continue;
+ }
+ if (!isPackageVisibleToListener(packageName, cookie)) {
+ continue;
+ }
try {
listener.onPackageAdded(user, packageName);
} catch (RemoteException re) {
@@ -1421,35 +1499,12 @@ public class LauncherAppsService extends SystemService {
mListeners.finishBroadcast();
}
super.onPackageAdded(packageName, uid);
- PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
- pmi.registerInstalledLoadingProgressCallback(packageName,
+ mPackageManagerInternal.registerInstalledLoadingProgressCallback(packageName,
new PackageLoadingProgressCallback(packageName, user),
user.getIdentifier());
}
@Override
- public void onPackageRemoved(String packageName, int uid) {
- UserHandle user = new UserHandle(getChangingUserId());
- final int n = mListeners.beginBroadcast();
- try {
- for (int i = 0; i < n; i++) {
- IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
- BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
- if (!isEnabledProfileOf(cookie.user, user, "onPackageRemoved")) continue;
- try {
- listener.onPackageRemoved(user, packageName);
- } catch (RemoteException re) {
- Slog.d(TAG, "Callback failed ", re);
- }
- }
- } finally {
- mListeners.finishBroadcast();
- }
-
- super.onPackageRemoved(packageName, uid);
- }
-
- @Override
public void onPackageModified(String packageName) {
onPackageChanged(packageName);
super.onPackageModified(packageName);
@@ -1462,7 +1517,12 @@ public class LauncherAppsService extends SystemService {
for (int i = 0; i < n; i++) {
IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
- if (!isEnabledProfileOf(cookie.user, user, "onPackageModified")) continue;
+ if (!isEnabledProfileOf(cookie.user, user, "onPackageModified")) {
+ continue;
+ }
+ if (!isPackageVisibleToListener(packageName, cookie)) {
+ continue;
+ }
try {
listener.onPackageChanged(user, packageName);
} catch (RemoteException re) {
@@ -1482,9 +1542,16 @@ public class LauncherAppsService extends SystemService {
for (int i = 0; i < n; i++) {
IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
- if (!isEnabledProfileOf(cookie.user, user, "onPackagesAvailable")) continue;
+ if (!isEnabledProfileOf(cookie.user, user, "onPackagesAvailable")) {
+ continue;
+ }
+ final String[] filteredPackages = getFilteredPackageNames(packages, cookie);
+ // If all packages are filtered, skip notifying listener.
+ if (ArrayUtils.isEmpty(filteredPackages)) {
+ continue;
+ }
try {
- listener.onPackagesAvailable(user, packages, isReplacing());
+ listener.onPackagesAvailable(user, filteredPackages, isReplacing());
} catch (RemoteException re) {
Slog.d(TAG, "Callback failed ", re);
}
@@ -1504,9 +1571,16 @@ public class LauncherAppsService extends SystemService {
for (int i = 0; i < n; i++) {
IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
- if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnavailable")) continue;
+ if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnavailable")) {
+ continue;
+ }
+ final String[] filteredPackages = getFilteredPackageNames(packages, cookie);
+ // If all packages are filtered, skip notifying listener.
+ if (ArrayUtils.isEmpty(filteredPackages)) {
+ continue;
+ }
try {
- listener.onPackagesUnavailable(user, packages, isReplacing());
+ listener.onPackagesUnavailable(user, filteredPackages, isReplacing());
} catch (RemoteException re) {
Slog.d(TAG, "Callback failed ", re);
}
@@ -1521,12 +1595,12 @@ public class LauncherAppsService extends SystemService {
@Override
public void onPackagesSuspended(String[] packages) {
UserHandle user = new UserHandle(getChangingUserId());
- PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
final ArrayList<Pair<String, Bundle>> packagesWithExtras = new ArrayList<>();
final ArrayList<String> packagesWithoutExtras = new ArrayList<>();
for (String pkg : packages) {
- final Bundle launcherExtras = pmi.getSuspendedPackageLauncherExtras(pkg,
- user.getIdentifier());
+ final Bundle launcherExtras =
+ mPackageManagerInternal.getSuspendedPackageLauncherExtras(pkg,
+ user.getIdentifier());
if (launcherExtras != null) {
packagesWithExtras.add(new Pair<>(pkg, launcherExtras));
} else {
@@ -1540,11 +1614,23 @@ public class LauncherAppsService extends SystemService {
for (int i = 0; i < n; i++) {
IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
- if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) continue;
+ if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) {
+ continue;
+ }
+ final String[] filteredPackagesWithoutExtras =
+ getFilteredPackageNames(packages, cookie);
+ // If all packages are filtered, skip notifying listener.
+ if (ArrayUtils.isEmpty(filteredPackagesWithoutExtras)) {
+ continue;
+ }
try {
- listener.onPackagesSuspended(user, packagesNullExtras, null);
+ listener.onPackagesSuspended(user, filteredPackagesWithoutExtras,
+ /* launcherExtras= */ null);
for (int idx = 0; idx < packagesWithExtras.size(); idx++) {
Pair<String, Bundle> packageExtraPair = packagesWithExtras.get(idx);
+ if (!isPackageVisibleToListener(packageExtraPair.first, cookie)) {
+ continue;
+ }
listener.onPackagesSuspended(user,
new String[]{packageExtraPair.first},
packageExtraPair.second);
@@ -1566,9 +1652,16 @@ public class LauncherAppsService extends SystemService {
for (int i = 0; i < n; i++) {
IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
- if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnsuspended")) continue;
+ if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnsuspended")) {
+ continue;
+ }
+ final String[] filteredPackages = getFilteredPackageNames(packages, cookie);
+ // If all packages are filtered, skip notifying listener.
+ if (ArrayUtils.isEmpty(filteredPackages)) {
+ continue;
+ }
try {
- listener.onPackagesUnsuspended(user, packages);
+ listener.onPackagesUnsuspended(user, filteredPackages);
} catch (RemoteException re) {
Slog.d(TAG, "Callback failed ", re);
}
@@ -1595,8 +1688,12 @@ public class LauncherAppsService extends SystemService {
for (int i = 0; i < n; i++) {
IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
- if (!isEnabledProfileOf(cookie.user, user, "onShortcutChanged")) continue;
-
+ if (!isEnabledProfileOf(cookie.user, user, "onShortcutChanged")) {
+ continue;
+ }
+ if (!isPackageVisibleToListener(packageName, cookie)) {
+ continue;
+ }
final int launcherUserId = cookie.user.getIdentifier();
// Make sure the caller has the permission.
@@ -1668,6 +1765,9 @@ public class LauncherAppsService extends SystemService {
if (!isEnabledProfileOf(cookie.user, mUser, "onLoadingProgressChanged")) {
continue;
}
+ if (!isPackageVisibleToListener(mPackageName, cookie)) {
+ continue;
+ }
try {
listener.onPackageLoadingProgressChanged(mUser, mPackageName, progress);
} catch (RemoteException re) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2cdf40a4d959..d2cbcf0598fc 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -15033,6 +15033,9 @@ public class PackageManagerService extends IPackageManager.Stub
uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
intent.putExtra(Intent.EXTRA_UID, uid);
}
+ if (broadcastAllowList != null && PLATFORM_PACKAGE_NAME.equals(targetPkg)) {
+ intent.putExtra(Intent.EXTRA_VISIBILITY_ALLOW_LIST, broadcastAllowList.get(id));
+ }
intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
if (DEBUG_BROADCASTS) {
@@ -21001,6 +21004,10 @@ public class PackageManagerService extends IPackageManager.Stub
removedPackage, extras, 0 /*flags*/,
installerPackageName, null, broadcastUsers, instantUserIds, null, null);
}
+ packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED_INTERNAL,
+ removedPackage, extras, 0 /*flags*/, PLATFORM_PACKAGE_NAME,
+ null /*finishedReceiver*/, broadcastUsers, instantUserIds,
+ broadcastAllowList, null /*bOptions*/);
if (dataRemoved && !isRemovedPackageSystemUpdate) {
packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null,