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

Commit 29e2888e authored by Himanshu Dagar's avatar Himanshu Dagar Committed by Android (Google) Code Review
Browse files

Merge "Media CP queries redirection from clone profile to its parent"

parents 0da783cc a0f1107f
Loading
Loading
Loading
Loading
+50 −4
Original line number Diff line number Diff line
@@ -48,10 +48,13 @@ import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.permission.PermissionCheckerManager;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseBooleanArray;

import com.android.internal.annotations.VisibleForTesting;

@@ -134,9 +137,18 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
    private boolean mExported;
    private boolean mNoPerms;
    private boolean mSingleUser;
    private SparseBooleanArray mUsersRedirectedToOwner = new SparseBooleanArray();

    private ThreadLocal<AttributionSource> mCallingAttributionSource;

    /**
     * @hide
     */
    public static boolean isAuthorityRedirectedForCloneProfile(String authority) {
        // For now, only MediaProvider gets redirected.
        return MediaStore.AUTHORITY.equals(authority);
    }

    private Transport mTransport = new Transport();

    /**
@@ -726,13 +738,47 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
    }

    boolean checkUser(int pid, int uid, Context context) {
        if (UserHandle.getUserId(uid) == context.getUserId() || mSingleUser) {
        int callingUserId = UserHandle.getUserId(uid);

        if (callingUserId == context.getUserId() || mSingleUser) {
            return true;
        }
        return context.checkPermission(INTERACT_ACROSS_USERS, pid, uid)
        if (context.checkPermission(INTERACT_ACROSS_USERS, pid, uid)
                == PackageManager.PERMISSION_GRANTED
                || context.checkPermission(INTERACT_ACROSS_USERS_FULL, pid, uid)
                    == PackageManager.PERMISSION_GRANTED;
                == PackageManager.PERMISSION_GRANTED) {
            return true;
        }

        if (isAuthorityRedirectedForCloneProfile(mAuthority)) {
            if (mUsersRedirectedToOwner.indexOfKey(callingUserId) >= 0) {
                return mUsersRedirectedToOwner.get(callingUserId);
            }

            // Haven't seen this user yet, look it up
            try {
                UserHandle callingUser = UserHandle.getUserHandleForUid(uid);
                Context callingUserContext = mContext.createPackageContextAsUser("system",
                        0, callingUser);
                UserManager um = callingUserContext.getSystemService(UserManager.class);

                if (um != null && um.isCloneProfile()) {
                    UserHandle parent = um.getProfileParent(callingUser);

                    if (parent != null && parent.equals(context.getUser())) {
                        mUsersRedirectedToOwner.put(callingUser.getIdentifier(), true);
                        return true;
                    }
                }
            } catch (PackageManager.NameNotFoundException e) {
                // ignore
            }

            mUsersRedirectedToOwner.put(UserHandle.getUserId(uid), false);
            return false;
        }

        return false;
    }

    /**
+36 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.server.am;

import static android.content.ContentProvider.isAuthorityRedirectedForCloneProfile;
import static android.os.Process.PROC_CHAR;
import static android.os.Process.PROC_OUT_LONG;
import static android.os.Process.PROC_PARENS;
@@ -46,6 +47,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
@@ -72,6 +74,7 @@ import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.RescueParty;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.parsing.pkg.AndroidPackage;

import java.io.FileDescriptor;
@@ -177,12 +180,22 @@ public class ContentProviderHelper {
                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
                if (cpr != null) {
                    cpi = cpr.info;

                    if (mService.isSingleton(
                            cpi.processName, cpi.applicationInfo, cpi.name, cpi.flags)
                                && mService.isValidSingletonCall(
                                        r == null ? callingUid : r.uid, cpi.applicationInfo.uid)) {
                        userId = UserHandle.USER_SYSTEM;
                        checkCrossUser = false;
                    } else if (isAuthorityRedirectedForCloneProfile(name)) {
                        UserManagerInternal umInternal = LocalServices.getService(
                                UserManagerInternal.class);
                        UserInfo userInfo = umInternal.getUserInfo(userId);

                        if (userInfo != null && userInfo.isCloneProfile()) {
                            userId = umInternal.getProfileParentId(userId);
                            checkCrossUser = false;
                        }
                    } else {
                        cpr = null;
                        cpi = null;
@@ -1026,6 +1039,7 @@ public class ContentProviderHelper {
     * at the given authority and user.
     */
    String checkContentProviderAccess(String authority, int userId) {
        boolean checkUser = true;
        if (userId == UserHandle.USER_ALL) {
            mService.mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
@@ -1041,6 +1055,17 @@ public class ContentProviderHelper {
                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                    userId);
            if (cpi == null && isAuthorityRedirectedForCloneProfile(authority)) {
                // This might be a provider that's running only in the system user that's
                // also serving clone profiles
                cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
                        ActivityManagerService.STOCK_PM_FLAGS
                                | PackageManager.GET_URI_PERMISSION_PATTERNS
                                | PackageManager.MATCH_DISABLED_COMPONENTS
                                | PackageManager.MATCH_DIRECT_BOOT_AWARE
                                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                        UserHandle.USER_SYSTEM);
            }
        } catch (RemoteException ignored) {
        }
        if (cpi == null) {
@@ -1048,6 +1073,16 @@ public class ContentProviderHelper {
                    + "; expected to find a valid ContentProvider for this authority";
        }

        if (isAuthorityRedirectedForCloneProfile(authority)) {
            UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
            UserInfo userInfo = umInternal.getUserInfo(userId);

            if (userInfo != null && userInfo.isCloneProfile()) {
                userId = umInternal.getProfileParentId(userId);
                checkUser = false;
            }
        }

        final int callingPid = Binder.getCallingPid();
        ProcessRecord r;
        final String appName;
@@ -1060,7 +1095,7 @@ public class ContentProviderHelper {
        }

        return checkContentProviderPermission(cpi, callingPid, Binder.getCallingUid(),
                userId, true, appName);
                userId, checkUser, appName);
    }

    int checkContentProviderUriPermission(Uri uri, int userId, int callingUid, int modeFlags) {
+26 −9
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.Manifest.permission.DELETE_PACKAGES;
import static android.Manifest.permission.INSTALL_PACKAGES;
import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
import static android.content.ContentProvider.isAuthorityRedirectedForCloneProfile;
import static android.content.Intent.ACTION_MAIN;
import static android.content.Intent.CATEGORY_DEFAULT;
import static android.content.Intent.CATEGORY_HOME;
@@ -92,14 +93,6 @@ import android.content.pm.SigningDetails;
import android.content.pm.SigningInfo;
import android.content.pm.UserInfo;
import android.content.pm.VersionedPackage;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedIntentInfo;
import com.android.server.pm.pkg.component.ParsedMainComponent;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.PackageUserStateUtils;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
@@ -142,6 +135,14 @@ import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.PackageStateUtils;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.PackageUserStateInternal;
import com.android.server.pm.pkg.PackageUserStateUtils;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedIntentInfo;
import com.android.server.pm.pkg.component.ParsedMainComponent;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import com.android.server.pm.verify.domain.DomainVerificationUtils;
import com.android.server.uri.UriGrantsManagerInternal;
@@ -4617,8 +4618,24 @@ public class ComputerEngine implements Computer {
            }
        }
        if (!checkedGrants) {
            enforceCrossUserPermission(callingUid, userId, false, false, "resolveContentProvider");
            boolean enforceCrossUser = true;

            if (isAuthorityRedirectedForCloneProfile(name)) {
                final UserManagerInternal umInternal = mInjector.getUserManagerInternal();

                UserInfo userInfo = umInternal.getUserInfo(UserHandle.getUserId(callingUid));
                if (userInfo != null && userInfo.isCloneProfile()
                        && userInfo.profileGroupId == userId) {
                    enforceCrossUser = false;
                }
            }

            if (enforceCrossUser) {
                enforceCrossUserPermission(callingUid, userId, false, false,
                        "resolveContentProvider");
            }
        }

        if (providerInfo == null) {
            return null;
        }