diff options
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/app/ActivityManager.java | 3 | ||||
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 21 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 11 | ||||
-rw-r--r-- | core/java/android/app/ApplicationPackageManager.java | 15 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 25 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 6 | ||||
-rw-r--r-- | core/java/android/app/LoadedApk.java | 10 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 2 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageManager.java | 54 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageParser.java | 52 | ||||
-rw-r--r-- | core/java/android/os/Binder.java | 31 | ||||
-rw-r--r-- | core/java/android/os/UserId.java | 90 |
12 files changed, 230 insertions, 90 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 9661b9e..d98d87b 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -30,6 +30,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; +import android.os.Binder; import android.os.Debug; import android.os.Handler; import android.os.Parcel; @@ -975,7 +976,7 @@ public class ActivityManager { public boolean clearApplicationUserData(String packageName, IPackageDataObserver observer) { try { return ActivityManagerNative.getDefault().clearApplicationUserData(packageName, - observer); + observer, Binder.getOrigCallingUser()); } catch (RemoteException e) { return false; } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 7994d7c..d80902d 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -91,7 +91,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM try { getDefault().broadcastIntent( null, intent, null, null, Activity.RESULT_OK, null, null, - null /*permission*/, false, true); + null /*permission*/, false, true, Binder.getOrigCallingUser()); } catch (RemoteException ex) { } } @@ -306,9 +306,10 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM String perm = data.readString(); boolean serialized = data.readInt() != 0; boolean sticky = data.readInt() != 0; + int userId = data.readInt(); int res = broadcastIntent(app, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, perm, - serialized, sticky); + serialized, sticky, userId); reply.writeNoException(); reply.writeInt(res); return true; @@ -320,7 +321,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM IBinder b = data.readStrongBinder(); IApplicationThread app = b != null ? ApplicationThreadNative.asInterface(b) : null; Intent intent = Intent.CREATOR.createFromParcel(data); - unbroadcastIntent(app, intent); + int userId = data.readInt(); + unbroadcastIntent(app, intent, userId); reply.writeNoException(); return true; } @@ -900,7 +902,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM String packageName = data.readString(); IPackageDataObserver observer = IPackageDataObserver.Stub.asInterface( data.readStrongBinder()); - boolean res = clearApplicationUserData(packageName, observer); + int userId = data.readInt(); + boolean res = clearApplicationUserData(packageName, observer, userId); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; @@ -1819,7 +1822,7 @@ class ActivityManagerProxy implements IActivityManager Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, - boolean sticky) throws RemoteException + boolean sticky, int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -1834,6 +1837,7 @@ class ActivityManagerProxy implements IActivityManager data.writeString(requiredPermission); data.writeInt(serialized ? 1 : 0); data.writeInt(sticky ? 1 : 0); + data.writeInt(userId); mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0); reply.readException(); int res = reply.readInt(); @@ -1841,13 +1845,15 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); return res; } - public void unbroadcastIntent(IApplicationThread caller, Intent intent) throws RemoteException + public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) + throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); intent.writeToParcel(data, 0); + data.writeInt(userId); mRemote.transact(UNBROADCAST_INTENT_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); @@ -2651,12 +2657,13 @@ class ActivityManagerProxy implements IActivityManager return res; } public boolean clearApplicationUserData(final String packageName, - final IPackageDataObserver observer) throws RemoteException { + final IPackageDataObserver observer, final int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeString(packageName); data.writeStrongBinder(observer.asBinder()); + data.writeInt(userId); mRemote.transact(CLEAR_APP_DATA_TRANSACTION, data, reply, 0); reply.readException(); boolean res = reply.readInt() != 0; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 3c5f53a..e4cfc99 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -47,6 +47,7 @@ import android.net.Proxy; import android.net.ProxyProperties; import android.opengl.GLUtils; import android.os.AsyncTask; +import android.os.Binder; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -60,6 +61,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; +import android.os.UserId; import android.util.AndroidRuntimeException; import android.util.DisplayMetrics; import android.util.EventLog; @@ -132,6 +134,7 @@ public final class ActivityThread { private static final boolean DEBUG_RESULTS = false; private static final boolean DEBUG_BACKUP = true; private static final boolean DEBUG_CONFIGURATION = false; + private static final boolean DEBUG_SERVICE = true; private static final long MIN_TIME_BETWEEN_GCS = 5*1000; private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";"); private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; @@ -635,6 +638,9 @@ public final class ActivityThread { s.intent = intent; s.rebind = rebind; + if (DEBUG_SERVICE) + Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" + + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); queueOrSendMessage(H.BIND_SERVICE, s); } @@ -1592,7 +1598,8 @@ public final class ActivityThread { boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0; boolean securityViolation = includeCode && ai.uid != 0 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null - ? ai.uid != mBoundApplication.appInfo.uid : true); + ? !UserId.isSameApp(ai.uid, mBoundApplication.appInfo.uid) + : true); if ((flags&(Context.CONTEXT_INCLUDE_CODE |Context.CONTEXT_IGNORE_SECURITY)) == Context.CONTEXT_INCLUDE_CODE) { @@ -2294,6 +2301,8 @@ public final class ActivityThread { private void handleBindService(BindServiceData data) { Service s = mServices.get(data.token); + if (DEBUG_SERVICE) + Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); if (s != null) { try { data.intent.setExtrasClassLoader(s.getClassLoader()); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 180a442..fee2beb 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1177,13 +1177,14 @@ final class ApplicationPackageManager extends PackageManager { */ @Override public List<UserInfo> getUsers() { - // TODO: - // Dummy code, always returns just the primary user - ArrayList<UserInfo> users = new ArrayList<UserInfo>(); - UserInfo primary = new UserInfo(0, "Root!", - UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); - users.add(primary); - return users; + try { + return mPM.getUsers(); + } catch (RemoteException re) { + ArrayList<UserInfo> users = new ArrayList<UserInfo>(); + UserInfo primary = new UserInfo(0, "Root!", UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); + users.add(primary); + return users; + } } /** diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 2bf1fb7..db5113e 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -75,6 +75,7 @@ import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserId; import android.os.Vibrator; import android.os.storage.StorageManager; import android.telephony.TelephonyManager; @@ -896,7 +897,8 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, null, false, false); + Activity.RESULT_OK, null, null, null, false, false, + Binder.getOrigCallingUser()); } catch (RemoteException e) { } } @@ -908,7 +910,8 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, receiverPermission, false, false); + Activity.RESULT_OK, null, null, receiverPermission, false, false, + Binder.getOrigCallingUser()); } catch (RemoteException e) { } } @@ -921,7 +924,8 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, receiverPermission, true, false); + Activity.RESULT_OK, null, null, receiverPermission, true, false, + Binder.getOrigCallingUser()); } catch (RemoteException e) { } } @@ -954,7 +958,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, receiverPermission, - true, false); + true, false, Binder.getOrigCallingUser()); } catch (RemoteException e) { } } @@ -966,7 +970,8 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, null, false, true); + Activity.RESULT_OK, null, null, null, false, true, + Binder.getOrigCallingUser()); } catch (RemoteException e) { } } @@ -999,7 +1004,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - true, true); + true, true, Binder.getOrigCallingUser()); } catch (RemoteException e) { } } @@ -1014,7 +1019,7 @@ class ContextImpl extends Context { try { intent.setAllowFds(false); ActivityManagerNative.getDefault().unbroadcastIntent( - mMainThread.getApplicationThread(), intent); + mMainThread.getApplicationThread(), intent, Binder.getOrigCallingUser()); } catch (RemoteException e) { } } @@ -1215,8 +1220,7 @@ class ContextImpl extends Context { int pid = Binder.getCallingPid(); if (pid != Process.myPid()) { - return checkPermission(permission, pid, - Binder.getCallingUid()); + return checkPermission(permission, pid, Binder.getCallingUid()); } return PackageManager.PERMISSION_DENIED; } @@ -1384,7 +1388,8 @@ class ContextImpl extends Context { Uri uri, int modeFlags, String message) { enforceForUri( modeFlags, checkCallingUriPermission(uri, modeFlags), - false, Binder.getCallingUid(), uri, message); + false, + Binder.getCallingUid(), uri, message); } public void enforceCallingOrSelfUriPermission( diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 5222d37..39817ac 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -114,8 +114,8 @@ public interface IActivityManager extends IInterface { public int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, - boolean serialized, boolean sticky) throws RemoteException; - public void unbroadcastIntent(IApplicationThread caller, Intent intent) throws RemoteException; + boolean serialized, boolean sticky, int userId) throws RemoteException; + public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException; /* oneway */ public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException; public void attachApplication(IApplicationThread app) throws RemoteException; @@ -209,7 +209,7 @@ public interface IActivityManager extends IInterface { int flags) throws RemoteException; public void cancelIntentSender(IIntentSender sender) throws RemoteException; public boolean clearApplicationUserData(final String packageName, - final IPackageDataObserver observer) throws RemoteException; + final IPackageDataObserver observer, int userId) throws RemoteException; public String getPackageForIntentSender(IIntentSender sender) throws RemoteException; public void setProcessLimit(int max) throws RemoteException; diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 0c6baeb..fcbcd81 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -36,6 +36,7 @@ import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.StrictMode; +import android.os.UserId; import android.util.AndroidRuntimeException; import android.util.Slog; import android.view.CompatibilityInfoHolder; @@ -67,6 +68,8 @@ final class ServiceConnectionLeaked extends AndroidRuntimeException { */ public final class LoadedApk { + private static final String TAG = "LoadedApk"; + private final ActivityThread mActivityThread; private final ApplicationInfo mApplicationInfo; final String mPackageName; @@ -113,8 +116,13 @@ public final class LoadedApk { mApplicationInfo = aInfo; mPackageName = aInfo.packageName; mAppDir = aInfo.sourceDir; - mResDir = aInfo.uid == Process.myUid() ? aInfo.sourceDir + final int myUid = Process.myUid(); + mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir; + if (!UserId.isSameUser(aInfo.uid, myUid)) { + aInfo.dataDir = PackageManager.getDataDirForUser(UserId.getUserId(myUid), + mPackageName); + } mSharedLibraries = aInfo.sharedLibraryFiles; mDataDir = aInfo.dataDir; mDataDirFile = mDataDir != null ? new File(mDataDir) : null; diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index decb974..bb35c29 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -364,4 +364,6 @@ interface IPackageManager { VerifierDeviceIdentity getVerifierDeviceIdentity(); boolean isFirstBoot(); + + List<UserInfo> getUsers(); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 8541748..26a9181 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -28,6 +28,7 @@ import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Environment; import android.util.AndroidException; import android.util.DisplayMetrics; @@ -753,13 +754,6 @@ public abstract class PackageManager { public static final int VERIFICATION_REJECT = -1; /** - * Range of IDs allocated for a user. - * - * @hide - */ - public static final int PER_USER_RANGE = 100000; - - /** * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device's * audio pipeline is low-latency, more suitable for audio applications sensitive to delays or * lag in sound input or output. @@ -2615,39 +2609,6 @@ public abstract class PackageManager { public abstract void updateUserFlags(int id, int flags); /** - * Checks to see if the user id is the same for the two uids, i.e., they belong to the same - * user. - * @hide - */ - public static boolean isSameUser(int uid1, int uid2) { - return getUserId(uid1) == getUserId(uid2); - } - - /** - * Returns the user id for a given uid. - * @hide - */ - public static int getUserId(int uid) { - return uid / PER_USER_RANGE; - } - - /** - * Returns the uid that is composed from the userId and the appId. - * @hide - */ - public static int getUid(int userId, int appId) { - return userId * PER_USER_RANGE + (appId % PER_USER_RANGE); - } - - /** - * Returns the app id (or base uid) for a given uid, stripping out the user id from it. - * @hide - */ - public static int getAppId(int uid) { - return uid % PER_USER_RANGE; - } - - /** * Returns the device identity that verifiers can use to associate their * scheme to a particular device. This should not be used by anything other * than a package verifier. @@ -2656,4 +2617,17 @@ public abstract class PackageManager { * @hide */ public abstract VerifierDeviceIdentity getVerifierDeviceIdentity(); + + /** + * Returns the data directory for a particular user and package, given the uid of the package. + * @param uid uid of the package, including the userId and appId + * @param packageName name of the package + * @return the user-specific data directory for the package + * @hide + */ + public static String getDataDirForUser(int userId, String packageName) { + // TODO: This should be shared with Installer's knowledge of user directory + return Environment.getDataDirectory().toString() + "/user/" + userId + + "/" + packageName; + } } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index e593d5b..faee873 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -24,18 +24,17 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; +import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.PatternMatcher; +import android.os.UserId; import android.util.AttributeSet; import android.util.Base64; import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; import android.util.TypedValue; -import com.android.internal.util.XmlUtils; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; import java.io.BufferedInputStream; import java.io.File; @@ -59,6 +58,11 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; +import com.android.internal.util.XmlUtils; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + /** * Package archive parsing * @@ -209,6 +213,8 @@ public class PackageParser { public static PackageInfo generatePackageInfo(PackageParser.Package p, int gids[], int flags, long firstInstallTime, long lastUpdateTime) { + final int userId = Binder.getOrigCallingUser(); + PackageInfo pi = new PackageInfo(); pi.packageName = p.packageName; pi.versionCode = p.mVersionCode; @@ -250,7 +256,8 @@ public class PackageParser { final Activity activity = p.activities.get(i); if (activity.info.enabled || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) { - pi.activities[j++] = generateActivityInfo(p.activities.get(i), flags); + pi.activities[j++] = generateActivityInfo(p.activities.get(i), flags, + userId); } } } @@ -271,7 +278,7 @@ public class PackageParser { final Activity activity = p.receivers.get(i); if (activity.info.enabled || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) { - pi.receivers[j++] = generateActivityInfo(p.receivers.get(i), flags); + pi.receivers[j++] = generateActivityInfo(p.receivers.get(i), flags, userId); } } } @@ -292,7 +299,7 @@ public class PackageParser { final Service service = p.services.get(i); if (service.info.enabled || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) { - pi.services[j++] = generateServiceInfo(p.services.get(i), flags); + pi.services[j++] = generateServiceInfo(p.services.get(i), flags, userId); } } } @@ -313,7 +320,7 @@ public class PackageParser { final Provider provider = p.providers.get(i); if (provider.info.enabled || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) { - pi.providers[j++] = generateProviderInfo(p.providers.get(i), flags); + pi.providers[j++] = generateProviderInfo(p.providers.get(i), flags, userId); } } } @@ -3241,8 +3248,12 @@ public class PackageParser { } public static ApplicationInfo generateApplicationInfo(Package p, int flags) { + return generateApplicationInfo(p, flags, UserId.getUserId(Binder.getCallingUid())); + } + + public static ApplicationInfo generateApplicationInfo(Package p, int flags, int userId) { if (p == null) return null; - if (!copyNeeded(flags, p, null)) { + if (!copyNeeded(flags, p, null) && userId == 0) { // CompatibilityMode is global state. It's safe to modify the instance // of the package. if (!sCompatibilityModeEnabled) { @@ -3258,6 +3269,10 @@ public class PackageParser { // Make shallow copy so we can store the metadata/libraries safely ApplicationInfo ai = new ApplicationInfo(p.applicationInfo); + if (userId != 0) { + ai.uid = UserId.getUid(userId, ai.uid); + ai.dataDir = PackageManager.getDataDirForUser(userId, ai.packageName); + } if ((flags & PackageManager.GET_META_DATA) != 0) { ai.metaData = p.mAppMetaData; } @@ -3325,16 +3340,15 @@ public class PackageParser { } } - public static final ActivityInfo generateActivityInfo(Activity a, - int flags) { + public static final ActivityInfo generateActivityInfo(Activity a, int flags, int userId) { if (a == null) return null; - if (!copyNeeded(flags, a.owner, a.metaData)) { + if (!copyNeeded(flags, a.owner, a.metaData) && userId == 0) { return a.info; } // Make shallow copies so we can store the metadata safely ActivityInfo ai = new ActivityInfo(a.info); ai.metaData = a.metaData; - ai.applicationInfo = generateApplicationInfo(a.owner, flags); + ai.applicationInfo = generateApplicationInfo(a.owner, flags, userId); return ai; } @@ -3359,15 +3373,15 @@ public class PackageParser { } } - public static final ServiceInfo generateServiceInfo(Service s, int flags) { + public static final ServiceInfo generateServiceInfo(Service s, int flags, int userId) { if (s == null) return null; - if (!copyNeeded(flags, s.owner, s.metaData)) { + if (!copyNeeded(flags, s.owner, s.metaData) && userId == 0) { return s.info; } // Make shallow copies so we can store the metadata safely ServiceInfo si = new ServiceInfo(s.info); si.metaData = s.metaData; - si.applicationInfo = generateApplicationInfo(s.owner, flags); + si.applicationInfo = generateApplicationInfo(s.owner, flags, userId); return si; } @@ -3400,12 +3414,12 @@ public class PackageParser { } } - public static final ProviderInfo generateProviderInfo(Provider p, - int flags) { + public static final ProviderInfo generateProviderInfo(Provider p, int flags, int userId) { if (p == null) return null; if (!copyNeeded(flags, p.owner, p.metaData) && ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) != 0 - || p.info.uriPermissionPatterns == null)) { + || p.info.uriPermissionPatterns == null) + && userId == 0) { return p.info; } // Make shallow copies so we can store the metadata safely @@ -3414,7 +3428,7 @@ public class PackageParser { if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) { pi.uriPermissionPatterns = null; } - pi.applicationInfo = generateApplicationInfo(p.owner, flags); + pi.applicationInfo = generateApplicationInfo(p.owner, flags, userId); return pi; } diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 24569fa..577fc43 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -49,6 +49,7 @@ public class Binder implements IBinder { private static final boolean FIND_POTENTIAL_LEAKS = false; private static final String TAG = "Binder"; + /* mObject is used by native code, do not remove or rename */ private int mObject; private IInterface mOwner; private String mDescriptor; @@ -70,7 +71,35 @@ public class Binder implements IBinder { * incoming transaction, then its own uid is returned. */ 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. + * <p/> + * This value cannot be reset by calls to {@link #clearCallingIdentity()}. + * @hide + */ + public static final int getOrigCallingUid() { + if (UserId.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 UserId.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/java/android/os/UserId.java b/core/java/android/os/UserId.java new file mode 100644 index 0000000..4124d51 --- /dev/null +++ b/core/java/android/os/UserId.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +/** + * @hide + */ +public final class UserId { + /** + * Range of IDs allocated for a user. + * + * @hide + */ + public static final int PER_USER_RANGE = 100000; + + public static final int USER_ALL = -1; + + /** + * Enable multi-user related side effects. Set this to false if there are problems with single + * user usecases. + * */ + public static final boolean MU_ENABLED = true; + + /** + * Checks to see if the user id is the same for the two uids, i.e., they belong to the same + * user. + * @hide + */ + public static final boolean isSameUser(int uid1, int uid2) { + return getUserId(uid1) == getUserId(uid2); + } + + /** + * Checks to see if both uids are referring to the same app id, ignoring the user id part of the + * uids. + * @param uid1 uid to compare + * @param uid2 other uid to compare + * @return whether the appId is the same for both uids + * @hide + */ + public static final boolean isSameApp(int uid1, int uid2) { + return getAppId(uid1) == getAppId(uid2); + } + + /** + * Returns the user id for a given uid. + * @hide + */ + public static final int getUserId(int uid) { + if (MU_ENABLED) { + return uid / PER_USER_RANGE; + } else { + return 0; + } + } + + /** + * Returns the uid that is composed from the userId and the appId. + * @hide + */ + public static final int getUid(int userId, int appId) { + if (MU_ENABLED) { + return userId * PER_USER_RANGE + (appId % PER_USER_RANGE); + } else { + return appId; + } + } + + /** + * Returns the app id (or base uid) for a given uid, stripping out the user id from it. + * @hide + */ + public static final int getAppId(int uid) { + return uid % PER_USER_RANGE; + } +} |