Move permission flag methods
Bug: 135279435 Test: atest android.content.pm.cts.PackageManagerTest Test: atest android.permission2.cts.RestrictedPermissionsTest Change-Id: I3a5a7d8d3a3ba9d0b3e0e62d178a18903a94ec26
This commit is contained in:
@@ -722,31 +722,32 @@ public class ApplicationPackageManager extends PackageManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
|
||||
public int getPermissionFlags(String permName, String packageName, UserHandle user) {
|
||||
try {
|
||||
return mPM.getPermissionFlags(permissionName, packageName, user.getIdentifier());
|
||||
return mPermissionManager
|
||||
.getPermissionFlags(permName, packageName, user.getIdentifier());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePermissionFlags(String permissionName, String packageName,
|
||||
public void updatePermissionFlags(String permName, String packageName,
|
||||
int flagMask, int flagValues, UserHandle user) {
|
||||
if (DEBUG_TRACE_GRANTS
|
||||
&& shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
|
||||
&& shouldTraceGrant(packageName, permName, user.getIdentifier())) {
|
||||
Log.i(TAG, "App " + mContext.getPackageName() + " is updating flags for "
|
||||
+ permissionName + " for user " + user.getIdentifier() + ": "
|
||||
+ permName + " for user " + user.getIdentifier() + ": "
|
||||
+ DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_", flagMask)
|
||||
+ " := " + DebugUtils.flagsToString(
|
||||
PackageManager.class, "FLAG_PERMISSION_", flagValues),
|
||||
new RuntimeException());
|
||||
}
|
||||
try {
|
||||
mPM.updatePermissionFlags(permissionName, packageName, flagMask,
|
||||
flagValues,
|
||||
mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q,
|
||||
user.getIdentifier());
|
||||
final boolean checkAdjustPolicyFlagPermission =
|
||||
mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q;
|
||||
mPermissionManager.updatePermissionFlags(permName, packageName, flagMask,
|
||||
flagValues, checkAdjustPolicyFlagPermission, user.getIdentifier());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -108,13 +108,6 @@ interface IPackageManager {
|
||||
|
||||
void resetRuntimePermissions();
|
||||
|
||||
int getPermissionFlags(String permissionName, String packageName, int userId);
|
||||
|
||||
void updatePermissionFlags(String permissionName, String packageName, int flagMask,
|
||||
int flagValues, boolean checkAdjustPolicyFlagPermission, int userId);
|
||||
|
||||
void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId);
|
||||
|
||||
List<String> getWhitelistedRestrictedPermissions(String packageName, int flags,
|
||||
int userId);
|
||||
|
||||
|
||||
@@ -742,17 +742,6 @@ public abstract class PackageManagerInternal {
|
||||
public abstract boolean filterAppAccess(
|
||||
@Nullable PackageParser.Package pkg, int callingUid, int userId);
|
||||
|
||||
/*
|
||||
* NOTE: The following methods are temporary until permissions are extracted from
|
||||
* the package manager into a component specifically for handling permissions.
|
||||
*/
|
||||
/** Returns the flags for the given permission. */
|
||||
public abstract @Nullable int getPermissionFlagsTEMP(@NonNull String permName,
|
||||
@NonNull String packageName, int userId);
|
||||
/** Updates the flags for the given permission. */
|
||||
public abstract void updatePermissionFlagsTEMP(@NonNull String permName,
|
||||
@NonNull String packageName, int flagMask, int flagValues, int userId);
|
||||
|
||||
/** Returns whether the given package was signed by the platform */
|
||||
public abstract boolean isPlatformSigned(String pkg);
|
||||
|
||||
@@ -1006,4 +995,22 @@ public abstract class PackageManagerInternal {
|
||||
* the settings have been written.
|
||||
*/
|
||||
public abstract void writeSettings(boolean async);
|
||||
|
||||
/**
|
||||
* Writes all permission settings for the given set of users to disk. If {@code async}
|
||||
* is {@code true}, the settings are written at some point in the future. Otherwise,
|
||||
* the call blocks until the settings have been written.
|
||||
*/
|
||||
public abstract void writePermissionSettings(@NonNull @UserIdInt int[] userIds, boolean async);
|
||||
|
||||
/**
|
||||
* Returns the target SDK for the given UID. Will return {@code 0} if there is no
|
||||
* package associated with the UID or if the package has not been installed for
|
||||
* the user. Will return the highest target SDK if the UID references packages with
|
||||
* a shared user id.
|
||||
*/
|
||||
public abstract int getTargetSdk(int uid);
|
||||
|
||||
/** HACK. Remove when listeners move to the permission manager */
|
||||
public abstract void onPermissionsChangedTEMP(int uid);
|
||||
}
|
||||
|
||||
@@ -39,4 +39,11 @@ interface IPermissionManager {
|
||||
boolean addPermission(in PermissionInfo info, boolean async);
|
||||
|
||||
void removePermission(String name);
|
||||
|
||||
int getPermissionFlags(String permName, String packageName, int userId);
|
||||
|
||||
void updatePermissionFlags(String permName, String packageName, int flagMask,
|
||||
int flagValues, boolean checkAdjustPolicyFlagPermission, int userId);
|
||||
|
||||
void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId);
|
||||
}
|
||||
|
||||
@@ -4569,55 +4569,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any package sharing/holding a uid has a low enough target SDK.
|
||||
*
|
||||
* @param uid The uid of the packages
|
||||
* @param higherTargetSDK The target SDK that might be higher than the searched package
|
||||
*
|
||||
* @return {@code true} if there is a package sharing/holding the uid with
|
||||
* {@code package.targetSDK < higherTargetSDK}
|
||||
*/
|
||||
private boolean hasTargetSdkInUidLowerThan(int uid, int higherTargetSDK) {
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
synchronized (mPackages) {
|
||||
Object obj = mSettings.getSettingLPr(UserHandle.getAppId(uid));
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj instanceof PackageSetting) {
|
||||
final PackageSetting ps = (PackageSetting) obj;
|
||||
|
||||
if (!ps.getInstalled(userId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ps.pkg.applicationInfo.targetSdkVersion < higherTargetSDK;
|
||||
} else if (obj instanceof SharedUserSetting) {
|
||||
final SharedUserSetting sus = (SharedUserSetting) obj;
|
||||
|
||||
final int numPkgs = sus.packages.size();
|
||||
for (int i = 0; i < numPkgs; i++) {
|
||||
final PackageSetting ps = sus.packages.valueAt(i);
|
||||
|
||||
if (!ps.getInstalled(userId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ps.pkg.applicationInfo.targetSdkVersion < higherTargetSDK) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getPackageGids(String packageName, int flags, int userId) {
|
||||
if (!sUserManager.exists(userId)) return null;
|
||||
@@ -5695,7 +5646,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final int flags = getPermissionFlags(permission, packageName, userId);
|
||||
final int flags = mPermissionManager
|
||||
.getPermissionFlags(permission, packageName, Binder.getCallingUid(), userId);
|
||||
return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
@@ -5798,63 +5750,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPermissionFlags(String permName, String packageName, int userId) {
|
||||
return mPermissionManager.getPermissionFlags(
|
||||
permName, packageName, getCallingUid(), userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePermissionFlags(String permName, String packageName, int flagMask,
|
||||
int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
|
||||
int callingUid = getCallingUid();
|
||||
boolean overridePolicy = false;
|
||||
|
||||
if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
|
||||
long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
|
||||
if (checkAdjustPolicyFlagPermission) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
|
||||
"Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
|
||||
+ " to change policy flags");
|
||||
} else if (!hasTargetSdkInUidLowerThan(callingUid, Build.VERSION_CODES.Q)) {
|
||||
throw new IllegalArgumentException(
|
||||
Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
|
||||
+ " to be checked for packages targeting "
|
||||
+ Build.VERSION_CODES.Q + " or later when changing policy "
|
||||
+ "flags");
|
||||
}
|
||||
|
||||
overridePolicy = true;
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(callingIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
mPermissionManager.updatePermissionFlags(
|
||||
permName, packageName, flagMask, flagValues, callingUid, userId,
|
||||
overridePolicy, mPermissionCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the permission flags for all packages and runtime permissions of a user in order
|
||||
* to allow device or profile owner to remove POLICY_FIXED.
|
||||
*/
|
||||
@Override
|
||||
public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
|
||||
synchronized (mPackages) {
|
||||
final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
|
||||
flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
|
||||
mPermissionCallback);
|
||||
if (changed) {
|
||||
mSettings.writeRuntimePermissionsForUserLPr(userId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
|
||||
@PermissionWhitelistFlags int whitelistFlags, @UserIdInt int userId) {
|
||||
@@ -6078,7 +5973,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldShowRequestPermissionRationale(String permissionName,
|
||||
public boolean shouldShowRequestPermissionRationale(String permName,
|
||||
String packageName, int userId) {
|
||||
if (UserHandle.getCallingUserId() != userId) {
|
||||
mContext.enforceCallingPermission(
|
||||
@@ -6091,7 +5986,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return false;
|
||||
}
|
||||
|
||||
if (checkPermission(permissionName, packageName, userId)
|
||||
if (checkPermission(permName, packageName, userId)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
return false;
|
||||
}
|
||||
@@ -6100,8 +5995,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
flags = getPermissionFlags(permissionName,
|
||||
packageName, userId);
|
||||
flags = mPermissionManager
|
||||
.getPermissionFlags(permName, packageName, Binder.getCallingUid(), userId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
@@ -24170,13 +24065,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
|
||||
private class PackageManagerInternalImpl extends PackageManagerInternal {
|
||||
@Override
|
||||
public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
|
||||
int flagValues, int userId) {
|
||||
PackageManagerService.this.updatePermissionFlags(
|
||||
permName, packageName, flagMask, flagValues, true, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
|
||||
int callingUid) {
|
||||
@@ -24257,11 +24145,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
|
||||
return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInstantApp(String packageName, int userId) {
|
||||
return PackageManagerService.this.isInstantApp(packageName, userId);
|
||||
@@ -25036,6 +24919,52 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePermissionSettings(int[] userIds, boolean async) {
|
||||
synchronized (mPackages) {
|
||||
for (int userId : userIds) {
|
||||
mSettings.writeRuntimePermissionsForUserLPr(userId, !async);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsChangedTEMP(int uid) {
|
||||
mOnPermissionChangeListeners.onPermissionsChanged(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTargetSdk(int uid) {
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
synchronized (mPackages) {
|
||||
final Object obj = mSettings.getSettingLPr(UserHandle.getAppId(uid));
|
||||
if (obj instanceof PackageSetting) {
|
||||
final PackageSetting ps = (PackageSetting) obj;
|
||||
if (!ps.getInstalled(userId)) {
|
||||
return 0;
|
||||
}
|
||||
return ps.pkg.applicationInfo.targetSdkVersion;
|
||||
} else if (obj instanceof SharedUserSetting) {
|
||||
int maxTargetSdk = 0;
|
||||
final SharedUserSetting sus = (SharedUserSetting) obj;
|
||||
final int numPkgs = sus.packages.size();
|
||||
for (int i = 0; i < numPkgs; i++) {
|
||||
final PackageSetting ps = sus.packages.valueAt(i);
|
||||
if (!ps.getInstalled(userId)) {
|
||||
continue;
|
||||
}
|
||||
if (ps.pkg.applicationInfo.targetSdkVersion < maxTargetSdk) {
|
||||
continue;
|
||||
}
|
||||
maxTargetSdk = ps.pkg.applicationInfo.targetSdkVersion;
|
||||
}
|
||||
return maxTargetSdk;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mPackages")
|
||||
|
||||
@@ -123,6 +123,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Manages all permissions and handles permissions related tasks.
|
||||
@@ -229,6 +230,56 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
final private ArrayList<OnRuntimePermissionStateChangedListener>
|
||||
mRuntimePermissionStateChangedListeners = new ArrayList<>();
|
||||
|
||||
// TODO: Take a look at the methods defined in the callback.
|
||||
// The callback was initially created to support the split between permission
|
||||
// manager and the package manager. However, it's started to be used for other
|
||||
// purposes. It may make sense to keep as an abstraction, but, the methods
|
||||
// necessary to be overridden may be different than what was initially needed
|
||||
// for the split.
|
||||
private PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
|
||||
@Override
|
||||
public void onGidsChanged(int appId, int userId) {
|
||||
// TODO: implement when methods have been fully migrated
|
||||
}
|
||||
@Override
|
||||
public void onPermissionGranted(int uid, int userId) {
|
||||
// TODO: implement when methods have been fully migrated
|
||||
}
|
||||
@Override
|
||||
public void onInstallPermissionGranted() {
|
||||
mPackageManagerInt.writeSettings(true);
|
||||
}
|
||||
@Override
|
||||
public void onPermissionRevoked(int uid, int userId) {
|
||||
// TODO: implement when methods have been fully migrated
|
||||
}
|
||||
@Override
|
||||
public void onInstallPermissionRevoked() {
|
||||
mPackageManagerInt.writeSettings(true);
|
||||
}
|
||||
@Override
|
||||
public void onPermissionUpdated(int[] userIds, boolean sync) {
|
||||
mPackageManagerInt.writePermissionSettings(userIds, !sync);
|
||||
}
|
||||
@Override
|
||||
public void onInstallPermissionUpdated() {
|
||||
mPackageManagerInt.writeSettings(true);
|
||||
}
|
||||
@Override
|
||||
public void onPermissionRemoved() {
|
||||
mPackageManagerInt.writeSettings(false);
|
||||
}
|
||||
public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
|
||||
int uid) {
|
||||
onPermissionUpdated(updatedUserIds, sync);
|
||||
mPackageManagerInt.onPermissionsChangedTEMP(uid);
|
||||
}
|
||||
public void onInstallPermissionUpdatedNotifyListener(int uid) {
|
||||
onInstallPermissionUpdated();
|
||||
mPackageManagerInt.onPermissionsChangedTEMP(uid);
|
||||
}
|
||||
};
|
||||
|
||||
PermissionManagerService(Context context,
|
||||
@NonNull Object externalLock) {
|
||||
mContext = context;
|
||||
@@ -456,6 +507,209 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPermissionFlags(String permName, String packageName, int userId) {
|
||||
final int callingUid = getCallingUid();
|
||||
return getPermissionFlagsInternal(permName, packageName, callingUid, userId);
|
||||
}
|
||||
|
||||
private int getPermissionFlagsInternal(
|
||||
String permName, String packageName, int callingUid, int userId) {
|
||||
if (!mUserManagerInt.exists(userId)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
false, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"getPermissionFlags");
|
||||
|
||||
final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
|
||||
if (pkg == null || pkg.mExtras == null) {
|
||||
return 0;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
if (mSettings.getPermissionLocked(permName) == null) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
|
||||
return 0;
|
||||
}
|
||||
final PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||
PermissionsState permissionsState = ps.getPermissionsState();
|
||||
return permissionsState.getPermissionFlags(permName, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePermissionFlags(String permName, String packageName, int flagMask,
|
||||
int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
|
||||
final int callingUid = getCallingUid();
|
||||
boolean overridePolicy = false;
|
||||
|
||||
if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
|
||||
long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
|
||||
if (checkAdjustPolicyFlagPermission) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
|
||||
"Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
|
||||
+ " to change policy flags");
|
||||
} else if (mPackageManagerInt.getTargetSdk(callingUid)
|
||||
>= Build.VERSION_CODES.Q) {
|
||||
throw new IllegalArgumentException(
|
||||
Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
|
||||
+ " to be checked for packages targeting "
|
||||
+ Build.VERSION_CODES.Q + " or later when changing policy "
|
||||
+ "flags");
|
||||
}
|
||||
overridePolicy = true;
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(callingIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
updatePermissionFlagsInternal(
|
||||
permName, packageName, flagMask, flagValues, callingUid, userId,
|
||||
overridePolicy, mDefaultPermissionCallback);
|
||||
}
|
||||
|
||||
private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
|
||||
int flagValues, int callingUid, int userId, boolean overridePolicy,
|
||||
PermissionCallback callback) {
|
||||
if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
|
||||
&& ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
|
||||
Log.i(TAG, "System is updating flags for "
|
||||
+ permName + " for user " + userId + " "
|
||||
+ DebugUtils.flagsToString(
|
||||
PackageManager.class, "FLAG_PERMISSION_", flagMask)
|
||||
+ " := "
|
||||
+ DebugUtils.flagsToString(
|
||||
PackageManager.class, "FLAG_PERMISSION_", flagValues)
|
||||
+ " on behalf of uid " + callingUid
|
||||
+ " " + mPackageManagerInt.getNameForUid(callingUid),
|
||||
new RuntimeException());
|
||||
}
|
||||
|
||||
if (!mUserManagerInt.exists(userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
|
||||
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
true, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"updatePermissionFlags");
|
||||
|
||||
if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
|
||||
throw new SecurityException("updatePermissionFlags requires "
|
||||
+ Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
|
||||
}
|
||||
|
||||
// Only the system can change these flags and nothing else.
|
||||
if (callingUid != Process.SYSTEM_UID) {
|
||||
flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
|
||||
}
|
||||
|
||||
final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
|
||||
if (pkg == null || pkg.mExtras == null) {
|
||||
Log.e(TAG, "Unknown package: " + packageName);
|
||||
return;
|
||||
}
|
||||
if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
|
||||
throw new IllegalArgumentException("Unknown package: " + packageName);
|
||||
}
|
||||
|
||||
final BasePermission bp;
|
||||
synchronized (mLock) {
|
||||
bp = mSettings.getPermissionLocked(permName);
|
||||
}
|
||||
if (bp == null) {
|
||||
throw new IllegalArgumentException("Unknown permission: " + permName);
|
||||
}
|
||||
|
||||
final PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||
final PermissionsState permissionsState = ps.getPermissionsState();
|
||||
final boolean hadState =
|
||||
permissionsState.getRuntimePermissionState(permName, userId) != null;
|
||||
final boolean permissionUpdated =
|
||||
permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
|
||||
if (permissionUpdated && bp.isRuntime()) {
|
||||
notifyRuntimePermissionStateChanged(packageName, userId);
|
||||
}
|
||||
if (permissionUpdated && callback != null) {
|
||||
// Install and runtime permissions are stored in different places,
|
||||
// so figure out what permission changed and persist the change.
|
||||
if (permissionsState.getInstallPermissionState(permName) != null) {
|
||||
callback.onInstallPermissionUpdatedNotifyListener(pkg.applicationInfo.uid);
|
||||
} else if (permissionsState.getRuntimePermissionState(permName, userId) != null
|
||||
|| hadState) {
|
||||
callback.onPermissionUpdatedNotifyListener(new int[] { userId }, false,
|
||||
pkg.applicationInfo.uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the permission flags for all packages and runtime permissions of a user in order
|
||||
* to allow device or profile owner to remove POLICY_FIXED.
|
||||
*/
|
||||
@Override
|
||||
public void updatePermissionFlagsForAllApps(int flagMask, int flagValues,
|
||||
final int userId) {
|
||||
final int callingUid = getCallingUid();
|
||||
if (!mUserManagerInt.exists(userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
enforceGrantRevokeRuntimePermissionPermissions(
|
||||
"updatePermissionFlagsForAllApps");
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
true, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"updatePermissionFlagsForAllApps");
|
||||
|
||||
// Only the system can change system fixed flags.
|
||||
final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID)
|
||||
? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID)
|
||||
? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
|
||||
final boolean[] changed = new boolean[1];
|
||||
mPackageManagerInt.forEachPackage(new Consumer<PackageParser.Package>() {
|
||||
@Override
|
||||
public void accept(Package pkg) {
|
||||
final PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||
if (ps == null) {
|
||||
return;
|
||||
}
|
||||
final PermissionsState permissionsState = ps.getPermissionsState();
|
||||
changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
|
||||
userId, effectiveFlagMask, effectiveFlagValues);
|
||||
mPackageManagerInt.onPermissionsChangedTEMP(pkg.applicationInfo.uid);
|
||||
}
|
||||
});
|
||||
|
||||
if (changed[0]) {
|
||||
mPackageManagerInt.writePermissionSettings(new int[] { userId }, true);
|
||||
}
|
||||
}
|
||||
|
||||
private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
|
||||
if (!mUserManagerInt.exists(userId)) {
|
||||
return PackageManager.PERMISSION_DENIED;
|
||||
@@ -2102,7 +2356,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
// In permission review mode we clear the review flag when we
|
||||
// are asked to install the app with all permissions granted.
|
||||
if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
|
||||
updatePermissionFlags(permission, pkg.packageName,
|
||||
updatePermissionFlagsInternal(permission, pkg.packageName,
|
||||
PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
|
||||
userId, false, callback);
|
||||
}
|
||||
@@ -2454,7 +2708,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
|
||||
}
|
||||
|
||||
updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
|
||||
updatePermissionFlagsInternal(permissionName, pkg.packageName, mask, newFlags,
|
||||
callingUid, userId, false, null /*callback*/);
|
||||
}
|
||||
|
||||
@@ -2541,37 +2795,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
return runtimePermissionChangedUserIds;
|
||||
}
|
||||
|
||||
private int getPermissionFlags(
|
||||
String permName, String packageName, int callingUid, int userId) {
|
||||
if (!mUserManagerInt.exists(userId)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
|
||||
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
false, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"getPermissionFlags");
|
||||
|
||||
final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
|
||||
if (pkg == null || pkg.mExtras == null) {
|
||||
return 0;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
if (mSettings.getPermissionLocked(permName) == null) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
|
||||
return 0;
|
||||
}
|
||||
final PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||
PermissionsState permissionsState = ps.getPermissionsState();
|
||||
return permissionsState.getPermissionFlags(permName, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update permissions when a package changed.
|
||||
*
|
||||
@@ -2880,127 +3103,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
return changed;
|
||||
}
|
||||
|
||||
private void updatePermissionFlags(String permName, String packageName, int flagMask,
|
||||
int flagValues, int callingUid, int userId, boolean overridePolicy,
|
||||
PermissionCallback callback) {
|
||||
if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
|
||||
&& ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
|
||||
Log.i(TAG, "System is updating flags for "
|
||||
+ permName + " for user " + userId + " "
|
||||
+ DebugUtils.flagsToString(
|
||||
PackageManager.class, "FLAG_PERMISSION_", flagMask)
|
||||
+ " := "
|
||||
+ DebugUtils.flagsToString(
|
||||
PackageManager.class, "FLAG_PERMISSION_", flagValues)
|
||||
+ " on behalf of uid " + callingUid
|
||||
+ " " + mPackageManagerInt.getNameForUid(callingUid),
|
||||
new RuntimeException());
|
||||
}
|
||||
|
||||
if (!mUserManagerInt.exists(userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
|
||||
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
true, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"updatePermissionFlags");
|
||||
|
||||
if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
|
||||
throw new SecurityException("updatePermissionFlags requires "
|
||||
+ Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
|
||||
}
|
||||
|
||||
// Only the system can change these flags and nothing else.
|
||||
if (callingUid != Process.SYSTEM_UID) {
|
||||
flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
|
||||
}
|
||||
|
||||
final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
|
||||
if (pkg == null || pkg.mExtras == null) {
|
||||
Log.e(TAG, "Unknown package: " + packageName);
|
||||
return;
|
||||
}
|
||||
if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
|
||||
throw new IllegalArgumentException("Unknown package: " + packageName);
|
||||
}
|
||||
|
||||
final BasePermission bp;
|
||||
synchronized (mLock) {
|
||||
bp = mSettings.getPermissionLocked(permName);
|
||||
}
|
||||
if (bp == null) {
|
||||
throw new IllegalArgumentException("Unknown permission: " + permName);
|
||||
}
|
||||
|
||||
final PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||
final PermissionsState permissionsState = ps.getPermissionsState();
|
||||
final boolean hadState =
|
||||
permissionsState.getRuntimePermissionState(permName, userId) != null;
|
||||
final boolean permissionUpdated =
|
||||
permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
|
||||
if (permissionUpdated && bp.isRuntime()) {
|
||||
notifyRuntimePermissionStateChanged(packageName, userId);
|
||||
}
|
||||
if (permissionUpdated && callback != null) {
|
||||
// Install and runtime permissions are stored in different places,
|
||||
// so figure out what permission changed and persist the change.
|
||||
if (permissionsState.getInstallPermissionState(permName) != null) {
|
||||
callback.onInstallPermissionUpdatedNotifyListener(pkg.applicationInfo.uid);
|
||||
} else if (permissionsState.getRuntimePermissionState(permName, userId) != null
|
||||
|| hadState) {
|
||||
callback.onPermissionUpdatedNotifyListener(new int[] { userId }, false,
|
||||
pkg.applicationInfo.uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
|
||||
int userId, Collection<Package> packages, PermissionCallback callback) {
|
||||
if (!mUserManagerInt.exists(userId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
enforceGrantRevokeRuntimePermissionPermissions(
|
||||
"updatePermissionFlagsForAllApps");
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
true, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"updatePermissionFlagsForAllApps");
|
||||
|
||||
// Only the system can change system fixed flags.
|
||||
if (callingUid != Process.SYSTEM_UID) {
|
||||
flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
for (PackageParser.Package pkg : packages) {
|
||||
final PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||
if (ps == null) {
|
||||
continue;
|
||||
}
|
||||
PermissionsState permissionsState = ps.getPermissionsState();
|
||||
changed |= permissionsState.updatePermissionFlagsForAllPermissions(
|
||||
userId, flagMask, flagValues);
|
||||
callback.onPermissionUpdatedNotifyListener(new int[] { userId }, false,
|
||||
pkg.applicationInfo.uid);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
|
||||
if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
|
||||
!= PackageManager.PERMISSION_GRANTED
|
||||
@@ -3231,24 +3333,18 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
@Override
|
||||
public int getPermissionFlags(String permName, String packageName, int callingUid,
|
||||
int userId) {
|
||||
return PermissionManagerService.this.getPermissionFlags(permName, packageName,
|
||||
callingUid, userId);
|
||||
return PermissionManagerService.this
|
||||
.getPermissionFlagsInternal(permName, packageName, callingUid, userId);
|
||||
}
|
||||
@Override
|
||||
public void updatePermissionFlags(String permName, String packageName, int flagMask,
|
||||
int flagValues, int callingUid, int userId, boolean overridePolicy,
|
||||
PermissionCallback callback) {
|
||||
PermissionManagerService.this.updatePermissionFlags(
|
||||
PermissionManagerService.this.updatePermissionFlagsInternal(
|
||||
permName, packageName, flagMask, flagValues, callingUid, userId,
|
||||
overridePolicy, callback);
|
||||
}
|
||||
@Override
|
||||
public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
|
||||
int userId, Collection<Package> packages, PermissionCallback callback) {
|
||||
return PermissionManagerService.this.updatePermissionFlagsForAllApps(
|
||||
flagMask, flagValues, callingUid, userId, packages, callback);
|
||||
}
|
||||
@Override
|
||||
public void enforceCrossUserPermission(int callingUid, int userId,
|
||||
boolean requireFullPermission, boolean checkShell, String message) {
|
||||
PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
|
||||
|
||||
@@ -169,13 +169,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
|
||||
public abstract void updatePermissionFlags(@NonNull String permName,
|
||||
@NonNull String packageName, int flagMask, int flagValues, int callingUid, int userId,
|
||||
boolean overridePolicy, @Nullable PermissionCallback callback);
|
||||
/**
|
||||
* Updates the flags for all applications by replacing the flags in the specified mask
|
||||
* with the provided flag values.
|
||||
*/
|
||||
public abstract boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues,
|
||||
int callingUid, int userId, @NonNull Collection<PackageParser.Package> packages,
|
||||
@Nullable PermissionCallback callback);
|
||||
|
||||
public abstract int checkPermission(@NonNull String permName, @NonNull String packageName,
|
||||
int callingUid, int userId);
|
||||
|
||||
@@ -196,6 +196,7 @@ import android.os.UserManager;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.os.UserManagerInternal.UserRestrictionsListener;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.permission.IPermissionManager;
|
||||
import android.permission.PermissionControllerManager;
|
||||
import android.provider.CalendarContract;
|
||||
import android.provider.ContactsContract.QuickContact;
|
||||
@@ -492,6 +493,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
final Context mContext;
|
||||
final Injector mInjector;
|
||||
final IPackageManager mIPackageManager;
|
||||
final IPermissionManager mIPermissionManager;
|
||||
final UserManager mUserManager;
|
||||
final UserManagerInternal mUserManagerInternal;
|
||||
final UsageStatsManagerInternal mUsageStatsManagerInternal;
|
||||
@@ -1974,6 +1976,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
return AppGlobals.getPackageManager();
|
||||
}
|
||||
|
||||
IPermissionManager getIPermissionManager() {
|
||||
return AppGlobals.getPermissionManager();
|
||||
}
|
||||
|
||||
IBackupManager getIBackupManager() {
|
||||
return IBackupManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.BACKUP_SERVICE));
|
||||
@@ -2217,6 +2223,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
mUsageStatsManagerInternal = Preconditions.checkNotNull(
|
||||
injector.getUsageStatsManagerInternal());
|
||||
mIPackageManager = Preconditions.checkNotNull(injector.getIPackageManager());
|
||||
mIPermissionManager = Preconditions.checkNotNull(injector.getIPermissionManager());
|
||||
mTelephonyManager = Preconditions.checkNotNull(injector.getTelephonyManager());
|
||||
|
||||
mLocalService = new LocalService();
|
||||
@@ -8217,7 +8224,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
saveSettingsLocked(userId);
|
||||
|
||||
try {
|
||||
mIPackageManager.updatePermissionFlagsForAllApps(
|
||||
mIPermissionManager.updatePermissionFlagsForAllApps(
|
||||
PackageManager.FLAG_PERMISSION_POLICY_FIXED,
|
||||
0 /* flagValues */, userId);
|
||||
pushUserRestrictions(userId);
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.os.PowerManagerInternal;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.permission.IPermissionManager;
|
||||
import android.security.KeyChain;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.ArrayMap;
|
||||
@@ -198,6 +199,11 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
|
||||
return services.ipackageManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
IPermissionManager getIPermissionManager() {
|
||||
return services.ipermissionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
IBackupManager getIBackupManager() {
|
||||
return services.ibackupManager;
|
||||
|
||||
@@ -52,6 +52,7 @@ import android.os.PowerManagerInternal;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.permission.IPermissionManager;
|
||||
import android.provider.Settings;
|
||||
import android.security.KeyChain;
|
||||
import android.telephony.TelephonyManager;
|
||||
@@ -97,6 +98,7 @@ public class MockSystemServices {
|
||||
public ActivityManagerInternal activityManagerInternal;
|
||||
public ActivityTaskManagerInternal activityTaskManagerInternal;
|
||||
public final IPackageManager ipackageManager;
|
||||
public final IPermissionManager ipermissionManager;
|
||||
public final IBackupManager ibackupManager;
|
||||
public final IAudioService iaudioService;
|
||||
public final LockPatternUtils lockPatternUtils;
|
||||
@@ -137,6 +139,7 @@ public class MockSystemServices {
|
||||
activityManagerInternal = mock(ActivityManagerInternal.class);
|
||||
activityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
|
||||
ipackageManager = mock(IPackageManager.class);
|
||||
ipermissionManager = mock(IPermissionManager.class);
|
||||
ibackupManager = mock(IBackupManager.class);
|
||||
iaudioService = mock(IAudioService.class);
|
||||
lockPatternUtils = mock(LockPatternUtils.class);
|
||||
|
||||
Reference in New Issue
Block a user