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

Commit e71438ab authored by Hai Zhang's avatar Hai Zhang Committed by Android (Google) Code Review
Browse files

Merge "Refactor getAppOpPermissionPackages() as API."

parents 6e4c4a82 65d46e9b
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -29,8 +29,6 @@ import android.permission.IOnPermissionsChangeListener;
 * @hide
 */
interface IPermissionManager {
    String[] getAppOpPermissionPackages(String permName);

    ParceledListSlice getAllPermissionGroups(int flags);

    PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags);
+24 −35
Original line number Diff line number Diff line
@@ -22,24 +22,21 @@ import android.Manifest;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserManager;
import android.permission.IPermissionManager;
import android.util.Log;

import java.util.List;
import java.util.Arrays;

/**
 * Select which activity is the first visible activity of the installation and forward the intent to
@@ -49,16 +46,14 @@ public class InstallStart extends Activity {
    private static final String LOG_TAG = InstallStart.class.getSimpleName();

    private static final String DOWNLOADS_AUTHORITY = "downloads";
    private IPackageManager mIPackageManager;
    private IPermissionManager mIPermissionManager;
    private PackageManager mPackageManager;
    private UserManager mUserManager;
    private boolean mAbortInstall = false;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mIPackageManager = AppGlobals.getPackageManager();
        mIPermissionManager = AppGlobals.getPermissionManager();
        mPackageManager = getPackageManager();
        mUserManager = getSystemService(UserManager.class);
        Intent intent = getIntent();
        String callingPackage = getCallingPackage();
@@ -94,7 +89,7 @@ public class InstallStart extends Activity {
                Log.w(LOG_TAG, "Cannot get target sdk version for uid " + originatingUid);
                // Invalid originating uid supplied. Abort install.
                mAbortInstall = true;
            } else if (targetSdkVersion >= Build.VERSION_CODES.O && !declaresAppOpPermission(
            } else if (targetSdkVersion >= Build.VERSION_CODES.O && !isUidRequestingPermission(
                    originatingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES)) {
                Log.e(LOG_TAG, "Requesting uid " + originatingUid + " needs to declare permission "
                        + Manifest.permission.REQUEST_INSTALL_PACKAGES);
@@ -150,27 +145,25 @@ public class InstallStart extends Activity {
        finish();
    }

    private boolean declaresAppOpPermission(int uid, String permission) {
        try {
            final String[] packages = mIPermissionManager.getAppOpPermissionPackages(permission);
            if (packages == null) {
    private boolean isUidRequestingPermission(int uid, String permission) {
        final String[] packageNames = mPackageManager.getPackagesForUid(uid);
        if (packageNames == null) {
            return false;
        }
            final List<UserInfo> users = mUserManager.getUsers();
            for (String packageName : packages) {
                for (UserInfo user : users) {
        for (final String packageName : packageNames) {
            final PackageInfo packageInfo;
            try {
                        if (uid == getPackageManager().getPackageUidAsUser(packageName, user.id)) {
                            return true;
                        }
                packageInfo = mPackageManager.getPackageInfo(packageName,
                        PackageManager.GET_PERMISSIONS);
            } catch (PackageManager.NameNotFoundException e) {
                // Ignore and try the next package
                continue;
            }
            if (packageInfo.requestedPermissions != null
                    && Arrays.asList(packageInfo.requestedPermissions).contains(permission)) {
                return true;
            }
        }
        } catch (RemoteException rexc) {
            // If remote package manager cannot be reached, install will likely fail anyway.
        }
        return false;
    }

@@ -215,14 +208,10 @@ public class InstallStart extends Activity {
                return PackageInstaller.SessionParams.UID_UNKNOWN;
            }
        }
        try {
            if (mIPackageManager.checkUidPermission(Manifest.permission.MANAGE_DOCUMENTS,
                    callingUid) == PackageManager.PERMISSION_GRANTED) {
        if (checkPermission(Manifest.permission.MANAGE_DOCUMENTS, -1, callingUid)
                == PackageManager.PERMISSION_GRANTED) {
            return uidFromIntent;
        }
        } catch (RemoteException rexc) {
            // Ignore. Should not happen.
        }
        if (isSystemDownloadsProvider(callingUid)) {
            return uidFromIntent;
        }
+27 −23
Original line number Diff line number Diff line
@@ -6606,14 +6606,16 @@ public class PackageManagerService extends IPackageManager.Stub
    }
    // NOTE: Can't remove due to unsupported app usage
    @NonNull
    @Override
    public String[] getAppOpPermissionPackages(String permName) {
        try {
            // Because this is accessed via the package manager service AIDL,
            // go through the permission manager service AIDL
            return mPermissionManagerService.getAppOpPermissionPackages(permName);
        } catch (RemoteException ignore) { }
        return null;
    public String[] getAppOpPermissionPackages(String permissionName) {
        if (permissionName == null) {
            return EmptyArray.STRING;
        }
        if (getInstantAppPackageName(getCallingUid()) != null) {
            return EmptyArray.STRING;
        }
        return mPermissionManager.getAppOpPermissionPackages(permissionName);
    }
    @Override
@@ -26121,28 +26123,30 @@ public class PackageManagerService extends IPackageManager.Stub
            throw new SecurityException(
                    "Caller uid " + callingUid + " does not own package " + packageName);
        }
        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
        if (info == null) {
        if (isInstantApp(packageName, userId)) {
            return false;
        }
        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
        synchronized (mLock) {
            final AndroidPackage pkg = mPackages.get(packageName);
            if (pkg == null) {
                return false;
            }
        if (isInstantApp(packageName, userId)) {
            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
                return false;
            }
        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
        String[] packagesDeclaringPermission =
                mPermissionManager.getAppOpPermissionPackages(appOpPermission, callingUid);
        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
            if (!pkg.getRequestedPermissions().contains(
                    android.Manifest.permission.REQUEST_INSTALL_PACKAGES)) {
                final String message = "Need to declare "
                        + android.Manifest.permission.REQUEST_INSTALL_PACKAGES
                        + " to call this api";
                if (throwIfPermNotDeclared) {
                throw new SecurityException("Need to declare " + appOpPermission
                        + " to call this api");
                    throw new SecurityException(message);
                } else {
                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
                    Slog.e(TAG, message);
                    return false;
                }
            }
        }
        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
                  || mUserManager.hasUserRestriction(
                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
+13 −18
Original line number Diff line number Diff line
@@ -582,21 +582,15 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        }
    }

    @Override
    public String[] getAppOpPermissionPackages(String permName) {
        return getAppOpPermissionPackagesInternal(permName, getCallingUid());
    }

    private String[] getAppOpPermissionPackagesInternal(String permName, int callingUid) {
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
        }
    @NonNull
    private String[] getAppOpPermissionPackagesInternal(@NonNull String permissionName) {
        synchronized (mLock) {
            final ArraySet<String> pkgs = mRegistry.getAppOpPermissionPackages(permName);
            if (pkgs == null) {
                return null;
            final ArraySet<String> packageNames = mRegistry.getAppOpPermissionPackages(
                    permissionName);
            if (packageNames == null) {
                return EmptyArray.STRING;
            }
            return pkgs.toArray(new String[pkgs.size()]);
            return packageNames.toArray(new String[0]);
        }
    }

@@ -5062,6 +5056,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        public int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId) {
            return PermissionManagerService.this.getPermissionGids(permissionName, userId);
        }
        @NonNull
        @Override
        public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
            Objects.requireNonNull(permissionName, "permissionName");
            return PermissionManagerService.this.getAppOpPermissionPackagesInternal(permissionName);
        }
        @Override
        public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
                String[] grantedPermissions, int callingUid) {
@@ -5107,11 +5107,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                    (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
        }
        @Override
        public String[] getAppOpPermissionPackages(String permName, int callingUid) {
            return PermissionManagerService.this
                    .getAppOpPermissionPackagesInternal(permName, callingUid);
        }
        @Override
        public void enforceCrossUserPermission(int callingUid, int userId,
                boolean requireFullPermission, boolean checkShell, String message) {
            PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
+9 −3
Original line number Diff line number Diff line
@@ -338,9 +338,15 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
    @Nullable
    public abstract int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId);

    /** Retrieve the packages that have requested the given app op permission */
    public abstract @Nullable String[] getAppOpPermissionPackages(
            @NonNull String permName, int callingUid);
    /**
     * Get the packages that have requested an app op permission.
     *
     * @param permissionName the name of the app op permission
     * @return the names of the packages that have requested the app op permission
     */
    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
    @NonNull
    public abstract String[] getAppOpPermissionPackages(@NonNull String permissionName);

    /**
     * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS