diff options
-rw-r--r-- | api/current.xml | 11 | ||||
-rw-r--r-- | core/java/android/content/Intent.java | 23 | ||||
-rw-r--r-- | services/java/com/android/server/PackageManagerService.java | 64 |
3 files changed, 70 insertions, 28 deletions
diff --git a/api/current.xml b/api/current.xml index 13e4c946ee37..d6af516188d1 100644 --- a/api/current.xml +++ b/api/current.xml @@ -36136,6 +36136,17 @@ visibility="public" > </field> +<field name="EXTRA_CHANGED_COMPONENT_NAME_LIST" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.intent.extra.changed_component_name_list"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="EXTRA_DATA_REMOVED" type="java.lang.String" transient="false" diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index c676a5bba6fe..398f2114931c 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1275,12 +1275,15 @@ public class Intent implements Parcelable { @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 changed (e.g. a component has been - * enabled or disabled. The data contains the name of the package. + * Broadcast Action: An existing application package has been changed (e.g. + * a component has been enabled or disabled). The data contains the name of + * the package. * <ul> * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package. - * <li> {@link #EXTRA_CHANGED_COMPONENT_NAME} containing the class name of the changed component. - * <li> {@link #EXTRA_DONT_KILL_APP} containing boolean field to override the default action of restarting the application. + * <li> {@link #EXTRA_CHANGED_COMPONENT_NAME_LIST} containing the class name + * of the changed components. + * <li> {@link #EXTRA_DONT_KILL_APP} containing boolean field to override the + * default action of restarting the application. * </ul> * * <p class="note">This is a protected intent that can only be sent @@ -2101,14 +2104,20 @@ public class Intent implements Parcelable { "android.intent.extra.remote_intent_token"; /** - * Used as an int extra field in {@link android.content.Intent#ACTION_PACKAGE_CHANGED} - * intent to supply the name of the component that changed. - * + * @Deprecated See {@link #EXTRA_CHANGED_COMPONENT_NAME_LIST}; this field + * will contain only the first name in the list. */ public static final String EXTRA_CHANGED_COMPONENT_NAME = "android.intent.extra.changed_component_name"; /** + * This field is part of {@link android.content.Intent#ACTION_PACKAGE_CHANGED} + * and contains a string array of all of the components that have changed. + */ + public static final String EXTRA_CHANGED_COMPONENT_NAME_LIST = + "android.intent.extra.changed_component_name_list"; + + /** * @hide * Magic extra system code can use when binding, to give a label for * who it is that has bound to a service. This is an integer giving diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index a83459edaba5..39129d4852b9 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -277,7 +277,8 @@ class PackageManagerService extends IPackageManager.Stub { PackageParser.Package mPlatformPackage; // Set of pending broadcasts for aggregating enable/disable of components. - final HashMap<String, String> mPendingBroadcasts = new HashMap<String, String>(); + final HashMap<String, ArrayList<String>> mPendingBroadcasts + = new HashMap<String, ArrayList<String>>(); static final int SEND_PENDING_BROADCAST = 1; // Delay time in millisecs static final int BROADCAST_DELAY = 10 * 1000; @@ -289,30 +290,40 @@ class PackageManagerService extends IPackageManager.Stub { public void handleMessage(Message msg) { switch (msg.what) { case SEND_PENDING_BROADCAST : { + String packages[]; + ArrayList components[]; int size = 0; - String broadcastList[]; - HashMap<String, String> tmpMap; int uids[]; synchronized (mPackages) { + if (mPendingBroadcasts == null) { + return; + } size = mPendingBroadcasts.size(); if (size <= 0) { // Nothing to be done. Just return return; } - broadcastList = new String[size]; - mPendingBroadcasts.keySet().toArray(broadcastList); - tmpMap = new HashMap<String, String>(mPendingBroadcasts); + packages = new String[size]; + components = new ArrayList[size]; uids = new int[size]; - for (int i = 0; i < size; i++) { - PackageSetting ps = mSettings.mPackages.get(mPendingBroadcasts.get(broadcastList[i])); + Iterator<HashMap.Entry<String, ArrayList<String>>> + it = mPendingBroadcasts.entrySet().iterator(); + int i = 0; + while (it.hasNext() && i < size) { + HashMap.Entry<String, ArrayList<String>> ent = it.next(); + packages[i] = ent.getKey(); + components[i] = ent.getValue(); + PackageSetting ps = mSettings.mPackages.get(ent.getKey()); uids[i] = (ps != null) ? ps.userId : -1; + i++; } + size = i; mPendingBroadcasts.clear(); } // Send broadcasts for (int i = 0; i < size; i++) { - String className = broadcastList[i]; - sendPackageChangedBroadcast(className, true, tmpMap.get(className), uids[i]); + sendPackageChangedBroadcast(packages[i], true, + (ArrayList<String>)components[i], uids[i]); } break; } @@ -5023,8 +5034,9 @@ class PackageManagerService extends IPackageManager.Stub { final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); boolean sendNow = false; boolean isApp = (className == null); - String key = isApp ? packageName : className; + String componentName = isApp ? packageName : className; int packageUid = -1; + ArrayList<String> components; synchronized (mPackages) { pkgSetting = mSettings.mPackages.get(packageName); if (pkgSetting == null) { @@ -5064,17 +5076,22 @@ class PackageManagerService extends IPackageManager.Stub { } mSettings.writeLP(); packageUid = pkgSetting.userId; + components = mPendingBroadcasts.get(packageName); + boolean newPackage = components == null; + if (newPackage) { + components = new ArrayList<String>(); + } + if (!components.contains(componentName)) { + components.add(componentName); + } if ((flags&PackageManager.DONT_KILL_APP) == 0) { sendNow = true; // Purge entry from pending broadcast list if another one exists already // since we are sending one right away. - if (mPendingBroadcasts.get(key) != null) { - mPendingBroadcasts.remove(key); - // Can ignore empty list since its handled in the handler anyway - } + mPendingBroadcasts.remove(packageName); } else { - if (mPendingBroadcasts.get(key) == null) { - mPendingBroadcasts.put(key, packageName); + if (newPackage) { + mPendingBroadcasts.put(packageName, components); } if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { // Schedule a message @@ -5087,7 +5104,7 @@ class PackageManagerService extends IPackageManager.Stub { try { if (sendNow) { sendPackageChangedBroadcast(packageName, - (flags&PackageManager.DONT_KILL_APP) != 0, key, packageUid); + (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); } } finally { Binder.restoreCallingIdentity(callingId); @@ -5095,9 +5112,14 @@ class PackageManagerService extends IPackageManager.Stub { } private void sendPackageChangedBroadcast(String packageName, - boolean killFlag, String componentName, int packageUid) { - Bundle extras = new Bundle(2); - extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentName); + boolean killFlag, ArrayList<String> componentNames, int packageUid) { + if (false) Log.v(TAG, "Sending package changed: package=" + packageName + + " components=" + componentNames); + Bundle extras = new Bundle(4); + extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); + String nameList[] = new String[componentNames.size()]; + componentNames.toArray(nameList); + extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); extras.putInt(Intent.EXTRA_UID, packageUid); sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras); |