Merge "Fix glyph cropping bug" into jb-mr1-dev
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 115c867..e9c4701 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1106,7 +1106,17 @@
     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 22807a4..6c19282 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -200,7 +200,7 @@
     List<PackageInfo> 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 f287ca5..2837931 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2460,6 +2460,17 @@
             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
      * assigning preferred activities and this can not be directly modified.
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index e63c57f..4937e1d 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -150,7 +150,8 @@
 
             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 @@
                     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 @@
         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 0d6e08d..430edf7 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -2422,6 +2422,9 @@
                 final int M = prefs.size();
                 for (int i=0; i<M; i++) {
                     final PreferredActivity pa = prefs.get(i);
+                    if (pa.mUserId != userId) {
+                        continue;
+                    }
                     if (pa.mPref.mMatch != match) {
                         continue;
                     }
@@ -7645,7 +7648,7 @@
                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
                         }
                     }
-                    clearPackagePreferredActivitiesLPw(deletedPs.name);
+                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
                 }
             }
             // can downgrade to reader
@@ -8112,26 +8115,28 @@
     }
     
     public void addPreferredActivity(IntentFilter filter, int match,
-            ComponentName[] set, ComponentName activity) {
+            ComponentName[] set, ComponentName activity, int userId) {
         // writer
+        int callingUid = Binder.getCallingUid();
+        checkValidCaller(callingUid, userId);
         synchronized (mPackages) {
             if (mContext.checkCallingOrSelfPermission(
                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
                     != PackageManager.PERMISSION_GRANTED) {
-                if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
+                if (getUidTargetSdkVersionLockedLPr(callingUid)
                         < Build.VERSION_CODES.FROYO) {
                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
-                            + Binder.getCallingUid());
+                            + callingUid);
                     return;
                 }
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
             }
-            
-            Slog.i(TAG, "Adding preferred activity " + activity + ":");
+
+            Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
             mSettings.mPreferredActivities.addFilter(
-                    new PreferredActivity(filter, match, set, activity));
+                    new PreferredActivity(filter, match, set, activity, userId));
             scheduleWriteSettingsLocked();            
         }
     }
@@ -8167,13 +8172,15 @@
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
             }
-            
+
+            final int callingUserId = UserHandle.getCallingUserId();
             ArrayList<PreferredActivity> removed = null;
             Iterator<PreferredActivity> 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<PreferredActivity>();
@@ -8189,7 +8196,7 @@
                     mSettings.mPreferredActivities.removeFilter(pa);
                 }
             }
-            addPreferredActivity(filter, match, set, activity);
+            addPreferredActivity(filter, match, set, activity, callingUserId);
         }
     }
 
@@ -8213,17 +8220,21 @@
                 }
             }
 
-            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<PreferredActivity> removed = null;
         Iterator<PreferredActivity> 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<PreferredActivity>();
@@ -8245,11 +8256,15 @@
             List<ComponentName> outActivities, String packageName) {
 
         int num = 0;
+        final int userId = UserHandle.getCallingUserId();
         // reader
         synchronized (mPackages) {
             final Iterator<PreferredActivity> 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 b100eb1..5539e84 100644
--- a/services/java/com/android/server/pm/PreferredActivity.java
+++ b/services/java/com/android/server/pm/PreferredActivity.java
@@ -33,22 +33,38 @@
     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 a828864..c69f7c8 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -506,6 +506,7 @@
             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;
     }