Remove Binder.getOrigCallingUid().

Replaced all remaining places that used it with explicit user
specification.

While doing this, I ran into stuff that was creating PendingIntent
objects (that now need to specify the explicit user they are for),
which are also posting notifications...  but have no way to specify
the user for the notification.

So the notification manager in the system process now also gets a
formal concept of a user associated with the notification, which
is passed in to all the necessary aidl calls.  I also removed the
old deprecated aidl interface for posting/cancelling notifications,
since we now always need a user supplied.

There is more work that needs to be done here, though.  For example
I think we need to be able to specify USER_ALL for a notification that
should be shown to all users (such as low storage or low battery).
Along with that, the PendingIntent creation needs to be tweaked to
be able to handle USER_CURRENT by evaluating the user at the point the
pending intent is sent.

That's for another change, however.

Change-Id: I468e14dce8def0e13e0870571e7c31ed32b6310c
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 8e341df..b869abd 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -31,6 +31,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -184,56 +185,62 @@
 
     @Override
     public int allocateAppWidgetId(String packageName, int hostId) throws RemoteException {
-        return getImplForUser().allocateAppWidgetId(packageName, hostId);
+        return getImplForUser(UserHandle.getCallingUserId()).allocateAppWidgetId(
+                packageName, hostId);
     }
     
     @Override
     public void deleteAppWidgetId(int appWidgetId) throws RemoteException {
-        getImplForUser().deleteAppWidgetId(appWidgetId);
+        getImplForUser(UserHandle.getCallingUserId()).deleteAppWidgetId(appWidgetId);
     }
 
     @Override
     public void deleteHost(int hostId) throws RemoteException {
-        getImplForUser().deleteHost(hostId);
+        getImplForUser(UserHandle.getCallingUserId()).deleteHost(hostId);
     }
 
     @Override
     public void deleteAllHosts() throws RemoteException {
-        getImplForUser().deleteAllHosts();
+        getImplForUser(UserHandle.getCallingUserId()).deleteAllHosts();
     }
 
     @Override
     public void bindAppWidgetId(int appWidgetId, ComponentName provider) throws RemoteException {
-        getImplForUser().bindAppWidgetId(appWidgetId, provider);
+        getImplForUser(UserHandle.getCallingUserId()).bindAppWidgetId(appWidgetId, provider);
     }
 
     @Override
     public boolean bindAppWidgetIdIfAllowed(
             String packageName, int appWidgetId, ComponentName provider) throws RemoteException {
-        return getImplForUser().bindAppWidgetIdIfAllowed(packageName, appWidgetId, provider);
+        return getImplForUser(UserHandle.getCallingUserId()).bindAppWidgetIdIfAllowed(
+                packageName, appWidgetId, provider);
     }
 
     @Override
     public boolean hasBindAppWidgetPermission(String packageName) throws RemoteException {
-        return getImplForUser().hasBindAppWidgetPermission(packageName);
+        return getImplForUser(UserHandle.getCallingUserId()).hasBindAppWidgetPermission(
+                packageName);
     }
 
     @Override
     public void setBindAppWidgetPermission(String packageName, boolean permission)
             throws RemoteException {
-        getImplForUser().setBindAppWidgetPermission(packageName, permission);
+        getImplForUser(UserHandle.getCallingUserId()).setBindAppWidgetPermission(
+                packageName, permission);
     }
 
     @Override
     public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection)
             throws RemoteException {
-        getImplForUser().bindRemoteViewsService(appWidgetId, intent, connection);
+        getImplForUser(UserHandle.getCallingUserId()).bindRemoteViewsService(
+                appWidgetId, intent, connection);
     }
 
     @Override
     public int[] startListening(IAppWidgetHost host, String packageName, int hostId,
             List<RemoteViews> updatedViews) throws RemoteException {
-        return getImplForUser().startListening(host, packageName, hostId, updatedViews);
+        return getImplForUser(UserHandle.getCallingUserId()).startListening(host,
+                packageName, hostId, updatedViews);
     }
 
     public void onUserRemoved(int userId) {
@@ -247,8 +254,7 @@
         }
     }
 
