From a3f133afe885f9e005dfc0584cb7b3b90f75f665 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Thu, 9 Aug 2012 17:11:28 -0700 Subject: [PATCH] Save preferred activity info with user id. So each user can have their own set of intent resolution preferences. ResolverActivity now launches the activity on the correct user, and persists the preference for the correct user. Bug: 6961905 Change-Id: I6d3a8a9af89bc649277d4fc8d0f367ee123f8392 --- .../app/ApplicationPackageManager.java | 12 +++++- .../android/content/pm/IPackageManager.aidl | 2 +- .../android/content/pm/PackageManager.java | 11 ++++++ .../internal/app/ResolverActivity.java | 9 +++-- .../server/pm/PackageManagerService.java | 37 +++++++++++++------ .../android/server/pm/PreferredActivity.java | 18 ++++++++- .../android/server/pm/UserManagerService.java | 1 + 7 files changed, 72 insertions(+), 18 deletions(-) diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 115c867e44c1f..e9c4701bb2c77 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1106,7 +1106,17 @@ final class ApplicationPackageManager extends PackageManager { public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) { try { - mPM.addPreferredActivity(filter, match, set, activity); + mPM.addPreferredActivity(filter, match, set, activity, UserHandle.myUserId()); + } catch (RemoteException e) { + // Should never happen! + } + } + + @Override + public void addPreferredActivity(IntentFilter filter, int match, + ComponentName[] set, ComponentName activity, int userId) { + try { + mPM.addPreferredActivity(filter, match, set, activity, userId); } catch (RemoteException e) { // Should never happen! } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 22807a4c58fc8..6c1928283f350 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -200,7 +200,7 @@ interface IPackageManager { List getPreferredPackages(int flags); void addPreferredActivity(in IntentFilter filter, int match, - in ComponentName[] set, in ComponentName activity); + in ComponentName[] set, in ComponentName activity, int userId); void replacePreferredActivity(in IntentFilter filter, int match, in ComponentName[] set, in ComponentName activity); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index f287ca51fea1c..283793133ca5c 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -2459,6 +2459,17 @@ public abstract class PackageManager { public abstract void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity); + /** + * Same as {@link #addPreferredActivity(IntentFilter, int, + ComponentName[], ComponentName)}, but with a specific userId to apply the preference + to. + * @hide + */ + public void addPreferredActivity(IntentFilter filter, int match, + ComponentName[] set, ComponentName activity, int userId) { + throw new RuntimeException("Not implemented. Must override in a subclass."); + } + /** * @deprecated This is a protected API that should not have been available * to third party applications. It is the platform's responsibility for diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index e63c57f47d80c..4937e1dd98d0b 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -150,7 +150,8 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte resizeGrid(); } else if (count == 1) { - startActivity(mAdapter.intentForPosition(0)); + startActivityAsUser(mAdapter.intentForPosition(0), + UserHandle.getUserId(mLaunchedFromUid)); mPackageMonitor.unregister(); mRegistered = false; finish(); @@ -363,12 +364,12 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte if (r.match > bestMatch) bestMatch = r.match; } getPackageManager().addPreferredActivity(filter, bestMatch, set, - intent.getComponent()); + intent.getComponent(), UserHandle.getUserId(mLaunchedFromUid)); } } if (intent != null) { - startActivity(intent); + startActivityAsUser(intent, UserHandle.getUserId(mLaunchedFromUid)); } } @@ -376,7 +377,7 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte Intent in = new Intent().setAction("android.settings.APPLICATION_DETAILS_SETTINGS") .setData(Uri.fromParts("package", ri.activityInfo.packageName, null)) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); - startActivity(in); + startActivityAsUser(in, UserHandle.getUserId(mLaunchedFromUid)); } private final class DisplayResolveInfo { diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 0d6e08d0a9221..430edf725e43f 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -2422,6 +2422,9 @@ public class PackageManagerService extends IPackageManager.Stub { final int M = prefs.size(); for (int i=0; i removed = null; Iterator it = mSettings.mPreferredActivities.filterIterator(); String action = filter.getAction(0); String category = filter.getCategory(0); while (it.hasNext()) { PreferredActivity pa = it.next(); + if (pa.mUserId != callingUserId) continue; if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) { if (removed == null) { removed = new ArrayList(); @@ -8189,7 +8196,7 @@ public class PackageManagerService extends IPackageManager.Stub { mSettings.mPreferredActivities.removeFilter(pa); } } - addPreferredActivity(filter, match, set, activity); + addPreferredActivity(filter, match, set, activity, callingUserId); } } @@ -8213,17 +8220,21 @@ public class PackageManagerService extends IPackageManager.Stub { } } - if (clearPackagePreferredActivitiesLPw(packageName)) { + if (clearPackagePreferredActivitiesLPw(packageName, UserHandle.getCallingUserId())) { scheduleWriteSettingsLocked(); } } } - boolean clearPackagePreferredActivitiesLPw(String packageName) { + /** This method takes a specific user id as well as UserHandle.USER_ALL. */ + boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { ArrayList removed = null; Iterator it = mSettings.mPreferredActivities.filterIterator(); while (it.hasNext()) { PreferredActivity pa = it.next(); + if (userId != UserHandle.USER_ALL && pa.mUserId != userId) { + continue; + } if (pa.mPref.mComponent.getPackageName().equals(packageName)) { if (removed == null) { removed = new ArrayList(); @@ -8245,11 +8256,15 @@ public class PackageManagerService extends IPackageManager.Stub { List outActivities, String packageName) { int num = 0; + final int userId = UserHandle.getCallingUserId(); // reader synchronized (mPackages) { final Iterator it = mSettings.mPreferredActivities.filterIterator(); while (it.hasNext()) { final PreferredActivity pa = it.next(); + if (pa.mUserId != userId) { + continue; + } if (packageName == null || pa.mPref.mComponent.getPackageName().equals(packageName)) { if (outFilters != null) { diff --git a/services/java/com/android/server/pm/PreferredActivity.java b/services/java/com/android/server/pm/PreferredActivity.java index b100eb1621ef9..5539e8457df36 100644 --- a/services/java/com/android/server/pm/PreferredActivity.java +++ b/services/java/com/android/server/pm/PreferredActivity.java @@ -33,22 +33,38 @@ class PreferredActivity extends IntentFilter implements PreferredComponent.Callb private static final String TAG = "PreferredActivity"; private static final boolean DEBUG_FILTERS = false; + static final String ATTR_USER_ID = "userId"; final PreferredComponent mPref; + final int mUserId; PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) { + this(filter, match, set, activity, 0); + } + + PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, + int userId) { super(filter); + mUserId = userId; mPref = new PreferredComponent(this, match, set, activity); } PreferredActivity(XmlPullParser parser) throws XmlPullParserException, IOException { + String userIdString = parser.getAttributeValue(null, ATTR_USER_ID); + if (userIdString != null && userIdString.length() > 0) { + mUserId = Integer.parseInt(userIdString); + } else { + // Old format with no userId specified - assume primary user + mUserId = 0; + } mPref = new PreferredComponent(this, parser); } public void writeToXml(XmlSerializer serializer) throws IOException { + serializer.attribute(null, ATTR_USER_ID, Integer.toString(mUserId)); mPref.writeToXml(serializer); serializer.startTag(null, "filter"); - super.writeToXml(serializer); + super.writeToXml(serializer); serializer.endTag(null, "filter"); } diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java index a828864035505..c69f7c830ec35 100644 --- a/services/java/com/android/server/pm/UserManagerService.java +++ b/services/java/com/android/server/pm/UserManagerService.java @@ -506,6 +506,7 @@ public class UserManagerService extends IUserManager.Stub { Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED); addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id); mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS); + mContext.sendBroadcastToUser(new Intent(Intent.ACTION_BOOT_COMPLETED), userInfo.id); } return userInfo; }