DO NOT MERGE: Enable ENABLE_DYNAMIC_PERMISSIONS depending on MediaProvider.
The flag is now enabled only when MediaProvider version is
high enough to have the changes that handle it.
Bug: 115619667
Test: atest UriGrantsManagerServiceTest
Change-Id: I9582bb86ecf150a2f99a911226a40bb3e1273d4d
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 8eefd8f..e8a0379 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -51,11 +51,15 @@
import android.app.GrantedUriPermission;
import android.app.IUriGrantsManager;
import android.content.ClipData;
+import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ModuleInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.PathPermission;
@@ -115,13 +119,19 @@
private static final String TAG = "UriGrantsManagerService";
// Maximum number of persisted Uri grants a package is allowed
private static final int MAX_PERSISTED_URI_GRANTS = 512;
- private static final boolean ENABLE_DYNAMIC_PERMISSIONS = false;
+ private static final boolean ENABLE_DYNAMIC_PERMISSIONS = true;
+ private static final String MEDIA_PROVIDER_MODULE_NAME = "com.android.mediaprovider";
+ private static final long MIN_DYNAMIC_PERMISSIONS_MP_VERSION = 301400000L;
private final Object mLock = new Object();
+ private final Context mContext;
private final H mH;
ActivityManagerInternal mAmInternal;
PackageManagerInternal mPmInternal;
+ private boolean isDynamicPermissionEnabledInMP = false;
+ private boolean isMPVersionChecked = false;
+
/** File storing persisted {@link #mGrantedUriPermissions}. */
@GuardedBy("mLock")
private final AtomicFile mGrantFile;
@@ -148,18 +158,19 @@
private final SparseArray<ArrayMap<GrantUri, UriPermission>>
mGrantedUriPermissions = new SparseArray<>();
- private UriGrantsManagerService() {
- this(SystemServiceManager.ensureSystemDir());
+ private UriGrantsManagerService(Context context) {
+ this(context, SystemServiceManager.ensureSystemDir());
}
- private UriGrantsManagerService(File systemDir) {
+ private UriGrantsManagerService(Context context, File systemDir) {
+ mContext = context;
mH = new H(IoThread.get().getLooper());
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
}
@VisibleForTesting
- static UriGrantsManagerService createForTest(File systemDir) {
- final UriGrantsManagerService service = new UriGrantsManagerService(systemDir);
+ static UriGrantsManagerService createForTest(Context context, File systemDir) {
+ final UriGrantsManagerService service = new UriGrantsManagerService(context, systemDir);
service.mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
service.mPmInternal = LocalServices.getService(PackageManagerInternal.class);
return service;
@@ -179,7 +190,7 @@
public Lifecycle(Context context) {
super(context);
- mService = new UriGrantsManagerService();
+ mService = new UriGrantsManagerService(context);
}
@Override
@@ -991,7 +1002,9 @@
// If this provider says that grants are always required, we need to
// consult it directly to determine if the UID has permission
final boolean forceMet;
- if (ENABLE_DYNAMIC_PERMISSIONS && pi.forceUriPermissions) {
+ if (ENABLE_DYNAMIC_PERMISSIONS
+ && pi.forceUriPermissions
+ && isDynamicPermissionEnabledInMP()) {
final int providerUserId = UserHandle.getUserId(pi.applicationInfo.uid);
final int clientUserId = UserHandle.getUserId(uid);
if (providerUserId == clientUserId) {
@@ -1009,6 +1022,35 @@
return readMet && writeMet && forceMet;
}
+ /**
+ * Returns true if the available MediaProvider version contains the changes that enable dynamic
+ * permission.
+ */
+ private boolean isDynamicPermissionEnabledInMP() {
+ if (isMPVersionChecked) {
+ return isDynamicPermissionEnabledInMP;
+ }
+
+ try {
+ ModuleInfo moduleInfo = mContext.getPackageManager().getModuleInfo(
+ MEDIA_PROVIDER_MODULE_NAME, PackageManager.MODULE_APEX_NAME);
+ PackageInfo packageInfo =
+ mContext.getPackageManager().getPackageInfo(
+ moduleInfo.getPackageName(), PackageManager.MATCH_APEX);
+ isDynamicPermissionEnabledInMP =
+ packageInfo.getLongVersionCode() >= MIN_DYNAMIC_PERMISSIONS_MP_VERSION;
+ } catch (NameNotFoundException e) {
+ Slog.i(TAG, "Module name not found: " + MEDIA_PROVIDER_MODULE_NAME);
+ // If module is not found, then MP changes are expected to be there (because both this
+ // change and the module change will be mandated together for non-module builds).
+ isDynamicPermissionEnabledInMP = true;
+ } finally {
+ isMPVersionChecked = true;
+ }
+
+ return isDynamicPermissionEnabledInMP;
+ }
+
@GuardedBy("mLock")
private void removeUriPermissionIfNeededLocked(UriPermission perm) {
if (perm.modeFlags != 0) {
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 614949c..1494642 100644
--- a/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java
@@ -79,7 +79,9 @@
@Before
public void setUp() throws Exception {
mContext = new UriGrantsMockContext(InstrumentationRegistry.getContext());
- mService = UriGrantsManagerService.createForTest(mContext.getFilesDir()).getLocalService();
+ mService = UriGrantsManagerService
+ .createForTest(mContext, mContext.getFilesDir())
+ .getLocalService();
}
/**