diff options
7 files changed, 78 insertions, 27 deletions
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index c86ccfdaa7d4..c7a75ed5ea9c 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -117,6 +117,7 @@ import java.util.Objects; * developer guide.</p> * </div> */ +@android.ravenwood.annotation.RavenwoodKeepPartialClass public abstract class ContentProvider implements ContentInterface, ComponentCallbacks2 { private static final String TAG = "ContentProvider"; @@ -2781,6 +2782,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep private Uri maybeGetUriWithoutUserId(Uri uri) { if (mSingleUser) { return uri; @@ -2789,6 +2791,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static int getUserIdFromAuthority(String auth, int defaultUserId) { if (auth == null) return defaultUserId; int end = auth.lastIndexOf('@'); @@ -2803,17 +2806,20 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static int getUserIdFromAuthority(String auth) { return getUserIdFromAuthority(auth, UserHandle.USER_CURRENT); } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static int getUserIdFromUri(Uri uri, int defaultUserId) { if (uri == null) return defaultUserId; return getUserIdFromAuthority(uri.getAuthority(), defaultUserId); } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static int getUserIdFromUri(Uri uri) { return getUserIdFromUri(uri, UserHandle.USER_CURRENT); } @@ -2824,6 +2830,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * @hide */ @TestApi + @android.ravenwood.annotation.RavenwoodKeep public @NonNull static UserHandle getUserHandleFromUri(@NonNull Uri uri) { return UserHandle.of(getUserIdFromUri(uri, Process.myUserHandle().getIdentifier())); } @@ -2834,6 +2841,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * If there is no userId in the authority, it symply returns the argument * @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static String getAuthorityWithoutUserId(String auth) { if (auth == null) return null; int end = auth.lastIndexOf('@'); @@ -2841,6 +2849,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static Uri getUriWithoutUserId(Uri uri) { if (uri == null) return null; Uri.Builder builder = uri.buildUpon(); @@ -2849,6 +2858,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean uriHasUserId(Uri uri) { if (uri == null) return false; return !TextUtils.isEmpty(uri.getUserInfo()); @@ -2872,6 +2882,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall */ @NonNull @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @android.ravenwood.annotation.RavenwoodKeep public static Uri createContentUriForUser( @NonNull Uri contentUri, @NonNull UserHandle userHandle) { if (!ContentResolver.SCHEME_CONTENT.equals(contentUri.getScheme())) { @@ -2898,6 +2909,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall /** @hide */ @UnsupportedAppUsage + @android.ravenwood.annotation.RavenwoodKeep public static Uri maybeAddUserId(Uri uri, int userId) { if (uri == null) return null; if (userId != UserHandle.USER_CURRENT diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt index 831fce12b9c9..e3f1932316da 100644 --- a/ravenwood/ravenwood-annotation-allowed-classes.txt +++ b/ravenwood/ravenwood-annotation-allowed-classes.txt @@ -88,6 +88,8 @@ android.graphics.PointF android.graphics.Rect android.graphics.RectF +android.content.ContentProvider + com.android.server.LocalServices com.android.internal.os.SomeArgs diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java index 7862f58374a3..e501b9dc9959 100644 --- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java +++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java @@ -146,17 +146,31 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements mGrantedUriPermissions = new SparseArray<>(); private UriGrantsManagerService() { - this(SystemServiceManager.ensureSystemDir()); + this(SystemServiceManager.ensureSystemDir(), "uri-grants"); } - private UriGrantsManagerService(File systemDir) { + private UriGrantsManagerService(File systemDir, String commitTag) { mH = new H(IoThread.get().getLooper()); - mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants"); + final File file = new File(systemDir, "urigrants.xml"); + mGrantFile = (commitTag != null) ? new AtomicFile(file, commitTag) : new AtomicFile(file); } @VisibleForTesting static UriGrantsManagerService createForTest(File systemDir) { - final UriGrantsManagerService service = new UriGrantsManagerService(systemDir); + final UriGrantsManagerService service = new UriGrantsManagerService(systemDir, null) { + @VisibleForTesting + protected int checkUidPermission(String permission, int uid) { + // Tests have no permission granted + return PackageManager.PERMISSION_DENIED; + } + + @VisibleForTesting + protected int checkComponentPermission(String permission, int uid, int owningUid, + boolean exported) { + // Tests have no permission granted + return PackageManager.PERMISSION_DENIED; + } + }; service.mAmInternal = LocalServices.getService(ActivityManagerInternal.class); service.mPmInternal = LocalServices.getService(PackageManagerInternal.class); return service; @@ -202,7 +216,8 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements } } - private int checkUidPermission(String permission, int uid) { + @VisibleForTesting + protected int checkUidPermission(String permission, int uid) { try { return AppGlobals.getPackageManager().checkUidPermission(permission, uid); } catch (RemoteException e) { @@ -210,6 +225,12 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements } } + @VisibleForTesting + protected int checkComponentPermission(String permission, int uid, int owningUid, + boolean exported) { + return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported); + } + /** * Grant uri permissions to the specified app. * @@ -916,7 +937,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { if (DEBUG) Slog.v(TAG, "checkHoldingPermissions: uri=" + grantUri + " uid=" + uid); if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { - if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) + if (checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) != PERMISSION_GRANTED) { return false; } @@ -1340,7 +1361,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements if (uid == Process.SYSTEM_UID || uid == Process.ROOT_UID) { return true; } - return ActivityManager.checkComponentPermission( + return checkComponentPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid, /* owningUid = */-1, /* exported = */ true) == PackageManager.PERMISSION_GRANTED; diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index 2ece8c74420c..9b8419021c5c 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -79,6 +79,7 @@ android_test { "coretests-aidl", "securebox", "flag-junit", + "ravenwood-junit", ], libs: [ @@ -140,6 +141,23 @@ android_test { resource_zips: [":FrameworksServicesTests_apks_as_resources"], } +android_ravenwood_test { + name: "FrameworksServicesTestsRavenwood", + libs: [ + "android.test.mock", + ], + static_libs: [ + "androidx.annotation_annotation", + "androidx.test.rules", + "mockito_ravenwood", + "services.core", + ], + srcs: [ + "src/com/android/server/uri/**/*.java", + ], + auto_gen_config: true, +} + java_library { name: "servicestests-core-utils", srcs: [ diff --git a/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java index e418d2f8d328..769ec5fac023 100644 --- a/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java @@ -57,17 +57,22 @@ import android.content.pm.ProviderInfo; import android.net.Uri; import android.os.Process; import android.os.UserHandle; +import android.platform.test.ravenwood.RavenwoodRule; import android.util.ArraySet; import androidx.test.InstrumentationRegistry; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import java.util.Arrays; import java.util.Set; public class UriGrantsManagerServiceTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + private UriGrantsMockContext mContext; private UriGrantsManagerInternal mService; @@ -79,7 +84,7 @@ public class UriGrantsManagerServiceTest { @Before public void setUp() throws Exception { - mContext = new UriGrantsMockContext(InstrumentationRegistry.getContext()); + mContext = new UriGrantsMockContext(); mService = UriGrantsManagerService.createForTest(mContext.getFilesDir()).getLocalService(); } diff --git a/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java b/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java index 7eb6c9789fe4..4c11de0924ba 100644 --- a/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java +++ b/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java @@ -21,11 +21,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import android.annotation.NonNull; import android.app.ActivityManagerInternal; -import android.content.ContentResolver; -import android.content.Context; -import android.content.ContextWrapper; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -33,18 +29,19 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.PathPermission; import android.content.pm.ProviderInfo; import android.net.Uri; -import android.os.FileUtils; import android.os.PatternMatcher; import android.os.Process; import android.os.UserHandle; -import android.test.mock.MockContentResolver; +import android.test.mock.MockContext; import android.test.mock.MockPackageManager; import com.android.server.LocalServices; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; -public class UriGrantsMockContext extends ContextWrapper { +public class UriGrantsMockContext extends MockContext { static final String TAG = "UriGrants"; static final int FLAG_READ = Intent.FLAG_GRANT_READ_URI_PERMISSION; @@ -98,19 +95,14 @@ public class UriGrantsMockContext extends ContextWrapper { private final File mDir; private final MockPackageManager mPackage; - private final MockContentResolver mResolver; final ActivityManagerInternal mAmInternal; final PackageManagerInternal mPmInternal; - public UriGrantsMockContext(@NonNull Context base) { - super(base); - mDir = new File(base.getFilesDir(), TAG); - mDir.mkdirs(); - FileUtils.deleteContents(mDir); + public UriGrantsMockContext() throws IOException { + mDir = Files.createTempDirectory(TAG).toFile(); mPackage = new MockPackageManager(); - mResolver = new MockContentResolver(this); mAmInternal = mock(ActivityManagerInternal.class); LocalServices.removeServiceForTest(ActivityManagerInternal.class); @@ -239,11 +231,6 @@ public class UriGrantsMockContext extends ContextWrapper { } @Override - public ContentResolver getContentResolver() { - return mResolver; - } - - @Override public File getFilesDir() { return mDir; } diff --git a/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java b/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java index 07005a9902d7..4d4f5ed15ad6 100644 --- a/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java +++ b/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java @@ -35,12 +35,18 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import android.platform.test.ravenwood.RavenwoodRule; + import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; public class UriPermissionTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + @Mock private UriGrantsManagerInternal mService; |