Merge "Hide camera and microphone indicators" into udc-dev

This commit is contained in:
Charles Chen
2023-04-10 17:18:55 +00:00
committed by Android (Google) Code Review
3 changed files with 80 additions and 7 deletions

View File

@@ -1461,9 +1461,25 @@ public class AppOpsManager {
*/
public static final int OP_USE_FULL_SCREEN_INTENT = AppProtoEnums.APP_OP_USE_FULL_SCREEN_INTENT;
/**
* Hides camera indicator for sandboxed detection apps that directly access the service.
*
* @hide
*/
public static final int OP_CAMERA_SANDBOXED =
AppProtoEnums.APP_OP_CAMERA_SANDBOXED;
/**
* Hides microphone indicator for sandboxed detection apps that directly access the service.
*
* @hide
*/
public static final int OP_RECORD_AUDIO_SANDBOXED =
AppProtoEnums.APP_OP_RECORD_AUDIO_SANDBOXED;
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static final int _NUM_OP = 134;
public static final int _NUM_OP = 136;
/**
* All app ops represented as strings.
@@ -1605,6 +1621,8 @@ public class AppOpsManager {
OPSTR_CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD,
OPSTR_BODY_SENSORS_WRIST_TEMPERATURE,
OPSTR_USE_FULL_SCREEN_INTENT,
OPSTR_CAMERA_SANDBOXED,
OPSTR_RECORD_AUDIO_SANDBOXED
})
public @interface AppOpString {}
@@ -2012,6 +2030,20 @@ public class AppOpsManager {
*/
public static final String OPSTR_COARSE_LOCATION_SOURCE = "android:coarse_location_source";
/**
* Camera is being recorded in sandboxed detection process.
*
* @hide
*/
public static final String OPSTR_CAMERA_SANDBOXED = "android:camera_sandboxed";
/**
* Audio is being recorded in sandboxed detection process.
*
* @hide
*/
public static final String OPSTR_RECORD_AUDIO_SANDBOXED = "android:record_audio_sandboxed";
/**
* Allow apps to create the requests to manage the media files without user confirmation.
*
@@ -2738,7 +2770,11 @@ public class AppOpsManager {
.setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
new AppOpInfo.Builder(OP_USE_FULL_SCREEN_INTENT, OPSTR_USE_FULL_SCREEN_INTENT,
"USE_FULL_SCREEN_INTENT").setPermission(Manifest.permission.USE_FULL_SCREEN_INTENT)
.build()
.build(),
new AppOpInfo.Builder(OP_CAMERA_SANDBOXED, OPSTR_CAMERA_SANDBOXED,
"CAMERA_SANDBOXED").setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
new AppOpInfo.Builder(OP_RECORD_AUDIO_SANDBOXED, OPSTR_RECORD_AUDIO_SANDBOXED,
"RECORD_AUDIO_SANDBOXED").setDefaultMode(AppOpsManager.MODE_ALLOWED).build()
};
// The number of longs needed to form a full bitmask of app ops

View File

@@ -34,6 +34,7 @@ import static android.app.AppOpsManager.MODE_ERRORED;
import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_CAMERA_SANDBOXED;
import static android.app.AppOpsManager.OP_FLAGS_ALL;
import static android.app.AppOpsManager.OP_FLAG_SELF;
import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
@@ -42,6 +43,7 @@ import static android.app.AppOpsManager.OP_PLAY_AUDIO;
import static android.app.AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD;
import static android.app.AppOpsManager.OP_RECORD_AUDIO_SANDBOXED;
import static android.app.AppOpsManager.OP_VIBRATE;
import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_FAILED;
import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_STARTED;
@@ -3027,17 +3029,29 @@ public class AppOpsService extends IAppOpsService.Stub {
packageName);
}
// As a special case for OP_RECORD_AUDIO_HOTWORD, which we use only for attribution
// purposes and not as a check, also make sure that the caller is allowed to access
// the data gated by OP_RECORD_AUDIO.
// As a special case for OP_RECORD_AUDIO_HOTWORD, OP_RECEIVE_AMBIENT_TRIGGER_AUDIO and
// OP_RECORD_AUDIO_SANDBOXED which we use only for attribution purposes and not as a check,
// also make sure that the caller is allowed to access the data gated by OP_RECORD_AUDIO.
//
// TODO: Revert this change before Android 12.
if (code == OP_RECORD_AUDIO_HOTWORD || code == OP_RECEIVE_AMBIENT_TRIGGER_AUDIO) {
int result = checkOperation(OP_RECORD_AUDIO, uid, packageName);
int result = MODE_DEFAULT;
if (code == OP_RECORD_AUDIO_HOTWORD || code == OP_RECEIVE_AMBIENT_TRIGGER_AUDIO
|| code == OP_RECORD_AUDIO_SANDBOXED) {
result = checkOperation(OP_RECORD_AUDIO, uid, packageName);
// Check result
if (result != AppOpsManager.MODE_ALLOWED) {
return new SyncNotedAppOp(result, code, attributionTag, packageName);
}
}
// As a special case for OP_CAMERA_SANDBOXED.
if (code == OP_CAMERA_SANDBOXED) {
result = checkOperation(OP_CAMERA, uid, packageName);
// Check result
if (result != AppOpsManager.MODE_ALLOWED) {
return new SyncNotedAppOp(result, code, attributionTag, packageName);
}
}
return startOperationUnchecked(clientId, code, uid, packageName, attributionTag,
Process.INVALID_UID, null, null, OP_FLAG_SELF, startIfModeDefault,
shouldCollectAsyncNotedOp, message, shouldCollectMessage, attributionFlags,

View File

@@ -316,6 +316,7 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
private int resolveDatasourceOp(int code, int uid, @NonNull String packageName,
@Nullable String attributionTag) {
code = resolveRecordAudioOp(code, uid);
code = resolveSandboxedServiceOp(code, uid);
if (attributionTag == null) {
return code;
}
@@ -439,6 +440,28 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
return code;
}
private int resolveSandboxedServiceOp(int code, int uid) {
if (!Process.isIsolated(uid) // simple check which fails-fast for the common case
|| !(code == AppOpsManager.OP_RECORD_AUDIO || code == AppOpsManager.OP_CAMERA)) {
return code;
}
final HotwordDetectionServiceIdentity hotwordDetectionServiceIdentity =
mVoiceInteractionManagerInternal.getHotwordDetectionServiceIdentity();
if (hotwordDetectionServiceIdentity != null
&& uid == hotwordDetectionServiceIdentity.getIsolatedUid()) {
// Upgrade the op such that no indicators is shown for camera or audio service. This
// will bypass the permission checking for the original OP_RECORD_AUDIO and OP_CAMERA.
switch (code) {
case AppOpsManager.OP_RECORD_AUDIO:
return AppOpsManager.OP_RECORD_AUDIO_SANDBOXED;
case AppOpsManager.OP_CAMERA:
return AppOpsManager.OP_CAMERA_SANDBOXED;
}
}
return code;
}
private int resolveUid(int code, int uid) {
// The HotwordDetectionService is an isolated service, which ordinarily cannot hold
// permissions. So we allow it to assume the owning package identity for certain