Merge "DO NOT MERGE: Enable ENABLE_DYNAMIC_PERMISSIONS depending on MediaProvider." into rvc-qpr-dev

This commit is contained in:
Corina Grigoras
2020-11-26 11:49:23 +00:00
committed by Android (Google) Code Review
2 changed files with 53 additions and 9 deletions

View File

@@ -51,11 +51,15 @@ import android.app.AppGlobals;
import android.app.GrantedUriPermission; import android.app.GrantedUriPermission;
import android.app.IUriGrantsManager; import android.app.IUriGrantsManager;
import android.content.ClipData; import android.content.ClipData;
import android.content.ComponentName;
import android.content.ContentProvider; import android.content.ContentProvider;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ModuleInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice; import android.content.pm.ParceledListSlice;
import android.content.pm.PathPermission; import android.content.pm.PathPermission;
@@ -115,13 +119,19 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
private static final String TAG = "UriGrantsManagerService"; private static final String TAG = "UriGrantsManagerService";
// Maximum number of persisted Uri grants a package is allowed // Maximum number of persisted Uri grants a package is allowed
private static final int MAX_PERSISTED_URI_GRANTS = 512; 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 Object mLock = new Object();
private final Context mContext;
private final H mH; private final H mH;
ActivityManagerInternal mAmInternal; ActivityManagerInternal mAmInternal;
PackageManagerInternal mPmInternal; PackageManagerInternal mPmInternal;
private boolean isDynamicPermissionEnabledInMP = false;
private boolean isMPVersionChecked = false;
/** File storing persisted {@link #mGrantedUriPermissions}. */ /** File storing persisted {@link #mGrantedUriPermissions}. */
@GuardedBy("mLock") @GuardedBy("mLock")
private final AtomicFile mGrantFile; private final AtomicFile mGrantFile;
@@ -148,18 +158,19 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
private final SparseArray<ArrayMap<GrantUri, UriPermission>> private final SparseArray<ArrayMap<GrantUri, UriPermission>>
mGrantedUriPermissions = new SparseArray<>(); mGrantedUriPermissions = new SparseArray<>();
private UriGrantsManagerService() { private UriGrantsManagerService(Context context) {
this(SystemServiceManager.ensureSystemDir()); this(context, SystemServiceManager.ensureSystemDir());
} }
private UriGrantsManagerService(File systemDir) { private UriGrantsManagerService(Context context, File systemDir) {
mContext = context;
mH = new H(IoThread.get().getLooper()); mH = new H(IoThread.get().getLooper());
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants"); mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
} }
@VisibleForTesting @VisibleForTesting
static UriGrantsManagerService createForTest(File systemDir) { static UriGrantsManagerService createForTest(Context context, File systemDir) {
final UriGrantsManagerService service = new UriGrantsManagerService(systemDir); final UriGrantsManagerService service = new UriGrantsManagerService(context, systemDir);
service.mAmInternal = LocalServices.getService(ActivityManagerInternal.class); service.mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
service.mPmInternal = LocalServices.getService(PackageManagerInternal.class); service.mPmInternal = LocalServices.getService(PackageManagerInternal.class);
return service; return service;
@@ -179,7 +190,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
public Lifecycle(Context context) { public Lifecycle(Context context) {
super(context); super(context);
mService = new UriGrantsManagerService(); mService = new UriGrantsManagerService(context);
} }
@Override @Override
@@ -991,7 +1002,9 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
// If this provider says that grants are always required, we need to // If this provider says that grants are always required, we need to
// consult it directly to determine if the UID has permission // consult it directly to determine if the UID has permission
final boolean forceMet; 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 providerUserId = UserHandle.getUserId(pi.applicationInfo.uid);
final int clientUserId = UserHandle.getUserId(uid); final int clientUserId = UserHandle.getUserId(uid);
if (providerUserId == clientUserId) { if (providerUserId == clientUserId) {
@@ -1009,6 +1022,35 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
return readMet && writeMet && forceMet; 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") @GuardedBy("mLock")
private void removeUriPermissionIfNeededLocked(UriPermission perm) { private void removeUriPermissionIfNeededLocked(UriPermission perm) {
if (perm.modeFlags != 0) { if (perm.modeFlags != 0) {

View File

@@ -79,7 +79,9 @@ public class UriGrantsManagerServiceTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
mContext = new UriGrantsMockContext(InstrumentationRegistry.getContext()); mContext = new UriGrantsMockContext(InstrumentationRegistry.getContext());
mService = UriGrantsManagerService.createForTest(mContext.getFilesDir()).getLocalService(); mService = UriGrantsManagerService
.createForTest(mContext, mContext.getFilesDir())
.getLocalService();
} }
/** /**