Note with featureId from ContentProvider
This takes the Context#getFeatureId from the calling context and pipes
it all way through to the noteOp calls done by the content provider.
Bug: 136595429
Test: atest CtsAppOpsTestCases (new test added to capture this case)
TelecomUnitTests:CallLogManagerTest
ContentProviderClientTest
TelecomUnitTests:MissedCallNotifierImplTest
TelecomUnitTests:BasicCallTests
MediaInserterTest
PreferencesHelperTest
RankingHelperTest
PinnedSliceStateTest
FrameworksCoreTests:ContentResolverTest
Change-Id: I53b1035626229c920b353509a5bece157b52fb51
diff --git a/api/current.txt b/api/current.txt
index 57bbd77..bec1bc8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9467,6 +9467,7 @@
method @NonNull public final android.content.ContentProvider.CallingIdentity clearCallingIdentity();
method public abstract int delete(@NonNull android.net.Uri, @Nullable String, @Nullable String[]);
method public void dump(java.io.FileDescriptor, java.io.PrintWriter, String[]);
+ method @Nullable public final String getCallingFeatureId();
method @Nullable public final String getCallingPackage();
method @Nullable public final android.content.Context getContext();
method @Nullable public final android.content.pm.PathPermission[] getPathPermissions();
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 55dbc17..7e278e9 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -508,7 +508,7 @@
@Override
public void onExecute(IContentProvider provider) throws Exception {
- provider.insert(resolveCallingPackage(), mUri, mContentValues);
+ provider.insert(resolveCallingPackage(), null, mUri, mContentValues);
}
}
@@ -522,7 +522,7 @@
@Override
public void onExecute(IContentProvider provider) throws Exception {
- provider.delete(resolveCallingPackage(), mUri, mWhere, null);
+ provider.delete(resolveCallingPackage(), null, mUri, mWhere, null);
}
}
@@ -557,7 +557,7 @@
@Override
public void onExecute(IContentProvider provider) throws Exception {
- Bundle result = provider.call(null, mUri.getAuthority(), mMethod, mArg, mExtras);
+ Bundle result = provider.call(null, null, mUri.getAuthority(), mMethod, mArg, mExtras);
if (result != null) {
result.size(); // unpack
}
@@ -584,7 +584,7 @@
@Override
public void onExecute(IContentProvider provider) throws Exception {
- try (ParcelFileDescriptor fd = provider.openFile(null, mUri, "r", null, null)) {
+ try (ParcelFileDescriptor fd = provider.openFile(null, null, mUri, "r", null, null)) {
FileUtils.copy(fd.getFileDescriptor(), FileDescriptor.out);
}
}
@@ -597,7 +597,7 @@
@Override
public void onExecute(IContentProvider provider) throws Exception {
- try (ParcelFileDescriptor fd = provider.openFile(null, mUri, "w", null, null)) {
+ try (ParcelFileDescriptor fd = provider.openFile(null, null, mUri, "w", null, null)) {
FileUtils.copy(FileDescriptor.in, fd.getFileDescriptor());
}
}
@@ -616,7 +616,7 @@
@Override
public void onExecute(IContentProvider provider) throws Exception {
- Cursor cursor = provider.query(resolveCallingPackage(), mUri, mProjection,
+ Cursor cursor = provider.query(resolveCallingPackage(), null, mUri, mProjection,
ContentResolver.createSqlQueryBundle(mWhere, null, mSortOrder), null);
if (cursor == null) {
System.out.println("No result found.");
@@ -679,7 +679,7 @@
@Override
public void onExecute(IContentProvider provider) throws Exception {
- provider.update(resolveCallingPackage(), mUri, mContentValues, mWhere, null);
+ provider.update(resolveCallingPackage(), null, mUri, mContentValues, mWhere, null);
}
}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
index 455e4bb..b23bf5d 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -67,7 +67,7 @@
throw new IllegalStateException("Could not find provider: " + providerName);
}
provider = holder.provider;
- cursor = provider.query(null, Settings.Secure.CONTENT_URI,
+ cursor = provider.query(null, null, Settings.Secure.CONTENT_URI,
new String[] {
Settings.Secure.VALUE
},
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 7de8793..17f1a07 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -53,6 +53,7 @@
import android.os.storage.StorageManager;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
@@ -136,7 +137,7 @@
private boolean mNoPerms;
private boolean mSingleUser;
- private ThreadLocal<String> mCallingPackage;
+ private ThreadLocal<Pair<String, String>> mCallingPackage;
private Transport mTransport = new Transport();
@@ -226,11 +227,13 @@
}
@Override
- public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection,
- @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) {
+ public Cursor query(String callingPkg, @Nullable String featureId, Uri uri,
+ @Nullable String[] projection, @Nullable Bundle queryArgs,
+ @Nullable ICancellationSignal cancellationSignal) {
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
- if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
+ if (enforceReadPermission(callingPkg, featureId, uri, null)
+ != AppOpsManager.MODE_ALLOWED) {
// The caller has no access to the data, so return an empty cursor with
// the columns in the requested order. The caller may ask for an invalid
// column and we would not catch that but this is not a problem in practice.
@@ -246,7 +249,8 @@
// we have to execute the query as if allowed to get a cursor with the
// columns. We then use the column names to return an empty cursor.
Cursor cursor;
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
cursor = mInterface.query(
uri, projection, queryArgs,
@@ -264,7 +268,8 @@
return new MatrixCursor(cursor.getColumnNames(), 0);
}
Trace.traceBegin(TRACE_TAG_DATABASE, "query");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.query(
uri, projection, queryArgs,
@@ -293,12 +298,15 @@
}
@Override
- public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) {
+ public Uri insert(String callingPkg, @Nullable String featureId, Uri uri,
+ ContentValues initialValues) {
uri = validateIncomingUri(uri);
int userId = getUserIdFromUri(uri);
uri = maybeGetUriWithoutUserId(uri);
- if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
- final String original = setCallingPackage(callingPkg);
+ if (enforceWritePermission(callingPkg, featureId, uri, null)
+ != AppOpsManager.MODE_ALLOWED) {
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return rejectInsert(uri, initialValues);
} finally {
@@ -306,7 +314,8 @@
}
}
Trace.traceBegin(TRACE_TAG_DATABASE, "insert");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return maybeAddUserId(mInterface.insert(uri, initialValues), userId);
} catch (RemoteException e) {
@@ -318,14 +327,17 @@
}
@Override
- public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) {
+ public int bulkInsert(String callingPkg, @Nullable String featureId, Uri uri,
+ ContentValues[] initialValues) {
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
- if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
+ if (enforceWritePermission(callingPkg, featureId, uri, null)
+ != AppOpsManager.MODE_ALLOWED) {
return 0;
}
Trace.traceBegin(TRACE_TAG_DATABASE, "bulkInsert");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.bulkInsert(uri, initialValues);
} catch (RemoteException e) {
@@ -337,8 +349,8 @@
}
@Override
- public ContentProviderResult[] applyBatch(String callingPkg, String authority,
- ArrayList<ContentProviderOperation> operations)
+ public ContentProviderResult[] applyBatch(String callingPkg, @Nullable String featureId,
+ String authority, ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
validateIncomingAuthority(authority);
int numOperations = operations.size();
@@ -355,20 +367,21 @@
operations.set(i, operation);
}
if (operation.isReadOperation()) {
- if (enforceReadPermission(callingPkg, uri, null)
+ if (enforceReadPermission(callingPkg, featureId, uri, null)
!= AppOpsManager.MODE_ALLOWED) {
throw new OperationApplicationException("App op not allowed", 0);
}
}
if (operation.isWriteOperation()) {
- if (enforceWritePermission(callingPkg, uri, null)
+ if (enforceWritePermission(callingPkg, featureId, uri, null)
!= AppOpsManager.MODE_ALLOWED) {
throw new OperationApplicationException("App op not allowed", 0);
}
}
}
Trace.traceBegin(TRACE_TAG_DATABASE, "applyBatch");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
ContentProviderResult[] results = mInterface.applyBatch(authority,
operations);
@@ -390,14 +403,17 @@
}
@Override
- public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) {
+ public int delete(String callingPkg, @Nullable String featureId, Uri uri, String selection,
+ String[] selectionArgs) {
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
- if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
+ if (enforceWritePermission(callingPkg, featureId, uri, null)
+ != AppOpsManager.MODE_ALLOWED) {
return 0;
}
Trace.traceBegin(TRACE_TAG_DATABASE, "delete");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.delete(uri, selection, selectionArgs);
} catch (RemoteException e) {
@@ -409,15 +425,17 @@
}
@Override
- public int update(String callingPkg, Uri uri, ContentValues values, String selection,
- String[] selectionArgs) {
+ public int update(String callingPkg, @Nullable String featureId, Uri uri,
+ ContentValues values, String selection, String[] selectionArgs) {
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
- if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
+ if (enforceWritePermission(callingPkg, featureId, uri, null)
+ != AppOpsManager.MODE_ALLOWED) {
return 0;
}
Trace.traceBegin(TRACE_TAG_DATABASE, "update");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.update(uri, values, selection, selectionArgs);
} catch (RemoteException e) {
@@ -429,14 +447,15 @@
}
@Override
- public ParcelFileDescriptor openFile(
- String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal,
- IBinder callerToken) throws FileNotFoundException {
+ public ParcelFileDescriptor openFile(String callingPkg, @Nullable String featureId,
+ Uri uri, String mode, ICancellationSignal cancellationSignal, IBinder callerToken)
+ throws FileNotFoundException {
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
- enforceFilePermission(callingPkg, uri, mode, callerToken);
+ enforceFilePermission(callingPkg, featureId, uri, mode, callerToken);
Trace.traceBegin(TRACE_TAG_DATABASE, "openFile");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.openFile(
uri, mode, CancellationSignal.fromTransport(cancellationSignal));
@@ -449,14 +468,15 @@
}
@Override
- public AssetFileDescriptor openAssetFile(
- String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
+ public AssetFileDescriptor openAssetFile(String callingPkg, @Nullable String featureId,
+ Uri uri, String mode, ICancellationSignal cancellationSignal)
throws FileNotFoundException {
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
- enforceFilePermission(callingPkg, uri, mode, null);
+ enforceFilePermission(callingPkg, featureId, uri, mode, null);
Trace.traceBegin(TRACE_TAG_DATABASE, "openAssetFile");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.openAssetFile(
uri, mode, CancellationSignal.fromTransport(cancellationSignal));
@@ -469,12 +489,13 @@
}
@Override
- public Bundle call(String callingPkg, String authority, String method, @Nullable String arg,
- @Nullable Bundle extras) {
+ public Bundle call(String callingPkg, @Nullable String featureId, String authority,
+ String method, @Nullable String arg, @Nullable Bundle extras) {
validateIncomingAuthority(authority);
Bundle.setDefusable(extras, true);
Trace.traceBegin(TRACE_TAG_DATABASE, "call");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.call(authority, method, arg, extras);
} catch (RemoteException e) {
@@ -501,14 +522,16 @@
}
@Override
- public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
- Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
+ public AssetFileDescriptor openTypedAssetFile(String callingPkg,
+ @Nullable String featureId, Uri uri, String mimeType, Bundle opts,
+ ICancellationSignal cancellationSignal) throws FileNotFoundException {
Bundle.setDefusable(opts, true);
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
- enforceFilePermission(callingPkg, uri, "r", null);
+ enforceFilePermission(callingPkg, featureId, uri, "r", null);
Trace.traceBegin(TRACE_TAG_DATABASE, "openTypedAssetFile");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.openTypedAssetFile(
uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
@@ -526,15 +549,17 @@
}
@Override
- public Uri canonicalize(String callingPkg, Uri uri) {
+ public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri uri) {
uri = validateIncomingUri(uri);
int userId = getUserIdFromUri(uri);
uri = getUriWithoutUserId(uri);
- if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
+ if (enforceReadPermission(callingPkg, featureId, uri, null)
+ != AppOpsManager.MODE_ALLOWED) {
return null;
}
Trace.traceBegin(TRACE_TAG_DATABASE, "canonicalize");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return maybeAddUserId(mInterface.canonicalize(uri), userId);
} catch (RemoteException e) {
@@ -546,15 +571,17 @@
}
@Override
- public Uri uncanonicalize(String callingPkg, Uri uri) {
+ public Uri uncanonicalize(String callingPkg, String featureId, Uri uri) {
uri = validateIncomingUri(uri);
int userId = getUserIdFromUri(uri);
uri = getUriWithoutUserId(uri);
- if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
+ if (enforceReadPermission(callingPkg, featureId, uri, null)
+ != AppOpsManager.MODE_ALLOWED) {
return null;
}
Trace.traceBegin(TRACE_TAG_DATABASE, "uncanonicalize");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return maybeAddUserId(mInterface.uncanonicalize(uri), userId);
} catch (RemoteException e) {
@@ -566,15 +593,17 @@
}
@Override
- public boolean refresh(String callingPkg, Uri uri, Bundle args,
+ public boolean refresh(String callingPkg, String featureId, Uri uri, Bundle args,
ICancellationSignal cancellationSignal) throws RemoteException {
uri = validateIncomingUri(uri);
uri = getUriWithoutUserId(uri);
- if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
+ if (enforceReadPermission(callingPkg, featureId, uri, null)
+ != AppOpsManager.MODE_ALLOWED) {
return false;
}
Trace.traceBegin(TRACE_TAG_DATABASE, "refresh");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.refresh(uri, args,
CancellationSignal.fromTransport(cancellationSignal));
@@ -585,11 +614,13 @@
}
@Override
- public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+ public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri,
+ int uid, int modeFlags) {
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
Trace.traceBegin(TRACE_TAG_DATABASE, "checkUriPermission");
- final String original = setCallingPackage(callingPkg);
+ final Pair<String, String> original = setCallingPackage(
+ new Pair<>(callingPkg, featureId));
try {
return mInterface.checkUriPermission(uri, uid, modeFlags);
} catch (RemoteException e) {
@@ -600,44 +631,47 @@
}
}
- private void enforceFilePermission(String callingPkg, Uri uri, String mode,
- IBinder callerToken) throws FileNotFoundException, SecurityException {
+ private void enforceFilePermission(String callingPkg, @Nullable String featureId, Uri uri,
+ String mode, IBinder callerToken) throws FileNotFoundException, SecurityException {
if (mode != null && mode.indexOf('w') != -1) {
- if (enforceWritePermission(callingPkg, uri, callerToken)
+ if (enforceWritePermission(callingPkg, featureId, uri, callerToken)
!= AppOpsManager.MODE_ALLOWED) {
throw new FileNotFoundException("App op not allowed");
}
} else {
- if (enforceReadPermission(callingPkg, uri, callerToken)
+ if (enforceReadPermission(callingPkg, featureId, uri, callerToken)
!= AppOpsManager.MODE_ALLOWED) {
throw new FileNotFoundException("App op not allowed");
}
}
}
- private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken)
+ private int enforceReadPermission(String callingPkg, @Nullable String featureId, Uri uri,
+ IBinder callerToken)
throws SecurityException {
- final int mode = enforceReadPermissionInner(uri, callingPkg, callerToken);
+ final int mode = enforceReadPermissionInner(uri, callingPkg, featureId, callerToken);
if (mode != MODE_ALLOWED) {
return mode;
}
- return noteProxyOp(callingPkg, mReadOp);
+ return noteProxyOp(callingPkg, featureId, mReadOp);
}
- private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken)
+ private int enforceWritePermission(String callingPkg, String featureId, Uri uri,
+ IBinder callerToken)
throws SecurityException {
- final int mode = enforceWritePermissionInner(uri, callingPkg, callerToken);
+ final int mode = enforceWritePermissionInner(uri, callingPkg, featureId, callerToken);
if (mode != MODE_ALLOWED) {
return mode;
}
- return noteProxyOp(callingPkg, mWriteOp);
+ return noteProxyOp(callingPkg, featureId, mWriteOp);
}
- private int noteProxyOp(String callingPkg, int op) {
+ private int noteProxyOp(String callingPkg, String featureId, int op) {
if (op != AppOpsManager.OP_NONE) {
- int mode = mAppOpsManager.noteProxyOp(op, callingPkg);
+ int mode = mAppOpsManager.noteProxyOp(op, callingPkg, Binder.getCallingUid(),
+ featureId, null);
return mode == MODE_DEFAULT ? MODE_IGNORED : mode;
}
@@ -659,18 +693,19 @@
* associated with that permission.
*/
private int checkPermissionAndAppOp(String permission, String callingPkg,
- IBinder callerToken) {
+ @Nullable String featureId, IBinder callerToken) {
if (getContext().checkPermission(permission, Binder.getCallingPid(), Binder.getCallingUid(),
callerToken) != PERMISSION_GRANTED) {
return MODE_ERRORED;
}
- return mTransport.noteProxyOp(callingPkg, AppOpsManager.permissionToOpCode(permission));
+ return mTransport.noteProxyOp(callingPkg, featureId,
+ AppOpsManager.permissionToOpCode(permission));
}
/** {@hide} */
- protected int enforceReadPermissionInner(Uri uri, String callingPkg, IBinder callerToken)
- throws SecurityException {
+ protected int enforceReadPermissionInner(Uri uri, String callingPkg,
+ @Nullable String featureId, IBinder callerToken) throws SecurityException {
final Context context = getContext();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
@@ -684,7 +719,8 @@
if (mExported && checkUser(pid, uid, context)) {
final String componentPerm = getReadPermission();
if (componentPerm != null) {
- final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken);
+ final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, featureId,
+ callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
@@ -703,7 +739,8 @@
for (PathPermission pp : pps) {
final String pathPerm = pp.getReadPermission();
if (pathPerm != null && pp.match(path)) {
- final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken);
+ final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, featureId,
+ callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
@@ -751,8 +788,8 @@
}
/** {@hide} */
- protected int enforceWritePermissionInner(Uri uri, String callingPkg, IBinder callerToken)
- throws SecurityException {
+ protected int enforceWritePermissionInner(Uri uri, String callingPkg,
+ @Nullable String featureId, IBinder callerToken) throws SecurityException {
final Context context = getContext();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
@@ -766,7 +803,8 @@
if (mExported && checkUser(pid, uid, context)) {
final String componentPerm = getWritePermission();
if (componentPerm != null) {
- final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken);
+ final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, featureId,
+ callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
@@ -785,7 +823,8 @@
for (PathPermission pp : pps) {
final String pathPerm = pp.getWritePermission();
if (pathPerm != null && pp.match(path)) {
- final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken);
+ final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, featureId,
+ callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
@@ -851,11 +890,11 @@
}
/**
- * Set the calling package, returning the current value (or {@code null})
+ * Set the calling package/feature, returning the current value (or {@code null})
* which can be used later to restore the previous state.
*/
- private String setCallingPackage(String callingPackage) {
- final String original = mCallingPackage.get();
+ private Pair<String, String> setCallingPackage(Pair<String, String> callingPackage) {
+ final Pair<String, String> original = mCallingPackage.get();
mCallingPackage.set(callingPackage);
onCallingPackageChanged();
return original;
@@ -876,16 +915,42 @@
* calling UID.
*/
public final @Nullable String getCallingPackage() {
- final String pkg = mCallingPackage.get();
+ final Pair<String, String> pkg = mCallingPackage.get();
if (pkg != null) {
- mTransport.mAppOpsManager.checkPackage(Binder.getCallingUid(), pkg);
+ mTransport.mAppOpsManager.checkPackage(Binder.getCallingUid(), pkg.first);
+ return pkg.first;
}
- return pkg;
+
+ return null;
+ }
+
+ /**
+ * Return the feature in the package of the caller that initiated the request being
+ * processed on the current thread. Returns {@code null} if not currently processing
+ * a request of the request is for the default feature.
+ * <p>
+ * This will always return {@code null} when processing
+ * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests.
+ *
+ * @see #getCallingPackage
+ */
+ public final @Nullable String getCallingFeatureId() {
+ final Pair<String, String> pkg = mCallingPackage.get();
+ if (pkg != null) {
+ return pkg.second;
+ }
+
+ return null;
}
/** {@hide} */
public final @Nullable String getCallingPackageUnchecked() {
- return mCallingPackage.get();
+ final Pair<String, String> pkg = mCallingPackage.get();
+ if (pkg != null) {
+ return pkg.first;
+ }
+
+ return null;
}
/** {@hide} */
@@ -899,10 +964,10 @@
/** {@hide} */
public final long binderToken;
/** {@hide} */
- public final String callingPackage;
+ public final Pair<String, String> callingPackage;
/** {@hide} */
- public CallingIdentity(long binderToken, String callingPackage) {
+ public CallingIdentity(long binderToken, Pair<String, String> callingPackage) {
this.binderToken = binderToken;
this.callingPackage = callingPackage;
}
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 8a4330e..d2632e7 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -80,6 +80,7 @@
private final IContentProvider mContentProvider;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private final String mPackageName;
+ private final @Nullable String mFeatureId;
private final String mAuthority;
private final boolean mStable;
@@ -103,6 +104,7 @@
mContentResolver = contentResolver;
mContentProvider = contentProvider;
mPackageName = contentResolver.mPackageName;
+ mFeatureId = contentResolver.mFeatureId;
mAuthority = authority;
mStable = stable;
@@ -193,7 +195,7 @@
cancellationSignal.setRemote(remoteCancellationSignal);
}
final Cursor cursor = mContentProvider.query(
- mPackageName, uri, projection, queryArgs, remoteCancellationSignal);
+ mPackageName, mFeatureId, uri, projection, queryArgs, remoteCancellationSignal);
if (cursor == null) {
return null;
}
@@ -253,7 +255,7 @@
beforeRemote();
try {
- return mContentProvider.canonicalize(mPackageName, url);
+ return mContentProvider.canonicalize(mPackageName, mFeatureId, url);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -271,7 +273,7 @@
beforeRemote();
try {
- return mContentProvider.uncanonicalize(mPackageName, url);
+ return mContentProvider.uncanonicalize(mPackageName, mFeatureId, url);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -296,7 +298,8 @@
remoteCancellationSignal = mContentProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
- return mContentProvider.refresh(mPackageName, url, args, remoteCancellationSignal);
+ return mContentProvider.refresh(mPackageName, mFeatureId, url, args,
+ remoteCancellationSignal);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -315,7 +318,8 @@
beforeRemote();
try {
- return mContentProvider.checkUriPermission(mPackageName, uri, uid, modeFlags);
+ return mContentProvider.checkUriPermission(mPackageName, mFeatureId, uri, uid,
+ modeFlags);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -334,7 +338,7 @@
beforeRemote();
try {
- return mContentProvider.insert(mPackageName, url, initialValues);
+ return mContentProvider.insert(mPackageName, mFeatureId, url, initialValues);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -354,7 +358,7 @@
beforeRemote();
try {
- return mContentProvider.bulkInsert(mPackageName, url, initialValues);
+ return mContentProvider.bulkInsert(mPackageName, mFeatureId, url, initialValues);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -373,7 +377,8 @@
beforeRemote();
try {
- return mContentProvider.delete(mPackageName, url, selection, selectionArgs);
+ return mContentProvider.delete(mPackageName, mFeatureId, url, selection,
+ selectionArgs);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -392,7 +397,8 @@
beforeRemote();
try {
- return mContentProvider.update(mPackageName, url, values, selection, selectionArgs);
+ return mContentProvider.update(mPackageName, mFeatureId, url, values, selection,
+ selectionArgs);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -436,7 +442,8 @@
remoteSignal = mContentProvider.createCancellationSignal();
signal.setRemote(remoteSignal);
}
- return mContentProvider.openFile(mPackageName, url, mode, remoteSignal, null);
+ return mContentProvider.openFile(mPackageName, mFeatureId, url, mode, remoteSignal,
+ null);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -480,7 +487,8 @@
remoteSignal = mContentProvider.createCancellationSignal();
signal.setRemote(remoteSignal);
}
- return mContentProvider.openAssetFile(mPackageName, url, mode, remoteSignal);
+ return mContentProvider.openAssetFile(mPackageName, mFeatureId, url, mode,
+ remoteSignal);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -521,7 +529,7 @@
signal.setRemote(remoteSignal);
}
return mContentProvider.openTypedAssetFile(
- mPackageName, uri, mimeTypeFilter, opts, remoteSignal);
+ mPackageName, mFeatureId, uri, mimeTypeFilter, opts, remoteSignal);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -548,7 +556,7 @@
beforeRemote();
try {
- return mContentProvider.applyBatch(mPackageName, authority, operations);
+ return mContentProvider.applyBatch(mPackageName, mFeatureId, authority, operations);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -574,7 +582,7 @@
beforeRemote();
try {
- return mContentProvider.call(mPackageName, authority, method, arg, extras);
+ return mContentProvider.call(mPackageName, mFeatureId, authority, method, arg, extras);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index cd735d4..f082690 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -83,6 +83,7 @@
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String callingFeatureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
// String[] projection
@@ -101,7 +102,8 @@
ICancellationSignal cancellationSignal = ICancellationSignal.Stub.asInterface(
data.readStrongBinder());
- Cursor cursor = query(callingPkg, url, projection, queryArgs, cancellationSignal);
+ Cursor cursor = query(callingPkg, callingFeatureId, url, projection, queryArgs,
+ cancellationSignal);
if (cursor != null) {
CursorToBulkCursorAdaptor adaptor = null;
@@ -148,10 +150,11 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
ContentValues values = ContentValues.CREATOR.createFromParcel(data);
- Uri out = insert(callingPkg, url, values);
+ Uri out = insert(callingPkg, featureId, url, values);
reply.writeNoException();
Uri.writeToParcel(reply, out);
return true;
@@ -161,10 +164,11 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
ContentValues[] values = data.createTypedArray(ContentValues.CREATOR);
- int count = bulkInsert(callingPkg, url, values);
+ int count = bulkInsert(callingPkg, featureId, url, values);
reply.writeNoException();
reply.writeInt(count);
return true;
@@ -174,6 +178,7 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
String authority = data.readString();
final int numOperations = data.readInt();
final ArrayList<ContentProviderOperation> operations =
@@ -181,8 +186,8 @@
for (int i = 0; i < numOperations; i++) {
operations.add(i, ContentProviderOperation.CREATOR.createFromParcel(data));
}
- final ContentProviderResult[] results = applyBatch(callingPkg, authority,
- operations);
+ final ContentProviderResult[] results = applyBatch(callingPkg, featureId,
+ authority, operations);
reply.writeNoException();
reply.writeTypedArray(results, 0);
return true;
@@ -192,11 +197,12 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
String selection = data.readString();
String[] selectionArgs = data.readStringArray();
- int count = delete(callingPkg, url, selection, selectionArgs);
+ int count = delete(callingPkg, featureId, url, selection, selectionArgs);
reply.writeNoException();
reply.writeInt(count);
@@ -207,12 +213,14 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
ContentValues values = ContentValues.CREATOR.createFromParcel(data);
String selection = data.readString();
String[] selectionArgs = data.readStringArray();
- int count = update(callingPkg, url, values, selection, selectionArgs);
+ int count = update(callingPkg, featureId, url, values, selection,
+ selectionArgs);
reply.writeNoException();
reply.writeInt(count);
@@ -223,6 +231,7 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
String mode = data.readString();
ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
@@ -230,7 +239,7 @@
IBinder callerToken = data.readStrongBinder();
ParcelFileDescriptor fd;
- fd = openFile(callingPkg, url, mode, signal, callerToken);
+ fd = openFile(callingPkg, featureId, url, mode, signal, callerToken);
reply.writeNoException();
if (fd != null) {
reply.writeInt(1);
@@ -246,13 +255,14 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
String mode = data.readString();
ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
data.readStrongBinder());
AssetFileDescriptor fd;
- fd = openAssetFile(callingPkg, url, mode, signal);
+ fd = openAssetFile(callingPkg, featureId, url, mode, signal);
reply.writeNoException();
if (fd != null) {
reply.writeInt(1);
@@ -269,12 +279,14 @@
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
String authority = data.readString();
String method = data.readString();
String stringArg = data.readString();
Bundle args = data.readBundle();
- Bundle responseBundle = call(callingPkg, authority, method, stringArg, args);
+ Bundle responseBundle = call(callingPkg, featureId, authority, method,
+ stringArg, args);
reply.writeNoException();
reply.writeBundle(responseBundle);
@@ -297,6 +309,7 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
String mimeType = data.readString();
Bundle opts = data.readBundle();
@@ -304,7 +317,7 @@
data.readStrongBinder());
AssetFileDescriptor fd;
- fd = openTypedAssetFile(callingPkg, url, mimeType, opts, signal);
+ fd = openTypedAssetFile(callingPkg, featureId, url, mimeType, opts, signal);
reply.writeNoException();
if (fd != null) {
reply.writeInt(1);
@@ -330,9 +343,10 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
- Uri out = canonicalize(callingPkg, url);
+ Uri out = canonicalize(callingPkg, featureId, url);
reply.writeNoException();
Uri.writeToParcel(reply, out);
return true;
@@ -342,9 +356,10 @@
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
- Uri out = uncanonicalize(callingPkg, url);
+ Uri out = uncanonicalize(callingPkg, featureId, url);
reply.writeNoException();
Uri.writeToParcel(reply, out);
return true;
@@ -353,12 +368,13 @@
case REFRESH_TRANSACTION: {
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
Bundle args = data.readBundle();
ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
data.readStrongBinder());
- boolean out = refresh(callingPkg, url, args, signal);
+ boolean out = refresh(callingPkg, featureId, url, args, signal);
reply.writeNoException();
reply.writeInt(out ? 0 : -1);
return true;
@@ -367,11 +383,12 @@
case CHECK_URI_PERMISSION_TRANSACTION: {
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
+ String featureId = data.readString();
Uri uri = Uri.CREATOR.createFromParcel(data);
int uid = data.readInt();
int modeFlags = data.readInt();
- int out = checkUriPermission(callingPkg, uri, uid, modeFlags);
+ int out = checkUriPermission(callingPkg, featureId, uri, uid, modeFlags);
reply.writeNoException();
reply.writeInt(out);
return true;
@@ -407,8 +424,9 @@
}
@Override
- public Cursor query(String callingPkg, Uri url, @Nullable String[] projection,
- @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal)
+ public Cursor query(String callingPkg, @Nullable String featureId, Uri url,
+ @Nullable String[] projection, @Nullable Bundle queryArgs,
+ @Nullable ICancellationSignal cancellationSignal)
throws RemoteException {
BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
Parcel data = Parcel.obtain();
@@ -417,6 +435,7 @@
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
int length = 0;
if (projection != null) {
@@ -478,7 +497,8 @@
}
@Override
- public Uri insert(String callingPkg, Uri url, ContentValues values) throws RemoteException
+ public Uri insert(String callingPkg, @Nullable String featureId, Uri url,
+ ContentValues values) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -486,6 +506,7 @@
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
values.writeToParcel(data, 0);
@@ -501,13 +522,15 @@
}
@Override
- public int bulkInsert(String callingPkg, Uri url, ContentValues[] values) throws RemoteException {
+ public int bulkInsert(String callingPkg, @Nullable String featureId, Uri url,
+ ContentValues[] values) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
data.writeTypedArray(values, 0);
@@ -523,14 +546,15 @@
}
@Override
- public ContentProviderResult[] applyBatch(String callingPkg, String authority,
- ArrayList<ContentProviderOperation> operations)
- throws RemoteException, OperationApplicationException {
+ public ContentProviderResult[] applyBatch(String callingPkg, @Nullable String featureId,
+ String authority, ArrayList<ContentProviderOperation> operations)
+ throws RemoteException, OperationApplicationException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
data.writeString(authority);
data.writeInt(operations.size());
for (ContentProviderOperation operation : operations) {
@@ -549,14 +573,15 @@
}
@Override
- public int delete(String callingPkg, Uri url, String selection, String[] selectionArgs)
- throws RemoteException {
+ public int delete(String callingPkg, @Nullable String featureId, Uri url, String selection,
+ String[] selectionArgs) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
data.writeString(selection);
data.writeStringArray(selectionArgs);
@@ -573,14 +598,15 @@
}
@Override
- public int update(String callingPkg, Uri url, ContentValues values, String selection,
- String[] selectionArgs) throws RemoteException {
+ public int update(String callingPkg, @Nullable String featureId, Uri url,
+ ContentValues values, String selection, String[] selectionArgs) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
values.writeToParcel(data, 0);
data.writeString(selection);
@@ -598,8 +624,8 @@
}
@Override
- public ParcelFileDescriptor openFile(
- String callingPkg, Uri url, String mode, ICancellationSignal signal, IBinder token)
+ public ParcelFileDescriptor openFile(String callingPkg, @Nullable String featureId, Uri url,
+ String mode, ICancellationSignal signal, IBinder token)
throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -607,6 +633,7 @@
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
data.writeString(mode);
data.writeStrongBinder(signal != null ? signal.asBinder() : null);
@@ -626,8 +653,8 @@
}
@Override
- public AssetFileDescriptor openAssetFile(
- String callingPkg, Uri url, String mode, ICancellationSignal signal)
+ public AssetFileDescriptor openAssetFile(String callingPkg, @Nullable String featureId,
+ Uri url, String mode, ICancellationSignal signal)
throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -635,6 +662,7 @@
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
data.writeString(mode);
data.writeStrongBinder(signal != null ? signal.asBinder() : null);
@@ -653,14 +681,15 @@
}
@Override
- public Bundle call(String callingPkg, String authority, String method, String request,
- Bundle args) throws RemoteException {
+ public Bundle call(String callingPkg, @Nullable String featureId, String authority,
+ String method, String request, Bundle args) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
data.writeString(authority);
data.writeString(method);
data.writeString(request);
@@ -700,14 +729,16 @@
}
@Override
- public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri url, String mimeType,
- Bundle opts, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
+ public AssetFileDescriptor openTypedAssetFile(String callingPkg, @Nullable String featureId,
+ Uri url, String mimeType, Bundle opts, ICancellationSignal signal)
+ throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
data.writeString(mimeType);
data.writeBundle(opts);
@@ -747,14 +778,15 @@
}
@Override
- public Uri canonicalize(String callingPkg, Uri url) throws RemoteException
- {
+ public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri url)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
mRemote.transact(IContentProvider.CANONICALIZE_TRANSACTION, data, reply, 0);
@@ -769,13 +801,15 @@
}
@Override
- public Uri uncanonicalize(String callingPkg, Uri url) throws RemoteException {
+ public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri url)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
mRemote.transact(IContentProvider.UNCANONICALIZE_TRANSACTION, data, reply, 0);
@@ -790,14 +824,15 @@
}
@Override
- public boolean refresh(String callingPkg, Uri url, Bundle args, ICancellationSignal signal)
- throws RemoteException {
+ public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle args,
+ ICancellationSignal signal) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
data.writeBundle(args);
data.writeStrongBinder(signal != null ? signal.asBinder() : null);
@@ -814,14 +849,15 @@
}
@Override
- public int checkUriPermission(String callingPkg, Uri url, int uid, int modeFlags)
- throws RemoteException {
+ public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri url, int uid,
+ int modeFlags) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
+ data.writeString(featureId);
url.writeToParcel(data, 0);
data.writeInt(uid);
data.writeInt(modeFlags);
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 7f9ea76..1031fe2 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -649,6 +649,7 @@
public ContentResolver(@Nullable Context context, @Nullable ContentInterface wrapped) {
mContext = context != null ? context : ActivityThread.currentApplication();
mPackageName = mContext.getOpPackageName();
+ mFeatureId = mContext.getFeatureId();
mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
mWrapped = wrapped;
}
@@ -968,7 +969,7 @@
cancellationSignal.setRemote(remoteCancellationSignal);
}
try {
- qCursor = unstableProvider.query(mPackageName, uri, projection,
+ qCursor = unstableProvider.query(mPackageName, mFeatureId, uri, projection,
queryArgs, remoteCancellationSignal);
} catch (DeadObjectException e) {
// The remote process has died... but we only hold an unstable
@@ -979,8 +980,8 @@
if (stableProvider == null) {
return null;
}
- qCursor = stableProvider.query(
- mPackageName, uri, projection, queryArgs, remoteCancellationSignal);
+ qCursor = stableProvider.query(mPackageName, mFeatureId, uri, projection,
+ queryArgs, remoteCancellationSignal);
}
if (qCursor == null) {
return null;
@@ -1070,7 +1071,7 @@
}
try {
- return provider.canonicalize(mPackageName, url);
+ return provider.canonicalize(mPackageName, mFeatureId, url);
} catch (RemoteException e) {
// Arbitrary and not worth documenting, as Activity
// Manager will kill this process shortly anyway.
@@ -1114,7 +1115,7 @@
}
try {
- return provider.uncanonicalize(mPackageName, url);
+ return provider.uncanonicalize(mPackageName, mFeatureId, url);
} catch (RemoteException e) {
// Arbitrary and not worth documenting, as Activity
// Manager will kill this process shortly anyway.
@@ -1163,7 +1164,8 @@
remoteCancellationSignal = provider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
- return provider.refresh(mPackageName, url, args, remoteCancellationSignal);
+ return provider.refresh(mPackageName, mFeatureId, url, args,
+ remoteCancellationSignal);
} catch (RemoteException e) {
// Arbitrary and not worth documenting, as Activity
// Manager will kill this process shortly anyway.
@@ -1564,7 +1566,7 @@
try {
fd = unstableProvider.openAssetFile(
- mPackageName, uri, mode, remoteCancellationSignal);
+ mPackageName, mFeatureId, uri, mode, remoteCancellationSignal);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
@@ -1579,7 +1581,7 @@
throw new FileNotFoundException("No content provider: " + uri);
}
fd = stableProvider.openAssetFile(
- mPackageName, uri, mode, remoteCancellationSignal);
+ mPackageName, mFeatureId, uri, mode, remoteCancellationSignal);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
@@ -1730,7 +1732,7 @@
try {
fd = unstableProvider.openTypedAssetFile(
- mPackageName, uri, mimeType, opts, remoteCancellationSignal);
+ mPackageName, mFeatureId, uri, mimeType, opts, remoteCancellationSignal);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
@@ -1745,7 +1747,7 @@
throw new FileNotFoundException("No content provider: " + uri);
}
fd = stableProvider.openTypedAssetFile(
- mPackageName, uri, mimeType, opts, remoteCancellationSignal);
+ mPackageName, mFeatureId, uri, mimeType, opts, remoteCancellationSignal);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
@@ -1870,7 +1872,7 @@
}
try {
long startTime = SystemClock.uptimeMillis();
- Uri createdRow = provider.insert(mPackageName, url, values);
+ Uri createdRow = provider.insert(mPackageName, mFeatureId, url, values);
long durationMillis = SystemClock.uptimeMillis() - startTime;
maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */);
return createdRow;
@@ -1951,7 +1953,7 @@
}
try {
long startTime = SystemClock.uptimeMillis();
- int rowsCreated = provider.bulkInsert(mPackageName, url, values);
+ int rowsCreated = provider.bulkInsert(mPackageName, mFeatureId, url, values);
long durationMillis = SystemClock.uptimeMillis() - startTime;
maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */);
return rowsCreated;
@@ -1991,7 +1993,8 @@
}
try {
long startTime = SystemClock.uptimeMillis();
- int rowsDeleted = provider.delete(mPackageName, url, where, selectionArgs);
+ int rowsDeleted = provider.delete(mPackageName, mFeatureId, url, where,
+ selectionArgs);
long durationMillis = SystemClock.uptimeMillis() - startTime;
maybeLogUpdateToEventLog(durationMillis, url, "delete", where);
return rowsDeleted;
@@ -2035,7 +2038,8 @@
}
try {
long startTime = SystemClock.uptimeMillis();
- int rowsUpdated = provider.update(mPackageName, uri, values, where, selectionArgs);
+ int rowsUpdated = provider.update(mPackageName, mFeatureId, uri, values, where,
+ selectionArgs);
long durationMillis = SystemClock.uptimeMillis() - startTime;
maybeLogUpdateToEventLog(durationMillis, uri, "update", where);
return rowsUpdated;
@@ -2084,7 +2088,8 @@
throw new IllegalArgumentException("Unknown authority " + authority);
}
try {
- final Bundle res = provider.call(mPackageName, authority, method, arg, extras);
+ final Bundle res = provider.call(mPackageName, mFeatureId, authority, method, arg,
+ extras);
Bundle.setDefusable(res, true);
return res;
} catch (RemoteException e) {
@@ -3436,6 +3441,11 @@
return mPackageName;
}
+ /** @hide */
+ public @Nullable String getFeatureId() {
+ return mFeatureId;
+ }
+
@UnsupportedAppUsage
private static volatile IContentService sContentService;
@UnsupportedAppUsage
@@ -3443,6 +3453,7 @@
@UnsupportedAppUsage
final String mPackageName;
+ final @Nullable String mFeatureId;
final int mTargetSdkVersion;
final ContentInterface mWrapped;
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index fade0ab..d2c97c4 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -16,7 +16,6 @@
package android.content;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetFileDescriptor;
@@ -38,66 +37,96 @@
* @hide
*/
public interface IContentProvider extends IInterface {
- public Cursor query(String callingPkg, Uri url, @Nullable String[] projection,
+ public Cursor query(String callingPkg, @Nullable String featureId, Uri url,
+ @Nullable String[] projection,
@Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal)
throws RemoteException;
public String getType(Uri url) throws RemoteException;
- @UnsupportedAppUsage
- public Uri insert(String callingPkg, Uri url, ContentValues initialValues)
- throws RemoteException;
- @UnsupportedAppUsage
- public int bulkInsert(String callingPkg, Uri url, ContentValues[] initialValues)
- throws RemoteException;
- @UnsupportedAppUsage
- public int delete(String callingPkg, Uri url, String selection, String[] selectionArgs)
- throws RemoteException;
- @UnsupportedAppUsage
- public int update(String callingPkg, Uri url, ContentValues values, String selection,
- String[] selectionArgs) throws RemoteException;
- public ParcelFileDescriptor openFile(
- String callingPkg, Uri url, String mode, ICancellationSignal signal,
- IBinder callerToken)
- throws RemoteException, FileNotFoundException;
- public AssetFileDescriptor openAssetFile(
- String callingPkg, Uri url, String mode, ICancellationSignal signal)
- throws RemoteException, FileNotFoundException;
-
@Deprecated
- public default ContentProviderResult[] applyBatch(String callingPkg,
- ArrayList<ContentProviderOperation> operations)
- throws RemoteException, OperationApplicationException {
- return applyBatch(callingPkg, "unknown", operations);
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
+ + "ContentProviderClient#insert(android.net.Uri, android.content.ContentValues)} "
+ + "instead")
+ public default Uri insert(String callingPkg, Uri url, ContentValues initialValues)
+ throws RemoteException {
+ return insert(callingPkg, null, url, initialValues);
}
+ public Uri insert(String callingPkg, String featureId, Uri url, ContentValues initialValues)
+ throws RemoteException;
+ @Deprecated
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
+ + "ContentProviderClient#bulkInsert(android.net.Uri, android.content.ContentValues[])"
+ + "} instead")
+ public default int bulkInsert(String callingPkg, Uri url, ContentValues[] initialValues)
+ throws RemoteException {
+ return bulkInsert(callingPkg, null, url, initialValues);
+ }
+ public int bulkInsert(String callingPkg, String featureId, Uri url,
+ ContentValues[] initialValues) throws RemoteException;
+ @Deprecated
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
+ + "ContentProviderClient#delete(android.net.Uri, java.lang.String, java.lang"
+ + ".String[])} instead")
+ public default int delete(String callingPkg, Uri url, String selection, String[] selectionArgs)
+ throws RemoteException {
+ return delete(callingPkg, null, url, selection, selectionArgs);
+ }
+ public int delete(String callingPkg, String featureId, Uri url, String selection,
+ String[] selectionArgs) throws RemoteException;
+ @Deprecated
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
+ + "ContentProviderClient#update(android.net.Uri, android.content.ContentValues, java"
+ + ".lang.String, java.lang.String[])} instead")
+ public default int update(String callingPkg, Uri url, ContentValues values, String selection,
+ String[] selectionArgs) throws RemoteException {
+ return update(callingPkg, null, url, values, selection, selectionArgs);
+ }
+ public int update(String callingPkg, String featureId, Uri url, ContentValues values,
+ String selection, String[] selectionArgs) throws RemoteException;
- public ContentProviderResult[] applyBatch(String callingPkg, String authority,
- ArrayList<ContentProviderOperation> operations)
+ public ParcelFileDescriptor openFile(String callingPkg, @Nullable String featureId, Uri url,
+ String mode, ICancellationSignal signal, IBinder callerToken)
+ throws RemoteException, FileNotFoundException;
+
+ public AssetFileDescriptor openAssetFile(String callingPkg, @Nullable String featureId,
+ Uri url, String mode, ICancellationSignal signal)
+ throws RemoteException, FileNotFoundException;
+
+ public ContentProviderResult[] applyBatch(String callingPkg, @Nullable String featureId,
+ String authority, ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException;
@Deprecated
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
+ + "ContentProviderClient#call(java.lang.String, java.lang.String, android.os.Bundle)} "
+ + "instead")
public default Bundle call(String callingPkg, String method,
@Nullable String arg, @Nullable Bundle extras) throws RemoteException {
- return call(callingPkg, "unknown", method, arg, extras);
+ return call(callingPkg, null, "unknown", method, arg, extras);
}
- public Bundle call(String callingPkg, String authority, String method,
- @Nullable String arg, @Nullable Bundle extras) throws RemoteException;
+ public Bundle call(String callingPkg, @Nullable String featureId, String authority,
+ String method, @Nullable String arg, @Nullable Bundle extras) throws RemoteException;
- public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags)
- throws RemoteException;
+ public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri, int uid,
+ int modeFlags) throws RemoteException;
public ICancellationSignal createCancellationSignal() throws RemoteException;
- public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException;
- public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException;
+ public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+ throws RemoteException;
- public boolean refresh(String callingPkg, Uri url, @Nullable Bundle args,
- ICancellationSignal cancellationSignal) throws RemoteException;
+ public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+ throws RemoteException;
+
+ public boolean refresh(String callingPkg, @Nullable String featureId, Uri url,
+ @Nullable Bundle args, ICancellationSignal cancellationSignal) throws RemoteException;
// Data interchange.
public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException;
- public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri url, String mimeType,
- Bundle opts, ICancellationSignal signal) throws RemoteException, FileNotFoundException;
+
+ public AssetFileDescriptor openTypedAssetFile(String callingPkg, @Nullable String featureId,
+ Uri url, String mimeType, Bundle opts, ICancellationSignal signal)
+ throws RemoteException, FileNotFoundException;
/* IPC constants */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 2143a0d..a80153d 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -1081,7 +1081,8 @@
// signed with platform signature can hold MANAGE_DOCUMENTS, we are going to check for
// MANAGE_DOCUMENTS or associated URI permission here instead
final Uri rootUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
- enforceWritePermissionInner(rootUri, getCallingPackage(), null);
+ enforceWritePermissionInner(rootUri, getCallingPackage(), getCallingFeatureId(),
+ null);
final String rootId = DocumentsContract.getRootId(rootUri);
ejectRoot(rootId);
@@ -1102,7 +1103,8 @@
enforceTree(documentUri);
if (METHOD_IS_CHILD_DOCUMENT.equals(method)) {
- enforceReadPermissionInner(documentUri, getCallingPackage(), null);
+ enforceReadPermissionInner(documentUri, getCallingPackage(), getCallingFeatureId(),
+ null);
final Uri childUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
final String childAuthority = childUri.getAuthority();
@@ -1114,7 +1116,8 @@
&& isChildDocument(documentId, childId));
} else if (METHOD_CREATE_DOCUMENT.equals(method)) {
- enforceWritePermissionInner(documentUri, getCallingPackage(), null);
+ enforceWritePermissionInner(documentUri, getCallingPackage(), getCallingFeatureId(),
+ null);
final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
@@ -1128,7 +1131,8 @@
out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);
} else if (METHOD_CREATE_WEB_LINK_INTENT.equals(method)) {
- enforceWritePermissionInner(documentUri, getCallingPackage(), null);
+ enforceWritePermissionInner(documentUri, getCallingPackage(), getCallingFeatureId(),
+ null);
final Bundle options = extras.getBundle(DocumentsContract.EXTRA_OPTIONS);
final IntentSender intentSender = createWebLinkIntent(documentId, options);
@@ -1136,7 +1140,8 @@
out.putParcelable(DocumentsContract.EXTRA_RESULT, intentSender);
} else if (METHOD_RENAME_DOCUMENT.equals(method)) {
- enforceWritePermissionInner(documentUri, getCallingPackage(), null);
+ enforceWritePermissionInner(documentUri, getCallingPackage(), getCallingFeatureId(),
+ null);
final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
final String newDocumentId = renameDocument(documentId, displayName);
@@ -1160,7 +1165,8 @@
}
} else if (METHOD_DELETE_DOCUMENT.equals(method)) {
- enforceWritePermissionInner(documentUri, getCallingPackage(), null);
+ enforceWritePermissionInner(documentUri, getCallingPackage(), getCallingFeatureId(),
+ null);
deleteDocument(documentId);
// Document no longer exists, clean up any grants.
@@ -1170,8 +1176,10 @@
final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
final String targetId = DocumentsContract.getDocumentId(targetUri);
- enforceReadPermissionInner(documentUri, getCallingPackage(), null);
- enforceWritePermissionInner(targetUri, getCallingPackage(), null);
+ enforceReadPermissionInner(documentUri, getCallingPackage(), getCallingFeatureId(),
+ null);
+ enforceWritePermissionInner(targetUri, getCallingPackage(), getCallingFeatureId(),
+ null);
final String newDocumentId = copyDocument(documentId, targetId);
@@ -1194,9 +1202,12 @@
final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
final String targetId = DocumentsContract.getDocumentId(targetUri);
- enforceWritePermissionInner(documentUri, getCallingPackage(), null);
- enforceReadPermissionInner(parentSourceUri, getCallingPackage(), null);
- enforceWritePermissionInner(targetUri, getCallingPackage(), null);
+ enforceWritePermissionInner(documentUri, getCallingPackage(), getCallingFeatureId(),
+ null);
+ enforceReadPermissionInner(parentSourceUri, getCallingPackage(), getCallingFeatureId(),
+ null);
+ enforceWritePermissionInner(targetUri, getCallingPackage(), getCallingFeatureId(),
+ null);
final String newDocumentId = moveDocument(documentId, parentSourceId, targetId);
@@ -1217,8 +1228,10 @@
final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
- enforceReadPermissionInner(parentSourceUri, getCallingPackage(), null);
- enforceWritePermissionInner(documentUri, getCallingPackage(), null);
+ enforceReadPermissionInner(parentSourceUri, getCallingPackage(), getCallingFeatureId(),
+ null);
+ enforceWritePermissionInner(documentUri, getCallingPackage(), getCallingFeatureId(),
+ null);
removeDocument(documentId, parentSourceId);
// It's responsibility of the provider to revoke any grants, as the document may be
@@ -1227,7 +1240,8 @@
final boolean isTreeUri = isTreeUri(documentUri);
if (isTreeUri) {
- enforceReadPermissionInner(documentUri, getCallingPackage(), null);
+ enforceReadPermissionInner(documentUri, getCallingPackage(), getCallingFeatureId(),
+ null);
} else {
getContext().enforceCallingPermission(Manifest.permission.MANAGE_DOCUMENTS, null);
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b5580d4..cce7c42 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2306,8 +2306,8 @@
arg.putBoolean(CALL_METHOD_MAKE_DEFAULT_KEY, true);
}
IContentProvider cp = mProviderHolder.getProvider(cr);
- cp.call(cr.getPackageName(), mProviderHolder.mUri.getAuthority(),
- mCallSetCommand, name, arg);
+ cp.call(cr.getPackageName(), cr.getFeatureId(),
+ mProviderHolder.mUri.getAuthority(), mCallSetCommand, name, arg);
} catch (RemoteException e) {
Log.w(TAG, "Can't set key " + name + " in " + mUri, e);
return false;
@@ -2380,14 +2380,15 @@
if (Settings.isInSystemServer() && Binder.getCallingUid() != Process.myUid()) {
final long token = Binder.clearCallingIdentity();
try {
- b = cp.call(cr.getPackageName(), mProviderHolder.mUri.getAuthority(),
- mCallGetCommand, name, args);
+ b = cp.call(cr.getPackageName(), cr.getFeatureId(),
+ mProviderHolder.mUri.getAuthority(), mCallGetCommand, name,
+ args);
} finally {
Binder.restoreCallingIdentity(token);
}
} else {
- b = cp.call(cr.getPackageName(), mProviderHolder.mUri.getAuthority(),
- mCallGetCommand, name, args);
+ b = cp.call(cr.getPackageName(), cr.getFeatureId(),
+ mProviderHolder.mUri.getAuthority(), mCallGetCommand, name, args);
}
if (b != null) {
String value = b.getString(Settings.NameValueTable.VALUE);
@@ -2455,14 +2456,14 @@
if (Settings.isInSystemServer() && Binder.getCallingUid() != Process.myUid()) {
final long token = Binder.clearCallingIdentity();
try {
- c = cp.query(cr.getPackageName(), mUri, SELECT_VALUE_PROJECTION, queryArgs,
- null);
+ c = cp.query(cr.getPackageName(), cr.getFeatureId(), mUri,
+ SELECT_VALUE_PROJECTION, queryArgs, null);
} finally {
Binder.restoreCallingIdentity(token);
}
} else {
- c = cp.query(cr.getPackageName(), mUri, SELECT_VALUE_PROJECTION, queryArgs,
- null);
+ c = cp.query(cr.getPackageName(), cr.getFeatureId(), mUri,
+ SELECT_VALUE_PROJECTION, queryArgs, null);
}
if (c == null) {
Log.w(TAG, "Can't get key " + name + " from " + mUri);
@@ -2557,8 +2558,8 @@
}
// Fetch all flags for the namespace at once for caching purposes
- Bundle b = cp.call(cr.getPackageName(), mProviderHolder.mUri.getAuthority(),
- mCallListCommand, null, args);
+ Bundle b = cp.call(cr.getPackageName(), cr.getFeatureId(),
+ mProviderHolder.mUri.getAuthority(), mCallListCommand, null, args);
if (b == null) {
// Invalid response, return an empty map
return keyValues;
@@ -5132,8 +5133,8 @@
}
arg.putInt(CALL_METHOD_RESET_MODE_KEY, mode);
IContentProvider cp = sProviderHolder.getProvider(resolver);
- cp.call(resolver.getPackageName(), sProviderHolder.mUri.getAuthority(),
- CALL_METHOD_RESET_SECURE, null, arg);
+ cp.call(resolver.getPackageName(), resolver.getFeatureId(),
+ sProviderHolder.mUri.getAuthority(), CALL_METHOD_RESET_SECURE, null, arg);
} catch (RemoteException e) {
Log.w(TAG, "Can't reset do defaults for " + CONTENT_URI, e);
}
@@ -12821,8 +12822,8 @@
}
arg.putInt(CALL_METHOD_RESET_MODE_KEY, mode);
IContentProvider cp = sProviderHolder.getProvider(resolver);
- cp.call(resolver.getPackageName(), sProviderHolder.mUri.getAuthority(),
- CALL_METHOD_RESET_GLOBAL, null, arg);
+ cp.call(resolver.getPackageName(), resolver.getFeatureId(),
+ sProviderHolder.mUri.getAuthority(), CALL_METHOD_RESET_GLOBAL, null, arg);
} catch (RemoteException e) {
Log.w(TAG, "Can't reset do defaults for " + CONTENT_URI, e);
}
@@ -13758,8 +13759,8 @@
arg.putString(Settings.CALL_METHOD_PREFIX_KEY, prefix);
}
IContentProvider cp = sProviderHolder.getProvider(resolver);
- cp.call(resolver.getPackageName(), sProviderHolder.mUri.getAuthority(),
- CALL_METHOD_RESET_CONFIG, null, arg);
+ cp.call(resolver.getPackageName(), resolver.getFeatureId(),
+ sProviderHolder.mUri.getAuthority(), CALL_METHOD_RESET_CONFIG, null, arg);
} catch (RemoteException e) {
Log.w(TAG, "Can't reset to defaults for " + DeviceConfig.CONTENT_URI, e);
}
diff --git a/core/tests/coretests/src/android/content/ContentResolverTest.java b/core/tests/coretests/src/android/content/ContentResolverTest.java
index f14f289..88967b5 100644
--- a/core/tests/coretests/src/android/content/ContentResolverTest.java
+++ b/core/tests/coretests/src/android/content/ContentResolverTest.java
@@ -82,7 +82,8 @@
final AssetFileDescriptor afd = new AssetFileDescriptor(
new ParcelFileDescriptor(mImage.getFileDescriptor()), 0, mSize, null);
- when(mProvider.openTypedAssetFile(any(), any(), any(), any(), any())).thenReturn(afd);
+ when(mProvider.openTypedAssetFile(any(), any(), any(), any(), any(), any())).thenReturn(
+ afd);
}
private static void assertImageAspectAndContents(Bitmap bitmap) {
diff --git a/core/tests/coretests/src/android/provider/TestDocumentsProvider.java b/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
index 1bd8ff6..5f640be 100644
--- a/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
+++ b/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
@@ -93,12 +93,14 @@
}
@Override
- protected int enforceReadPermissionInner(Uri uri, String callingPkg, IBinder callerToken) {
+ protected int enforceReadPermissionInner(Uri uri, String callingPkg,
+ @Nullable String callingFeatureId, IBinder callerToken) {
return AppOpsManager.MODE_ALLOWED;
}
@Override
- protected int enforceWritePermissionInner(Uri uri, String callingPkg, IBinder callerToken) {
+ protected int enforceWritePermissionInner(Uri uri, String callingPkg,
+ @Nullable String callingFeatureId, IBinder callerToken) {
return AppOpsManager.MODE_ALLOWED;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
index 74bf1a2..de353bf 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
@@ -42,6 +42,7 @@
public class MediaInserterTest extends InstrumentationTestCase {
+ private static final String TEST_FEATURE_ID = "testFeature";
private MediaInserter mMediaInserter;
private static final int TEST_BUFFER_SIZE = 10;
private @Mock IContentProvider mMockProvider;
@@ -86,7 +87,8 @@
MockitoAnnotations.initMocks(this);
final ContentProviderClient client = new ContentProviderClient(
- getInstrumentation().getContext().getContentResolver(), mMockProvider, true);
+ getInstrumentation().getContext().createFeatureContext(TEST_FEATURE_ID)
+ .getContentResolver(), mMockProvider, true);
mMediaInserter = new MediaInserter(client, TEST_BUFFER_SIZE);
mPackageName = getInstrumentation().getContext().getPackageName();
mFilesCounter = 0;
@@ -142,31 +144,36 @@
fillBuffer(sVideoUri, TEST_BUFFER_SIZE - 2);
fillBuffer(sImagesUri, TEST_BUFFER_SIZE - 1);
- verify(mMockProvider, never()).bulkInsert(eq(mPackageName), any(), any());
+ verify(mMockProvider, never()).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+ any());
}
@SmallTest
public void testInsertContentsEqualToBufferSize() throws Exception {
- when(mMockProvider.bulkInsert(eq(mPackageName), any(), any())).thenReturn(1);
+ when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+ any())).thenReturn(1);
fillBuffer(sFilesUri, TEST_BUFFER_SIZE);
fillBuffer(sAudioUri, TEST_BUFFER_SIZE);
fillBuffer(sVideoUri, TEST_BUFFER_SIZE);
fillBuffer(sImagesUri, TEST_BUFFER_SIZE);
- verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), any(), any());
+ verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+ any());
}
@SmallTest
public void testInsertContentsMoreThanBufferSize() throws Exception {
- when(mMockProvider.bulkInsert(eq(mPackageName), any(), any())).thenReturn(1);
+ when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+ any())).thenReturn(1);
fillBuffer(sFilesUri, TEST_BUFFER_SIZE + 1);
fillBuffer(sAudioUri, TEST_BUFFER_SIZE + 2);
fillBuffer(sVideoUri, TEST_BUFFER_SIZE + 3);
fillBuffer(sImagesUri, TEST_BUFFER_SIZE + 4);
- verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), any(), any());
+ verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+ any());
}
@SmallTest
@@ -176,7 +183,8 @@
@SmallTest
public void testFlushAllWithSomeContents() throws Exception {
- when(mMockProvider.bulkInsert(eq(mPackageName), any(), any())).thenReturn(1);
+ when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+ any())).thenReturn(1);
fillBuffer(sFilesUri, TEST_BUFFER_SIZE - 4);
fillBuffer(sAudioUri, TEST_BUFFER_SIZE - 3);
@@ -184,12 +192,14 @@
fillBuffer(sImagesUri, TEST_BUFFER_SIZE - 1);
mMediaInserter.flushAll();
- verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), any(), any());
+ verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+ any());
}
@SmallTest
public void testInsertContentsAfterFlushAll() throws Exception {
- when(mMockProvider.bulkInsert(eq(mPackageName), any(), any())).thenReturn(1);
+ when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+ any())).thenReturn(1);
fillBuffer(sFilesUri, TEST_BUFFER_SIZE - 4);
fillBuffer(sAudioUri, TEST_BUFFER_SIZE - 3);
@@ -202,15 +212,20 @@
fillBuffer(sVideoUri, TEST_BUFFER_SIZE + 3);
fillBuffer(sImagesUri, TEST_BUFFER_SIZE + 4);
- verify(mMockProvider, times(8)).bulkInsert(eq(mPackageName), any(), any());
+ verify(mMockProvider, times(8)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), any(),
+ any());
}
@SmallTest
public void testInsertContentsWithDifferentSizePerContentType() throws Exception {
- when(mMockProvider.bulkInsert(eq(mPackageName), eqUri(sFilesUri), any())).thenReturn(1);
- when(mMockProvider.bulkInsert(eq(mPackageName), eqUri(sAudioUri), any())).thenReturn(1);
- when(mMockProvider.bulkInsert(eq(mPackageName), eqUri(sVideoUri), any())).thenReturn(1);
- when(mMockProvider.bulkInsert(eq(mPackageName), eqUri(sImagesUri), any())).thenReturn(1);
+ when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), eqUri(sFilesUri),
+ any())).thenReturn(1);
+ when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), eqUri(sAudioUri),
+ any())).thenReturn(1);
+ when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), eqUri(sVideoUri),
+ any())).thenReturn(1);
+ when(mMockProvider.bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID), eqUri(sImagesUri),
+ any())).thenReturn(1);
for (int i = 0; i < TEST_BUFFER_SIZE; ++i) {
fillBuffer(sFilesUri, 1);
@@ -219,9 +234,13 @@
fillBuffer(sImagesUri, 4);
}
- verify(mMockProvider, times(1)).bulkInsert(eq(mPackageName), eqUri(sFilesUri), any());
- verify(mMockProvider, times(2)).bulkInsert(eq(mPackageName), eqUri(sAudioUri), any());
- verify(mMockProvider, times(3)).bulkInsert(eq(mPackageName), eqUri(sVideoUri), any());
- verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eqUri(sImagesUri), any());
+ verify(mMockProvider, times(1)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID),
+ eqUri(sFilesUri), any());
+ verify(mMockProvider, times(2)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID),
+ eqUri(sAudioUri), any());
+ verify(mMockProvider, times(3)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID),
+ eqUri(sVideoUri), any());
+ verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eq(TEST_FEATURE_ID),
+ eqUri(sImagesUri), any());
}
}
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 48d34ae..af96982 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -129,17 +129,17 @@
}
@Override
- protected int enforceReadPermissionInner(Uri uri, String callingPkg, IBinder callerToken)
- throws SecurityException {
+ protected int enforceReadPermissionInner(Uri uri, String callingPkg,
+ @Nullable String featureId, IBinder callerToken) throws SecurityException {
enforceShellRestrictions();
- return super.enforceReadPermissionInner(uri, callingPkg, callerToken);
+ return super.enforceReadPermissionInner(uri, callingPkg, featureId, callerToken);
}
@Override
- protected int enforceWritePermissionInner(Uri uri, String callingPkg, IBinder callerToken)
- throws SecurityException {
+ protected int enforceWritePermissionInner(Uri uri, String callingPkg,
+ @Nullable String featureId, IBinder callerToken) throws SecurityException {
enforceShellRestrictions();
- return super.enforceWritePermissionInner(uri, callingPkg, callerToken);
+ return super.enforceWritePermissionInner(uri, callingPkg, featureId, callerToken);
}
public void updateVolumes() {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index c4df2e8..b9daf7f 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -406,8 +406,8 @@
return null;
}
try {
- return provider.call(context.getPackageName(), uri.getAuthority(),
- method, uri.toString(), bundle);
+ return provider.call(context.getPackageName(), context.getFeatureId(),
+ uri.getAuthority(), method, uri.toString(), bundle);
} catch (RemoteException e) {
return null;
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index 8fb879d..1e75fe7 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -248,7 +248,7 @@
Bundle args = new Bundle();
args.putInt(Settings.CALL_METHOD_USER_KEY,
ActivityManager.getService().getCurrentUser().id);
- Bundle b = provider.call(resolveCallingPackage(), Settings.AUTHORITY,
+ Bundle b = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
Settings.CALL_METHOD_DELETE_CONFIG, compositeKey, args);
success = (b != null && b.getInt(SettingsProvider.RESULT_ROWS_DELETED) == 1);
} catch (RemoteException e) {
@@ -264,7 +264,7 @@
Bundle args = new Bundle();
args.putInt(Settings.CALL_METHOD_USER_KEY,
ActivityManager.getService().getCurrentUser().id);
- Bundle b = provider.call(resolveCallingPackage(), Settings.AUTHORITY,
+ Bundle b = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
Settings.CALL_METHOD_LIST_CONFIG, null, args);
if (b != null) {
Map<String, String> flagsToValues =
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
index 36360a3..3b3ca5b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
@@ -309,7 +309,7 @@
try {
Bundle arg = new Bundle();
arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
- Bundle result = provider.call(resolveCallingPackage(), Settings.AUTHORITY,
+ Bundle result = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
callListCommand, null, arg);
lines.addAll(result.getStringArrayList(SettingsProvider.RESULT_SETTINGS_LIST));
Collections.sort(lines);
@@ -334,7 +334,7 @@
try {
Bundle arg = new Bundle();
arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
- Bundle b = provider.call(resolveCallingPackage(), Settings.AUTHORITY,
+ Bundle b = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
callGetCommand, key, arg);
if (b != null) {
result = b.getPairValue();
@@ -372,7 +372,7 @@
if (makeDefault) {
arg.putBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY, true);
}
- provider.call(resolveCallingPackage(), Settings.AUTHORITY,
+ provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
callPutCommand, key, arg);
} catch (RemoteException e) {
throw new RuntimeException("Failed in IPC", e);
@@ -396,7 +396,7 @@
try {
Bundle arg = new Bundle();
arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
- Bundle result = provider.call(resolveCallingPackage(), Settings.AUTHORITY,
+ Bundle result = provider.call(resolveCallingPackage(), null, Settings.AUTHORITY,
callDeleteCommand, key, arg);
return result.getInt(SettingsProvider.RESULT_ROWS_DELETED);
} catch (RemoteException e) {
@@ -423,7 +423,7 @@
}
String packageName = mPackageName != null ? mPackageName : resolveCallingPackage();
arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
- provider.call(packageName, Settings.AUTHORITY, callResetCommand, null, arg);
+ provider.call(packageName, null, Settings.AUTHORITY, callResetCommand, null, arg);
} catch (RemoteException e) {
throw new RuntimeException("Failed in IPC", e);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 11cfe12..5df4543 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7758,7 +7758,7 @@
holder = getContentProviderExternalUnchecked(name, null, callingUid,
"*checkContentProviderUriPermission*", userId);
if (holder != null) {
- return holder.provider.checkUriPermission(null, uri, callingUid, modeFlags);
+ return holder.provider.checkUriPermission(null, null, uri, callingUid, modeFlags);
}
} catch (RemoteException e) {
Log.w(TAG, "Content provider dead retrieving " + uri, e);
@@ -7923,7 +7923,7 @@
sCallerIdentity.set(new Identity(
token, Binder.getCallingPid(), Binder.getCallingUid()));
try {
- pfd = cph.provider.openFile(null, uri, "r", null, token);
+ pfd = cph.provider.openFile(null, null, uri, "r", null, token);
} catch (FileNotFoundException e) {
// do nothing; pfd will be returned null
} finally {
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 1ad7b6e..79af34d 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -191,7 +191,7 @@
@After
public void tearDown() throws Exception {
mHandlerThread.quitSafely();
- LocalServices.removeServiceForTest(PackageManagerInternal.class);
+ LocalServices.removeServiceForTest(PermissionManagerServiceInternal.class);
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 80439cf..a1322b9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -62,7 +62,6 @@
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
-
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.TestableContentResolver;
import android.util.ArrayMap;
@@ -162,11 +161,11 @@
when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
- when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI)))
+ when(mTestIContentProvider.canonicalize(any(), any(), eq(SOUND_URI)))
.thenReturn(CANONICAL_SOUND_URI);
- when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
+ when(mTestIContentProvider.canonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
.thenReturn(CANONICAL_SOUND_URI);
- when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
+ when(mTestIContentProvider.uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
.thenReturn(SOUND_URI);
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
@@ -465,7 +464,7 @@
// Testing that in restore we are given the canonical version
loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
- verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
+ verify(mTestIContentProvider).uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI));
}
@Test
@@ -475,11 +474,11 @@
.appendQueryParameter("title", "Test")
.appendQueryParameter("canonical", "1")
.build();
- when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
+ when(mTestIContentProvider.canonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
.thenReturn(canonicalBasedOnLocal);
- when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
+ when(mTestIContentProvider.uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
.thenReturn(localUri);
- when(mTestIContentProvider.uncanonicalize(any(), eq(canonicalBasedOnLocal)))
+ when(mTestIContentProvider.uncanonicalize(any(), any(), eq(canonicalBasedOnLocal)))
.thenReturn(localUri);
NotificationChannel channel =
@@ -499,9 +498,9 @@
@Test
public void testRestoreXml_withNonExistentCanonicalizedSoundUri() throws Exception {
Thread.sleep(3000);
- when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
+ when(mTestIContentProvider.canonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
.thenReturn(null);
- when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
+ when(mTestIContentProvider.uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
.thenReturn(null);
NotificationChannel channel =
@@ -526,7 +525,7 @@
@Test
public void testRestoreXml_withUncanonicalizedNonLocalSoundUri() throws Exception {
// Not a local uncanonicalized uri, simulating that it fails to exist locally
- when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI))).thenReturn(null);
+ when(mTestIContentProvider.canonicalize(any(), any(), eq(SOUND_URI))).thenReturn(null);
String id = "id";
String backupWithUncanonicalizedSoundUri = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 2abd340..8774b63 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -132,11 +132,11 @@
when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
contentResolver.addProvider(TEST_AUTHORITY, testContentProvider);
- when(mTestIContentProvider.canonicalize(any(), eq(SOUND_URI)))
+ when(mTestIContentProvider.canonicalize(any(), any(), eq(SOUND_URI)))
.thenReturn(CANONICAL_SOUND_URI);
- when(mTestIContentProvider.canonicalize(any(), eq(CANONICAL_SOUND_URI)))
+ when(mTestIContentProvider.canonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
.thenReturn(CANONICAL_SOUND_URI);
- when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
+ when(mTestIContentProvider.uncanonicalize(any(), any(), eq(CANONICAL_SOUND_URI)))
.thenReturn(SOUND_URI);
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
index 3b336eb..aceed86 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
@@ -12,6 +12,7 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -109,8 +110,8 @@
mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
TestableLooper.get(this).processAllMessages();
- verify(mIContentProvider).call(anyString(), anyString(), eq(SliceProvider.METHOD_PIN),
- eq(null), argThat(b -> {
+ verify(mIContentProvider).call(anyString(), nullable(String.class), anyString(),
+ eq(SliceProvider.METHOD_PIN), eq(null), argThat(b -> {
assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
return true;
}));
@@ -167,8 +168,8 @@
// Throw exception when trying to pin
doAnswer(invocation -> {
throw new Exception("Pin failed");
- }).when(mIContentProvider).call(
- anyString(), anyString(), anyString(), eq(null), any());
+ }).when(mIContentProvider).call(anyString(), nullable(String.class), anyString(),
+ anyString(), eq(null), any());
TestableLooper.get(this).processAllMessages();
@@ -176,8 +177,8 @@
mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
TestableLooper.get(this).processAllMessages();
- verify(mIContentProvider).call(anyString(), anyString(), eq(SliceProvider.METHOD_PIN),
- eq(null), argThat(b -> {
+ verify(mIContentProvider).call(anyString(), nullable(String.class), anyString(),
+ eq(SliceProvider.METHOD_PIN), eq(null), argThat(b -> {
assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
return true;
}));
diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java
index 4d8c7d9..9d3e120 100644
--- a/test-mock/src/android/test/mock/MockContentProvider.java
+++ b/test-mock/src/android/test/mock/MockContentProvider.java
@@ -56,21 +56,22 @@
*/
private class InversionIContentProvider implements IContentProvider {
@Override
- public ContentProviderResult[] applyBatch(String callingPackage, String authority,
+ public ContentProviderResult[] applyBatch(String callingPackage,
+ @Nullable String featureId, String authority,
ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException {
return MockContentProvider.this.applyBatch(authority, operations);
}
@Override
- public int bulkInsert(String callingPackage, Uri url, ContentValues[] initialValues)
- throws RemoteException {
+ public int bulkInsert(String callingPackage, @Nullable String featureId, Uri url,
+ ContentValues[] initialValues) throws RemoteException {
return MockContentProvider.this.bulkInsert(url, initialValues);
}
@Override
- public int delete(String callingPackage, Uri url, String selection, String[] selectionArgs)
- throws RemoteException {
+ public int delete(String callingPackage, @Nullable String featureId, Uri url,
+ String selection, String[] selectionArgs) throws RemoteException {
return MockContentProvider.this.delete(url, selection, selectionArgs);
}
@@ -80,42 +81,42 @@
}
@Override
- public Uri insert(String callingPackage, Uri url, ContentValues initialValues)
- throws RemoteException {
+ public Uri insert(String callingPackage, @Nullable String featureId, Uri url,
+ ContentValues initialValues) throws RemoteException {
return MockContentProvider.this.insert(url, initialValues);
}
@Override
- public AssetFileDescriptor openAssetFile(
- String callingPackage, Uri url, String mode, ICancellationSignal signal)
+ public AssetFileDescriptor openAssetFile(String callingPackage,
+ @Nullable String featureId, Uri url, String mode, ICancellationSignal signal)
throws RemoteException, FileNotFoundException {
return MockContentProvider.this.openAssetFile(url, mode);
}
@Override
- public ParcelFileDescriptor openFile(
- String callingPackage, Uri url, String mode, ICancellationSignal signal,
- IBinder callerToken) throws RemoteException, FileNotFoundException {
+ public ParcelFileDescriptor openFile(String callingPackage, @Nullable String featureId,
+ Uri url, String mode, ICancellationSignal signal, IBinder callerToken)
+ throws RemoteException, FileNotFoundException {
return MockContentProvider.this.openFile(url, mode);
}
@Override
- public Cursor query(String callingPackage, Uri url, @Nullable String[] projection,
- @Nullable Bundle queryArgs,
- @Nullable ICancellationSignal cancellationSignal)
- throws RemoteException {
+ public Cursor query(String callingPackage, @Nullable String featureId, Uri url,
+ @Nullable String[] projection, @Nullable Bundle queryArgs,
+ @Nullable ICancellationSignal cancellationSignal) throws RemoteException {
return MockContentProvider.this.query(url, projection, queryArgs, null);
}
@Override
- public int update(String callingPackage, Uri url, ContentValues values, String selection,
- String[] selectionArgs) throws RemoteException {
+ public int update(String callingPackage, @Nullable String featureId, Uri url,
+ ContentValues values, String selection, String[] selectionArgs)
+ throws RemoteException {
return MockContentProvider.this.update(url, values, selection, selectionArgs);
}
@Override
- public Bundle call(String callingPackage, String authority, String method, String request,
- Bundle args) throws RemoteException {
+ public Bundle call(String callingPackage, @Nullable String featureId, String authority,
+ String method, String request, Bundle args) throws RemoteException {
return MockContentProvider.this.call(authority, method, request, args);
}
@@ -130,9 +131,9 @@
}
@Override
- public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri url,
- String mimeType, Bundle opts, ICancellationSignal signal)
- throws RemoteException, FileNotFoundException {
+ public AssetFileDescriptor openTypedAssetFile(String callingPackage,
+ @Nullable String featureId, Uri url, String mimeType, Bundle opts,
+ ICancellationSignal signal) throws RemoteException, FileNotFoundException {
return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts);
}
@@ -142,23 +143,26 @@
}
@Override
- public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
+ public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+ throws RemoteException {
return MockContentProvider.this.canonicalize(uri);
}
@Override
- public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException {
+ public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+ throws RemoteException {
return MockContentProvider.this.uncanonicalize(uri);
}
@Override
- public boolean refresh(String callingPkg, Uri url, Bundle args,
- ICancellationSignal cancellationSignal) throws RemoteException {
+ public boolean refresh(String callingPkg, @Nullable String featureId, Uri url,
+ Bundle args, ICancellationSignal cancellationSignal) throws RemoteException {
return MockContentProvider.this.refresh(url, args);
}
@Override
- public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+ public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri,
+ int uid, int modeFlags) {
return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags);
}
}
diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java
index b072d74..e512b52 100644
--- a/test-mock/src/android/test/mock/MockIContentProvider.java
+++ b/test-mock/src/android/test/mock/MockIContentProvider.java
@@ -16,14 +16,12 @@
package android.test.mock;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.EntityIterator;
import android.content.IContentProvider;
-import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
@@ -45,14 +43,15 @@
*/
public class MockIContentProvider implements IContentProvider {
@Override
- public int bulkInsert(String callingPackage, Uri url, ContentValues[] initialValues) {
+ public int bulkInsert(String callingPackage, @Nullable String featureId, Uri url,
+ ContentValues[] initialValues) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
@SuppressWarnings("unused")
- public int delete(String callingPackage, Uri url, String selection, String[] selectionArgs)
- throws RemoteException {
+ public int delete(String callingPackage, @Nullable String featureId, Uri url,
+ String selection, String[] selectionArgs) throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
@@ -63,33 +62,33 @@
@Override
@SuppressWarnings("unused")
- public Uri insert(String callingPackage, Uri url, ContentValues initialValues)
- throws RemoteException {
+ public Uri insert(String callingPackage, @Nullable String featureId, Uri url,
+ ContentValues initialValues) throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
- public ParcelFileDescriptor openFile(
- String callingPackage, Uri url, String mode, ICancellationSignal signal,
- IBinder callerToken) {
+ public ParcelFileDescriptor openFile(String callingPackage, @Nullable String featureId,
+ Uri url, String mode, ICancellationSignal signal, IBinder callerToken) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
- public AssetFileDescriptor openAssetFile(
- String callingPackage, Uri uri, String mode, ICancellationSignal signal) {
+ public AssetFileDescriptor openAssetFile(String callingPackage, @Nullable String featureId,
+ Uri uri, String mode, ICancellationSignal signal) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
- public ContentProviderResult[] applyBatch(String callingPackage, String authority,
- ArrayList<ContentProviderOperation> operations) {
+ public ContentProviderResult[] applyBatch(String callingPackage, @Nullable String featureId,
+ String authority, ArrayList<ContentProviderOperation> operations) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
- public Cursor query(String callingPackage, Uri url, @Nullable String[] projection,
- @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) {
+ public Cursor query(String callingPackage, @Nullable String featureId, Uri url,
+ @Nullable String[] projection, @Nullable Bundle queryArgs,
+ @Nullable ICancellationSignal cancellationSignal) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@@ -99,14 +98,14 @@
}
@Override
- public int update(String callingPackage, Uri url, ContentValues values, String selection,
- String[] selectionArgs) throws RemoteException {
+ public int update(String callingPackage, @Nullable String featureId, Uri url,
+ ContentValues values, String selection, String[] selectionArgs) throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
- public Bundle call(String callingPackage, String authority, String method, String request,
- Bundle args) throws RemoteException {
+ public Bundle call(String callingPackage, @Nullable String featureId, String authority,
+ String method, String request, Bundle args) throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
@@ -121,8 +120,9 @@
}
@Override
- public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri url, String mimeType,
- Bundle opts, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
+ public AssetFileDescriptor openTypedAssetFile(String callingPackage,
+ @Nullable String featureId, Uri url, String mimeType, Bundle opts,
+ ICancellationSignal signal) throws RemoteException, FileNotFoundException {
throw new UnsupportedOperationException("unimplemented mock method");
}
@@ -132,24 +132,27 @@
}
@Override
- public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
+ public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+ throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
- public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException {
+ public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+ throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
- public boolean refresh(String callingPkg, Uri url, Bundle args,
+ public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle args,
ICancellationSignal cancellationSignal) throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
/** {@hide} */
@Override
- public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+ public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri, int uid,
+ int modeFlags) {
throw new UnsupportedOperationException("unimplemented mock method call");
}
}