-    private AppWidgetServiceImpl getImplForUser() {
-        final int userId = Binder.getOrigCallingUser();
+    private AppWidgetServiceImpl getImplForUser(int userId) {
         AppWidgetServiceImpl service = mAppWidgetServices.get(userId);
         if (service == null) {
             Slog.e(TAG, "Unable to find AppWidgetServiceImpl for the current user");
@@ -265,27 +271,27 @@
 
     @Override
     public int[] getAppWidgetIds(ComponentName provider) throws RemoteException {
-        return getImplForUser().getAppWidgetIds(provider);
+        return getImplForUser(UserHandle.getCallingUserId()).getAppWidgetIds(provider);
     }
 
     @Override
     public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) throws RemoteException {
-        return getImplForUser().getAppWidgetInfo(appWidgetId);
+        return getImplForUser(UserHandle.getCallingUserId()).getAppWidgetInfo(appWidgetId);
     }
 
     @Override
     public RemoteViews getAppWidgetViews(int appWidgetId) throws RemoteException {
-        return getImplForUser().getAppWidgetViews(appWidgetId);
+        return getImplForUser(UserHandle.getCallingUserId()).getAppWidgetViews(appWidgetId);
     }
 
     @Override
     public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
-        getImplForUser().updateAppWidgetOptions(appWidgetId, options);
+        getImplForUser(UserHandle.getCallingUserId()).updateAppWidgetOptions(appWidgetId, options);
     }
 
     @Override
     public Bundle getAppWidgetOptions(int appWidgetId) {
-        return getImplForUser().getAppWidgetOptions(appWidgetId);
+        return getImplForUser(UserHandle.getCallingUserId()).getAppWidgetOptions(appWidgetId);
     }
 
     static int[] getAppWidgetIds(Provider p) {
@@ -299,40 +305,43 @@
 
     @Override
     public List<AppWidgetProviderInfo> getInstalledProviders() throws RemoteException {
-        return getImplForUser().getInstalledProviders();
+        return getImplForUser(UserHandle.getCallingUserId()).getInstalledProviders();
     }
 
     @Override
     public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId)
             throws RemoteException {
-        getImplForUser().notifyAppWidgetViewDataChanged(appWidgetIds, viewId);
+        getImplForUser(UserHandle.getCallingUserId()).notifyAppWidgetViewDataChanged(
+                appWidgetIds, viewId);
     }
 
     @Override
     public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views)
             throws RemoteException {
-        getImplForUser().partiallyUpdateAppWidgetIds(appWidgetIds, views);
+        getImplForUser(UserHandle.getCallingUserId()).partiallyUpdateAppWidgetIds(
+                appWidgetIds, views);
     }
 
     @Override
     public void stopListening(int hostId) throws RemoteException {
-        getImplForUser().stopListening(hostId);
+        getImplForUser(UserHandle.getCallingUserId()).stopListening(hostId);
     }
 
     @Override
     public void unbindRemoteViewsService(int appWidgetId, Intent intent) throws RemoteException {
-        getImplForUser().unbindRemoteViewsService(appWidgetId, intent);
+        getImplForUser(UserHandle.getCallingUserId()).unbindRemoteViewsService(
+                appWidgetId, intent);
     }
 
     @Override
     public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views) throws RemoteException {
-        getImplForUser().updateAppWidgetIds(appWidgetIds, views);
+        getImplForUser(UserHandle.getCallingUserId()).updateAppWidgetIds(appWidgetIds, views);
     }
 
     @Override
     public void updateAppWidgetProvider(ComponentName provider, RemoteViews views)
             throws RemoteException {
-        getImplForUser().updateAppWidgetProvider(provider, views);
+        getImplForUser(UserHandle.getCallingUserId()).updateAppWidgetProvider(provider, views);
     }
 
     @Override
@@ -349,7 +358,12 @@
             String action = intent.getAction();
             // Slog.d(TAG, "received " + action);
             if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
-                getImplForUser().sendInitialBroadcasts();
+                int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                if (userId >= 0) {
+                    getImplForUser(userId).sendInitialBroadcasts();
+                } else {
+                    Slog.w(TAG, "Not user handle supplied in " + intent);
+                }
             } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
                 for (int i = 0; i < mAppWidgetServices.size(); i++) {
                     AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i);
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 8be0ba8..955ea23 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -1663,8 +1663,7 @@
         synchronized(mClearDataLock) {
             mClearingData = true;
             try {
-                mActivityManager.clearApplicationUserData(packageName, observer,
-                        Binder.getOrigCallingUser());
+                mActivityManager.clearApplicationUserData(packageName, observer, 0);
             } catch (RemoteException e) {
                 // can't happen because the activity manager is in this process
             }
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index e45cee3..40f6ecf 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -20,6 +20,7 @@
 import static org.xmlpull.v1.XmlPullParser.END_TAG;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
@@ -318,17 +319,20 @@
         final int id;
         final int uid;
         final int initialPid;
+        final int userId;
         final Notification notification;
         final int score;
         IBinder statusBarKey;
 
-        NotificationRecord(String pkg, String tag, int id, int uid, int initialPid, int score, Notification notification)
+        NotificationRecord(String pkg, String tag, int id, int uid, int initialPid,
+                int userId, int score, Notification notification)
         {
             this.pkg = pkg;
             this.tag = tag;
             this.id = id;
             this.uid = uid;
             this.initialPid = initialPid;
+            this.userId = userId;
             this.score = score;
             this.notification = notification;
         }
@@ -343,7 +347,7 @@
             pw.println(prefix + "  deleteIntent=" + notification.deleteIntent);
             pw.println(prefix + "  tickerText=" + notification.tickerText);
             pw.println(prefix + "  contentView=" + notification.contentView);
-            pw.println(prefix + "  uid=" + uid);
+            pw.println(prefix + "  uid=" + uid + " userId=" + userId);
             pw.println(prefix + "  defaults=0x" + Integer.toHexString(notification.defaults));
             pw.println(prefix + "  flags=0x" + Integer.toHexString(notification.flags));
             pw.println(prefix + "  sound=" + notification.sound);
@@ -430,18 +434,25 @@
         }
 
         public void onClearAll() {
-            cancelAll();
+            // XXX to be totally correct, the caller should tell us which user
+            // this is for.
+            cancelAll(ActivityManager.getCurrentUser());
         }
 
         public void onNotificationClick(String pkg, String tag, int id) {
+            // XXX to be totally correct, the caller should tell us which user
+            // this is for.
             cancelNotification(pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
-                    Notification.FLAG_FOREGROUND_SERVICE, false);
+                    Notification.FLAG_FOREGROUND_SERVICE, false,
+                    ActivityManager.getCurrentUser());
         }
 
         public void onNotificationClear(String pkg, String tag, int id) {
+            // XXX to be totally correct, the caller should tell us which user
+            // this is for.
             cancelNotification(pkg, tag, id, 0,
                 Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
-                true);
+                true, ActivityManager.getCurrentUser());
         }
 
         public void onPanelRevealed() {
@@ -480,7 +491,9 @@
                 int uid, int initialPid, String message) {
             Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id
                     + "; will crashApplication(uid=" + uid + ", pid=" + initialPid + ")");
