Merge "Add OEM config for enhanced confirmation mode and add restricted read ops" into tm-dev

This commit is contained in:
Ricky Wai
2022-04-22 14:53:01 +00:00
committed by Android (Google) Code Review
5 changed files with 168 additions and 1 deletions

View File

@@ -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.
*/
@@ -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

View File

@@ -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

View File

@@ -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" />

View File

@@ -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 {

View File

@@ -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;
@@ -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 */
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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);