From 8dbe612dc60526d635e57257b58627b33a099678 Mon Sep 17 00:00:00 2001 From: Satish Sampath Date: Tue, 2 Jun 2009 23:35:54 +0100 Subject: [PATCH] Adding internal method replacePreferredActivity. This was required because we need a way to set the preferred activity for a particular intent filter based on user selection (in our case the ACTION_WEB_SEARCH intent filter for selecting the preferred search engine from the list of available search engines providers). The current addPreferredActivity call was not sufficient since it leaves the existing preferred activities in the list and does not remove them, which this call does. --- core/java/android/app/ApplicationContext.java | 10 +++++ .../android/content/pm/IPackageManager.aidl | 5 +++ .../android/content/pm/PackageManager.java | 20 ++++++++++ .../android/server/PackageManagerService.java | 37 +++++++++++++++++++ .../android/test/mock/MockPackageManager.java | 10 +++++ 5 files changed, 82 insertions(+) diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java index 2c2310a030d45..2d6381a632dfe 100644 --- a/core/java/android/app/ApplicationContext.java +++ b/core/java/android/app/ApplicationContext.java @@ -2424,6 +2424,16 @@ class ApplicationContext extends Context { } } + @Override + public void replacePreferredActivity(IntentFilter filter, + int match, ComponentName[] set, ComponentName activity) { + try { + mPM.replacePreferredActivity(filter, match, set, activity); + } catch (RemoteException e) { + // Should never happen! + } + } + @Override public void clearPackagePreferredActivities(String packageName) { try { diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index bb913cdca90c1..5f62248bcd146 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -167,7 +167,12 @@ interface IPackageManager { void addPreferredActivity(in IntentFilter filter, int match, in ComponentName[] set, in ComponentName activity); + + void replacePreferredActivity(in IntentFilter filter, int match, + in ComponentName[] set, in ComponentName activity); + void clearPackagePreferredActivities(String packageName); + int getPreferredActivities(out List outFilters, out List outActivities, String packageName); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 238a98afd683e..a2c82e890e41b 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1629,6 +1629,26 @@ public abstract class PackageManager { public abstract void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity); + /** + * Replaces an existing preferred activity mapping to the system, and if that were not present + * adds a new preferred activity. This will be used + * to automatically select the given activity component when + * {@link Context#startActivity(Intent) Context.startActivity()} finds + * multiple matching activities and also matches the given filter. + * + * @param filter The set of intents under which this activity will be + * made preferred. + * @param match The IntentFilter match category that this preference + * applies to. + * @param set The set of activities that the user was picking from when + * this preference was made. + * @param activity The component name of the activity that is to be + * preferred. + * @hide + */ + public abstract void replacePreferredActivity(IntentFilter filter, int match, + ComponentName[] set, ComponentName activity); + /** * Remove all preferred activity mappings, previously added with * {@link #addPreferredActivity}, from the diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index c9bdd3c7ebef1..8da40acf93723 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -19,6 +19,7 @@ package com.android.server; import com.android.internal.app.ResolverActivity; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; +import com.android.server.PackageManagerService.PreferredActivity; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -4507,6 +4508,42 @@ class PackageManagerService extends IPackageManager.Stub { } } + public void replacePreferredActivity(IntentFilter filter, int match, + ComponentName[] set, ComponentName activity) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); + if (filter.countActions() != 1) { + throw new IllegalArgumentException( + "replacePreferredActivity expects filter to have only 1 action."); + } + if (filter.countCategories() != 1) { + throw new IllegalArgumentException( + "replacePreferredActivity expects filter to have only 1 category."); + } + if (filter.countDataAuthorities() != 0 + || filter.countDataPaths() != 0 + || filter.countDataSchemes() != 0 + || filter.countDataTypes() != 0) { + throw new IllegalArgumentException( + "replacePreferredActivity expects filter to have no data authorities, " + + "paths, schemes or types."); + } + synchronized (mPackages) { + Iterator it = mSettings.mPreferredActivities.filterIterator(); + String action = filter.getAction(0); + String category = filter.getCategory(0); + while (it.hasNext()) { + PreferredActivity pa = it.next(); + if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) { + it.remove(); + Log.i(TAG, "Removed preferred activity " + pa.mActivity + ":"); + filter.dump(new LogPrinter(Log.INFO, TAG), " "); + } + } + addPreferredActivity(filter, match, set, activity); + } + } + public void clearPackagePreferredActivities(String packageName) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java index 73ae3b91308ee..6ef5539ad0c8e 100644 --- a/test-runner/android/test/mock/MockPackageManager.java +++ b/test-runner/android/test/mock/MockPackageManager.java @@ -392,6 +392,16 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } + /** + * @hide - to match hiding in superclass + */ + @Override + public void replacePreferredActivity(IntentFilter filter, + int match, ComponentName[] set, ComponentName activity) { + throw new UnsupportedOperationException(); + } + + @Override public void clearPackagePreferredActivities(String packageName) { throw new UnsupportedOperationException();