-            cancelNotification(pkg, tag, id, 0, 0, false);
+            // XXX to be totally correct, the caller should tell us which user
+            // this is for.
+            cancelNotification(pkg, tag, id, 0, 0, false, UserHandle.getUserId(uid));
             long ident = Binder.clearCallingIdentity();
             try {
                 ActivityManagerNative.getDefault().crashApplication(uid, initialPid, pkg,
@@ -532,7 +545,8 @@
                 }
                 if (pkgList != null && (pkgList.length > 0)) {
                     for (String pkgName : pkgList) {
-                        cancelAllNotificationsInt(pkgName, 0, 0, !queryRestart);
+                        cancelAllNotificationsInt(pkgName, 0, 0, !queryRestart,
+                                UserHandle.USER_ALL);
                     }
                 }
             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
@@ -548,7 +562,7 @@
             } else if (action.equals(Intent.ACTION_USER_STOPPED)) {
                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 if (userHandle >= 0) {
-                    cancelAllNotificationsUser(userHandle);
+                    cancelAllNotificationsInt(null, 0, 0, true, userHandle);
                 }
             } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                 // turn off LED when user passes through lock screen
@@ -856,17 +870,11 @@
 
     // Notifications
     // ============================================================================
-    @Deprecated
-    public void enqueueNotification(String pkg, int id, Notification notification, int[] idOut)
-    {
-        enqueueNotificationWithTag(pkg, null /* tag */, id, notification, idOut);
-    }
-
     public void enqueueNotificationWithTag(String pkg, String tag, int id, Notification notification,
-            int[] idOut)
+            int[] idOut, int userId)
     {
         enqueueNotificationInternal(pkg, Binder.getCallingUid(), Binder.getCallingPid(),
-                tag, id, notification, idOut);
+                tag, id, notification, idOut, userId);
     }
     
     private final static int clamp(int x, int low, int high) {
@@ -877,7 +885,7 @@
     // Not exposed via Binder; for system use only (otherwise malicious apps could spoof the
     // uid/pid of another application)
     public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid,
-            String tag, int id, Notification notification, int[] idOut)
+            String tag, int id, Notification notification, int[] idOut, int userId)
     {
         if (DBG) {
             Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
@@ -885,6 +893,9 @@
         checkCallerIsSystemOrSameApp(pkg);
         final boolean isSystemNotification = ("android".equals(pkg));
 
+        userId = ActivityManager.handleIncomingUser(callingPid,
+                callingUid, userId, false, true, "enqueueNotification", pkg);
+
         // Limit the number of notifications that any given package except the android
         // package can enqueue.  Prevents DOS attacks and deals with leaks.
         if (!isSystemNotification) {
@@ -959,12 +970,12 @@
 
         synchronized (mNotificationList) {
             NotificationRecord r = new NotificationRecord(pkg, tag, id, 
-                    callingUid, callingPid, 
+                    callingUid, callingPid, userId,
                     score,
                     notification);
             NotificationRecord old = null;
 
-            int index = indexOfNotificationLocked(pkg, tag, id);
+            int index = indexOfNotificationLocked(pkg, tag, id, userId);
             if (index < 0) {
                 mNotificationList.add(r);
             } else {
@@ -1195,12 +1206,12 @@
      * and none of the {@code mustNotHaveFlags}.
      */
     private void cancelNotification(String pkg, String tag, int id, int mustHaveFlags,
-            int mustNotHaveFlags, boolean sendDelete) {
+            int mustNotHaveFlags, boolean sendDelete, int userId) {
         EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag,
                 mustHaveFlags, mustNotHaveFlags);
 
         synchronized (mNotificationList) {
-            int index = indexOfNotificationLocked(pkg, tag, id);
+            int index = indexOfNotificationLocked(pkg, tag, id, userId);
             if (index >= 0) {
                 NotificationRecord r = mNotificationList.get(index);
 
@@ -1224,7 +1235,7 @@
      * {@code mustHaveFlags}.
      */
     boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags,
-            int mustNotHaveFlags, boolean doit) {
+            int mustNotHaveFlags, boolean doit, int userId) {
         EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, mustHaveFlags,
                 mustNotHaveFlags);
 
@@ -1233,6 +1244,9 @@
             boolean canceledSomething = false;
             for (int i = N-1; i >= 0; --i) {
                 NotificationRecord r = mNotificationList.get(i);
+                if (userId != UserHandle.USER_ALL && r.userId != userId) {
+                    continue;
+                }
                 if ((r.notification.flags & mustHaveFlags) != mustHaveFlags) {
                     continue;
                 }
@@ -1256,48 +1270,25 @@
         }
     }
 
-    /**
-     * Cancels all notifications from a given user.
-     */
-    boolean cancelAllNotificationsUser(int userHandle) {
-        synchronized (mNotificationList) {
-            final int N = mNotificationList.size();
-            boolean canceledSomething = false;
-            for (int i = N-1; i >= 0; --i) {
-                NotificationRecord r = mNotificationList.get(i);
-                if (UserHandle.getUserId(r.uid) != userHandle) {
-                    continue;
-                }
-                canceledSomething = true;
-                mNotificationList.remove(i);
-                cancelNotificationLocked(r, false);
-            }
-            if (canceledSomething) {
-                updateLightsLocked();
-            }
-            return canceledSomething;
-        }
-    }
-
-    @Deprecated
-    public void cancelNotification(String pkg, int id) {
-        cancelNotificationWithTag(pkg, null /* tag */, id);
-    }
-
-    public void cancelNotificationWithTag(String pkg, String tag, int id) {
+    public void cancelNotificationWithTag(String pkg, String tag, int id, int userId) {
         checkCallerIsSystemOrSameApp(pkg);
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+                Binder.getCallingUid(), userId, false, true, "cancelNotificationWithTag", pkg);
         // Don't allow client applications to cancel foreground service notis.
         cancelNotification(pkg, tag, id, 0,
                 Binder.getCallingUid() == Process.SYSTEM_UID
-                ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false);
+                ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId);
     }
 
-    public void cancelAllNotifications(String pkg) {
+    public void cancelAllNotifications(String pkg, int userId) {
         checkCallerIsSystemOrSameApp(pkg);
 
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+                Binder.getCallingUid(), userId, true, true, "cancelAllNotifications", pkg);
+
         // Calling from user space, don't allow the canceling of actively
         // running foreground services.
-        cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true);
+        cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId);
     }
 
     void checkCallerIsSystem() {
@@ -1325,12 +1316,16 @@
         }
     }
 
-    void cancelAll() {
+    void cancelAll(int userId) {
         synchronized (mNotificationList) {
             final int N = mNotificationList.size();
             for (int i=N-1; i>=0; i--) {
                 NotificationRecord r = mNotificationList.get(i);
 
+                if (r.userId != userId) {
+                    continue;
+                }
+
                 if ((r.notification.flags & (Notification.FLAG_ONGOING_EVENT
                                 | Notification.FLAG_NO_CLEAR)) == 0) {
                     mNotificationList.remove(i);
@@ -1375,12 +1370,15 @@
     }
 
     // lock on mNotificationList
-    private int indexOfNotificationLocked(String pkg, String tag, int id)
+    private int indexOfNotificationLocked(String pkg, String tag, int id, int userId)
     {
         ArrayList<NotificationRecord> list = mNotificationList;
         final int len = list.size();
         for (int i=0; i<len; i++) {
             NotificationRecord r = list.get(i);
+            if (r.userId != userId || r.id != id) {
+                continue;
+            }
             if (tag == null) {
                 if (r.tag != null) {
                     continue;
@@ -1390,7 +1388,7 @@
                     continue;
                 }
             }
-            if (r.id == id && r.pkg.equals(pkg)) {
+            if (r.pkg.equals(pkg)) {
                 return i;
             }
         }
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 78c0c12..9f53fad 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -27,7 +27,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Slog;
-import android.view.View;
 
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.IStatusBarService;
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 4900e00..f618263 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -165,7 +165,7 @@
                     try {
                         ActivityManagerNative.getDefault().startActivityWithConfig(
                                 null, homeIntent, null, null, null, 0, 0,
-                                newConfig, null);
+                                newConfig, null, UserHandle.USER_CURRENT);
                         mHoldingConfiguration = false;
                     } catch (RemoteException e) {
                         Slog.w(TAG, e.getCause());
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 643e937..2ddfaa2 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -776,11 +776,11 @@
             intent.setComponent(componentName);
             intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                     com.android.internal.R.string.wallpaper_binding_label);
-            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
+            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser(
                     mContext, 0,
                     Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
                             mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
-                            0));
+                    0, null, new UserHandle(serviceUserId)));
             if (!mContext.bindService(intent, newConn, Context.BIND_AUTO_CREATE, serviceUserId)) {
                 String msg = "Unable to bind service: "
                         + componentName;
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index e836e77..6a3010b 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -323,7 +323,7 @@
             int startId) {
         if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
                 + " " + token + " startId=" + startId);
-        ServiceRecord r = findServiceLocked(className, token);
+        ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
         if (r != null) {
             if (startId >= 0) {
                 // Asked to only stop if done with all work.  Note that
@@ -366,9 +366,10 @@
 
     public void setServiceForegroundLocked(ComponentName className, IBinder token,
             int id, Notification notification, boolean removeNotification) {
+        final int userId = UserHandle.getCallingUserId();
         final long origId = Binder.clearCallingIdentity();
         try {
-            ServiceRecord r = findServiceLocked(className, token);
+            ServiceRecord r = findServiceLocked(className, token, userId);
             if (r != null) {
                 if (id != 0) {
                     if (notification == null) {
@@ -427,9 +428,6 @@
         if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
                 + " type=" + resolvedType + " conn=" + connection.asBinder()
                 + " flags=0x" + Integer.toHexString(flags));
-        if (DEBUG_MU)
-            Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
-                    + Binder.getOrigCallingUid());
         final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
         if (callerApp == null) {
             throw new SecurityException(
@@ -677,8 +675,8 @@
     }
 
     private final ServiceRecord findServiceLocked(ComponentName name,
-            IBinder token) {
-        ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
+            IBinder token, int userId) {
+        ServiceRecord r = mServiceMap.getServiceByName(name, userId);
         return r == token ? r : null;
     }
 
@@ -1424,9 +1422,6 @@
                     r.callStart = false;
                 }
             }
-            if (DEBUG_MU)
-                Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
-                        + Binder.getOrigCallingUid());
             final long origId = Binder.clearCallingIdentity();
             serviceDoneExecutingLocked(r, inStopping);
             Binder.restoreCallingIdentity(origId);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 6c87252..590e9d9 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1129,13 +1129,15 @@
                     notification.vibrate = null;
                     notification.setLatestEventInfo(context, text,
                             mContext.getText(R.string.heavy_weight_notification_detail),
-                            PendingIntent.getActivity(mContext, 0, root.intent,
-                                    PendingIntent.FLAG_CANCEL_CURRENT));
+                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
+                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
+                                    new UserHandle(root.userId)));
                     
                     try {
                         int[] outId = new int[1];
-                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
-                                notification, outId);
+                        inm.enqueueNotificationWithTag("android", null,
+                                R.string.heavy_weight_notification,
+                                notification, outId, root.userId);
                     } catch (RuntimeException e) {
                         Slog.w(ActivityManagerService.TAG,
                                 "Error showing notification for heavy-weight app", e);
@@ -1151,8 +1153,8 @@
                     return;
                 }
                 try {
-                    inm.cancelNotification("android",
-                            R.string.heavy_weight_notification);
+                    inm.cancelNotificationWithTag("android", null,
+                            R.string.heavy_weight_notification,  msg.arg1);
                 } catch (RuntimeException e) {
                     Slog.w(ActivityManagerService.TAG,
                             "Error canceling notification for service", e);
@@ -2371,14 +2373,6 @@
                 // Requesting home, set the identity to the current user
                 // HACK!
                 userId = mCurrentUserId;
-            } else {
-                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
-                // the current user's userId
-                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
-                    userId = 0;
-                } else {
-                    userId = Binder.getOrigCallingUser();
-                }
             }
         }
         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
@@ -2392,21 +2386,22 @@
             ParcelFileDescriptor profileFd, Bundle options) {
         enforceNotIsolatedCaller("startActivityAndWait");
         WaitResult res = new WaitResult();
-        int userId = Binder.getOrigCallingUser();
         mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
-                res, null, options, userId);
+                res, null, options, UserHandle.getCallingUserId());
         return res;
     }
 
     public final int startActivityWithConfig(IApplicationThread caller,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, Configuration config,
-            Bundle options) {
+            Bundle options, int userId) {
         enforceNotIsolatedCaller("startActivityWithConfig");
+        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
+                false, true, "startActivityWithConfig", null);
         int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags,
