Loading cmds/content/src/com/android/commands/content/Content.java +37 −19 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.database.Cursor; import android.net.Uri; import android.os.Binder; import android.os.IBinder; import android.os.UserHandle; import android.text.TextUtils; /** Loading Loading @@ -63,7 +64,8 @@ public class Content { private static final String USAGE = "usage: adb shell content [subcommand] [options]\n" + "\n" + "usage: adb shell content insert --uri <URI> --bind <BINDING> [--bind <BINDING>...]\n" + "usage: adb shell content insert --uri <URI> [--user <USER_ID>]" + " --bind <BINDING> [--bind <BINDING>...]\n" + " <URI> a content provider URI.\n" + " <BINDING> binds a typed value to a column and is formatted:\n" + " <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n" Loading @@ -75,7 +77,7 @@ public class Content { + " adb shell content insert --uri content://settings/secure --bind name:s:new_setting" + " --bind value:s:new_value\n" + "\n" + "usage: adb shell content update --uri <URI> [--where <WHERE>]\n" + "usage: adb shell content update --uri <URI> [--user <USER_ID>] [--where <WHERE>]\n" + " <WHERE> is a SQL style where clause in quotes (You have to escape single quotes" + " - see example below).\n" + " Example:\n" Loading @@ -83,15 +85,15 @@ public class Content { + " adb shell content update --uri content://settings/secure --bind" + " value:s:newer_value --where \"name=\'new_setting\'\"\n" + "\n" + "usage: adb shell content delete --uri <URI> --bind <BINDING>" + "usage: adb shell content delete --uri <URI> [--user <USER_ID>] --bind <BINDING>" + " [--bind <BINDING>...] [--where <WHERE>]\n" + " Example:\n" + " # Remove \"new_setting\" secure setting.\n" + " adb shell content delete --uri content://settings/secure " + "--where \"name=\'new_setting\'\"\n" + "\n" + "usage: adb shell content query --uri <URI> [--projection <PROJECTION>]" + " [--where <WHERE>] [--sort <SORT_ORDER>]\n" + "usage: adb shell content query --uri <URI> [--user <USER_ID>]" + " [--projection <PROJECTION>] [--where <WHERE>] [--sort <SORT_ORDER>]\n" + " <PROJECTION> is a list of colon separated column names and is formatted:\n" + " <COLUMN_NAME>[:<COLUMN_NAME>...]\n" + " <SORT_OREDER> is the order in which rows in the result should be sorted.\n" Loading @@ -110,6 +112,7 @@ public class Content { private static final String ARGUMENT_WHERE = "--where"; private static final String ARGUMENT_BIND = "--bind"; private static final String ARGUMENT_URI = "--uri"; private static final String ARGUMENT_USER = "--user"; private static final String ARGUMENT_PROJECTION = "--projection"; private static final String ARGUMENT_SORT = "--sort"; private static final String TYPE_BOOLEAN = "b"; Loading Loading @@ -150,10 +153,13 @@ public class Content { private InsertCommand parseInsertCommand() { Uri uri = null; int userId = UserHandle.USER_OWNER; ContentValues values = new ContentValues(); for (String argument; (argument = mTokenizer.nextArg()) != null;) { if (ARGUMENT_URI.equals(argument)) { uri = Uri.parse(argumentValueRequired(argument)); } else if (ARGUMENT_USER.equals(argument)) { userId = Integer.parseInt(argumentValueRequired(argument)); } else if (ARGUMENT_BIND.equals(argument)) { parseBindValue(values); } else { Loading @@ -168,15 +174,18 @@ public class Content { throw new IllegalArgumentException("Bindings not specified." + " Did you specify --bind argument(s)?"); } return new InsertCommand(uri, values); return new InsertCommand(uri, userId, values); } private DeleteCommand parseDeleteCommand() { Uri uri = null; int userId = UserHandle.USER_OWNER; String where = null; for (String argument; (argument = mTokenizer.nextArg())!= null;) { if (ARGUMENT_URI.equals(argument)) { uri = Uri.parse(argumentValueRequired(argument)); } else if (ARGUMENT_USER.equals(argument)) { userId = Integer.parseInt(argumentValueRequired(argument)); } else if (ARGUMENT_WHERE.equals(argument)) { where = argumentValueRequired(argument); } else { Loading @@ -187,16 +196,19 @@ public class Content { throw new IllegalArgumentException("Content provider URI not specified." + " Did you specify --uri argument?"); } return new DeleteCommand(uri, where); return new DeleteCommand(uri, userId, where); } private UpdateCommand parseUpdateCommand() { Uri uri = null; int userId = UserHandle.USER_OWNER; String where = null; ContentValues values = new ContentValues(); for (String argument; (argument = mTokenizer.nextArg())!= null;) { if (ARGUMENT_URI.equals(argument)) { uri = Uri.parse(argumentValueRequired(argument)); } else if (ARGUMENT_USER.equals(argument)) { userId = Integer.parseInt(argumentValueRequired(argument)); } else if (ARGUMENT_WHERE.equals(argument)) { where = argumentValueRequired(argument); } else if (ARGUMENT_BIND.equals(argument)) { Loading @@ -213,17 +225,20 @@ public class Content { throw new IllegalArgumentException("Bindings not specified." + " Did you specify --bind argument(s)?"); } return new UpdateCommand(uri, values, where); return new UpdateCommand(uri, userId, values, where); } public QueryCommand parseQueryCommand() { Uri uri = null; int userId = UserHandle.USER_OWNER; String[] projection = null; String sort = null; String where = null; for (String argument; (argument = mTokenizer.nextArg())!= null;) { if (ARGUMENT_URI.equals(argument)) { uri = Uri.parse(argumentValueRequired(argument)); } else if (ARGUMENT_USER.equals(argument)) { userId = Integer.parseInt(argumentValueRequired(argument)); } else if (ARGUMENT_WHERE.equals(argument)) { where = argumentValueRequired(argument); } else if (ARGUMENT_SORT.equals(argument)) { Loading @@ -238,7 +253,7 @@ public class Content { throw new IllegalArgumentException("Content provider URI not specified." + " Did you specify --uri argument?"); } return new QueryCommand(uri, projection, where, sort); return new QueryCommand(uri, userId, projection, where, sort); } private void parseBindValue(ContentValues values) { Loading Loading @@ -298,9 +313,11 @@ public class Content { private static abstract class Command { final Uri mUri; final int mUserId; public Command(Uri uri) { public Command(Uri uri, int userId) { mUri = uri; mUserId = userId; } public final void execute() { Loading @@ -311,7 +328,7 @@ public class Content { IBinder token = new Binder(); try { ContentProviderHolder holder = activityManager.getContentProviderExternal( providerName, token); providerName, mUserId, token); if (holder == null) { throw new IllegalStateException("Could not find provider: " + providerName); } Loading @@ -334,8 +351,8 @@ public class Content { private static class InsertCommand extends Command { final ContentValues mContentValues; public InsertCommand(Uri uri, ContentValues contentValues) { super(uri); public InsertCommand(Uri uri, int userId, ContentValues contentValues) { super(uri, userId); mContentValues = contentValues; } Loading @@ -348,8 +365,8 @@ public class Content { private static class DeleteCommand extends Command { final String mWhere; public DeleteCommand(Uri uri, String where) { super(uri); public DeleteCommand(Uri uri, int userId, String where) { super(uri, userId); mWhere = where; } Loading @@ -363,8 +380,9 @@ public class Content { final String[] mProjection; final String mSortOrder; public QueryCommand(Uri uri, String[] projection, String where, String sortOrder) { super(uri, where); public QueryCommand( Uri uri, int userId, String[] projection, String where, String sortOrder) { super(uri, userId, where); mProjection = projection; mSortOrder = sortOrder; } Loading Loading @@ -426,8 +444,8 @@ public class Content { private static class UpdateCommand extends InsertCommand { final String mWhere; public UpdateCommand(Uri uri, ContentValues contentValues, String where) { super(uri, contentValues); public UpdateCommand(Uri uri, int userId, ContentValues contentValues, String where) { super(uri, userId, contentValues); mWhere = where; } Loading core/java/android/app/ActivityManagerNative.java +9 −6 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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(); Loading core/java/android/app/ActivityThread.java +47 −17 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -4640,16 +4667,19 @@ 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]); 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; Loading core/java/android/app/ContextImpl.java +36 −23 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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; } Loading @@ -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); Loading @@ -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) { Loading Loading @@ -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 Loading @@ -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 Loading @@ -1946,7 +1961,5 @@ class ContextImpl extends Context { public void unstableProviderDied(IContentProvider icp) { mMainThread.handleUnstableProviderDied(icp.asBinder(), true); } private final ActivityThread mMainThread; } } core/java/android/app/IActivityManager.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
cmds/content/src/com/android/commands/content/Content.java +37 −19 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.database.Cursor; import android.net.Uri; import android.os.Binder; import android.os.IBinder; import android.os.UserHandle; import android.text.TextUtils; /** Loading Loading @@ -63,7 +64,8 @@ public class Content { private static final String USAGE = "usage: adb shell content [subcommand] [options]\n" + "\n" + "usage: adb shell content insert --uri <URI> --bind <BINDING> [--bind <BINDING>...]\n" + "usage: adb shell content insert --uri <URI> [--user <USER_ID>]" + " --bind <BINDING> [--bind <BINDING>...]\n" + " <URI> a content provider URI.\n" + " <BINDING> binds a typed value to a column and is formatted:\n" + " <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n" Loading @@ -75,7 +77,7 @@ public class Content { + " adb shell content insert --uri content://settings/secure --bind name:s:new_setting" + " --bind value:s:new_value\n" + "\n" + "usage: adb shell content update --uri <URI> [--where <WHERE>]\n" + "usage: adb shell content update --uri <URI> [--user <USER_ID>] [--where <WHERE>]\n" + " <WHERE> is a SQL style where clause in quotes (You have to escape single quotes" + " - see example below).\n" + " Example:\n" Loading @@ -83,15 +85,15 @@ public class Content { + " adb shell content update --uri content://settings/secure --bind" + " value:s:newer_value --where \"name=\'new_setting\'\"\n" + "\n" + "usage: adb shell content delete --uri <URI> --bind <BINDING>" + "usage: adb shell content delete --uri <URI> [--user <USER_ID>] --bind <BINDING>" + " [--bind <BINDING>...] [--where <WHERE>]\n" + " Example:\n" + " # Remove \"new_setting\" secure setting.\n" + " adb shell content delete --uri content://settings/secure " + "--where \"name=\'new_setting\'\"\n" + "\n" + "usage: adb shell content query --uri <URI> [--projection <PROJECTION>]" + " [--where <WHERE>] [--sort <SORT_ORDER>]\n" + "usage: adb shell content query --uri <URI> [--user <USER_ID>]" + " [--projection <PROJECTION>] [--where <WHERE>] [--sort <SORT_ORDER>]\n" + " <PROJECTION> is a list of colon separated column names and is formatted:\n" + " <COLUMN_NAME>[:<COLUMN_NAME>...]\n" + " <SORT_OREDER> is the order in which rows in the result should be sorted.\n" Loading @@ -110,6 +112,7 @@ public class Content { private static final String ARGUMENT_WHERE = "--where"; private static final String ARGUMENT_BIND = "--bind"; private static final String ARGUMENT_URI = "--uri"; private static final String ARGUMENT_USER = "--user"; private static final String ARGUMENT_PROJECTION = "--projection"; private static final String ARGUMENT_SORT = "--sort"; private static final String TYPE_BOOLEAN = "b"; Loading Loading @@ -150,10 +153,13 @@ public class Content { private InsertCommand parseInsertCommand() { Uri uri = null; int userId = UserHandle.USER_OWNER; ContentValues values = new ContentValues(); for (String argument; (argument = mTokenizer.nextArg()) != null;) { if (ARGUMENT_URI.equals(argument)) { uri = Uri.parse(argumentValueRequired(argument)); } else if (ARGUMENT_USER.equals(argument)) { userId = Integer.parseInt(argumentValueRequired(argument)); } else if (ARGUMENT_BIND.equals(argument)) { parseBindValue(values); } else { Loading @@ -168,15 +174,18 @@ public class Content { throw new IllegalArgumentException("Bindings not specified." + " Did you specify --bind argument(s)?"); } return new InsertCommand(uri, values); return new InsertCommand(uri, userId, values); } private DeleteCommand parseDeleteCommand() { Uri uri = null; int userId = UserHandle.USER_OWNER; String where = null; for (String argument; (argument = mTokenizer.nextArg())!= null;) { if (ARGUMENT_URI.equals(argument)) { uri = Uri.parse(argumentValueRequired(argument)); } else if (ARGUMENT_USER.equals(argument)) { userId = Integer.parseInt(argumentValueRequired(argument)); } else if (ARGUMENT_WHERE.equals(argument)) { where = argumentValueRequired(argument); } else { Loading @@ -187,16 +196,19 @@ public class Content { throw new IllegalArgumentException("Content provider URI not specified." + " Did you specify --uri argument?"); } return new DeleteCommand(uri, where); return new DeleteCommand(uri, userId, where); } private UpdateCommand parseUpdateCommand() { Uri uri = null; int userId = UserHandle.USER_OWNER; String where = null; ContentValues values = new ContentValues(); for (String argument; (argument = mTokenizer.nextArg())!= null;) { if (ARGUMENT_URI.equals(argument)) { uri = Uri.parse(argumentValueRequired(argument)); } else if (ARGUMENT_USER.equals(argument)) { userId = Integer.parseInt(argumentValueRequired(argument)); } else if (ARGUMENT_WHERE.equals(argument)) { where = argumentValueRequired(argument); } else if (ARGUMENT_BIND.equals(argument)) { Loading @@ -213,17 +225,20 @@ public class Content { throw new IllegalArgumentException("Bindings not specified." + " Did you specify --bind argument(s)?"); } return new UpdateCommand(uri, values, where); return new UpdateCommand(uri, userId, values, where); } public QueryCommand parseQueryCommand() { Uri uri = null; int userId = UserHandle.USER_OWNER; String[] projection = null; String sort = null; String where = null; for (String argument; (argument = mTokenizer.nextArg())!= null;) { if (ARGUMENT_URI.equals(argument)) { uri = Uri.parse(argumentValueRequired(argument)); } else if (ARGUMENT_USER.equals(argument)) { userId = Integer.parseInt(argumentValueRequired(argument)); } else if (ARGUMENT_WHERE.equals(argument)) { where = argumentValueRequired(argument); } else if (ARGUMENT_SORT.equals(argument)) { Loading @@ -238,7 +253,7 @@ public class Content { throw new IllegalArgumentException("Content provider URI not specified." + " Did you specify --uri argument?"); } return new QueryCommand(uri, projection, where, sort); return new QueryCommand(uri, userId, projection, where, sort); } private void parseBindValue(ContentValues values) { Loading Loading @@ -298,9 +313,11 @@ public class Content { private static abstract class Command { final Uri mUri; final int mUserId; public Command(Uri uri) { public Command(Uri uri, int userId) { mUri = uri; mUserId = userId; } public final void execute() { Loading @@ -311,7 +328,7 @@ public class Content { IBinder token = new Binder(); try { ContentProviderHolder holder = activityManager.getContentProviderExternal( providerName, token); providerName, mUserId, token); if (holder == null) { throw new IllegalStateException("Could not find provider: " + providerName); } Loading @@ -334,8 +351,8 @@ public class Content { private static class InsertCommand extends Command { final ContentValues mContentValues; public InsertCommand(Uri uri, ContentValues contentValues) { super(uri); public InsertCommand(Uri uri, int userId, ContentValues contentValues) { super(uri, userId); mContentValues = contentValues; } Loading @@ -348,8 +365,8 @@ public class Content { private static class DeleteCommand extends Command { final String mWhere; public DeleteCommand(Uri uri, String where) { super(uri); public DeleteCommand(Uri uri, int userId, String where) { super(uri, userId); mWhere = where; } Loading @@ -363,8 +380,9 @@ public class Content { final String[] mProjection; final String mSortOrder; public QueryCommand(Uri uri, String[] projection, String where, String sortOrder) { super(uri, where); public QueryCommand( Uri uri, int userId, String[] projection, String where, String sortOrder) { super(uri, userId, where); mProjection = projection; mSortOrder = sortOrder; } Loading Loading @@ -426,8 +444,8 @@ public class Content { private static class UpdateCommand extends InsertCommand { final String mWhere; public UpdateCommand(Uri uri, ContentValues contentValues, String where) { super(uri, contentValues); public UpdateCommand(Uri uri, int userId, ContentValues contentValues, String where) { super(uri, userId, contentValues); mWhere = where; } Loading
core/java/android/app/ActivityManagerNative.java +9 −6 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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(); Loading
core/java/android/app/ActivityThread.java +47 −17 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -4640,16 +4667,19 @@ 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]); 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; Loading
core/java/android/app/ContextImpl.java +36 −23 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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; } Loading @@ -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); Loading @@ -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) { Loading Loading @@ -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 Loading @@ -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 Loading @@ -1946,7 +1961,5 @@ class ContextImpl extends Context { public void unstableProviderDied(IContentProvider icp) { mMainThread.handleUnstableProviderDied(icp.asBinder(), true); } private final ActivityThread mMainThread; } }
core/java/android/app/IActivityManager.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading