Merge "Expose create uri as user as system api." into sc-dev
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 64f56bf3..a140e8a 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -55,6 +55,10 @@
package android.content {
+ public abstract class ContentProvider implements android.content.ComponentCallbacks2 {
+ method @NonNull public static android.net.Uri createContentUriAsUser(@NonNull android.net.Uri, @NonNull android.os.UserHandle);
+ }
+
public abstract class Context {
method @NonNull public android.os.UserHandle getUser();
}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 49248b5..73b4f62 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -2621,6 +2621,48 @@
return !TextUtils.isEmpty(uri.getUserInfo());
}
+ /**
+ * Returns the given content URI explicitly associated with the given {@link UserHandle}.
+ *
+ * @param contentUri The content URI to be associated with a user handle.
+ * @param userHandle The user handle with which to associate the URI.
+ *
+ * @throws IllegalArgumentException if
+ * <ul>
+ * <li>the given URI is not content URI (a content URI has {@link Uri#getScheme} equal to
+ * {@link ContentResolver.SCHEME_CONTENT}) or</li>
+ * <li>the given URI is already explicitly associated with a {@link UserHandle}, which is
+ * different than the given one.</li>
+ * </ul>
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static Uri createContentUriAsUser(
+ @NonNull Uri contentUri, @NonNull UserHandle userHandle) {
+ if (!ContentResolver.SCHEME_CONTENT.equals(contentUri.getScheme())) {
+ throw new IllegalArgumentException(String.format(
+ "Given URI [%s] is not a content URI: ", contentUri));
+ }
+
+ int userId = userHandle.getIdentifier();
+ if (uriHasUserId(contentUri)) {
+ if (String.valueOf(userId).equals(contentUri.getUserInfo())) {
+ return contentUri;
+ }
+ throw new IllegalArgumentException(String.format(
+ "Given URI [%s] already has a user ID, different from given user handle [%s]",
+ contentUri,
+ userId));
+ }
+
+ Uri.Builder builder = contentUri.buildUpon();
+ builder.encodedAuthority(
+ "" + userHandle.getIdentifier() + "@" + contentUri.getEncodedAuthority());
+ return builder.build();
+ }
+
/** @hide */
@UnsupportedAppUsage
public static Uri maybeAddUserId(Uri uri, int userId) {
diff --git a/core/tests/coretests/src/android/content/ContentProviderTest.java b/core/tests/coretests/src/android/content/ContentProviderTest.java
index 8895f9b..b282064 100644
--- a/core/tests/coretests/src/android/content/ContentProviderTest.java
+++ b/core/tests/coretests/src/android/content/ContentProviderTest.java
@@ -23,6 +23,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.ProviderInfo;
import android.net.Uri;
+import android.os.UserHandle;
import androidx.test.runner.AndroidJUnit4;
@@ -86,4 +87,11 @@
mCp.validateIncomingUri(
Uri.parse("content://com.example/foo/bar?foo=b//ar#foo=b//ar")));
}
+
+ @Test
+ public void testCreateContentUriAsUser() {
+ Uri uri = Uri.parse("content://com.example/foo/bar");
+ Uri expectedUri = Uri.parse("content://7@com.example/foo/bar");
+ assertEquals(expectedUri, ContentProvider.createContentUriAsUser(uri, UserHandle.of(7)));
+ }
}