-                null, null, null, config, options, Binder.getOrigCallingUser());
+                null, null, null, config, options, userId);
         return ret;
     }
 
@@ -2537,21 +2532,16 @@
         }
     }
 
-    public final int startActivityInPackage(int uid,
+    final int startActivityInPackage(int uid,
             Intent intent, String resolvedType, IBinder resultTo,
-            String resultWho, int requestCode, int startFlags, Bundle options) {
-        
-        // This is so super not safe, that only the system (or okay root)
-        // can do it.
-        final int callingUid = Binder.getCallingUid();
-        if (callingUid != 0 && callingUid != Process.myUid()) {
-            throw new SecurityException(
-                    "startActivityInPackage only available to the system");
-        }
+            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
+
+        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
+                false, true, "startActivityInPackage", null);
 
         int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags,
-                null, null, null, null, options, UserHandle.getUserId(uid));
+                null, null, null, null, options, userId);
         return ret;
     }
 
@@ -2559,23 +2549,18 @@
             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
         enforceNotIsolatedCaller("startActivities");
         int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
-                options, Binder.getOrigCallingUser());
+                options, UserHandle.getCallingUserId());
         return ret;
     }
 
-    public final int startActivitiesInPackage(int uid,
+    final int startActivitiesInPackage(int uid,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
-            Bundle options) {
+            Bundle options, int userId) {
 
-        // This is so super not safe, that only the system (or okay root)
-        // can do it.
-        final int callingUid = Binder.getCallingUid();
-        if (callingUid != 0 && callingUid != Process.myUid()) {
-            throw new SecurityException(
-                    "startActivityInPackage only available to the system");
-        }
+        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
+                false, true, "startActivityInPackage", null);
         int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
-                options, UserHandle.getUserId(uid));
+                options, userId);
         return ret;
     }
 
