Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d744eaa5 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6997403 from 29c2b7e6 to rvc-qpr2-release

Change-Id: Ib4e97b529afc1888928da384a4411984a3eb790e
parents 059ae75f 29c2b7e6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -3268,8 +3268,8 @@ public final class ViewRootImpl implements ViewParent,

            // Note: must be done after the focus change callbacks,
            // so all of the view state is set up correctly.
            mImeFocusController.onPostWindowFocus(mView.findFocus(), hasWindowFocus,
                    mWindowAttributes);
            mImeFocusController.onPostWindowFocus(mView != null ? mView.findFocus() : null,
                    hasWindowFocus, mWindowAttributes);

            if (hasWindowFocus) {
                // Clear the forward bit.  We can just do this directly, since
+4 −4
Original line number Diff line number Diff line
@@ -11009,12 +11009,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                    MotionEvent.actionToString(event.getActionMasked()),
                    event.getX(), event.getY());
        }
        final int action = event.getActionMasked();
        if (mEditor != null) {
            if (!isFromPrimePointer(event, false)) {
                return true;
            }
        final int action = event.getActionMasked();
        if (mEditor != null) {
            mEditor.onTouchEvent(event);
            if (mEditor.mInsertionPointCursorController != null
+56 −15
Original line number Diff line number Diff line
@@ -127,9 +127,11 @@ public abstract class SoftRestrictedPermissionPolicy {
                final boolean isWhiteListed;
                boolean shouldApplyRestriction;
                final int targetSDK;
                final boolean hasLegacyExternalStorage;
                final boolean hasRequestedLegacyExternalStorage;
                final boolean shouldPreserveLegacyExternalStorage;
                final boolean hasRequestedPreserveLegacyExternalStorage;
                final boolean hasWriteMediaStorageGrantedForUid;
                final boolean isForcedScopedStorage;

                if (appInfo != null) {
                    PackageManager pm = context.getPackageManager();
@@ -137,27 +139,27 @@ public abstract class SoftRestrictedPermissionPolicy {
                            LocalServices.getService(StorageManagerInternal.class);
                    int flags = pm.getPermissionFlags(permission, appInfo.packageName, user);
                    isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
                    hasLegacyExternalStorage = smInternal.hasLegacyExternalStorage(appInfo.uid);
                    hasRequestedLegacyExternalStorage = hasUidRequestedLegacyExternalStorage(
                            appInfo.uid, context);
                    hasWriteMediaStorageGrantedForUid = hasWriteMediaStorageGrantedForUid(
                            appInfo.uid, context);
                    shouldPreserveLegacyExternalStorage = pkg.hasPreserveLegacyExternalStorage()
                            && smInternal.hasLegacyExternalStorage(appInfo.uid);
                    hasRequestedPreserveLegacyExternalStorage =
                            pkg.hasPreserveLegacyExternalStorage();
                    targetSDK = getMinimumTargetSDK(context, appInfo, user);

                    shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0
                            || (targetSDK > Build.VERSION_CODES.Q
                            && !shouldPreserveLegacyExternalStorage)
                            // If the device is configured to force this app into scoped storage,
                            // then we should apply the restriction
                            || sForcedScopedStorageAppWhitelist.contains(appInfo.packageName);
                    shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
                    isForcedScopedStorage = sForcedScopedStorageAppWhitelist
                            .contains(appInfo.packageName);
                } else {
                    isWhiteListed = false;
                    shouldApplyRestriction = false;
                    targetSDK = 0;
                    hasLegacyExternalStorage = false;
                    hasRequestedLegacyExternalStorage = false;
                    shouldPreserveLegacyExternalStorage = false;
                    hasRequestedPreserveLegacyExternalStorage = false;
                    hasWriteMediaStorageGrantedForUid = false;
                    isForcedScopedStorage = false;
                }

                // We have a check in PermissionPolicyService.PermissionToOpSynchroniser.setUidMode
@@ -175,14 +177,53 @@ public abstract class SoftRestrictedPermissionPolicy {
                    }
                    @Override
                    public boolean mayAllowExtraAppOp() {
                        return !shouldApplyRestriction
                                && (hasRequestedLegacyExternalStorage
                                        || hasWriteMediaStorageGrantedForUid
                                        || shouldPreserveLegacyExternalStorage);
                        // The only way to get LEGACY_STORAGE (if you didn't already have it)
                        // is that all of the following must be true:
                        // 1. The flag shouldn't be restricted
                        if (shouldApplyRestriction) {
                            return false;
                        }

                        // 2. The app shouldn't be in sForcedScopedStorageAppWhitelist
                        if (isForcedScopedStorage) {
                            return false;
                        }

                        // 3. The app has WRITE_MEDIA_STORAGE, OR
                        //      the app already has legacy external storage or requested it,
                        //      and is < R.
                        return hasWriteMediaStorageGrantedForUid
                                || ((hasLegacyExternalStorage || hasRequestedLegacyExternalStorage)
                                    && targetSDK < Build.VERSION_CODES.R);
                    }
                    @Override
                    public boolean mayDenyExtraAppOpIfGranted() {
                        return shouldApplyRestriction;
                        // If you're an app targeting < R, you can keep the app op for
                        // as long as you meet the conditions required to acquire it.
                        if (targetSDK < Build.VERSION_CODES.R) {
                            return !mayAllowExtraAppOp();
                        }

                        // For an app targeting R, the only way to lose LEGACY_STORAGE if you
                        // already had it is in one or more of the following conditions:
                        // 1. The flag became restricted
                        if (shouldApplyRestriction) {
                            return true;
                        }

                        // The package is now a part of the forced scoped storage whitelist
                        if (isForcedScopedStorage) {
                            return true;
                        }

                        // The package doesn't have WRITE_MEDIA_STORAGE,
                        // AND didn't request legacy storage to be preserved
                        if (!hasWriteMediaStorageGrantedForUid
                                && !hasRequestedPreserveLegacyExternalStorage) {
                            return true;
                        }

                        return false;
                    }
                };
            }
+50 −8
Original line number Diff line number Diff line
@@ -51,11 +51,15 @@ import android.app.AppGlobals;
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 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
    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 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
    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 class UriGrantsManagerService extends IUriGrantsManager.Stub {

        public Lifecycle(Context context) {
            super(context);
            mService = new UriGrantsManagerService();
            mService = new UriGrantsManagerService(context);
        }

        @Override
@@ -991,7 +1002,9 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
        // 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 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
        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) {
+3 −1
Original line number Diff line number Diff line
@@ -79,7 +79,9 @@ public class UriGrantsManagerServiceTest {
    @Before
    public void setUp() throws Exception {
        mContext = new UriGrantsMockContext(InstrumentationRegistry.getContext());
        mService = UriGrantsManagerService.createForTest(mContext.getFilesDir()).getLocalService();
        mService = UriGrantsManagerService
            .createForTest(mContext, mContext.getFilesDir())
            .getLocalService();
    }

    /**