diff options
| author | Amith Yamasani <yamasani@google.com> | 2011-05-04 14:49:28 -0700 |
|---|---|---|
| committer | Amith Yamasani <yamasani@google.com> | 2012-02-03 12:01:47 -0800 |
| commit | 742a67127366c376fdf188ff99ba30b27d3bf90c (patch) | |
| tree | 4a801b0b2e9ee10fb322e3b450e2af9eb6e3002f /core/java/android/app | |
| parent | 8ca8a69d5801ad4b809e7b9dbf53bd728820924b (diff) | |
Multi-user - 1st major checkin
Switching activity stacks
Cache ContentProvider per user
Long-press power to switch users (on phone)
Added ServiceMap for separating services by user
Launch PendingIntents on the correct user's uid
Fix task switching from Recents list
AppWidgetService is mostly working.
Commands added to pm and am to allow creating and switching profiles.
Change-Id: I15810e8cfbe50a04bd3323a7ef5a8ff4230870ed
Diffstat (limited to 'core/java/android/app')
| -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 |
7 files changed, 61 insertions, 30 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 9661b9e0d32b..d98d87b3129a 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 7994d7cd3bfb..d80902d734fb 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 3c5f53a6efd8..e4cfc9948704 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 180a442f52c1..fee2beb779ac 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 2bf1fb712304..db5113ec905b 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 5222d375a439..39817ac2cde8 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 0c6baebf26b9..fcbcd8172c47 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; |
