diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 15 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 64 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 59 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 4 | ||||
-rw-r--r-- | core/java/android/app/Notification.java | 14 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 11 | ||||
-rw-r--r-- | core/java/android/content/ContextWrapper.java | 7 | ||||
-rw-r--r-- | core/java/android/widget/RemoteViews.java | 20 | ||||
-rw-r--r-- | core/java/com/android/internal/statusbar/StatusBarNotification.java | 51 |
9 files changed, 170 insertions, 75 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index b0df660..c3f57e8 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -632,8 +632,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); String name = data.readString(); + int userId = data.readInt(); boolean stable = data.readInt() != 0; - ContentProviderHolder cph = getContentProvider(app, name, stable); + ContentProviderHolder cph = getContentProvider(app, name, userId, stable); reply.writeNoException(); if (cph != null) { reply.writeInt(1); @@ -647,8 +648,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String name = data.readString(); + int userId = data.readInt(); IBinder token = data.readStrongBinder(); - ContentProviderHolder cph = getContentProviderExternal(name, token); + ContentProviderHolder cph = getContentProviderExternal(name, userId, token); reply.writeNoException(); if (cph != null) { reply.writeInt(1); @@ -2495,12 +2497,13 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } public ContentProviderHolder getContentProvider(IApplicationThread caller, - String name, boolean stable) throws RemoteException { + String name, int userId, boolean stable) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); data.writeString(name); + data.writeInt(userId); data.writeInt(stable ? 1 : 0); mRemote.transact(GET_CONTENT_PROVIDER_TRANSACTION, data, reply, 0); reply.readException(); @@ -2513,13 +2516,13 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); return cph; } - public ContentProviderHolder getContentProviderExternal(String name, IBinder token) - throws RemoteException - { + public ContentProviderHolder getContentProviderExternal(String name, int userId, IBinder token) + throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeString(name); + data.writeInt(userId); data.writeStrongBinder(token); mRemote.transact(GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION, data, reply, 0); reply.readException(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 67ecf5b..aa8ef21 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -89,6 +89,7 @@ import android.renderscript.RenderScript; import com.android.internal.os.BinderInternal; import com.android.internal.os.RuntimeInit; import com.android.internal.os.SamplingProfilerIntegration; +import com.android.internal.util.Objects; import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl; @@ -214,9 +215,33 @@ public final class ActivityThread { = new ArrayList<ActivityClientRecord>(); Configuration mPendingConfiguration = null; + private static final class ProviderKey { + final String authority; + final int userId; + + public ProviderKey(String authority, int userId) { + this.authority = authority; + this.userId = userId; + } + + @Override + public boolean equals(Object o) { + if (o instanceof ProviderKey) { + final ProviderKey other = (ProviderKey) o; + return Objects.equal(authority, other.authority) && userId == other.userId; + } + return false; + } + + @Override + public int hashCode() { + return ((authority != null) ? authority.hashCode() : 0) ^ userId; + } + } + // The lock of mProviderMap protects the following variables. - final HashMap<String, ProviderClientRecord> mProviderMap - = new HashMap<String, ProviderClientRecord>(); + final HashMap<ProviderKey, ProviderClientRecord> mProviderMap + = new HashMap<ProviderKey, ProviderClientRecord>(); final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap = new HashMap<IBinder, ProviderRefCount>(); final HashMap<IBinder, ProviderClientRecord> mLocalProviders @@ -4360,8 +4385,9 @@ public final class ActivityThread { } } - public final IContentProvider acquireProvider(Context c, String name, boolean stable) { - IContentProvider provider = acquireExistingProvider(c, name, stable); + public final IContentProvider acquireProvider( + Context c, String auth, int userId, boolean stable) { + final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); if (provider != null) { return provider; } @@ -4375,11 +4401,11 @@ public final class ActivityThread { IActivityManager.ContentProviderHolder holder = null; try { holder = ActivityManagerNative.getDefault().getContentProvider( - getApplicationThread(), name, stable); + getApplicationThread(), auth, userId, stable); } catch (RemoteException ex) { } if (holder == null) { - Slog.e(TAG, "Failed to find provider info for " + name); + Slog.e(TAG, "Failed to find provider info for " + auth); return null; } @@ -4456,10 +4482,11 @@ public final class ActivityThread { } } - public final IContentProvider acquireExistingProvider(Context c, String name, - boolean stable) { + public final IContentProvider acquireExistingProvider( + Context c, String auth, int userId, boolean stable) { synchronized (mProviderMap) { - ProviderClientRecord pr = mProviderMap.get(name); + final ProviderKey key = new ProviderKey(auth, userId); + final ProviderClientRecord pr = mProviderMap.get(key); if (pr == null) { return null; } @@ -4639,17 +4666,20 @@ public final class ActivityThread { } private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, - ContentProvider localProvider,IActivityManager.ContentProviderHolder holder) { - String names[] = PATTERN_SEMICOLON.split(holder.info.authority); - ProviderClientRecord pcr = new ProviderClientRecord(names, provider, - localProvider, holder); - for (int i = 0; i < names.length; i++) { - ProviderClientRecord existing = mProviderMap.get(names[i]); + ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { + final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority); + final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); + + final ProviderClientRecord pcr = new ProviderClientRecord( + auths, provider, localProvider, holder); + for (String auth : auths) { + final ProviderKey key = new ProviderKey(auth, userId); + final ProviderClientRecord existing = mProviderMap.get(key); if (existing != null) { Slog.w(TAG, "Content provider " + pcr.mHolder.info.name - + " already published as " + names[i]); + + " already published as " + auth); } else { - mProviderMap.put(names[i], pcr); + mProviderMap.put(key, pcr); } } return pcr; diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 56b745f..a6ec9b6 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -17,6 +17,7 @@ package android.app; import com.android.internal.policy.PolicyManager; +import com.android.internal.util.Preconditions; import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; @@ -35,6 +36,7 @@ import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; @@ -183,6 +185,7 @@ class ContextImpl extends Context { private Display mDisplay; // may be null if default display private Context mReceiverRestrictedContext = null; private boolean mRestricted; + private UserHandle mUser; private final Object mSync = new Object(); @@ -1676,7 +1679,13 @@ class ContextImpl extends Context { @Override public Context createPackageContext(String packageName, int flags) - throws PackageManager.NameNotFoundException { + throws NameNotFoundException { + return createPackageContextAsUser(packageName, flags, Process.myUserHandle()); + } + + @Override + public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) + throws NameNotFoundException { if (packageName.equals("system") || packageName.equals("android")) { final ContextImpl context = new ContextImpl(mMainThread.getSystemContext()); context.mBasePackageName = mBasePackageName; @@ -1688,7 +1697,7 @@ class ContextImpl extends Context { if (pi != null) { ContextImpl c = new ContextImpl(); c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; - c.init(pi, null, mMainThread, mResources, mBasePackageName); + c.init(pi, null, mMainThread, mResources, mBasePackageName, user); if (c.mResources != null) { return c; } @@ -1769,8 +1778,8 @@ class ContextImpl extends Context { } static ContextImpl createSystemContext(ActivityThread mainThread) { - ContextImpl context = new ContextImpl(); - context.init(Resources.getSystem(), mainThread); + final ContextImpl context = new ContextImpl(); + context.init(Resources.getSystem(), mainThread, Process.myUserHandle()); return context; } @@ -1790,18 +1799,17 @@ class ContextImpl extends Context { mResources = context.mResources; mMainThread = context.mMainThread; mContentResolver = context.mContentResolver; + mUser = context.mUser; mDisplay = context.mDisplay; mOuterContext = this; } - final void init(LoadedApk packageInfo, - IBinder activityToken, ActivityThread mainThread) { - init(packageInfo, activityToken, mainThread, null, null); + final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) { + init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle()); } - final void init(LoadedApk packageInfo, - IBinder activityToken, ActivityThread mainThread, - Resources container, String basePackageName) { + final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread, + Resources container, String basePackageName, UserHandle user) { mPackageInfo = packageInfo; mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName; mResources = mPackageInfo.getResources(mainThread); @@ -1818,16 +1826,18 @@ class ContextImpl extends Context { null, container.getCompatibilityInfo()); } mMainThread = mainThread; - mContentResolver = new ApplicationContentResolver(this, mainThread); mActivityToken = activityToken; + mContentResolver = new ApplicationContentResolver(this, mainThread, user); + mUser = user; } - final void init(Resources resources, ActivityThread mainThread) { + final void init(Resources resources, ActivityThread mainThread, UserHandle user) { mPackageInfo = null; mBasePackageName = null; mResources = resources; mMainThread = mainThread; - mContentResolver = new ApplicationContentResolver(this, mainThread); + mContentResolver = new ApplicationContentResolver(this, mainThread, user); + mUser = user; } final void scheduleFinalCleanup(String who, String what) { @@ -1912,19 +1922,24 @@ class ContextImpl extends Context { // ---------------------------------------------------------------------- private static final class ApplicationContentResolver extends ContentResolver { - public ApplicationContentResolver(Context context, ActivityThread mainThread) { + private final ActivityThread mMainThread; + private final UserHandle mUser; + + public ApplicationContentResolver( + Context context, ActivityThread mainThread, UserHandle user) { super(context); - mMainThread = mainThread; + mMainThread = Preconditions.checkNotNull(mainThread); + mUser = Preconditions.checkNotNull(user); } @Override - protected IContentProvider acquireProvider(Context context, String name) { - return mMainThread.acquireProvider(context, name, true); + protected IContentProvider acquireProvider(Context context, String auth) { + return mMainThread.acquireProvider(context, auth, mUser.getIdentifier(), true); } @Override - protected IContentProvider acquireExistingProvider(Context context, String name) { - return mMainThread.acquireExistingProvider(context, name, true); + protected IContentProvider acquireExistingProvider(Context context, String auth) { + return mMainThread.acquireExistingProvider(context, auth, mUser.getIdentifier(), true); } @Override @@ -1933,8 +1948,8 @@ class ContextImpl extends Context { } @Override - protected IContentProvider acquireUnstableProvider(Context c, String name) { - return mMainThread.acquireProvider(c, name, false); + protected IContentProvider acquireUnstableProvider(Context c, String auth) { + return mMainThread.acquireProvider(c, auth, mUser.getIdentifier(), false); } @Override @@ -1946,7 +1961,5 @@ class ContextImpl extends Context { public void unstableProviderDied(IContentProvider icp) { mMainThread.handleUnstableProviderDied(icp.asBinder(), true); } - - private final ActivityThread mMainThread; } } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index ed17d0e..2b2679e 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -117,8 +117,8 @@ public interface IActivityManager extends IInterface { public void reportThumbnail(IBinder token, Bitmap thumbnail, CharSequence description) throws RemoteException; public ContentProviderHolder getContentProvider(IApplicationThread caller, - String name, boolean stable) throws RemoteException; - public ContentProviderHolder getContentProviderExternal(String name, IBinder token) + String name, int userId, boolean stable) throws RemoteException; + public ContentProviderHolder getContentProviderExternal(String name, int userId, IBinder token) throws RemoteException; public void removeContentProvider(IBinder connection, boolean stable) throws RemoteException; public void removeContentProviderExternal(String name, IBinder token) throws RemoteException; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 17c2c6b..182ebef 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -29,6 +29,7 @@ import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; +import android.os.UserHandle; import android.text.TextUtils; import android.util.IntProperty; import android.util.Log; @@ -893,6 +894,19 @@ public class Notification implements Parcelable return sb.toString(); } + /** {@hide} */ + public void setUser(UserHandle user) { + if (tickerView != null) { + tickerView.setUser(user); + } + if (contentView != null) { + contentView.setUser(user); + } + if (bigContentView != null) { + bigContentView.setUser(user); + } + } + /** * Builder class for {@link Notification} objects. * diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 161670f..524962cb 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2574,6 +2574,17 @@ public abstract class Context { int flags) throws PackageManager.NameNotFoundException; /** + * Similar to {@link #createPackageContext(String, int)}, but with a + * different {@link UserHandle}. For example, {@link #getContentResolver()} + * will open any {@link Uri} as the given user. + * + * @hide + */ + public abstract Context createPackageContextAsUser( + String packageName, int flags, UserHandle user) + throws PackageManager.NameNotFoundException; + + /** * Return a new Context object for the current Context but whose resources * are adjusted to match the given Configuration. Each call to this method * returns a new instance of a Context object; Context objects are not diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 6101f4e..d824f1e 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -586,6 +586,13 @@ public class ContextWrapper extends Context { return mBase.createPackageContext(packageName, flags); } + /** @hide */ + @Override + public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) + throws PackageManager.NameNotFoundException { + return mBase.createPackageContextAsUser(packageName, flags, user); + } + @Override public Context createConfigurationContext(Configuration overrideConfiguration) { return mBase.createConfigurationContext(overrideConfiguration); diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 87ef23f..5d65324 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -23,7 +23,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentSender; import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.graphics.Bitmap; @@ -35,9 +34,9 @@ import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; -import android.util.TypedValue; import android.view.LayoutInflater; import android.view.LayoutInflater.Filter; import android.view.RemotableViewMethod; @@ -72,6 +71,13 @@ public class RemoteViews implements Parcelable, Filter { static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId"; /** + * User that these views should be applied as. Requires + * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} when + * crossing user boundaries. + */ + private UserHandle mUser = android.os.Process.myUserHandle(); + + /** * The package name of the package containing the layout * resource. (Added to the parcel) */ @@ -1438,11 +1444,16 @@ public class RemoteViews implements Parcelable, Filter { recalculateMemoryUsage(); } + /** {@hide} */ + public void setUser(UserHandle user) { + mUser = user; + } + private boolean hasLandscapeAndPortraitLayouts() { return (mLandscape != null) && (mPortrait != null); } - /** + /** * Create a new RemoteViews object that will inflate as the specified * landspace or portrait RemoteViews, depending on the current configuration. * @@ -2301,7 +2312,8 @@ public class RemoteViews implements Parcelable, Filter { if (packageName != null) { try { - c = context.createPackageContext(packageName, Context.CONTEXT_RESTRICTED); + c = context.createPackageContextAsUser( + packageName, Context.CONTEXT_RESTRICTED, mUser); } catch (NameNotFoundException e) { Log.e(LOG_TAG, "Package name " + packageName + " not found"); c = context; diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.java b/core/java/com/android/internal/statusbar/StatusBarNotification.java index cb87ac4..f9a38a5 100644 --- a/core/java/com/android/internal/statusbar/StatusBarNotification.java +++ b/core/java/com/android/internal/statusbar/StatusBarNotification.java @@ -20,8 +20,6 @@ import android.app.Notification; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; -import android.widget.RemoteViews; - /* boolean clearable = !n.ongoingEvent && ((notification.flags & Notification.FLAG_NO_CLEAR) == 0); @@ -39,19 +37,25 @@ if (truncatedTicker != null && truncatedTicker.length() > maxTickerLen) { * Class encapsulating a Notification. Sent by the NotificationManagerService to the IStatusBar (in System UI). */ public class StatusBarNotification implements Parcelable { - public String pkg; - public int id; - public String tag; - public int uid; - public int initialPid; - public Notification notification; - public int score; - - public StatusBarNotification() { + public final String pkg; + public final int id; + public final String tag; + public final int uid; + public final int initialPid; + // TODO: make this field private and move callers to an accessor that + // ensures sourceUser is applied. + public final Notification notification; + public final int score; + public final UserHandle user; + + @Deprecated + public StatusBarNotification(String pkg, int id, String tag, int uid, int initialPid, int score, + Notification notification) { + this(pkg, id, tag, uid, initialPid, score, notification, UserHandle.OWNER); } - public StatusBarNotification(String pkg, int id, String tag, - int uid, int initialPid, int score, Notification notification) { + public StatusBarNotification(String pkg, int id, String tag, int uid, int initialPid, int score, + Notification notification, UserHandle user) { if (pkg == null) throw new NullPointerException(); if (notification == null) throw new NullPointerException(); @@ -62,13 +66,11 @@ public class StatusBarNotification implements Parcelable { this.initialPid = initialPid; this.score = score; this.notification = notification; + this.user = user; + this.notification.setUser(user); } public StatusBarNotification(Parcel in) { - readFromParcel(in); - } - - public void readFromParcel(Parcel in) { this.pkg = in.readString(); this.id = in.readInt(); if (in.readInt() != 0) { @@ -80,6 +82,8 @@ public class StatusBarNotification implements Parcelable { this.initialPid = in.readInt(); this.score = in.readInt(); this.notification = new Notification(in); + this.user = UserHandle.readFromParcel(in); + this.notification.setUser(user); } public void writeToParcel(Parcel out, int flags) { @@ -95,6 +99,7 @@ public class StatusBarNotification implements Parcelable { out.writeInt(this.initialPid); out.writeInt(this.score); this.notification.writeToParcel(out, flags); + user.writeToParcel(out, flags); } public int describeContents() { @@ -115,14 +120,16 @@ public class StatusBarNotification implements Parcelable { } }; + @Override public StatusBarNotification clone() { - return new StatusBarNotification(this.pkg, this.id, this.tag, - this.uid, this.initialPid, this.score, this.notification.clone()); + return new StatusBarNotification(this.pkg, this.id, this.tag, this.uid, this.initialPid, + this.score, this.notification.clone(), this.user); } + @Override public String toString() { - return "StatusBarNotification(pkg=" + pkg + " id=" + id + " tag=" + tag - + " score=" + score + " notn=" + notification + ")"; + return "StatusBarNotification(pkg=" + pkg + " id=" + id + " tag=" + tag + " score=" + score + + " notn=" + notification + " user=" + user + ")"; } public boolean isOngoing() { @@ -139,5 +146,3 @@ public class StatusBarNotification implements Parcelable { return UserHandle.getUserId(this.uid); } } - - |