Merge "Add RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO AppOp"
This commit is contained in:
committed by
Android (Google) Code Review
commit
83fbf2407d
@@ -587,6 +587,7 @@ package android.app {
|
||||
field public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
|
||||
field public static final String OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO = "android:receive_ambient_trigger_audio";
|
||||
field public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST = "android:receive_emergency_broadcast";
|
||||
field public static final String OPSTR_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO = "android:receive_explicit_user_interaction_audio";
|
||||
field public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
|
||||
field public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
|
||||
field public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.annotation.TestApi;
|
||||
@@ -1342,9 +1343,19 @@ public class AppOpsManager {
|
||||
public static final int OP_RECEIVE_AMBIENT_TRIGGER_AUDIO =
|
||||
AppProtoEnums.APP_OP_RECEIVE_AMBIENT_TRIGGER_AUDIO;
|
||||
|
||||
/**
|
||||
* Receive audio from near-field mic (ie. TV remote)
|
||||
* Allows audio recording regardless of sensor privacy state,
|
||||
* as it is an intentional user interaction: hold-to-talk
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO =
|
||||
AppProtoEnums.APP_OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO;
|
||||
|
||||
/** @hide */
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||
public static final int _NUM_OP = 121;
|
||||
public static final int _NUM_OP = 122;
|
||||
|
||||
/** Access to coarse location information. */
|
||||
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
|
||||
@@ -1816,6 +1827,18 @@ public class AppOpsManager {
|
||||
public static final String OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO =
|
||||
"android:receive_ambient_trigger_audio";
|
||||
|
||||
/**
|
||||
* Record audio from near-field microphone (ie. TV remote)
|
||||
* Allows audio recording regardless of sensor privacy state,
|
||||
* as it is an intentional user interaction: hold-to-talk
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@SuppressLint("IntentName")
|
||||
public static final String OPSTR_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO =
|
||||
"android:receive_explicit_user_interaction_audio";
|
||||
|
||||
/** {@link #sAppOpsToNote} not initialized yet for this op */
|
||||
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
|
||||
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
|
||||
@@ -2285,7 +2308,11 @@ public class AppOpsManager {
|
||||
.setDisableReset(true).setRestrictRead(true).build(),
|
||||
new AppOpInfo.Builder(OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO,
|
||||
"RECEIVE_SOUNDTRIGGER_AUDIO").setDefaultMode(AppOpsManager.MODE_ALLOWED)
|
||||
.setForceCollectNotes(true).build()
|
||||
.setForceCollectNotes(true).build(),
|
||||
new AppOpInfo.Builder(OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO,
|
||||
OPSTR_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO,
|
||||
"RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO").setDefaultMode(
|
||||
AppOpsManager.MODE_ALLOWED).build()
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -16043,6 +16043,18 @@ public final class Settings {
|
||||
public static final String KEY_CHORD_POWER_VOLUME_UP =
|
||||
"key_chord_power_volume_up";
|
||||
|
||||
/**
|
||||
* Record audio from near-field microphone (ie. TV remote)
|
||||
* Allows audio recording regardless of sensor privacy state,
|
||||
* as it is an intentional user interaction: hold-to-talk
|
||||
*
|
||||
* Type: int (0 to disable, 1 to enable)
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED =
|
||||
"receive_explicit_user_interaction_audio_enabled";
|
||||
|
||||
/**
|
||||
* Keyguard should be on the left hand side of the screen, for wide screen layouts.
|
||||
*
|
||||
|
||||
@@ -84,6 +84,7 @@ public class GlobalSettings {
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT,
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH,
|
||||
Settings.Global.POWER_BUTTON_LONG_PRESS,
|
||||
Settings.Global.RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED,
|
||||
Settings.Global.Wearable.SMART_REPLIES_ENABLED,
|
||||
Settings.Global.Wearable.CLOCKWORK_AUTO_TIME,
|
||||
Settings.Global.Wearable.CLOCKWORK_AUTO_TIME_ZONE,
|
||||
|
||||
@@ -329,6 +329,8 @@ public class GlobalSettingsValidators {
|
||||
VALIDATORS.put(Global.USER_PREFERRED_REFRESH_RATE, NON_NEGATIVE_FLOAT_VALIDATOR);
|
||||
VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_HEIGHT, ANY_INTEGER_VALIDATOR);
|
||||
VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_WIDTH, ANY_INTEGER_VALIDATOR);
|
||||
VALIDATORS.put(Global.RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED,
|
||||
new DiscreteValueValidator(new String[]{"0", "1"}));
|
||||
VALIDATORS.put(Global.Wearable.WET_MODE_ON, BOOLEAN_VALIDATOR);
|
||||
VALIDATORS.put(Global.Wearable.COOLDOWN_MODE_ON, BOOLEAN_VALIDATOR);
|
||||
VALIDATORS.put(
|
||||
|
||||
@@ -103,6 +103,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon
|
||||
AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
|
||||
AppOpsManager.OP_RECORD_AUDIO,
|
||||
AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO,
|
||||
AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO,
|
||||
AppOpsManager.OP_PHONE_CALL_MICROPHONE,
|
||||
AppOpsManager.OP_COARSE_LOCATION,
|
||||
AppOpsManager.OP_FINE_LOCATION
|
||||
|
||||
@@ -56,7 +56,8 @@ class AppOpsPrivacyItemMonitor @Inject constructor(
|
||||
val OPS_MIC_CAMERA = intArrayOf(AppOpsManager.OP_CAMERA,
|
||||
AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO,
|
||||
AppOpsManager.OP_PHONE_CALL_MICROPHONE,
|
||||
AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO)
|
||||
AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO,
|
||||
AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO)
|
||||
val OPS_LOCATION = intArrayOf(
|
||||
AppOpsManager.OP_COARSE_LOCATION,
|
||||
AppOpsManager.OP_FINE_LOCATION)
|
||||
@@ -210,6 +211,7 @@ class AppOpsPrivacyItemMonitor @Inject constructor(
|
||||
AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION
|
||||
AppOpsManager.OP_PHONE_CALL_MICROPHONE,
|
||||
AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO,
|
||||
AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO,
|
||||
AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE
|
||||
else -> return null
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ 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_RECEIVE_AMBIENT_TRIGGER_AUDIO;
|
||||
import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO;
|
||||
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
|
||||
import static android.content.Intent.EXTRA_PACKAGE_NAME;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
|
||||
@@ -81,6 +82,7 @@ import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.hardware.ISensorPrivacyListener;
|
||||
import android.hardware.ISensorPrivacyManager;
|
||||
@@ -199,6 +201,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
if (phase == PHASE_SYSTEM_SERVICES_READY) {
|
||||
mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
|
||||
mCallStateHelper = new CallStateHelper();
|
||||
mSensorPrivacyServiceImpl.registerSettingsObserver();
|
||||
} else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
|
||||
mCameraPrivacyLightController = new CameraPrivacyLightController(mContext);
|
||||
}
|
||||
@@ -271,7 +274,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
mSensorPrivacyStateController = SensorPrivacyStateController.getInstance();
|
||||
|
||||
int[] micAndCameraOps = new int[]{OP_RECORD_AUDIO, OP_PHONE_CALL_MICROPHONE,
|
||||
OP_CAMERA, OP_PHONE_CALL_CAMERA};
|
||||
OP_CAMERA, OP_PHONE_CALL_CAMERA, OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO};
|
||||
mAppOpsManager.startWatchingNoted(micAndCameraOps, this);
|
||||
mAppOpsManager.startWatchingStarted(micAndCameraOps, this);
|
||||
|
||||
@@ -340,7 +343,8 @@ public final class SensorPrivacyService extends SystemService {
|
||||
|
||||
int sensor;
|
||||
if (result == MODE_IGNORED) {
|
||||
if (code == OP_RECORD_AUDIO || code == OP_PHONE_CALL_MICROPHONE) {
|
||||
if (code == OP_RECORD_AUDIO || code == OP_PHONE_CALL_MICROPHONE
|
||||
|| code == OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO) {
|
||||
sensor = MICROPHONE;
|
||||
} else if (code == OP_CAMERA || code == OP_PHONE_CALL_CAMERA) {
|
||||
sensor = CAMERA;
|
||||
@@ -1072,6 +1076,14 @@ public final class SensorPrivacyService extends SystemService {
|
||||
// restrict it when the microphone is disabled
|
||||
mAppOpsManagerInternal.setGlobalRestriction(OP_RECEIVE_AMBIENT_TRIGGER_AUDIO,
|
||||
enabled, mAppOpsRestrictionToken);
|
||||
|
||||
// Set restriction for OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO
|
||||
boolean allowed = (Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED, 1)
|
||||
== 1);
|
||||
mAppOpsManagerInternal.setGlobalRestriction(
|
||||
OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, enabled && !allowed,
|
||||
mAppOpsRestrictionToken);
|
||||
break;
|
||||
case CAMERA:
|
||||
mAppOpsManagerInternal.setGlobalRestriction(OP_CAMERA, enabled,
|
||||
@@ -1112,6 +1124,19 @@ public final class SensorPrivacyService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void registerSettingsObserver() {
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Global.getUriFor(
|
||||
Settings.Global.RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED),
|
||||
false, new ContentObserver(mHandler) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
setGlobalRestriction(MICROPHONE,
|
||||
isCombinedToggleSensorPrivacyEnabled(MICROPHONE));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A owner of a suppressor token died. Clean up.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user