@@ -2709,8 +2694,9 @@
                 }
             }
             
+            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
+                    mHeavyWeightProcess.userId, 0));
             mHeavyWeightProcess = null;
-            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
         }
     }
     
@@ -3884,8 +3870,9 @@
         mProcessNames.remove(name, uid);
         mIsolatedProcesses.remove(app.uid);
         if (mHeavyWeightProcess == app) {
+            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
+                    mHeavyWeightProcess.userId, 0));
             mHeavyWeightProcess = null;
-            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
         }
         boolean needRestart = false;
         if (app.pid > 0 && app.pid != MY_PID) {
@@ -3931,8 +3918,9 @@
             mProcessNames.remove(app.processName, app.uid);
             mIsolatedProcesses.remove(app.uid);
             if (mHeavyWeightProcess == app) {
+                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
+                        mHeavyWeightProcess.userId, 0));
                 mHeavyWeightProcess = null;
-                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
             }
             // Take care of any launching providers waiting for this process.
             checkAppInLaunchingProvidersLocked(app, true);
@@ -4288,12 +4276,13 @@
                     UserStartedState uss = mStartedUsers.valueAt(i);
                     if (uss.mState == UserStartedState.STATE_BOOTING) {
                         uss.mState = UserStartedState.STATE_RUNNING;
-                        broadcastIntentLocked(null, null,
-                                new Intent(Intent.ACTION_BOOT_COMPLETED, null),
+                        final int userId = mStartedUsers.keyAt(i);
+                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
+                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+                        broadcastIntentLocked(null, null, intent,
                                 null, null, 0, null, null,
                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
-                                false, false, MY_PID, Process.SYSTEM_UID,
-                                mStartedUsers.keyAt(i));
+                                false, false, MY_PID, Process.SYSTEM_UID, userId);
                     }
                 }
             }
