Loading core/java/android/app/AppOpsManager.java +135 −0 Original line number Diff line number Diff line Loading @@ -2915,6 +2915,133 @@ public class AppOpsManager { true, // ACCESS_RESTRICTED_SETTINGS }; /** * This specifies whether each option is only allowed to be read * by apps with manage appops permission. */ private static boolean[] sOpRestrictRead = new boolean[] { false, // COARSE_LOCATION false, // FINE_LOCATION false, // GPS false, // VIBRATE false, // READ_CONTACTS false, // WRITE_CONTACTS false, // READ_CALL_LOG false, // WRITE_CALL_LOG false, // READ_CALENDAR false, // WRITE_CALENDAR false, // WIFI_SCAN false, // POST_NOTIFICATION false, // NEIGHBORING_CELLS false, // CALL_PHONE false, // READ_SMS false, // WRITE_SMS false, // RECEIVE_SMS false, // RECEIVE_EMERGENCY_BROADCAST false, // RECEIVE_MMS false, // RECEIVE_WAP_PUSH false, // SEND_SMS false, // READ_ICC_SMS false, // WRITE_ICC_SMS false, // WRITE_SETTINGS false, // SYSTEM_ALERT_WINDOW false, // ACCESS_NOTIFICATIONS false, // CAMERA false, // RECORD_AUDIO false, // PLAY_AUDIO false, // READ_CLIPBOARD false, // WRITE_CLIPBOARD false, // TAKE_MEDIA_BUTTONS false, // TAKE_AUDIO_FOCUS false, // AUDIO_MASTER_VOLUME false, // AUDIO_VOICE_VOLUME false, // AUDIO_RING_VOLUME false, // AUDIO_MEDIA_VOLUME false, // AUDIO_ALARM_VOLUME false, // AUDIO_NOTIFICATION_VOLUME false, // AUDIO_BLUETOOTH_VOLUME false, // WAKE_LOCK false, // MONITOR_LOCATION false, // MONITOR_HIGH_POWER_LOCATION false, // GET_USAGE_STATS false, // MUTE_MICROPHONE false, // TOAST_WINDOW false, // PROJECT_MEDIA false, // ACTIVATE_VPN false, // WRITE_WALLPAPER false, // ASSIST_STRUCTURE false, // ASSIST_SCREENSHOT false, // READ_PHONE_STATE false, // ADD_VOICEMAIL false, // USE_SIP false, // PROCESS_OUTGOING_CALLS false, // USE_FINGERPRINT false, // BODY_SENSORS false, // READ_CELL_BROADCASTS false, // MOCK_LOCATION false, // READ_EXTERNAL_STORAGE false, // WRITE_EXTERNAL_STORAGE false, // TURN_SCREEN_ON false, // GET_ACCOUNTS false, // RUN_IN_BACKGROUND false, // AUDIO_ACCESSIBILITY_VOLUME false, // READ_PHONE_NUMBERS false, // REQUEST_INSTALL_PACKAGES false, // PICTURE_IN_PICTURE false, // INSTANT_APP_START_FOREGROUND false, // ANSWER_PHONE_CALLS false, // RUN_ANY_IN_BACKGROUND false, // CHANGE_WIFI_STATE false, // REQUEST_DELETE_PACKAGES false, // BIND_ACCESSIBILITY_SERVICE false, // ACCEPT_HANDOVER false, // MANAGE_IPSEC_TUNNELS false, // START_FOREGROUND false, // BLUETOOTH_SCAN false, // USE_BIOMETRIC false, // ACTIVITY_RECOGNITION false, // SMS_FINANCIAL_TRANSACTIONS false, // READ_MEDIA_AUDIO false, // WRITE_MEDIA_AUDIO false, // READ_MEDIA_VIDEO false, // WRITE_MEDIA_VIDEO false, // READ_MEDIA_IMAGES false, // WRITE_MEDIA_IMAGES false, // LEGACY_STORAGE false, // ACCESS_ACCESSIBILITY false, // READ_DEVICE_IDENTIFIERS false, // ACCESS_MEDIA_LOCATION false, // QUERY_ALL_PACKAGES false, // MANAGE_EXTERNAL_STORAGE false, // INTERACT_ACROSS_PROFILES false, // ACTIVATE_PLATFORM_VPN false, // LOADER_USAGE_STATS false, // deprecated operation false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED false, // AUTO_REVOKE_MANAGED_BY_INSTALLER false, // NO_ISOLATED_STORAGE false, // PHONE_CALL_MICROPHONE false, // PHONE_CALL_CAMERA false, // RECORD_AUDIO_HOTWORD false, // MANAGE_ONGOING_CALLS false, // MANAGE_CREDENTIALS false, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER false, // RECORD_AUDIO_OUTPUT false, // SCHEDULE_EXACT_ALARM false, // ACCESS_FINE_LOCATION_SOURCE false, // ACCESS_COARSE_LOCATION_SOURCE false, // MANAGE_MEDIA false, // BLUETOOTH_CONNECT false, // UWB_RANGING false, // ACTIVITY_RECOGNITION_SOURCE false, // BLUETOOTH_ADVERTISE false, // RECORD_INCOMING_PHONE_AUDIO false, // NEARBY_WIFI_DEVICES false, // OP_ESTABLISH_VPN_SERVICE false, // OP_ESTABLISH_VPN_MANAGER true, // ACCESS_RESTRICTED_SETTINGS }; /** * Mapping from an app op name to the app op code. */ Loading Loading @@ -3142,6 +3269,14 @@ public class AppOpsManager { return "mode=" + mode; } /** * Retrieve whether the op can be read by apps with manage appops permission. * @hide */ public static boolean opRestrictsRead(int op) { return sOpRestrictRead[op]; } /** * Retrieve whether the op allows itself to be reset. * @hide Loading core/res/res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -2966,6 +2966,9 @@ config_preventImeStartupUnlessTextEditor. --> <string-array name="config_nonPreemptibleInputMethods" translatable="false" /> <!-- Flag indicating that enhanced confirmation mode is enabled. --> <bool name="config_enhancedConfirmationModeEnabled">true</bool> <!-- The list of classes that should be added to the notification ranking pipeline. See {@link com.android.server.notification.NotificationSignalExtractor} If you add a new extractor to this list make sure to update Loading core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2256,6 +2256,7 @@ <java-symbol type="bool" name="config_killableInputMethods" /> <java-symbol type="bool" name="config_preventImeStartupUnlessTextEditor" /> <java-symbol type="array" name="config_nonPreemptibleInputMethods" /> <java-symbol type="bool" name="config_enhancedConfirmationModeEnabled" /> <java-symbol type="layout" name="resolver_list" /> <java-symbol type="id" name="resolver_list" /> Loading packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java +3 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,9 @@ public class RestrictedSwitchPreference extends SwitchPreference { final int mode = mAppOpsManager.noteOpNoThrow( AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, uid, packageName); final boolean appOpsAllowed = mode == AppOpsManager.MODE_ALLOWED; final boolean ecmEnabled = getContext().getResources().getBoolean( com.android.internal.R.bool.config_enhancedConfirmationModeEnabled); final boolean appOpsAllowed = !ecmEnabled || mode == AppOpsManager.MODE_ALLOWED; if (appOpsAllowed || isEnabled) { setEnabled(true); } else { Loading services/core/java/com/android/server/appop/AppOpsService.java +26 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import static android.app.AppOpsManager.extractUidStateFromKey; import static android.app.AppOpsManager.makeKey; import static android.app.AppOpsManager.modeToName; import static android.app.AppOpsManager.opAllowSystemBypassRestriction; import static android.app.AppOpsManager.opRestrictsRead; import static android.app.AppOpsManager.opToName; import static android.app.AppOpsManager.opToPublicName; import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState; Loading Loading @@ -2875,6 +2876,10 @@ public class AppOpsService extends IAppOpsService.Stub { // features may require permissions our remote caller does not have. final long identity = Binder.clearCallingIdentity(); try { if (shouldIgnoreCallback(switchedCode, callback.mCallingPid, callback.mCallingUid)) { continue; } callback.mCallback.opChanged(switchedCode, uid, packageName); } catch (RemoteException e) { /* ignore */ Loading Loading @@ -4205,6 +4210,9 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i = 0; i < callbackCount; i++) { final ActiveCallback callback = callbacks.valueAt(i); try { if (shouldIgnoreCallback(code, callback.mCallingPid, callback.mCallingUid)) { continue; } callback.mCallback.opActiveChanged(code, uid, packageName, attributionTag, active, attributionFlags, attributionChainId); } catch (RemoteException e) { Loading Loading @@ -4258,6 +4266,9 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i = 0; i < callbackCount; i++) { final StartedCallback callback = callbacks.valueAt(i); try { if (shouldIgnoreCallback(code, callback.mCallingPid, callback.mCallingUid)) { continue; } callback.mCallback.opStarted(code, uid, packageName, attributionTag, flags, result, startedType, attributionFlags, attributionChainId); } catch (RemoteException e) { Loading Loading @@ -4306,6 +4317,9 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i = 0; i < callbackCount; i++) { final NotedCallback callback = callbacks.valueAt(i); try { if (shouldIgnoreCallback(code, callback.mCallingPid, callback.mCallingUid)) { continue; } callback.mCallback.opNoted(code, uid, packageName, attributionTag, flags, result); } catch (RemoteException e) { Loading Loading @@ -4370,8 +4384,20 @@ public class AppOpsService extends IAppOpsService.Stub { Binder.getCallingPid(), Binder.getCallingUid(), null); } private boolean shouldIgnoreCallback(int op, int watcherPid, int watcherUid) { // If it's a restricted read op, ignore it if watcher doesn't have manage ops permission, // as watcher should not use this to signal if the value is changed. return opRestrictsRead(op) && mContext.checkPermission(Manifest.permission.MANAGE_APPOPS, watcherPid, watcherUid) != PackageManager.PERMISSION_GRANTED; } private void verifyIncomingOp(int op) { if (op >= 0 && op < AppOpsManager._NUM_OP) { // Enforce manage appops permission if it's a restricted read op. if (opRestrictsRead(op)) { mContext.enforcePermission(Manifest.permission.MANAGE_APPOPS, Binder.getCallingPid(), Binder.getCallingUid(), "verifyIncomingOp"); } return; } throw new IllegalArgumentException("Bad operation #" + op); Loading Loading
core/java/android/app/AppOpsManager.java +135 −0 Original line number Diff line number Diff line Loading @@ -2915,6 +2915,133 @@ public class AppOpsManager { true, // ACCESS_RESTRICTED_SETTINGS }; /** * This specifies whether each option is only allowed to be read * by apps with manage appops permission. */ private static boolean[] sOpRestrictRead = new boolean[] { false, // COARSE_LOCATION false, // FINE_LOCATION false, // GPS false, // VIBRATE false, // READ_CONTACTS false, // WRITE_CONTACTS false, // READ_CALL_LOG false, // WRITE_CALL_LOG false, // READ_CALENDAR false, // WRITE_CALENDAR false, // WIFI_SCAN false, // POST_NOTIFICATION false, // NEIGHBORING_CELLS false, // CALL_PHONE false, // READ_SMS false, // WRITE_SMS false, // RECEIVE_SMS false, // RECEIVE_EMERGENCY_BROADCAST false, // RECEIVE_MMS false, // RECEIVE_WAP_PUSH false, // SEND_SMS false, // READ_ICC_SMS false, // WRITE_ICC_SMS false, // WRITE_SETTINGS false, // SYSTEM_ALERT_WINDOW false, // ACCESS_NOTIFICATIONS false, // CAMERA false, // RECORD_AUDIO false, // PLAY_AUDIO false, // READ_CLIPBOARD false, // WRITE_CLIPBOARD false, // TAKE_MEDIA_BUTTONS false, // TAKE_AUDIO_FOCUS false, // AUDIO_MASTER_VOLUME false, // AUDIO_VOICE_VOLUME false, // AUDIO_RING_VOLUME false, // AUDIO_MEDIA_VOLUME false, // AUDIO_ALARM_VOLUME false, // AUDIO_NOTIFICATION_VOLUME false, // AUDIO_BLUETOOTH_VOLUME false, // WAKE_LOCK false, // MONITOR_LOCATION false, // MONITOR_HIGH_POWER_LOCATION false, // GET_USAGE_STATS false, // MUTE_MICROPHONE false, // TOAST_WINDOW false, // PROJECT_MEDIA false, // ACTIVATE_VPN false, // WRITE_WALLPAPER false, // ASSIST_STRUCTURE false, // ASSIST_SCREENSHOT false, // READ_PHONE_STATE false, // ADD_VOICEMAIL false, // USE_SIP false, // PROCESS_OUTGOING_CALLS false, // USE_FINGERPRINT false, // BODY_SENSORS false, // READ_CELL_BROADCASTS false, // MOCK_LOCATION false, // READ_EXTERNAL_STORAGE false, // WRITE_EXTERNAL_STORAGE false, // TURN_SCREEN_ON false, // GET_ACCOUNTS false, // RUN_IN_BACKGROUND false, // AUDIO_ACCESSIBILITY_VOLUME false, // READ_PHONE_NUMBERS false, // REQUEST_INSTALL_PACKAGES false, // PICTURE_IN_PICTURE false, // INSTANT_APP_START_FOREGROUND false, // ANSWER_PHONE_CALLS false, // RUN_ANY_IN_BACKGROUND false, // CHANGE_WIFI_STATE false, // REQUEST_DELETE_PACKAGES false, // BIND_ACCESSIBILITY_SERVICE false, // ACCEPT_HANDOVER false, // MANAGE_IPSEC_TUNNELS false, // START_FOREGROUND false, // BLUETOOTH_SCAN false, // USE_BIOMETRIC false, // ACTIVITY_RECOGNITION false, // SMS_FINANCIAL_TRANSACTIONS false, // READ_MEDIA_AUDIO false, // WRITE_MEDIA_AUDIO false, // READ_MEDIA_VIDEO false, // WRITE_MEDIA_VIDEO false, // READ_MEDIA_IMAGES false, // WRITE_MEDIA_IMAGES false, // LEGACY_STORAGE false, // ACCESS_ACCESSIBILITY false, // READ_DEVICE_IDENTIFIERS false, // ACCESS_MEDIA_LOCATION false, // QUERY_ALL_PACKAGES false, // MANAGE_EXTERNAL_STORAGE false, // INTERACT_ACROSS_PROFILES false, // ACTIVATE_PLATFORM_VPN false, // LOADER_USAGE_STATS false, // deprecated operation false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED false, // AUTO_REVOKE_MANAGED_BY_INSTALLER false, // NO_ISOLATED_STORAGE false, // PHONE_CALL_MICROPHONE false, // PHONE_CALL_CAMERA false, // RECORD_AUDIO_HOTWORD false, // MANAGE_ONGOING_CALLS false, // MANAGE_CREDENTIALS false, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER false, // RECORD_AUDIO_OUTPUT false, // SCHEDULE_EXACT_ALARM false, // ACCESS_FINE_LOCATION_SOURCE false, // ACCESS_COARSE_LOCATION_SOURCE false, // MANAGE_MEDIA false, // BLUETOOTH_CONNECT false, // UWB_RANGING false, // ACTIVITY_RECOGNITION_SOURCE false, // BLUETOOTH_ADVERTISE false, // RECORD_INCOMING_PHONE_AUDIO false, // NEARBY_WIFI_DEVICES false, // OP_ESTABLISH_VPN_SERVICE false, // OP_ESTABLISH_VPN_MANAGER true, // ACCESS_RESTRICTED_SETTINGS }; /** * Mapping from an app op name to the app op code. */ Loading Loading @@ -3142,6 +3269,14 @@ public class AppOpsManager { return "mode=" + mode; } /** * Retrieve whether the op can be read by apps with manage appops permission. * @hide */ public static boolean opRestrictsRead(int op) { return sOpRestrictRead[op]; } /** * Retrieve whether the op allows itself to be reset. * @hide Loading
core/res/res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -2966,6 +2966,9 @@ config_preventImeStartupUnlessTextEditor. --> <string-array name="config_nonPreemptibleInputMethods" translatable="false" /> <!-- Flag indicating that enhanced confirmation mode is enabled. --> <bool name="config_enhancedConfirmationModeEnabled">true</bool> <!-- The list of classes that should be added to the notification ranking pipeline. See {@link com.android.server.notification.NotificationSignalExtractor} If you add a new extractor to this list make sure to update Loading
core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2256,6 +2256,7 @@ <java-symbol type="bool" name="config_killableInputMethods" /> <java-symbol type="bool" name="config_preventImeStartupUnlessTextEditor" /> <java-symbol type="array" name="config_nonPreemptibleInputMethods" /> <java-symbol type="bool" name="config_enhancedConfirmationModeEnabled" /> <java-symbol type="layout" name="resolver_list" /> <java-symbol type="id" name="resolver_list" /> Loading
packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java +3 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,9 @@ public class RestrictedSwitchPreference extends SwitchPreference { final int mode = mAppOpsManager.noteOpNoThrow( AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, uid, packageName); final boolean appOpsAllowed = mode == AppOpsManager.MODE_ALLOWED; final boolean ecmEnabled = getContext().getResources().getBoolean( com.android.internal.R.bool.config_enhancedConfirmationModeEnabled); final boolean appOpsAllowed = !ecmEnabled || mode == AppOpsManager.MODE_ALLOWED; if (appOpsAllowed || isEnabled) { setEnabled(true); } else { Loading
services/core/java/com/android/server/appop/AppOpsService.java +26 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import static android.app.AppOpsManager.extractUidStateFromKey; import static android.app.AppOpsManager.makeKey; import static android.app.AppOpsManager.modeToName; import static android.app.AppOpsManager.opAllowSystemBypassRestriction; import static android.app.AppOpsManager.opRestrictsRead; import static android.app.AppOpsManager.opToName; import static android.app.AppOpsManager.opToPublicName; import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState; Loading Loading @@ -2875,6 +2876,10 @@ public class AppOpsService extends IAppOpsService.Stub { // features may require permissions our remote caller does not have. final long identity = Binder.clearCallingIdentity(); try { if (shouldIgnoreCallback(switchedCode, callback.mCallingPid, callback.mCallingUid)) { continue; } callback.mCallback.opChanged(switchedCode, uid, packageName); } catch (RemoteException e) { /* ignore */ Loading Loading @@ -4205,6 +4210,9 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i = 0; i < callbackCount; i++) { final ActiveCallback callback = callbacks.valueAt(i); try { if (shouldIgnoreCallback(code, callback.mCallingPid, callback.mCallingUid)) { continue; } callback.mCallback.opActiveChanged(code, uid, packageName, attributionTag, active, attributionFlags, attributionChainId); } catch (RemoteException e) { Loading Loading @@ -4258,6 +4266,9 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i = 0; i < callbackCount; i++) { final StartedCallback callback = callbacks.valueAt(i); try { if (shouldIgnoreCallback(code, callback.mCallingPid, callback.mCallingUid)) { continue; } callback.mCallback.opStarted(code, uid, packageName, attributionTag, flags, result, startedType, attributionFlags, attributionChainId); } catch (RemoteException e) { Loading Loading @@ -4306,6 +4317,9 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i = 0; i < callbackCount; i++) { final NotedCallback callback = callbacks.valueAt(i); try { if (shouldIgnoreCallback(code, callback.mCallingPid, callback.mCallingUid)) { continue; } callback.mCallback.opNoted(code, uid, packageName, attributionTag, flags, result); } catch (RemoteException e) { Loading Loading @@ -4370,8 +4384,20 @@ public class AppOpsService extends IAppOpsService.Stub { Binder.getCallingPid(), Binder.getCallingUid(), null); } private boolean shouldIgnoreCallback(int op, int watcherPid, int watcherUid) { // If it's a restricted read op, ignore it if watcher doesn't have manage ops permission, // as watcher should not use this to signal if the value is changed. return opRestrictsRead(op) && mContext.checkPermission(Manifest.permission.MANAGE_APPOPS, watcherPid, watcherUid) != PackageManager.PERMISSION_GRANTED; } private void verifyIncomingOp(int op) { if (op >= 0 && op < AppOpsManager._NUM_OP) { // Enforce manage appops permission if it's a restricted read op. if (opRestrictsRead(op)) { mContext.enforcePermission(Manifest.permission.MANAGE_APPOPS, Binder.getCallingPid(), Binder.getCallingUid(), "verifyIncomingOp"); } return; } throw new IllegalArgumentException("Bad operation #" + op); Loading