Merge "Reset mode for app op permission when app no longer requests it." into rvc-dev
This commit is contained in:
@@ -4639,11 +4639,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtection(
|
public @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtection(
|
||||||
@PermissionInfo.Protection int protection) {
|
@PermissionInfo.Protection int protection) {
|
||||||
ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
|
ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
|
||||||
|
|
||||||
synchronized (PermissionManagerService.this.mLock) {
|
synchronized (mLock) {
|
||||||
int numTotalPermissions = mSettings.mPermissions.size();
|
int numTotalPermissions = mSettings.mPermissions.size();
|
||||||
|
|
||||||
for (int i = 0; i < numTotalPermissions; i++) {
|
for (int i = 0; i < numTotalPermissions; i++) {
|
||||||
@@ -4659,6 +4659,28 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
|||||||
return matchingPermissions;
|
return matchingPermissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||||
|
@PermissionInfo.ProtectionFlags int protectionFlags) {
|
||||||
|
ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
|
||||||
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
int numTotalPermissions = mSettings.mPermissions.size();
|
||||||
|
|
||||||
|
for (int i = 0; i < numTotalPermissions; i++) {
|
||||||
|
BasePermission bp = mSettings.mPermissions.valueAt(i);
|
||||||
|
|
||||||
|
if (bp.perm != null && (bp.perm.getProtectionFlags() & protectionFlags)
|
||||||
|
== protectionFlags) {
|
||||||
|
matchingPermissions.add(
|
||||||
|
PackageInfoUtils.generatePermissionInfo(bp.perm, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchingPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
|
public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
|
||||||
return PermissionManagerService.this.backupRuntimePermissions(user);
|
return PermissionManagerService.this.backupRuntimePermissions(user);
|
||||||
|
|||||||
@@ -302,10 +302,14 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
|
|||||||
/** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
|
/** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
|
||||||
public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
|
public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
|
||||||
|
|
||||||
/** Get all permission that have a certain protection level */
|
/** Get all permissions that have a certain protection */
|
||||||
public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtection(
|
public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtection(
|
||||||
@PermissionInfo.Protection int protection);
|
@PermissionInfo.Protection int protection);
|
||||||
|
|
||||||
|
/** Get all permissions that have certain protection flags */
|
||||||
|
public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags(
|
||||||
|
@PermissionInfo.ProtectionFlags int protectionFlags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the delegate used to influence permission checking.
|
* Returns the delegate used to influence permission checking.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
|||||||
import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback;
|
import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -112,6 +113,15 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final ArraySet<Pair<String, Integer>> mIsPackageSyncsScheduled = new ArraySet<>();
|
private final ArraySet<Pair<String, Integer>> mIsPackageSyncsScheduled = new ArraySet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether an async {@link #resetAppOpPermissionsIfNotRequestedForUid} is currently
|
||||||
|
* scheduled for a uid.
|
||||||
|
*/
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private final SparseBooleanArray mIsUidSyncScheduled = new SparseBooleanArray();
|
||||||
|
|
||||||
|
private List<String> mAppOpPermissions;
|
||||||
|
|
||||||
public PermissionPolicyService(@NonNull Context context) {
|
public PermissionPolicyService(@NonNull Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
@@ -122,7 +132,7 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
public void onStart() {
|
public void onStart() {
|
||||||
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
|
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
|
||||||
PackageManagerInternal.class);
|
PackageManagerInternal.class);
|
||||||
final PermissionManagerServiceInternal permManagerInternal = LocalServices.getService(
|
final PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
|
||||||
PermissionManagerServiceInternal.class);
|
PermissionManagerServiceInternal.class);
|
||||||
final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
|
final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.APP_OPS_SERVICE));
|
ServiceManager.getService(Context.APP_OPS_SERVICE));
|
||||||
@@ -130,38 +140,44 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
packageManagerInternal.getPackageList(new PackageListObserver() {
|
packageManagerInternal.getPackageList(new PackageListObserver() {
|
||||||
@Override
|
@Override
|
||||||
public void onPackageAdded(String packageName, int uid) {
|
public void onPackageAdded(String packageName, int uid) {
|
||||||
onPackageChanged(packageName, uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPackageChanged(String packageName, int uid) {
|
|
||||||
final int userId = UserHandle.getUserId(uid);
|
final int userId = UserHandle.getUserId(uid);
|
||||||
|
|
||||||
if (isStarted(userId)) {
|
if (isStarted(userId)) {
|
||||||
synchronizePackagePermissionsAndAppOpsForUser(packageName, userId);
|
synchronizePackagePermissionsAndAppOpsForUser(packageName, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPackageChanged(String packageName, int uid) {
|
||||||
|
final int userId = UserHandle.getUserId(uid);
|
||||||
|
if (isStarted(userId)) {
|
||||||
|
synchronizePackagePermissionsAndAppOpsForUser(packageName, userId);
|
||||||
|
resetAppOpPermissionsIfNotRequestedForUid(uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPackageRemoved(String packageName, int uid) {
|
public void onPackageRemoved(String packageName, int uid) {
|
||||||
/* do nothing */
|
final int userId = UserHandle.getUserId(uid);
|
||||||
|
if (isStarted(userId)) {
|
||||||
|
resetAppOpPermissionsIfNotRequestedForUid(uid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
permManagerInternal.addOnRuntimePermissionStateChangedListener(
|
permissionManagerInternal.addOnRuntimePermissionStateChangedListener(
|
||||||
this::synchronizePackagePermissionsAndAppOpsAsyncForUser);
|
this::synchronizePackagePermissionsAndAppOpsAsyncForUser);
|
||||||
|
|
||||||
mAppOpsCallback = new IAppOpsCallback.Stub() {
|
mAppOpsCallback = new IAppOpsCallback.Stub() {
|
||||||
public void opChanged(int op, int uid, String packageName) {
|
public void opChanged(int op, int uid, String packageName) {
|
||||||
synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName,
|
synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName,
|
||||||
UserHandle.getUserId(uid));
|
UserHandle.getUserId(uid));
|
||||||
|
resetAppOpPermissionsIfNotRequestedForUidAsync(uid);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
final ArrayList<PermissionInfo> dangerousPerms =
|
final ArrayList<PermissionInfo> dangerousPerms =
|
||||||
permManagerInternal.getAllPermissionWithProtection(
|
permissionManagerInternal.getAllPermissionsWithProtection(
|
||||||
PermissionInfo.PROTECTION_DANGEROUS);
|
PermissionInfo.PROTECTION_DANGEROUS);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int numDangerousPerms = dangerousPerms.size();
|
int numDangerousPerms = dangerousPerms.size();
|
||||||
for (int i = 0; i < numDangerousPerms; i++) {
|
for (int i = 0; i < numDangerousPerms; i++) {
|
||||||
@@ -184,6 +200,26 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
Slog.wtf(LOG_TAG, "Cannot set up app-ops listener");
|
Slog.wtf(LOG_TAG, "Cannot set up app-ops listener");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<PermissionInfo> appOpPermissionInfos =
|
||||||
|
permissionManagerInternal.getAllPermissionsWithProtectionFlags(
|
||||||
|
PermissionInfo.PROTECTION_FLAG_APPOP);
|
||||||
|
mAppOpPermissions = new ArrayList<>();
|
||||||
|
final int appOpPermissionInfosSize = appOpPermissionInfos.size();
|
||||||
|
for (int i = 0; i < appOpPermissionInfosSize; i++) {
|
||||||
|
final PermissionInfo appOpPermissionInfo = appOpPermissionInfos.get(i);
|
||||||
|
|
||||||
|
final int appOpCode = AppOpsManager.permissionToOpCode(appOpPermissionInfo.name);
|
||||||
|
if (appOpCode != OP_NONE) {
|
||||||
|
mAppOpPermissions.add(appOpPermissionInfo.name);
|
||||||
|
|
||||||
|
try {
|
||||||
|
appOpsService.startWatchingMode(appOpCode, null, mAppOpsCallback);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.wtf(LOG_TAG, "Cannot set up app-ops listener", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
||||||
intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
|
intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
|
||||||
@@ -491,6 +527,70 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
synchronizer.syncPackages();
|
synchronizer.syncPackages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetAppOpPermissionsIfNotRequestedForUidAsync(int uid) {
|
||||||
|
if (isStarted(UserHandle.getUserId(uid))) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (!mIsUidSyncScheduled.get(uid)) {
|
||||||
|
mIsUidSyncScheduled.put(uid, true);
|
||||||
|
FgThread.getHandler().sendMessage(PooledLambda.obtainMessage(
|
||||||
|
PermissionPolicyService::resetAppOpPermissionsIfNotRequestedForUid,
|
||||||
|
this, uid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetAppOpPermissionsIfNotRequestedForUid(int uid) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mIsUidSyncScheduled.delete(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Context context = getContext();
|
||||||
|
final PackageManager userPackageManager = getUserContext(context,
|
||||||
|
UserHandle.getUserHandleForUid(uid)).getPackageManager();
|
||||||
|
final String[] packageNames = userPackageManager.getPackagesForUid(uid);
|
||||||
|
if (packageNames == null || packageNames.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ArraySet<String> requestedPermissions = new ArraySet<>();
|
||||||
|
for (String packageName : packageNames) {
|
||||||
|
final PackageInfo packageInfo;
|
||||||
|
try {
|
||||||
|
packageInfo = userPackageManager.getPackageInfo(packageName, GET_PERMISSIONS);
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (packageInfo == null || packageInfo.requestedPermissions == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Collections.addAll(requestedPermissions, packageInfo.requestedPermissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
|
||||||
|
final AppOpsManagerInternal appOpsManagerInternal = LocalServices.getService(
|
||||||
|
AppOpsManagerInternal.class);
|
||||||
|
final int appOpPermissionsSize = mAppOpPermissions.size();
|
||||||
|
for (int i = 0; i < appOpPermissionsSize; i++) {
|
||||||
|
final String appOpPermission = mAppOpPermissions.get(i);
|
||||||
|
|
||||||
|
if (!requestedPermissions.contains(appOpPermission)) {
|
||||||
|
final int appOpCode = AppOpsManager.permissionToOpCode(appOpPermission);
|
||||||
|
final int defaultAppOpMode = AppOpsManager.opToDefaultMode(appOpCode);
|
||||||
|
for (String packageName : packageNames) {
|
||||||
|
final int appOpMode = appOpsManager.unsafeCheckOpRawNoThrow(appOpCode, uid,
|
||||||
|
packageName);
|
||||||
|
if (appOpMode != defaultAppOpMode) {
|
||||||
|
appOpsManagerInternal.setUidModeFromPermissionPolicy(appOpCode, uid,
|
||||||
|
defaultAppOpMode, mAppOpsCallback);
|
||||||
|
appOpsManagerInternal.setModeFromPermissionPolicy(appOpCode, uid,
|
||||||
|
packageName, defaultAppOpMode, mAppOpsCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronizes permission to app ops. You *must* always sync all packages
|
* Synchronizes permission to app ops. You *must* always sync all packages
|
||||||
* in a shared UID at the same time to ensure proper synchronization.
|
* in a shared UID at the same time to ensure proper synchronization.
|
||||||
@@ -545,7 +645,7 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
|
PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
|
||||||
PermissionManagerServiceInternal.class);
|
PermissionManagerServiceInternal.class);
|
||||||
List<PermissionInfo> permissionInfos =
|
List<PermissionInfo> permissionInfos =
|
||||||
permissionManagerInternal.getAllPermissionWithProtection(
|
permissionManagerInternal.getAllPermissionsWithProtection(
|
||||||
PermissionInfo.PROTECTION_DANGEROUS);
|
PermissionInfo.PROTECTION_DANGEROUS);
|
||||||
int permissionInfosSize = permissionInfos.size();
|
int permissionInfosSize = permissionInfos.size();
|
||||||
for (int i = 0; i < permissionInfosSize; i++) {
|
for (int i = 0; i < permissionInfosSize; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user