Loading core/api/module-lib-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -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(); } Loading core/java/android/content/ContentProvider.java +42 −0 Original line number Diff line number Diff line Loading @@ -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 * <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) { Loading core/tests/coretests/src/android/content/ContentProviderTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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))); } } Loading
core/api/module-lib-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -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(); } Loading
core/java/android/content/ContentProvider.java +42 −0 Original line number Diff line number Diff line Loading @@ -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 * <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) { Loading
core/tests/coretests/src/android/content/ContentProviderTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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))); } }