From 4120375d46091df8527bb701882e056fbb0e6b06 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Fri, 31 Aug 2012 14:05:51 -0700 Subject: [PATCH] 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 --- cmds/pm/src/com/android/commands/pm/Pm.java | 4 +- .../accounts/AccountManagerService.java | 23 ++- core/java/android/app/Activity.java | 3 +- core/java/android/app/ActivityManager.java | 28 ++- .../android/app/ActivityManagerNative.java | 134 ++++--------- core/java/android/app/ContextImpl.java | 14 +- core/java/android/app/IActivityManager.java | 20 +- .../android/app/INotificationManager.aidl | 11 +- .../java/android/app/NotificationManager.java | 41 +++- core/java/android/app/PendingIntent.java | 31 ++- core/java/android/content/SyncManager.java | 25 ++- core/java/android/os/Binder.java | 28 --- core/jni/android_util_Binder.cpp | 6 - .../android/app/activity/BroadcastTest.java | 4 +- .../statusbar/policy/LocationController.java | 14 +- .../com/android/server/AppWidgetService.java | 64 +++--- .../android/server/BackupManagerService.java | 3 +- .../server/NotificationManagerService.java | 112 ++++++----- .../server/StatusBarManagerService.java | 1 - .../android/server/UiModeManagerService.java | 2 +- .../server/WallpaperManagerService.java | 4 +- .../com/android/server/am/ActiveServices.java | 15 +- .../server/am/ActivityManagerService.java | 186 ++++++++++-------- .../com/android/server/am/ActivityStack.java | 2 +- .../server/am/PendingIntentRecord.java | 12 +- .../com/android/server/am/ProviderMap.java | 37 ++-- .../com/android/server/am/ServiceRecord.java | 5 +- .../net/NetworkPolicyManagerService.java | 10 +- .../NetworkPolicyManagerServiceTest.java | 5 +- .../statusbartest/NotificationTestList.java | 10 +- 30 files changed, 443 insertions(+), 411 deletions(-) diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index e621ceb48b696..36bf38a3a5a6e 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -1120,8 +1120,8 @@ public final class Pm { ClearDataObserver obs = new ClearDataObserver(); try { - if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, - Binder.getOrigCallingUser())) { + // XXX TO DO: add user arg + if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, 0)) { System.err.println("Failed"); } diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 7a9f2859109ad..b749d8e45e56f 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -1052,7 +1052,7 @@ public class AccountManagerService if (account == null) throw new IllegalArgumentException("account is null"); if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); checkBinderPermission(Manifest.permission.USE_CREDENTIALS); - UserAccounts accounts = getUserAccountsForCaller(); + final UserAccounts accounts = getUserAccountsForCaller(); AccountAuthenticatorCache.ServiceInfo authenticatorInfo = mAuthenticatorCache.getServiceInfo( AuthenticatorDescription.newKey(account.type)); @@ -1141,7 +1141,7 @@ public class AccountManagerService if (intent != null && notifyOnAuthFailure && !customTokens) { doNotification(mAccounts, account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE), - intent); + intent, accounts.userId); } } super.onResult(result); @@ -1152,7 +1152,8 @@ public class AccountManagerService } } - private void createNoCredentialsPermissionNotification(Account account, Intent intent) { + private void createNoCredentialsPermissionNotification(Account account, Intent intent, + int userId) { int uid = intent.getIntExtra( GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, -1); String authTokenType = intent.getStringExtra( @@ -1172,9 +1173,10 @@ public class AccountManagerService title = titleAndSubtitle.substring(0, index); subtitle = titleAndSubtitle.substring(index + 1); } - n.setLatestEventInfo(mContext, - title, subtitle, - PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)); + n.setLatestEventInfo(mContext, title, subtitle, + PendingIntent.getActivityAsUser(mContext, 0, intent, + PendingIntent.FLAG_CANCEL_CURRENT, + null, new UserHandle(userId))); installNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), n); } @@ -2083,7 +2085,7 @@ public class AccountManagerService } private void doNotification(UserAccounts accounts, Account account, CharSequence message, - Intent intent) { + Intent intent, int userId) { long identityToken = clearCallingIdentity(); try { if (Log.isLoggable(TAG, Log.VERBOSE)) { @@ -2093,7 +2095,7 @@ public class AccountManagerService if (intent.getComponent() != null && GrantCredentialsPermissionActivity.class.getName().equals( intent.getComponent().getClassName())) { - createNoCredentialsPermissionNotification(account, intent); + createNoCredentialsPermissionNotification(account, intent, userId); } else { final Integer notificationId = getSigninRequiredNotificationId(accounts, account); intent.addCategory(String.valueOf(notificationId)); @@ -2103,8 +2105,9 @@ public class AccountManagerService mContext.getText(R.string.notification_title).toString(); n.setLatestEventInfo(mContext, String.format(notificationTitleFormat, account.name), - message, PendingIntent.getActivity( - mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)); + message, PendingIntent.getActivityAsUser( + mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, + null, new UserHandle(userId))); installNotification(notificationId, n); } } finally { diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index d5580b708036a..99dfccbab273d 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -4278,7 +4278,8 @@ public class Activity extends ContextThemeWrapper ActivityManagerNative.getDefault().getIntentSender( ActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName, mParent == null ? mToken : mParent.mToken, - mEmbeddedID, requestCode, new Intent[] { data }, null, flags, null); + mEmbeddedID, requestCode, new Intent[] { data }, null, flags, null, + UserHandle.myUserId()); return target != null ? new PendingIntent(target) : null; } catch (RemoteException e) { // Empty diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 26d8c178830d7..cd22aad90fc14 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -27,6 +27,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.ConfigurationInfo; import android.content.pm.IPackageDataObserver; import android.content.pm.PackageManager; +import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; @@ -1225,7 +1226,7 @@ public class ActivityManager { public boolean clearApplicationUserData(String packageName, IPackageDataObserver observer) { try { return ActivityManagerNative.getDefault().clearApplicationUserData(packageName, - observer, Binder.getOrigCallingUser()); + observer, UserHandle.myUserId()); } catch (RemoteException e) { return false; } @@ -1902,6 +1903,31 @@ public class ActivityManager { return PackageManager.PERMISSION_DENIED; } + /** @hide */ + public static int handleIncomingUser(int callingPid, int callingUid, int userId, + boolean allowAll, boolean requireFull, String name, String callerPackage) { + if (UserHandle.getUserId(callingUid) == userId) { + return userId; + } + try { + return ActivityManagerNative.getDefault().handleIncomingUser(callingPid, + callingUid, userId, allowAll, requireFull, name, callerPackage); + } catch (RemoteException e) { + throw new SecurityException("Failed calling activity manager", e); + } + } + + /** @hide */ + public static int getCurrentUser() { + UserInfo ui; + try { + ui = ActivityManagerNative.getDefault().getCurrentUser(); + return ui != null ? ui.id : 0; + } catch (RemoteException e) { + return 0; + } + } + /** * Returns the usage statistics of each installed package. * diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 16b7c2a82dc5a..14ba537960b66 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -199,8 +199,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM Configuration config = Configuration.CREATOR.createFromParcel(data); Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null; + int userId = data.readInt(); int result = startActivityWithConfig(app, intent, resolvedType, - resultTo, resultWho, requestCode, startFlags, config, options); + resultTo, resultWho, requestCode, startFlags, config, options, userId); reply.writeNoException(); reply.writeInt(result); return true; @@ -897,9 +898,10 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM int fl = data.readInt(); Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null; + int userId = data.readInt(); IIntentSender res = getIntentSender(type, packageName, token, resultWho, requestCode, requestIntents, - requestResolvedTypes, fl, options); + requestResolvedTypes, fl, options, userId); reply.writeNoException(); reply.writeStrongBinder(res != null ? res.asBinder() : null); return true; @@ -934,6 +936,22 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case HANDLE_INCOMING_USER_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + int callingPid = data.readInt(); + int callingUid = data.readInt(); + int userId = data.readInt(); + boolean allowAll = data.readInt() != 0 ; + boolean requireFull = data.readInt() != 0; + String name = data.readString(); + String callerPackage = data.readString(); + int res = handleIncomingUser(callingPid, callingUid, userId, allowAll, + requireFull, name, callerPackage); + reply.writeNoException(); + reply.writeInt(res); + return true; + } + case SET_PROCESS_LIMIT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int max = data.readInt(); @@ -1304,25 +1322,6 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } - case START_ACTIVITY_IN_PACKAGE_TRANSACTION: - { - data.enforceInterface(IActivityManager.descriptor); - int uid = data.readInt(); - Intent intent = Intent.CREATOR.createFromParcel(data); - String resolvedType = data.readString(); - IBinder resultTo = data.readStrongBinder(); - String resultWho = data.readString(); - int requestCode = data.readInt(); - int startFlags = data.readInt(); - Bundle options = data.readInt() != 0 - ? Bundle.CREATOR.createFromParcel(data) : null; - int result = startActivityInPackage(uid, intent, resolvedType, - resultTo, resultWho, requestCode, startFlags, options); - reply.writeNoException(); - reply.writeInt(result); - return true; - } - case KILL_APPLICATION_WITH_UID_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String pkg = data.readString(); @@ -1489,22 +1488,6 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } - case START_ACTIVITIES_IN_PACKAGE_TRANSACTION: - { - data.enforceInterface(IActivityManager.descriptor); - int uid = data.readInt(); - Intent[] intents = data.createTypedArray(Intent.CREATOR); - String[] resolvedTypes = data.createStringArray(); - IBinder resultTo = data.readStrongBinder(); - Bundle options = data.readInt() != 0 - ? Bundle.CREATOR.createFromParcel(data) : null; - int result = startActivitiesInPackage(uid, intents, resolvedTypes, - resultTo, options); - reply.writeNoException(); - reply.writeInt(result); - return true; - } - case START_ACTIVITIES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); @@ -1877,7 +1860,7 @@ class ActivityManagerProxy implements IActivityManager public int startActivityWithConfig(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration config, - Bundle options) throws RemoteException { + Bundle options, int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -1895,6 +1878,7 @@ class ActivityManagerProxy implements IActivityManager } else { data.writeInt(0); } + data.writeInt(userId); mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); @@ -2840,7 +2824,7 @@ class ActivityManagerProxy implements IActivityManager public IIntentSender getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, - Bundle options) throws RemoteException { + Bundle options, int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -2863,6 +2847,7 @@ class ActivityManagerProxy implements IActivityManager } else { data.writeInt(0); } + data.writeInt(userId); mRemote.transact(GET_INTENT_SENDER_TRANSACTION, data, reply, 0); reply.readException(); IIntentSender res = IIntentSender.Stub.asInterface( @@ -2905,6 +2890,25 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); return res; } + public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, + boolean requireFull, String name, String callerPackage) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(callingPid); + data.writeInt(callingUid); + data.writeInt(userId); + data.writeInt(allowAll ? 1 : 0); + data.writeInt(requireFull ? 1 : 0); + data.writeString(name); + data.writeString(callerPackage); + mRemote.transact(HANDLE_INCOMING_USER_TRANSACTION, data, reply, 0); + reply.readException(); + int res = reply.readInt(); + data.recycle(); + reply.recycle(); + return res; + } public void setProcessLimit(int max) throws RemoteException { Parcel data = Parcel.obtain(); @@ -3360,34 +3364,6 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); } - public int startActivityInPackage(int uid, - Intent intent, String resolvedType, IBinder resultTo, - String resultWho, int requestCode, int startFlags, Bundle options) - throws RemoteException { - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); - data.writeInterfaceToken(IActivityManager.descriptor); - data.writeInt(uid); - intent.writeToParcel(data, 0); - data.writeString(resolvedType); - data.writeStrongBinder(resultTo); - data.writeString(resultWho); - data.writeInt(requestCode); - data.writeInt(startFlags); - if (options != null) { - data.writeInt(1); - options.writeToParcel(data, 0); - } else { - data.writeInt(0); - } - mRemote.transact(START_ACTIVITY_IN_PACKAGE_TRANSACTION, data, reply, 0); - reply.readException(); - int result = reply.readInt(); - reply.recycle(); - data.recycle(); - return result; - } - public void killApplicationWithUid(String pkg, int uid) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -3655,30 +3631,6 @@ class ActivityManagerProxy implements IActivityManager return result; } - public int startActivitiesInPackage(int uid, - Intent[] intents, String[] resolvedTypes, IBinder resultTo, - Bundle options) throws RemoteException { - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); - data.writeInterfaceToken(IActivityManager.descriptor); - data.writeInt(uid); - data.writeTypedArray(intents, 0); - data.writeStringArray(resolvedTypes); - data.writeStrongBinder(resultTo); - if (options != null) { - data.writeInt(1); - options.writeToParcel(data, 0); - } else { - data.writeInt(0); - } - mRemote.transact(START_ACTIVITIES_IN_PACKAGE_TRANSACTION, data, reply, 0); - reply.readException(); - int result = reply.readInt(); - reply.recycle(); - data.recycle(); - return result; - } - public int getFrontActivityScreenCompatMode() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 1b6f84ba70522..408820db65618 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -994,7 +994,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false, - Binder.getOrigCallingUser()); + UserHandle.myUserId()); } catch (RemoteException e) { } } @@ -1007,7 +1007,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermission, false, false, - Binder.getOrigCallingUser()); + UserHandle.myUserId()); } catch (RemoteException e) { } } @@ -1021,7 +1021,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermission, true, false, - Binder.getOrigCallingUser()); + UserHandle.myUserId()); } catch (RemoteException e) { } } @@ -1054,7 +1054,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, receiverPermission, - true, false, Binder.getOrigCallingUser()); + true, false, UserHandle.myUserId()); } catch (RemoteException e) { } } @@ -1125,7 +1125,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, true, - Binder.getOrigCallingUser()); + UserHandle.myUserId()); } catch (RemoteException e) { } } @@ -1158,7 +1158,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - true, true, Binder.getOrigCallingUser()); + true, true, UserHandle.myUserId()); } catch (RemoteException e) { } } @@ -1173,7 +1173,7 @@ class ContextImpl extends Context { try { intent.setAllowFds(false); ActivityManagerNative.getDefault().unbroadcastIntent( - mMainThread.getApplicationThread(), intent, Binder.getOrigCallingUser()); + mMainThread.getApplicationThread(), intent, UserHandle.myUserId()); } catch (RemoteException e) { } } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 70d8445f89294..f7c701332703f 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -66,7 +66,7 @@ public interface IActivityManager extends IInterface { public int startActivityWithConfig(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration newConfig, - Bundle options) throws RemoteException; + Bundle options, int userId) throws RemoteException; public int startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, @@ -177,13 +177,16 @@ public interface IActivityManager extends IInterface { public IIntentSender getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, - int flags, Bundle options) throws RemoteException; + int flags, Bundle options, int userId) throws RemoteException; public void cancelIntentSender(IIntentSender sender) throws RemoteException; public boolean clearApplicationUserData(final String packageName, final IPackageDataObserver observer, int userId) throws RemoteException; public String getPackageForIntentSender(IIntentSender sender) throws RemoteException; public int getUidForIntentSender(IIntentSender sender) throws RemoteException; + public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, + boolean requireFull, String name, String callerPackage) throws RemoteException; + public void setProcessLimit(int max) throws RemoteException; public int getProcessLimit() throws RemoteException; @@ -272,11 +275,6 @@ public interface IActivityManager extends IInterface { public void stopAppSwitches() throws RemoteException; public void resumeAppSwitches() throws RemoteException; - public int startActivityInPackage(int uid, - Intent intent, String resolvedType, IBinder resultTo, - String resultWho, int requestCode, int startFlags, Bundle options) - throws RemoteException; - public void killApplicationWithUid(String pkg, int uid) throws RemoteException; public void closeSystemDialogs(String reason) throws RemoteException; @@ -316,9 +314,6 @@ public interface IActivityManager extends IInterface { public int startActivities(IApplicationThread caller, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) throws RemoteException; - public int startActivitiesInPackage(int uid, - Intent[] intents, String[] resolvedTypes, IBinder resultTo, - Bundle options) throws RemoteException; public int getFrontActivityScreenCompatMode() throws RemoteException; public void setFrontActivityScreenCompatMode(int mode) throws RemoteException; @@ -551,9 +546,8 @@ public interface IActivityManager extends IInterface { int BACKUP_AGENT_CREATED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+90; int UNBIND_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+91; int GET_UID_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92; + int HANDLE_INCOMING_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93; - - int START_ACTIVITY_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94; int KILL_APPLICATION_WITH_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95; int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96; int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97; @@ -580,7 +574,7 @@ public interface IActivityManager extends IInterface { int CHECK_GRANT_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+118; int DUMP_HEAP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+119; int START_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+120; - int START_ACTIVITIES_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+121; + int ACTIVITY_SLEPT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+122; int GET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+123; int SET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+124; diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 6f95e26ae79bc..62d496216748e 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -24,16 +24,13 @@ import android.content.Intent; /** {@hide} */ interface INotificationManager { - /** @deprecated use {@link #enqueueNotificationWithTag} instead */ - void enqueueNotification(String pkg, int id, in Notification notification, inout int[] idReceived); - /** @deprecated use {@link #cancelNotificationWithTag} instead */ - void cancelNotification(String pkg, int id); - void cancelAllNotifications(String pkg); + void cancelAllNotifications(String pkg, int userId); void enqueueToast(String pkg, ITransientNotification callback, int duration); void cancelToast(String pkg, ITransientNotification callback); - void enqueueNotificationWithTag(String pkg, String tag, int id, in Notification notification, inout int[] idReceived); - void cancelNotificationWithTag(String pkg, String tag, int id); + void enqueueNotificationWithTag(String pkg, String tag, int id, + in Notification notification, inout int[] idReceived, int userId); + void cancelNotificationWithTag(String pkg, String tag, int id, int userId); void setNotificationsEnabledForPackage(String pkg, boolean enabled); boolean areNotificationsEnabledForPackage(String pkg); diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 69c20b0a0648d..c095280e57d4f 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -21,6 +21,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.util.Log; /** @@ -125,7 +126,27 @@ public class NotificationManager String pkg = mContext.getPackageName(); if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); try { - service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut); + service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut, + UserHandle.myUserId()); + if (id != idOut[0]) { + Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]); + } + } catch (RemoteException e) { + } + } + + /** + * @hide + */ + public void notifyAsUser(String tag, int id, Notification notification, UserHandle user) + { + int[] idOut = new int[1]; + INotificationManager service = getService(); + String pkg = mContext.getPackageName(); + if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); + try { + service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut, + user.getIdentifier()); if (id != idOut[0]) { Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]); } @@ -154,7 +175,21 @@ public class NotificationManager String pkg = mContext.getPackageName(); if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")"); try { - service.cancelNotificationWithTag(pkg, tag, id); + service.cancelNotificationWithTag(pkg, tag, id, UserHandle.myUserId()); + } catch (RemoteException e) { + } + } + + /** + * @hide + */ + public void cancelAsUser(String tag, int id, UserHandle user) + { + INotificationManager service = getService(); + String pkg = mContext.getPackageName(); + if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")"); + try { + service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier()); } catch (RemoteException e) { } } @@ -169,7 +204,7 @@ public class NotificationManager String pkg = mContext.getPackageName(); if (localLOGV) Log.v(TAG, pkg + ": cancelAll()"); try { - service.cancelAllNotifications(pkg); + service.cancelAllNotifications(pkg, UserHandle.myUserId()); } catch (RemoteException e) { } } diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index a57c516649693..bcd42ea00b0a0 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -228,7 +228,29 @@ public final class PendingIntent implements Parcelable { ActivityManager.INTENT_SENDER_ACTIVITY, packageName, null, null, requestCode, new Intent[] { intent }, resolvedType != null ? new String[] { resolvedType } : null, - flags, options); + flags, options, UserHandle.myUserId()); + return target != null ? new PendingIntent(target) : null; + } catch (RemoteException e) { + } + return null; + } + + /** + * @hide + */ + public static PendingIntent getActivityAsUser(Context context, int requestCode, + Intent intent, int flags, Bundle options, UserHandle user) { + String packageName = context.getPackageName(); + String resolvedType = intent != null ? intent.resolveTypeIfNeeded( + context.getContentResolver()) : null; + try { + intent.setAllowFds(false); + IIntentSender target = + ActivityManagerNative.getDefault().getIntentSender( + ActivityManager.INTENT_SENDER_ACTIVITY, packageName, + null, null, requestCode, new Intent[] { intent }, + resolvedType != null ? new String[] { resolvedType } : null, + flags, options, user.getIdentifier()); return target != null ? new PendingIntent(target) : null; } catch (RemoteException e) { } @@ -334,7 +356,8 @@ public final class PendingIntent implements Parcelable { IIntentSender target = ActivityManagerNative.getDefault().getIntentSender( ActivityManager.INTENT_SENDER_ACTIVITY, packageName, - null, null, requestCode, intents, resolvedTypes, flags, options); + null, null, requestCode, intents, resolvedTypes, flags, options, + UserHandle.myUserId()); return target != null ? new PendingIntent(target) : null; } catch (RemoteException e) { } @@ -372,7 +395,7 @@ public final class PendingIntent implements Parcelable { ActivityManager.INTENT_SENDER_BROADCAST, packageName, null, null, requestCode, new Intent[] { intent }, resolvedType != null ? new String[] { resolvedType } : null, - flags, null); + flags, null, UserHandle.myUserId()); return target != null ? new PendingIntent(target) : null; } catch (RemoteException e) { } @@ -411,7 +434,7 @@ public final class PendingIntent implements Parcelable { ActivityManager.INTENT_SENDER_SERVICE, packageName, null, null, requestCode, new Intent[] { intent }, resolvedType != null ? new String[] { resolvedType } : null, - flags, null); + flags, null, UserHandle.myUserId()); return target != null ? new PendingIntent(target) : null; } catch (RemoteException e) { } diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index ee075b426c736..6b5e6e28ddd10 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -980,7 +980,7 @@ public class SyncManager implements OnAccountsUpdateListener { mSyncHandler.sendMessage(msg); } - boolean bindToSyncAdapter(RegisteredServicesCache.ServiceInfo info) { + boolean bindToSyncAdapter(RegisteredServicesCache.ServiceInfo info, int userId) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.d(TAG, "bindToSyncAdapter: " + info.componentName + ", connection " + this); } @@ -989,8 +989,9 @@ public class SyncManager implements OnAccountsUpdateListener { intent.setComponent(info.componentName); intent.putExtra(Intent.EXTRA_CLIENT_LABEL, com.android.internal.R.string.sync_binding_label); - intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( - mContext, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0)); + intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser( + mContext, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0, + null, new UserHandle(userId))); mBound = true; final boolean bindResult = mContext.bindService(intent, this, Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND @@ -2132,7 +2133,7 @@ public class SyncManager implements OnAccountsUpdateListener { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext); } - if (!activeSyncContext.bindToSyncAdapter(syncAdapterInfo)) { + if (!activeSyncContext.bindToSyncAdapter(syncAdapterInfo, op.userId)) { Log.e(TAG, "Bind attempt failed to " + syncAdapterInfo); closeActiveSyncContext(activeSyncContext); return false; @@ -2255,10 +2256,12 @@ public class SyncManager implements OnAccountsUpdateListener { if (syncResult != null && syncResult.tooManyDeletions) { installHandleTooManyDeletesNotification(syncOperation.account, - syncOperation.authority, syncResult.stats.numDeletes); + syncOperation.authority, syncResult.stats.numDeletes, + syncOperation.userId); } else { - mNotificationMgr.cancel( - syncOperation.account.hashCode() ^ syncOperation.authority.hashCode()); + mNotificationMgr.cancelAsUser(null, + syncOperation.account.hashCode() ^ syncOperation.authority.hashCode(), + new UserHandle(syncOperation.userId)); } if (syncResult != null && syncResult.fullSyncRequested) { @@ -2471,7 +2474,7 @@ public class SyncManager implements OnAccountsUpdateListener { } private void installHandleTooManyDeletesNotification(Account account, String authority, - long numDeletes) { + long numDeletes, int userId) { if (mNotificationMgr == null) return; final ProviderInfo providerInfo = mContext.getPackageManager().resolveContentProvider( @@ -2493,7 +2496,8 @@ public class SyncManager implements OnAccountsUpdateListener { } final PendingIntent pendingIntent = PendingIntent - .getActivity(mContext, 0, clickIntent, PendingIntent.FLAG_CANCEL_CURRENT); + .getActivityAsUser(mContext, 0, clickIntent, + PendingIntent.FLAG_CANCEL_CURRENT, null, new UserHandle(userId)); CharSequence tooManyDeletesDescFormat = mContext.getResources().getText( R.string.contentServiceTooManyDeletesNotificationDesc); @@ -2507,7 +2511,8 @@ public class SyncManager implements OnAccountsUpdateListener { String.format(tooManyDeletesDescFormat.toString(), authorityName), pendingIntent); notification.flags |= Notification.FLAG_ONGOING_EVENT; - mNotificationMgr.notify(account.hashCode() ^ authority.hashCode(), notification); + mNotificationMgr.notifyAsUser(null, account.hashCode() ^ authority.hashCode(), + notification, new UserHandle(userId)); } /** diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 5d404568591e9..ea14098a10f3b 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -72,34 +72,6 @@ public class Binder implements IBinder { */ public static final native int getCallingUid(); - /** - * Return the original ID of the user assigned to the process that sent you the current - * transaction that is being processed. This uid can be used with higher-level system services - * to determine its identity and check permissions. If the current thread is not currently - * executing an incoming transaction, then its own uid is returned. - *

- * This value cannot be reset by calls to {@link #clearCallingIdentity()}. - * @hide - */ - public static final int getOrigCallingUid() { - if (UserHandle.MU_ENABLED) { - return getOrigCallingUidNative(); - } else { - return getCallingUid(); - } - } - - private static final native int getOrigCallingUidNative(); - - /** - * Utility function to return the user id of the calling process. - * @return userId of the calling process, extracted from the callingUid - * @hide - */ - public static final int getOrigCallingUser() { - return UserHandle.getUserId(getOrigCallingUid()); - } - /** * Reset the identity of the incoming IPC on the current thread. This can * be useful if, while handling an incoming call, you will be calling diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 04dc49fe31369..881d9a0a3526c 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -729,11 +729,6 @@ static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz) return IPCThreadState::self()->getCallingUid(); } -static jint android_os_Binder_getOrigCallingUid(JNIEnv* env, jobject clazz) -{ - return IPCThreadState::self()->getOrigCallingUid(); -} - static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz) { return IPCThreadState::self()->clearCallingIdentity(); @@ -805,7 +800,6 @@ static const JNINativeMethod gBinderMethods[] = { /* name, signature, funcPtr */ { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid }, { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid }, - { "getOrigCallingUidNative", "()I", (void*)android_os_Binder_getOrigCallingUid }, { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity }, { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity }, { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy }, diff --git a/core/tests/coretests/src/android/app/activity/BroadcastTest.java b/core/tests/coretests/src/android/app/activity/BroadcastTest.java index 7f551b0d3d5f7..f28ba7e07ff85 100644 --- a/core/tests/coretests/src/android/app/activity/BroadcastTest.java +++ b/core/tests/coretests/src/android/app/activity/BroadcastTest.java @@ -305,7 +305,7 @@ public class BroadcastTest extends ActivityTestsBase { Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null); intent.putExtra("test", LaunchpadActivity.DATA_1); ActivityManagerNative.getDefault().unbroadcastIntent(null, intent, - Binder.getOrigCallingUser()); + UserHandle.myUserId()); ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId()); addIntermediate("finished-broadcast"); @@ -323,7 +323,7 @@ public class BroadcastTest extends ActivityTestsBase { ActivityManagerNative.getDefault().unbroadcastIntent( null, new Intent(LaunchpadActivity.BROADCAST_STICKY1, null), - Binder.getOrigCallingUser()); + UserHandle.myUserId()); addIntermediate("finished-unbroadcast"); IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java index a60bba7ce106e..bec5d721c7cfc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.location.LocationManager; +import android.os.UserHandle; import android.provider.Settings; import android.util.Slog; import android.view.View; @@ -84,10 +85,12 @@ public class LocationController extends BroadcastReceiver { } try { + // XXX WHAT TO DO ABOUT MULTI-USER? if (visible) { Intent gpsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); gpsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, gpsIntent, 0); + PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, 0, + gpsIntent, 0, null, UserHandle.CURRENT); Notification n = new Notification.Builder(mContext) .setSmallIcon(iconId) @@ -108,11 +111,12 @@ public class LocationController extends BroadcastReceiver { null, GPS_NOTIFICATION_ID, n, - idOut); + idOut, + UserHandle.USER_CURRENT); } else { - mNotificationService.cancelNotification( - mContext.getPackageName(), - GPS_NOTIFICATION_ID); + mNotificationService.cancelNotificationWithTag( + mContext.getPackageName(), null, + GPS_NOTIFICATION_ID, UserHandle.USER_CURRENT); } } catch (android.os.RemoteException ex) { // well, it was worth a shot diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index 8e341df8dd95b..b869abd6a9898 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -31,6 +31,7 @@ import android.os.Binder; 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 @@ class AppWidgetService extends IAppWidgetService.Stub @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 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 @@ class AppWidgetService extends IAppWidgetService.Stub } } - 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 @@ class AppWidgetService extends IAppWidgetService.Stub @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 @@ class AppWidgetService extends IAppWidgetService.Stub @Override public List 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 @@ class AppWidgetService extends IAppWidgetService.Stub 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 8be0ba8af3e73..955ea23ff0c41 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -1663,8 +1663,7 @@ class BackupManagerService extends IBackupManager.Stub { 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 e45cee30c3a47..40f6ecf76b437 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_DOCUMENT; 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 @@ public class NotificationManagerService extends INotificationManager.Stub 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 @@ public class NotificationManagerService extends INotificationManager.Stub 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 class NotificationManagerService extends INotificationManager.Stub } 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 @@ public class NotificationManagerService extends INotificationManager.Stub 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 @@ public class NotificationManagerService extends INotificationManager.Stub } 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 @@ public class NotificationManagerService extends INotificationManager.Stub } 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 @@ public class NotificationManagerService extends INotificationManager.Stub // 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 @@ public class NotificationManagerService extends INotificationManager.Stub // 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 @@ public class NotificationManagerService extends INotificationManager.Stub 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 @@ public class NotificationManagerService extends INotificationManager.Stub 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 @@ public class NotificationManagerService extends INotificationManager.Stub * 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 @@ public class NotificationManagerService extends INotificationManager.Stub * {@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 @@ public class NotificationManagerService extends INotificationManager.Stub 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 @@ public class NotificationManagerService extends INotificationManager.Stub } } - /** - * 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 @@ public class NotificationManagerService extends INotificationManager.Stub } } - 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 @@ public class NotificationManagerService extends INotificationManager.Stub } // lock on mNotificationList - private int indexOfNotificationLocked(String pkg, String tag, int id) + private int indexOfNotificationLocked(String pkg, String tag, int id, int userId) { ArrayList list = mNotificationList; final int len = list.size(); for (int i=0; i 0 && app.pid != MY_PID) { @@ -3931,8 +3918,9 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative } } - 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 ref; ref = mIntentSenderRecords.get(key); PendingIntentRecord rec = ref != null ? ref.get() : null; @@ -6233,7 +6220,7 @@ public final class ActivityManagerService extends ActivityManagerNative } 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 @@ public final class ActivityManagerService extends ActivityManagerNative + " (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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative //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 final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative return null; } finally { if (holder != null) { - removeContentProviderExternalUnchecked(name, null); + removeContentProviderExternalUnchecked(name, null, userId); } Binder.restoreCallingIdentity(ident); } @@ -6894,8 +6885,9 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative } // 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative } 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 final class ActivityManagerService extends ActivityManagerNative } } + 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 @@ public final class ActivityManagerService extends ActivityManagerNative // 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 ef4e9bee7130b..399ea597cae8b 100755 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -3077,7 +3077,7 @@ final class ActivityStack { 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 8e70376fc26b8..37e90178208f2 100644 --- a/services/java/com/android/server/am/PendingIntentRecord.java +++ b/services/java/com/android/server/am/PendingIntentRecord.java @@ -243,11 +243,10 @@ class PendingIntentRecord extends IIntentSender.Stub { 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 @@ class PendingIntentRecord extends IIntentSender.Stub { 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 @@ class PendingIntentRecord extends IIntentSender.Stub { 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 15fbb988417b2..7a4fef66a30ed 100644 --- a/services/java/com/android/server/am/ProviderMap.java +++ b/services/java/com/android/server/am/ProviderMap.java @@ -116,48 +116,46 @@ public class ProviderMap { } } - 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 map = getProvidersByName(optionalUserId); + "Removing from providersByName name=" + name + " user=" + userId); + HashMap 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 map = getProvidersByClass(optionalUserId); + "Removing from providersByClass name=" + name + " user=" + userId); + HashMap 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 getProvidersByName(int optionalUserId) { - final int userId = optionalUserId >= 0 - ? optionalUserId : Binder.getOrigCallingUser(); + private HashMap getProvidersByName(int userId) { + if (userId < 0) throw new IllegalArgumentException("Bad user " + userId); final HashMap map = mProvidersByNamePerUser.get(userId); if (map == null) { HashMap newMap = new HashMap(); @@ -168,12 +166,13 @@ public class ProviderMap { } } - HashMap getProvidersByClass(int optionalUserId) { - final int userId = optionalUserId >= 0 - ? optionalUserId : Binder.getOrigCallingUser(); - final HashMap map = mProvidersByClassPerUser.get(userId); + HashMap getProvidersByClass(int userId) { + if (userId < 0) throw new IllegalArgumentException("Bad user " + userId); + final HashMap map + = mProvidersByClassPerUser.get(userId); if (map == null) { - HashMap newMap = new HashMap(); + HashMap newMap + = new HashMap(); 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 5d60b9cf7efab..7055fdc66386e 100644 --- a/services/java/com/android/server/am/ServiceRecord.java +++ b/services/java/com/android/server/am/ServiceRecord.java @@ -370,7 +370,7 @@ class ServiceRecord extends Binder { 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 @@ class ServiceRecord extends Binder { 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 c6e66cf5ec88f..46bddc4030fa3 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -788,11 +788,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } // 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 } diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index 3373fd4744495..a2104bba6c6c9 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -880,7 +880,8 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { private Future expectClearNotifications() throws Exception { final FutureAnswer future = new FutureAnswer(); - mNotifManager.cancelNotificationWithTag(isA(String.class), isA(String.class), anyInt()); + mNotifManager.cancelNotificationWithTag(isA(String.class), isA(String.class), anyInt(), + UserHandle.myUserId()); expectLastCall().andAnswer(future).anyTimes(); return future; } @@ -888,7 +889,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { private Future expectEnqueueNotification() throws Exception { final FutureCapture tag = new FutureCapture(); mNotifManager.enqueueNotificationWithTag(isA(String.class), capture(tag.capture), anyInt(), - isA(Notification.class), isA(int[].class)); + isA(Notification.class), isA(int[].class), UserHandle.myUserId()); return tag; } diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java index 70e2aac96d925..ec39aabb16755 100644 --- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java +++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java @@ -28,6 +28,7 @@ import android.os.Bundle; import android.os.Environment; import android.os.Vibrator; import android.os.Handler; +import android.os.UserHandle; import android.util.Log; import android.net.Uri; import android.os.SystemClock; @@ -798,7 +799,8 @@ public class NotificationTestList extends TestActivity null, 100, n, - idOut); + idOut, + UserHandle.myUserId()); } catch (android.os.RemoteException ex) { // oh well } @@ -822,7 +824,8 @@ public class NotificationTestList extends TestActivity null, 200, n, - idOut); + idOut, + UserHandle.myUserId()); } catch (android.os.RemoteException ex) { // oh well } @@ -846,7 +849,8 @@ public class NotificationTestList extends TestActivity null, 1, n, - idOut); + idOut, + UserHandle.myUserId()); } catch (android.os.RemoteException ex) { // oh well }