Loading core/java/android/app/AppOpsManagerInternal.java +6 −0 Original line number Diff line number Diff line Loading @@ -209,4 +209,10 @@ public abstract class AppOpsManagerInternal { */ public abstract void setModeFromPermissionPolicy(int code, int uid, @NonNull String packageName, int mode, @Nullable IAppOpsCallback callback); /** * Sets a global restriction on an op code. */ public abstract void setGlobalRestriction(int code, boolean restricted, IBinder token); } core/java/com/android/internal/app/IAppOpsService.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ interface IAppOpsService { void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle); void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in PackageTagsList excludedPackageTags); void removeUser(int userHandle); void startWatchingActive(in int[] ops, IAppOpsActiveCallback callback); Loading services/core/java/com/android/server/SensorPrivacyService.java +38 −27 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA; import static android.app.AppOpsManager.OP_PHONE_CALL_MICROPHONE; import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD; import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.pm.PackageManager.PERMISSION_GRANTED; Loading @@ -47,6 +46,7 @@ import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.AppOpsManager; import android.app.AppOpsManagerInternal; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationChannel; Loading Loading @@ -163,6 +163,7 @@ public final class SensorPrivacyService extends SystemService { private final ActivityManagerInternal mActivityManagerInternal; private final ActivityTaskManager mActivityTaskManager; private final AppOpsManager mAppOpsManager; private final AppOpsManagerInternal mAppOpsManagerInternal; private final TelephonyManager mTelephonyManager; private final IBinder mAppOpsRestrictionToken = new Binder(); Loading @@ -172,16 +173,18 @@ public final class SensorPrivacyService extends SystemService { private EmergencyCallHelper mEmergencyCallHelper; private KeyguardManager mKeyguardManager; private int mCurrentUser = -1; public SensorPrivacyService(Context context) { super(context); mContext = context; mAppOpsManager = context.getSystemService(AppOpsManager.class); mAppOpsManagerInternal = getLocalService(AppOpsManagerInternal.class); mUserManagerInternal = getLocalService(UserManagerInternal.class); mActivityManager = context.getSystemService(ActivityManager.class); mActivityManagerInternal = getLocalService(ActivityManagerInternal.class); mActivityTaskManager = context.getSystemService(ActivityTaskManager.class); mTelephonyManager = context.getSystemService(TelephonyManager.class); mSensorPrivacyServiceImpl = new SensorPrivacyServiceImpl(); } Loading @@ -201,6 +204,20 @@ public final class SensorPrivacyService extends SystemService { } } @Override public void onUserStarting(TargetUser user) { if (mCurrentUser == -1) { mCurrentUser = user.getUserIdentifier(); setGlobalRestriction(); } } @Override public void onUserSwitching(TargetUser from, TargetUser to) { mCurrentUser = to.getUserIdentifier(); setGlobalRestriction(); } class SensorPrivacyServiceImpl extends ISensorPrivacyManager.Stub implements AppOpsManager.OnOpNotedListener, AppOpsManager.OnOpStartedListener, IBinder.DeathRecipient, UserManagerInternal.UserRestrictionsListener { Loading Loading @@ -262,17 +279,6 @@ public final class SensorPrivacyService extends SystemService { if (readPersistedSensorPrivacyStateLocked()) { persistSensorPrivacyStateLocked(); } for (int i = 0; i < mIndividualEnabled.size(); i++) { int userId = mIndividualEnabled.keyAt(i); SparseBooleanArray userIndividualEnabled = mIndividualEnabled.valueAt(i); for (int j = 0; j < userIndividualEnabled.size(); j++) { int sensor = userIndividualEnabled.keyAt(j); boolean enabled = userIndividualEnabled.valueAt(j); setUserRestriction(userId, sensor, enabled); } } } int[] micAndCameraOps = new int[]{OP_RECORD_AUDIO, OP_PHONE_CALL_MICROPHONE, Loading Loading @@ -1379,7 +1385,10 @@ public final class SensorPrivacyService extends SystemService { SparseArray<RemoteCallbackList<ISensorPrivacyListener>> listenersForUser = mIndividualSensorListeners.get(userId); setUserRestriction(userId, sensor, enabled); setGlobalRestriction(); if (userId == mCurrentUser) { setGlobalRestriction(); } if (listenersForUser == null) { return; Loading Loading @@ -1408,16 +1417,18 @@ public final class SensorPrivacyService extends SystemService { } } private void setUserRestriction(int userId, int sensor, boolean enabled) { if (sensor == CAMERA) { mAppOpsManager.setUserRestrictionForUser(OP_CAMERA, enabled, mAppOpsRestrictionToken, null, userId); } else if (sensor == MICROPHONE) { mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO, enabled, mAppOpsRestrictionToken, null, userId); mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO_HOTWORD, enabled, mAppOpsRestrictionToken, null, userId); } private void setGlobalRestriction() { boolean camState = mSensorPrivacyServiceImpl .isIndividualSensorPrivacyEnabled(mCurrentUser, CAMERA); boolean micState = mSensorPrivacyServiceImpl .isIndividualSensorPrivacyEnabled(mCurrentUser, MICROPHONE); mAppOpsManagerInternal .setGlobalRestriction(OP_CAMERA, camState, mAppOpsRestrictionToken); mAppOpsManagerInternal .setGlobalRestriction(OP_RECORD_AUDIO, micState, mAppOpsRestrictionToken); } private final class DeathRecipient implements IBinder.DeathRecipient { Loading Loading @@ -1535,7 +1546,7 @@ public final class SensorPrivacyService extends SystemService { } private class EmergencyCallHelper { private OutogingEmergencyStateCallback mEmergencyStateCallback; private OutgoingEmergencyStateCallback mEmergencyStateCallback; private CallStateCallback mCallStateCallback; private boolean mIsInEmergencyCall; Loading @@ -1544,7 +1555,7 @@ public final class SensorPrivacyService extends SystemService { private Object mEmergencyStateLock = new Object(); EmergencyCallHelper() { mEmergencyStateCallback = new OutogingEmergencyStateCallback(); mEmergencyStateCallback = new OutgoingEmergencyStateCallback(); mCallStateCallback = new CallStateCallback(); mTelephonyManager.registerTelephonyCallback(FgThread.getExecutor(), Loading @@ -1559,7 +1570,7 @@ public final class SensorPrivacyService extends SystemService { } } private class OutogingEmergencyStateCallback extends TelephonyCallback implements private class OutgoingEmergencyStateCallback extends TelephonyCallback implements TelephonyCallback.OutgoingEmergencyCallListener { @Override public void onOutgoingEmergencyCall(EmergencyNumber placedEmergencyNumber, Loading services/core/java/com/android/server/appop/AppOpsService.java +119 −9 Original line number Diff line number Diff line Loading @@ -338,7 +338,14 @@ public class AppOpsService extends IAppOpsService.Stub { /* * These are app op restrictions imposed per user from various parties. */ private final ArrayMap<IBinder, ClientRestrictionState> mOpUserRestrictions = new ArrayMap<>(); private final ArrayMap<IBinder, ClientUserRestrictionState> mOpUserRestrictions = new ArrayMap<>(); /* * These are app op restrictions imposed globally from various parties within the system. */ private final ArrayMap<IBinder, ClientGlobalRestrictionState> mOpGlobalRestrictions = new ArrayMap<>(); SparseIntArray mProfileOwners; Loading Loading @@ -4722,13 +4729,22 @@ public class AppOpsService extends IAppOpsService.Stub { private boolean isOpRestrictedLocked(int uid, int code, String packageName, String attributionTag, @Nullable RestrictionBypass appBypass) { int restrictionSetCount = mOpGlobalRestrictions.size(); for (int i = 0; i < restrictionSetCount; i++) { ClientGlobalRestrictionState restrictionState = mOpGlobalRestrictions.valueAt(i); if (restrictionState.hasRestriction(code)) { return true; } } int userHandle = UserHandle.getUserId(uid); final int restrictionSetCount = mOpUserRestrictions.size(); restrictionSetCount = mOpUserRestrictions.size(); for (int i = 0; i < restrictionSetCount; i++) { // For each client, check that the given op is not restricted, or that the given // package is exempt from the restriction. ClientRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); ClientUserRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); if (restrictionState.hasRestriction(code, packageName, attributionTag, userHandle)) { RestrictionBypass opBypass = opAllowSystemBypassRestriction(code); if (opBypass != null) { Loading Loading @@ -6295,10 +6311,31 @@ public class AppOpsService extends IAppOpsService.Stub { pw.println(); } final int globalRestrictionCount = mOpGlobalRestrictions.size(); for (int i = 0; i < globalRestrictionCount; i++) { IBinder token = mOpGlobalRestrictions.keyAt(i); ClientGlobalRestrictionState restrictionState = mOpGlobalRestrictions.valueAt(i); ArraySet<Integer> restrictedOps = restrictionState.mRestrictedOps; pw.println(" Global restrictions for token " + token + ":"); StringBuilder restrictedOpsValue = new StringBuilder(); restrictedOpsValue.append("["); final int restrictedOpCount = restrictedOps.size(); for (int j = 0; j < restrictedOpCount; j++) { if (restrictedOpsValue.length() > 1) { restrictedOpsValue.append(", "); } restrictedOpsValue.append(AppOpsManager.opToName(restrictedOps.valueAt(j))); } restrictedOpsValue.append("]"); pw.println(" Restricted ops: " + restrictedOpsValue); } final int userRestrictionCount = mOpUserRestrictions.size(); for (int i = 0; i < userRestrictionCount; i++) { IBinder token = mOpUserRestrictions.keyAt(i); ClientRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); ClientUserRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); boolean printedTokenHeader = false; if (dumpMode >= 0 || dumpWatchers || dumpHistory) { Loading Loading @@ -6444,11 +6481,11 @@ public class AppOpsService extends IAppOpsService.Stub { private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token, int userHandle, PackageTagsList excludedPackageTags) { synchronized (AppOpsService.this) { ClientRestrictionState restrictionState = mOpUserRestrictions.get(token); ClientUserRestrictionState restrictionState = mOpUserRestrictions.get(token); if (restrictionState == null) { try { restrictionState = new ClientRestrictionState(token); restrictionState = new ClientUserRestrictionState(token); } catch (RemoteException e) { return; } Loading Loading @@ -6528,7 +6565,7 @@ public class AppOpsService extends IAppOpsService.Stub { synchronized (AppOpsService.this) { final int tokenCount = mOpUserRestrictions.size(); for (int i = tokenCount - 1; i >= 0; i--) { ClientRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i); ClientUserRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i); opRestrictions.removeUser(userHandle); } removeUidsForUserLocked(userHandle); Loading Loading @@ -6986,12 +7023,12 @@ public class AppOpsService extends IAppOpsService.Stub { return packageNames; } private final class ClientRestrictionState implements DeathRecipient { private final class ClientUserRestrictionState implements DeathRecipient { private final IBinder token; SparseArray<boolean[]> perUserRestrictions; SparseArray<PackageTagsList> perUserExcludedPackageTags; public ClientRestrictionState(IBinder token) ClientUserRestrictionState(IBinder token) throws RemoteException { token.linkToDeath(this, 0); this.token = token; Loading Loading @@ -7082,6 +7119,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (perUserExclusions == null) { return true; } return !perUserExclusions.contains(packageName, attributionTag); } Loading Loading @@ -7143,6 +7181,42 @@ public class AppOpsService extends IAppOpsService.Stub { } } private final class ClientGlobalRestrictionState implements DeathRecipient { final IBinder mToken; final ArraySet<Integer> mRestrictedOps = new ArraySet<>(); ClientGlobalRestrictionState(IBinder token) throws RemoteException { token.linkToDeath(this, 0); this.mToken = token; } boolean setRestriction(int code, boolean restricted) { if (restricted) { return mRestrictedOps.add(code); } else { return mRestrictedOps.remove(code); } } boolean hasRestriction(int code) { return mRestrictedOps.contains(code); } boolean isDefault() { return mRestrictedOps.isEmpty(); } @Override public void binderDied() { destroy(); } void destroy() { mToken.unlinkToDeath(this, 0); } } private final class AppOpsManagerInternalImpl extends AppOpsManagerInternal { @Override public void setDeviceAndProfileOwners(SparseIntArray owners) { synchronized (AppOpsService.this) { Loading @@ -7167,6 +7241,42 @@ public class AppOpsService extends IAppOpsService.Stub { int mode, @Nullable IAppOpsCallback callback) { setMode(code, uid, packageName, mode, callback); } @Override public void setGlobalRestriction(int code, boolean restricted, IBinder token) { if (Binder.getCallingPid() != Process.myPid()) { // TODO instead of this enforcement put in AppOpsManagerInternal throw new SecurityException("Only the system can set global restrictions"); } synchronized (AppOpsService.this) { ClientGlobalRestrictionState restrictionState = mOpGlobalRestrictions.get(token); if (restrictionState == null) { try { restrictionState = new ClientGlobalRestrictionState(token); } catch (RemoteException e) { return; } mOpGlobalRestrictions.put(token, restrictionState); } if (restrictionState.setRestriction(code, restricted)) { mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::notifyWatchersOfChange, AppOpsService.this, code, UID_ANY)); mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::updateStartedOpModeForUser, AppOpsService.this, code, restricted, UserHandle.USER_ALL)); } if (restrictionState.isDefault()) { mOpGlobalRestrictions.remove(token); restrictionState.destroy(); } } } } /** Loading Loading
core/java/android/app/AppOpsManagerInternal.java +6 −0 Original line number Diff line number Diff line Loading @@ -209,4 +209,10 @@ public abstract class AppOpsManagerInternal { */ public abstract void setModeFromPermissionPolicy(int code, int uid, @NonNull String packageName, int mode, @Nullable IAppOpsCallback callback); /** * Sets a global restriction on an op code. */ public abstract void setGlobalRestriction(int code, boolean restricted, IBinder token); }
core/java/com/android/internal/app/IAppOpsService.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ interface IAppOpsService { void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle); void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in PackageTagsList excludedPackageTags); void removeUser(int userHandle); void startWatchingActive(in int[] ops, IAppOpsActiveCallback callback); Loading
services/core/java/com/android/server/SensorPrivacyService.java +38 −27 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA; import static android.app.AppOpsManager.OP_PHONE_CALL_MICROPHONE; import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD; import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.pm.PackageManager.PERMISSION_GRANTED; Loading @@ -47,6 +46,7 @@ import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.AppOpsManager; import android.app.AppOpsManagerInternal; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationChannel; Loading Loading @@ -163,6 +163,7 @@ public final class SensorPrivacyService extends SystemService { private final ActivityManagerInternal mActivityManagerInternal; private final ActivityTaskManager mActivityTaskManager; private final AppOpsManager mAppOpsManager; private final AppOpsManagerInternal mAppOpsManagerInternal; private final TelephonyManager mTelephonyManager; private final IBinder mAppOpsRestrictionToken = new Binder(); Loading @@ -172,16 +173,18 @@ public final class SensorPrivacyService extends SystemService { private EmergencyCallHelper mEmergencyCallHelper; private KeyguardManager mKeyguardManager; private int mCurrentUser = -1; public SensorPrivacyService(Context context) { super(context); mContext = context; mAppOpsManager = context.getSystemService(AppOpsManager.class); mAppOpsManagerInternal = getLocalService(AppOpsManagerInternal.class); mUserManagerInternal = getLocalService(UserManagerInternal.class); mActivityManager = context.getSystemService(ActivityManager.class); mActivityManagerInternal = getLocalService(ActivityManagerInternal.class); mActivityTaskManager = context.getSystemService(ActivityTaskManager.class); mTelephonyManager = context.getSystemService(TelephonyManager.class); mSensorPrivacyServiceImpl = new SensorPrivacyServiceImpl(); } Loading @@ -201,6 +204,20 @@ public final class SensorPrivacyService extends SystemService { } } @Override public void onUserStarting(TargetUser user) { if (mCurrentUser == -1) { mCurrentUser = user.getUserIdentifier(); setGlobalRestriction(); } } @Override public void onUserSwitching(TargetUser from, TargetUser to) { mCurrentUser = to.getUserIdentifier(); setGlobalRestriction(); } class SensorPrivacyServiceImpl extends ISensorPrivacyManager.Stub implements AppOpsManager.OnOpNotedListener, AppOpsManager.OnOpStartedListener, IBinder.DeathRecipient, UserManagerInternal.UserRestrictionsListener { Loading Loading @@ -262,17 +279,6 @@ public final class SensorPrivacyService extends SystemService { if (readPersistedSensorPrivacyStateLocked()) { persistSensorPrivacyStateLocked(); } for (int i = 0; i < mIndividualEnabled.size(); i++) { int userId = mIndividualEnabled.keyAt(i); SparseBooleanArray userIndividualEnabled = mIndividualEnabled.valueAt(i); for (int j = 0; j < userIndividualEnabled.size(); j++) { int sensor = userIndividualEnabled.keyAt(j); boolean enabled = userIndividualEnabled.valueAt(j); setUserRestriction(userId, sensor, enabled); } } } int[] micAndCameraOps = new int[]{OP_RECORD_AUDIO, OP_PHONE_CALL_MICROPHONE, Loading Loading @@ -1379,7 +1385,10 @@ public final class SensorPrivacyService extends SystemService { SparseArray<RemoteCallbackList<ISensorPrivacyListener>> listenersForUser = mIndividualSensorListeners.get(userId); setUserRestriction(userId, sensor, enabled); setGlobalRestriction(); if (userId == mCurrentUser) { setGlobalRestriction(); } if (listenersForUser == null) { return; Loading Loading @@ -1408,16 +1417,18 @@ public final class SensorPrivacyService extends SystemService { } } private void setUserRestriction(int userId, int sensor, boolean enabled) { if (sensor == CAMERA) { mAppOpsManager.setUserRestrictionForUser(OP_CAMERA, enabled, mAppOpsRestrictionToken, null, userId); } else if (sensor == MICROPHONE) { mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO, enabled, mAppOpsRestrictionToken, null, userId); mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO_HOTWORD, enabled, mAppOpsRestrictionToken, null, userId); } private void setGlobalRestriction() { boolean camState = mSensorPrivacyServiceImpl .isIndividualSensorPrivacyEnabled(mCurrentUser, CAMERA); boolean micState = mSensorPrivacyServiceImpl .isIndividualSensorPrivacyEnabled(mCurrentUser, MICROPHONE); mAppOpsManagerInternal .setGlobalRestriction(OP_CAMERA, camState, mAppOpsRestrictionToken); mAppOpsManagerInternal .setGlobalRestriction(OP_RECORD_AUDIO, micState, mAppOpsRestrictionToken); } private final class DeathRecipient implements IBinder.DeathRecipient { Loading Loading @@ -1535,7 +1546,7 @@ public final class SensorPrivacyService extends SystemService { } private class EmergencyCallHelper { private OutogingEmergencyStateCallback mEmergencyStateCallback; private OutgoingEmergencyStateCallback mEmergencyStateCallback; private CallStateCallback mCallStateCallback; private boolean mIsInEmergencyCall; Loading @@ -1544,7 +1555,7 @@ public final class SensorPrivacyService extends SystemService { private Object mEmergencyStateLock = new Object(); EmergencyCallHelper() { mEmergencyStateCallback = new OutogingEmergencyStateCallback(); mEmergencyStateCallback = new OutgoingEmergencyStateCallback(); mCallStateCallback = new CallStateCallback(); mTelephonyManager.registerTelephonyCallback(FgThread.getExecutor(), Loading @@ -1559,7 +1570,7 @@ public final class SensorPrivacyService extends SystemService { } } private class OutogingEmergencyStateCallback extends TelephonyCallback implements private class OutgoingEmergencyStateCallback extends TelephonyCallback implements TelephonyCallback.OutgoingEmergencyCallListener { @Override public void onOutgoingEmergencyCall(EmergencyNumber placedEmergencyNumber, Loading
services/core/java/com/android/server/appop/AppOpsService.java +119 −9 Original line number Diff line number Diff line Loading @@ -338,7 +338,14 @@ public class AppOpsService extends IAppOpsService.Stub { /* * These are app op restrictions imposed per user from various parties. */ private final ArrayMap<IBinder, ClientRestrictionState> mOpUserRestrictions = new ArrayMap<>(); private final ArrayMap<IBinder, ClientUserRestrictionState> mOpUserRestrictions = new ArrayMap<>(); /* * These are app op restrictions imposed globally from various parties within the system. */ private final ArrayMap<IBinder, ClientGlobalRestrictionState> mOpGlobalRestrictions = new ArrayMap<>(); SparseIntArray mProfileOwners; Loading Loading @@ -4722,13 +4729,22 @@ public class AppOpsService extends IAppOpsService.Stub { private boolean isOpRestrictedLocked(int uid, int code, String packageName, String attributionTag, @Nullable RestrictionBypass appBypass) { int restrictionSetCount = mOpGlobalRestrictions.size(); for (int i = 0; i < restrictionSetCount; i++) { ClientGlobalRestrictionState restrictionState = mOpGlobalRestrictions.valueAt(i); if (restrictionState.hasRestriction(code)) { return true; } } int userHandle = UserHandle.getUserId(uid); final int restrictionSetCount = mOpUserRestrictions.size(); restrictionSetCount = mOpUserRestrictions.size(); for (int i = 0; i < restrictionSetCount; i++) { // For each client, check that the given op is not restricted, or that the given // package is exempt from the restriction. ClientRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); ClientUserRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); if (restrictionState.hasRestriction(code, packageName, attributionTag, userHandle)) { RestrictionBypass opBypass = opAllowSystemBypassRestriction(code); if (opBypass != null) { Loading Loading @@ -6295,10 +6311,31 @@ public class AppOpsService extends IAppOpsService.Stub { pw.println(); } final int globalRestrictionCount = mOpGlobalRestrictions.size(); for (int i = 0; i < globalRestrictionCount; i++) { IBinder token = mOpGlobalRestrictions.keyAt(i); ClientGlobalRestrictionState restrictionState = mOpGlobalRestrictions.valueAt(i); ArraySet<Integer> restrictedOps = restrictionState.mRestrictedOps; pw.println(" Global restrictions for token " + token + ":"); StringBuilder restrictedOpsValue = new StringBuilder(); restrictedOpsValue.append("["); final int restrictedOpCount = restrictedOps.size(); for (int j = 0; j < restrictedOpCount; j++) { if (restrictedOpsValue.length() > 1) { restrictedOpsValue.append(", "); } restrictedOpsValue.append(AppOpsManager.opToName(restrictedOps.valueAt(j))); } restrictedOpsValue.append("]"); pw.println(" Restricted ops: " + restrictedOpsValue); } final int userRestrictionCount = mOpUserRestrictions.size(); for (int i = 0; i < userRestrictionCount; i++) { IBinder token = mOpUserRestrictions.keyAt(i); ClientRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); ClientUserRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); boolean printedTokenHeader = false; if (dumpMode >= 0 || dumpWatchers || dumpHistory) { Loading Loading @@ -6444,11 +6481,11 @@ public class AppOpsService extends IAppOpsService.Stub { private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token, int userHandle, PackageTagsList excludedPackageTags) { synchronized (AppOpsService.this) { ClientRestrictionState restrictionState = mOpUserRestrictions.get(token); ClientUserRestrictionState restrictionState = mOpUserRestrictions.get(token); if (restrictionState == null) { try { restrictionState = new ClientRestrictionState(token); restrictionState = new ClientUserRestrictionState(token); } catch (RemoteException e) { return; } Loading Loading @@ -6528,7 +6565,7 @@ public class AppOpsService extends IAppOpsService.Stub { synchronized (AppOpsService.this) { final int tokenCount = mOpUserRestrictions.size(); for (int i = tokenCount - 1; i >= 0; i--) { ClientRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i); ClientUserRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i); opRestrictions.removeUser(userHandle); } removeUidsForUserLocked(userHandle); Loading Loading @@ -6986,12 +7023,12 @@ public class AppOpsService extends IAppOpsService.Stub { return packageNames; } private final class ClientRestrictionState implements DeathRecipient { private final class ClientUserRestrictionState implements DeathRecipient { private final IBinder token; SparseArray<boolean[]> perUserRestrictions; SparseArray<PackageTagsList> perUserExcludedPackageTags; public ClientRestrictionState(IBinder token) ClientUserRestrictionState(IBinder token) throws RemoteException { token.linkToDeath(this, 0); this.token = token; Loading Loading @@ -7082,6 +7119,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (perUserExclusions == null) { return true; } return !perUserExclusions.contains(packageName, attributionTag); } Loading Loading @@ -7143,6 +7181,42 @@ public class AppOpsService extends IAppOpsService.Stub { } } private final class ClientGlobalRestrictionState implements DeathRecipient { final IBinder mToken; final ArraySet<Integer> mRestrictedOps = new ArraySet<>(); ClientGlobalRestrictionState(IBinder token) throws RemoteException { token.linkToDeath(this, 0); this.mToken = token; } boolean setRestriction(int code, boolean restricted) { if (restricted) { return mRestrictedOps.add(code); } else { return mRestrictedOps.remove(code); } } boolean hasRestriction(int code) { return mRestrictedOps.contains(code); } boolean isDefault() { return mRestrictedOps.isEmpty(); } @Override public void binderDied() { destroy(); } void destroy() { mToken.unlinkToDeath(this, 0); } } private final class AppOpsManagerInternalImpl extends AppOpsManagerInternal { @Override public void setDeviceAndProfileOwners(SparseIntArray owners) { synchronized (AppOpsService.this) { Loading @@ -7167,6 +7241,42 @@ public class AppOpsService extends IAppOpsService.Stub { int mode, @Nullable IAppOpsCallback callback) { setMode(code, uid, packageName, mode, callback); } @Override public void setGlobalRestriction(int code, boolean restricted, IBinder token) { if (Binder.getCallingPid() != Process.myPid()) { // TODO instead of this enforcement put in AppOpsManagerInternal throw new SecurityException("Only the system can set global restrictions"); } synchronized (AppOpsService.this) { ClientGlobalRestrictionState restrictionState = mOpGlobalRestrictions.get(token); if (restrictionState == null) { try { restrictionState = new ClientGlobalRestrictionState(token); } catch (RemoteException e) { return; } mOpGlobalRestrictions.put(token, restrictionState); } if (restrictionState.setRestriction(code, restricted)) { mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::notifyWatchersOfChange, AppOpsService.this, code, UID_ANY)); mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::updateStartedOpModeForUser, AppOpsService.this, code, restricted, UserHandle.USER_ALL)); } if (restrictionState.isDefault()) { mOpGlobalRestrictions.remove(token); restrictionState.destroy(); } } } } /** Loading