@@ -4405,7 +4394,7 @@
     public IIntentSender getIntentSender(int type,
             String packageName, IBinder token, String resultWho,
             int requestCode, Intent[] intents, String[] resolvedTypes,
-            int flags, Bundle options) {
+            int flags, Bundle options, int userId) {
         enforceNotIsolatedCaller("getIntentSender");
         // Refuse possible leaked file descriptors
         if (intents != null) {
@@ -4439,6 +4428,8 @@
         
         synchronized(this) {
             int callingUid = Binder.getCallingUid();
+            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
+                    false, true, "getIntentSender", null);
             try {
                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
                     int uid = AppGlobals.getPackageManager()
@@ -4453,11 +4444,8 @@
                         throw new SecurityException(msg);
                     }
                 }
-                
-                if (DEBUG_MU)
-                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
-                            + Binder.getOrigCallingUid());
-                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
+
+                return getIntentSenderLocked(type, packageName, callingUid, userId,
                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
                 
             } catch (RemoteException e) {
@@ -4466,8 +4454,8 @@
         }
     }
     
-    IIntentSender getIntentSenderLocked(int type,
-            String packageName, int callingUid, IBinder token, String resultWho,
+    IIntentSender getIntentSenderLocked(int type, String packageName,
+            int callingUid, int userId, IBinder token, String resultWho,
             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
             Bundle options) {
         if (DEBUG_MU)
@@ -4491,8 +4479,7 @@
 
         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
                 type, packageName, activity, resultWho,
-                requestCode, intents, resolvedTypes, flags, options,
-                UserHandle.getUserId(callingUid));
+                requestCode, intents, resolvedTypes, flags, options, userId);
         WeakReference<PendingIntentRecord> ref;
         ref = mIntentSenderRecords.get(key);
         PendingIntentRecord rec = ref != null ? ref.get() : null;
@@ -6233,7 +6220,7 @@
     }
 
     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
-            String name, IBinder token, boolean stable) {
+            String name, IBinder token, boolean stable, int userId) {
         ContentProviderRecord cpr;
         ContentProviderConnection conn = null;
         ProviderInfo cpi = null;
@@ -6248,10 +6235,13 @@
                           + " (pid=" + Binder.getCallingPid()
                           + ") when getting content provider " + name);
                 }
+                if (r.userId != userId) {
+                    throw new SecurityException("Calling requested user " + userId
+                            + " but app is user " + r.userId);
+                }
             }
 
             // First check if this content provider has been published...
-            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
             cpr = mProviderMap.getProviderByName(name, userId);
             boolean providerRunning = cpr != null;
             if (providerRunning) {
@@ -6506,17 +6496,19 @@
             throw new SecurityException(msg);
         }
 
-        return getContentProviderImpl(caller, name, null, stable);
+        return getContentProviderImpl(caller, name, null, stable,
+                UserHandle.getCallingUserId());
     }
 
     public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
             "Do not have permission in call getContentProviderExternal()");
-        return getContentProviderExternalUnchecked(name, token);
+        return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
     }
 
