Loading services/core/java/com/android/server/pm/permission/PermissionManagerService.java +24 −2 Original line number Diff line number Diff line Loading @@ -4639,11 +4639,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtection( public @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtection( @PermissionInfo.Protection int protection) { ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>(); synchronized (PermissionManagerService.this.mLock) { synchronized (mLock) { int numTotalPermissions = mSettings.mPermissions.size(); for (int i = 0; i < numTotalPermissions; i++) { Loading @@ -4659,6 +4659,28 @@ public class PermissionManagerService extends IPermissionManager.Stub { 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 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) { return PermissionManagerService.this.backupRuntimePermissions(user); Loading services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +6 −2 Original line number Diff line number Diff line Loading @@ -302,10 +302,14 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */ public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName); /** Get all permission that have a certain protection level */ public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtection( /** Get all permissions that have a certain protection */ public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtection( @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. * Loading services/core/java/com/android/server/policy/PermissionPolicyService.java +108 −8 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; Loading Loading @@ -112,6 +113,15 @@ public final class PermissionPolicyService extends SystemService { @GuardedBy("mLock") 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) { super(context); Loading @@ -122,7 +132,7 @@ public final class PermissionPolicyService extends SystemService { public void onStart() { final PackageManagerInternal packageManagerInternal = LocalServices.getService( PackageManagerInternal.class); final PermissionManagerServiceInternal permManagerInternal = LocalServices.getService( final PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService( PermissionManagerServiceInternal.class); final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface( ServiceManager.getService(Context.APP_OPS_SERVICE)); Loading @@ -130,38 +140,44 @@ public final class PermissionPolicyService extends SystemService { packageManagerInternal.getPackageList(new PackageListObserver() { @Override public void onPackageAdded(String packageName, int uid) { onPackageChanged(packageName, uid); final int userId = UserHandle.getUserId(uid); if (isStarted(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 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); mAppOpsCallback = new IAppOpsCallback.Stub() { public void opChanged(int op, int uid, String packageName) { synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName, UserHandle.getUserId(uid)); resetAppOpPermissionsIfNotRequestedForUidAsync(uid); } }; final ArrayList<PermissionInfo> dangerousPerms = permManagerInternal.getAllPermissionWithProtection( permissionManagerInternal.getAllPermissionsWithProtection( PermissionInfo.PROTECTION_DANGEROUS); try { int numDangerousPerms = dangerousPerms.size(); for (int i = 0; i < numDangerousPerms; i++) { Loading @@ -184,6 +200,26 @@ public final class PermissionPolicyService extends SystemService { 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.addAction(Intent.ACTION_PACKAGE_ADDED); intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); Loading Loading @@ -491,6 +527,70 @@ public final class PermissionPolicyService extends SystemService { 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 * in a shared UID at the same time to ensure proper synchronization. Loading Loading @@ -545,7 +645,7 @@ public final class PermissionPolicyService extends SystemService { PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService( PermissionManagerServiceInternal.class); List<PermissionInfo> permissionInfos = permissionManagerInternal.getAllPermissionWithProtection( permissionManagerInternal.getAllPermissionsWithProtection( PermissionInfo.PROTECTION_DANGEROUS); int permissionInfosSize = permissionInfos.size(); for (int i = 0; i < permissionInfosSize; i++) { Loading Loading
services/core/java/com/android/server/pm/permission/PermissionManagerService.java +24 −2 Original line number Diff line number Diff line Loading @@ -4639,11 +4639,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtection( public @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtection( @PermissionInfo.Protection int protection) { ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>(); synchronized (PermissionManagerService.this.mLock) { synchronized (mLock) { int numTotalPermissions = mSettings.mPermissions.size(); for (int i = 0; i < numTotalPermissions; i++) { Loading @@ -4659,6 +4659,28 @@ public class PermissionManagerService extends IPermissionManager.Stub { 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 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) { return PermissionManagerService.this.backupRuntimePermissions(user); Loading
services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +6 −2 Original line number Diff line number Diff line Loading @@ -302,10 +302,14 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */ public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName); /** Get all permission that have a certain protection level */ public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtection( /** Get all permissions that have a certain protection */ public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtection( @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. * Loading
services/core/java/com/android/server/policy/PermissionPolicyService.java +108 −8 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; Loading Loading @@ -112,6 +113,15 @@ public final class PermissionPolicyService extends SystemService { @GuardedBy("mLock") 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) { super(context); Loading @@ -122,7 +132,7 @@ public final class PermissionPolicyService extends SystemService { public void onStart() { final PackageManagerInternal packageManagerInternal = LocalServices.getService( PackageManagerInternal.class); final PermissionManagerServiceInternal permManagerInternal = LocalServices.getService( final PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService( PermissionManagerServiceInternal.class); final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface( ServiceManager.getService(Context.APP_OPS_SERVICE)); Loading @@ -130,38 +140,44 @@ public final class PermissionPolicyService extends SystemService { packageManagerInternal.getPackageList(new PackageListObserver() { @Override public void onPackageAdded(String packageName, int uid) { onPackageChanged(packageName, uid); final int userId = UserHandle.getUserId(uid); if (isStarted(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 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); mAppOpsCallback = new IAppOpsCallback.Stub() { public void opChanged(int op, int uid, String packageName) { synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName, UserHandle.getUserId(uid)); resetAppOpPermissionsIfNotRequestedForUidAsync(uid); } }; final ArrayList<PermissionInfo> dangerousPerms = permManagerInternal.getAllPermissionWithProtection( permissionManagerInternal.getAllPermissionsWithProtection( PermissionInfo.PROTECTION_DANGEROUS); try { int numDangerousPerms = dangerousPerms.size(); for (int i = 0; i < numDangerousPerms; i++) { Loading @@ -184,6 +200,26 @@ public final class PermissionPolicyService extends SystemService { 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.addAction(Intent.ACTION_PACKAGE_ADDED); intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); Loading Loading @@ -491,6 +527,70 @@ public final class PermissionPolicyService extends SystemService { 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 * in a shared UID at the same time to ensure proper synchronization. Loading Loading @@ -545,7 +645,7 @@ public final class PermissionPolicyService extends SystemService { PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService( PermissionManagerServiceInternal.class); List<PermissionInfo> permissionInfos = permissionManagerInternal.getAllPermissionWithProtection( permissionManagerInternal.getAllPermissionsWithProtection( PermissionInfo.PROTECTION_DANGEROUS); int permissionInfosSize = permissionInfos.size(); for (int i = 0; i < permissionInfosSize; i++) { Loading