From 3fcaa5218caa57e061a1e0c67601d54796301964 Mon Sep 17 00:00:00 2001 From: Corina Date: Thu, 4 Mar 2021 10:29:28 +0000 Subject: [PATCH] Expose create uri as user as system api. Bug: 179659160 Test: atest ContentProviderTest Change-Id: I86edc2d4fa0911366a91170819140b274f5d6480 --- core/api/module-lib-current.txt | 4 ++ .../java/android/content/ContentProvider.java | 42 +++++++++++++++++++ .../android/content/ContentProviderTest.java | 8 ++++ 3 files changed, 54 insertions(+) diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 18b0a43444147..bffb1cc0acfd2 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -55,6 +55,10 @@ package android.app.usage { 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 49248b51a5c7c..73b4f62a23e4e 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -2621,6 +2621,48 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall 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 + * + * + * @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 8895f9bdf23d3..b28206402137d 100644 --- a/core/tests/coretests/src/android/content/ContentProviderTest.java +++ b/core/tests/coretests/src/android/content/ContentProviderTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.withSettings; 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 @@ public class ContentProviderTest { 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))); + } }