-    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
-        return getContentProviderImpl(null, name, token, true);
+    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
+            IBinder token, int userId) {
+        return getContentProviderImpl(null, name, token, true, userId);
     }
 
     /**
@@ -6547,13 +6539,12 @@
     public void removeContentProviderExternal(String name, IBinder token) {
         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
             "Do not have permission in call removeContentProviderExternal()");
-        removeContentProviderExternalUnchecked(name, token);
+        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
     }
 
-    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
+    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
         synchronized (this) {
-            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
-                    Binder.getOrigCallingUser());
+            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
             if(cpr == null) {
                 //remove from mProvidersByClass
                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
@@ -6562,8 +6553,7 @@
 
             //update content provider record entry info
             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
-            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
-                    Binder.getOrigCallingUser());
+            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
             if (localCpr.hasExternalProcessHandles()) {
                 if (localCpr.removeExternalProcessHandleLocked(token)) {
                     updateOomAdjLocked();
@@ -6777,11 +6767,12 @@
     public String getProviderMimeType(Uri uri) {
         enforceNotIsolatedCaller("getProviderMimeType");
         final String name = uri.getAuthority();
+        final int userId = UserHandle.getCallingUserId();
         final long ident = Binder.clearCallingIdentity();
         ContentProviderHolder holder = null;
 
         try {
-            holder = getContentProviderExternalUnchecked(name, null);
+            holder = getContentProviderExternalUnchecked(name, null, userId);
             if (holder != null) {
                 return holder.provider.getType(uri);
             }
@@ -6790,7 +6781,7 @@
             return null;
         } finally {
             if (holder != null) {
-                removeContentProviderExternalUnchecked(name, null);
+                removeContentProviderExternalUnchecked(name, null, userId);
             }
             Binder.restoreCallingIdentity(ident);
         }
@@ -6894,8 +6885,9 @@
 
     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
         enforceNotIsolatedCaller("openContentUri");
+        final int userId = UserHandle.getCallingUserId();
         String name = uri.getAuthority();
-        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
+        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
         ParcelFileDescriptor pfd = null;
         if (cph != null) {
             // We record the binder invoker's uid in thread-local storage before
@@ -6917,7 +6909,7 @@
             }
 
             // We've got the fd now, so we're done with the provider.
-            removeContentProviderExternalUnchecked(name, null);
+            removeContentProviderExternalUnchecked(name, null, userId);
         } else {
             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
         }
@@ -10562,8 +10554,9 @@
             mProcessNames.remove(app.processName, app.uid);
             mIsolatedProcesses.remove(app.uid);
             if (mHeavyWeightProcess == app) {
+                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
+                        mHeavyWeightProcess.userId, 0));
                 mHeavyWeightProcess = null;
-                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
             }
         } else if (!app.removed) {
             // This app is persistent, so we need to keep its record around.
@@ -10663,13 +10656,13 @@
     }
 
     ComponentName startServiceInPackage(int uid,
-            Intent service, String resolvedType) {
+            Intent service, String resolvedType, int userId) {
         synchronized(this) {
             if (DEBUG_SERVICE)
                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
             final long origId = Binder.clearCallingIdentity();
             ComponentName res = mServices.startServiceLocked(null, service,
-                    resolvedType, -1, uid, UserHandle.getUserId(uid));
+                    resolvedType, -1, uid, userId);
             Binder.restoreCallingIdentity(origId);
             return res;
         }
@@ -10716,6 +10709,14 @@
         }
     }
 
+    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
+            boolean requireFull, String name, String callerPackage) {
+        synchronized(this) {
+            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
+                    requireFull, name, callerPackage);
+        }        
+    }
+
     int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
             boolean requireFull, String name, String callerPackage) {
         final int callingUserId = UserHandle.getUserId(callingUid);
@@ -10733,13 +10734,24 @@
                         // owner user instead of failing.
                         userId = callingUserId;
                     } else {
-                        String msg = "Permission Denial: " + name + " from " + callerPackage
-                                + " asks to run as user " + userId
-                                + " but is calling from user " + UserHandle.getUserId(callingUid)
-                                + "; this requires "
-                                + (requireFull
-                                        ? android.Manifest.permission.INTERACT_ACROSS_USERS_FULL
-                                        : android.Manifest.permission.INTERACT_ACROSS_USERS);
+                        StringBuilder builder = new StringBuilder(128);
+                        builder.append("Permission Denial: ");
+                        builder.append(name);
+                        if (callerPackage != null) {
+                            builder.append(" from ");
+                            builder.append(callerPackage);
+                        }
+                        builder.append(" asks to run as user ");
+                        builder.append(userId);
+                        builder.append(" but is calling from user ");
+                        builder.append(UserHandle.getUserId(callingUid));
+                        builder.append("; this requires ");
+                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+                        if (!requireFull) {
+                            builder.append("or");
+                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
+                        }
+                        String msg = builder.toString();
                         Slog.w(TAG, msg);
                         throw new SecurityException(msg);
                     }
@@ -13760,11 +13772,13 @@
             if (uss.mState == UserStartedState.STATE_BOOTING
                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
                 uss.mState = UserStartedState.STATE_RUNNING;
-                broadcastIntentLocked(null, null,
-                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
+                final int userId = uss.mHandle.getIdentifier();
+                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
+                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+                broadcastIntentLocked(null, null, intent,
                         null, null, 0, null, null,
                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
-                        false, false, MY_PID, Process.SYSTEM_UID, uss.mHandle.getIdentifier());
+                        false, false, MY_PID, Process.SYSTEM_UID, userId);
             }
         }
     }
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index ef4e9be..399ea59 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -3077,7 +3077,7 @@
                         
                         IIntentSender target = mService.getIntentSenderLocked(
                                 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
-                                realCallingUid, null, null, 0, new Intent[] { intent },
+                                realCallingUid, userId, null, null, 0, new Intent[] { intent },
                                 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
                                 | PendingIntent.FLAG_ONE_SHOT, null);
                         
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 8e70376..37e9017 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -243,11 +243,10 @@
                                 allIntents[allIntents.length-1] = finalIntent;
                                 allResolvedTypes[allResolvedTypes.length-1] = resolvedType;
                                 owner.startActivitiesInPackage(uid, allIntents,
-                                        allResolvedTypes, resultTo, options);
+                                        allResolvedTypes, resultTo, options, key.userId);
                             } else {
-                                owner.startActivityInPackage(uid,
-                                        finalIntent, resolvedType,
-                                        resultTo, resultWho, requestCode, 0, options);
+                                owner.startActivityInPackage(uid, finalIntent, resolvedType,
+                                        resultTo, resultWho, requestCode, 0, options, key.userId);
                             }
                         } catch (RuntimeException e) {
                             Slog.w(ActivityManagerService.TAG,
@@ -265,8 +264,7 @@
                             owner.broadcastIntentInPackage(key.packageName, uid,
                                     finalIntent, resolvedType,
                                     finishedReceiver, code, null, null,
-                                requiredPermission, (finishedReceiver != null), false, UserHandle
-                                        .getUserId(uid));
+                                requiredPermission, (finishedReceiver != null), false, key.userId);
                             sendFinish = false;
                         } catch (RuntimeException e) {
                             Slog.w(ActivityManagerService.TAG,
@@ -276,7 +274,7 @@
                     case ActivityManager.INTENT_SENDER_SERVICE:
                         try {
                             owner.startServiceInPackage(uid,
-                                    finalIntent, resolvedType);
+                                    finalIntent, resolvedType, key.userId);
                         } catch (RuntimeException e) {
                             Slog.w(ActivityManagerService.TAG,
                                     "Unable to send startService intent", e);
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index 15fbb98..7a4fef6 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -116,48 +116,46 @@
         }
     }
 
-    void removeProviderByName(String name, int optionalUserId) {
+    void removeProviderByName(String name, int userId) {
         if (mSingletonByName.containsKey(name)) {
             if (DBG)
                 Slog.i(TAG, "Removing from globalByName name=" + name);
             mSingletonByName.remove(name);
         } else {
-            // TODO: Verify this works, i.e., the caller happens to be from the correct user
+            if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
             if (DBG)
                 Slog.i(TAG,
-                        "Removing from providersByName name=" + name + " user="
-                        + (optionalUserId == -1 ? Binder.getOrigCallingUser() : optionalUserId));
-            HashMap<String, ContentProviderRecord> map = getProvidersByName(optionalUserId);
+                        "Removing from providersByName name=" + name + " user=" + userId);
+            HashMap<String, ContentProviderRecord> map = getProvidersByName(userId);
             // map returned by getProvidersByName wouldn't be null
             map.remove(name);
             if (map.size() == 0) {
-                mProvidersByNamePerUser.remove(optionalUserId);
+                mProvidersByNamePerUser.remove(userId);
             }
         }
     }
 
-    void removeProviderByClass(ComponentName name, int optionalUserId) {
+    void removeProviderByClass(ComponentName name, int userId) {
         if (mSingletonByClass.containsKey(name)) {
             if (DBG)
                 Slog.i(TAG, "Removing from globalByClass name=" + name);
             mSingletonByClass.remove(name);
         } else {
+            if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
             if (DBG)
                 Slog.i(TAG,
-                        "Removing from providersByClass name=" + name + " user="
-                        + (optionalUserId == -1 ? Binder.getOrigCallingUser() : optionalUserId));
-            HashMap<ComponentName, ContentProviderRecord> map = getProvidersByClass(optionalUserId);
+                        "Removing from providersByClass name=" + name + " user=" + userId);
+            HashMap<ComponentName, ContentProviderRecord> map = getProvidersByClass(userId);
             // map returned by getProvidersByClass wouldn't be null
             map.remove(name);
             if (map.size() == 0) {
-                mProvidersByClassPerUser.remove(optionalUserId);
+                mProvidersByClassPerUser.remove(userId);
             }
         }
     }
 
-    private HashMap<String, ContentProviderRecord> getProvidersByName(int optionalUserId) {
-        final int userId = optionalUserId >= 0
-                ? optionalUserId : Binder.getOrigCallingUser();
+    private HashMap<String, ContentProviderRecord> getProvidersByName(int userId) {
+        if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
         final HashMap<String, ContentProviderRecord> map = mProvidersByNamePerUser.get(userId);
         if (map == null) {
             HashMap<String, ContentProviderRecord> newMap = new HashMap<String, ContentProviderRecord>();
@@ -168,12 +166,13 @@
         }
     }
 
-    HashMap<ComponentName, ContentProviderRecord> getProvidersByClass(int optionalUserId) {
-        final int userId = optionalUserId >= 0
-                ? optionalUserId : Binder.getOrigCallingUser();
-        final HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.get(userId);
+    HashMap<ComponentName, ContentProviderRecord> getProvidersByClass(int userId) {
+        if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
+        final HashMap<ComponentName, ContentProviderRecord> map
+                = mProvidersByClassPerUser.get(userId);
         if (map == null) {
-            HashMap<ComponentName, ContentProviderRecord> newMap = new HashMap<ComponentName, ContentProviderRecord>();
+            HashMap<ComponentName, ContentProviderRecord> newMap
+                    = new HashMap<ComponentName, ContentProviderRecord>();
             mProvidersByClassPerUser.put(userId, newMap);
             return newMap;
         } else {
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 5d60b9c..7055fdc 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -370,7 +370,7 @@
                     try {
                         int[] outId = new int[1];
                         nm.enqueueNotificationInternal(localPackageName, appUid, appPid,
-                                null, localForegroundId, localForegroundNoti, outId);
+                                null, localForegroundId, localForegroundNoti, outId, userId);
                     } catch (RuntimeException e) {
                         Slog.w(ActivityManagerService.TAG,
                                 "Error showing notification for service", e);
@@ -399,7 +399,8 @@
                         return;
                     }
                     try {
-                        inm.cancelNotification(localPackageName, localForegroundId);
+                        inm.cancelNotificationWithTag(localPackageName, null,
+                                localForegroundId, userId);
                     } catch (RuntimeException e) {
                         Slog.w(ActivityManagerService.TAG,
                                 "Error canceling notification for service", e);
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index c6e66cf..46bddc4 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -788,11 +788,13 @@
         }
 
         // TODO: move to NotificationManager once we can mock it
+        // XXX what to do about multi-user?
         try {
             final String packageName = mContext.getPackageName();
             final int[] idReceived = new int[1];
             mNotifManager.enqueueNotificationWithTag(
-                    packageName, tag, 0x0, builder.getNotification(), idReceived);
+                    packageName, tag, 0x0, builder.getNotification(), idReceived,
+                    UserHandle.USER_OWNER);
             mActiveNotifs.add(tag);
         } catch (RemoteException e) {
             // ignored; service lives in system_server
@@ -822,11 +824,12 @@
                 PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
 
         // TODO: move to NotificationManager once we can mock it
+        // XXX what to do about multi-user?
         try {
             final String packageName = mContext.getPackageName();
             final int[] idReceived = new int[1];
             mNotifManager.enqueueNotificationWithTag(packageName, tag,
-                    0x0, builder.getNotification(), idReceived);
+                    0x0, builder.getNotification(), idReceived, UserHandle.USER_OWNER);
             mActiveNotifs.add(tag);
         } catch (RemoteException e) {
             // ignored; service lives in system_server
@@ -835,10 +838,11 @@
 
     private void cancelNotification(String tag) {
         // TODO: move to NotificationManager once we can mock it
+        // XXX what to do about multi-user?
         try {
             final String packageName = mContext.getPackageName();
             mNotifManager.cancelNotificationWithTag(
-                    packageName, tag, 0x0);
+                    packageName, tag, 0x0, UserHandle.USER_OWNER);
         } catch (RemoteException e) {
             // ignored; service lives in system_server
         }