diff options
| author | 2021-05-17 08:55:28 +0000 | |
|---|---|---|
| committer | 2021-06-17 12:30:11 +0000 | |
| commit | 536a5f789fc8f34df9264c568a825232b7829c7a (patch) | |
| tree | af76b9517ba59309304bec73e473fae51698921f | |
| parent | 2463594fdd27fa3bef21b3309db30a9706a11dba (diff) | |
Show a bottom sheet when the mic/camera is blocked
On mobile a normal dialog is shown when a sensor is blocked by the
global toggle.
Bug: 186720017
Test: manual
For one sensor and both sensors together:
1) Block sensor(s) in settings or with 'adb shell cmd sensor_privacy enable 0 microphone' (/camera)
2) open the Duo app
3) Try to access blocked sensor(s): 'adb shell appops start
com.google.android.apps.tachyon 27' (/26)
4) Sensor(s) should be unblocked if 'unblock' is selected or remain
blocked if cancelled (check in settings or 'adb shell dumpsys sensor_prvacy' where disabled means unblocked or privacy indicator will show up)
Change-Id: I69fb67478460d05acf6b1d570705dc4f73ca8d1e
4 files changed, 164 insertions, 0 deletions
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml index 3ecb1dddd916..55e5685b95e5 100644 --- a/core/res/res/values-television/config.xml +++ b/core/res/res/values-television/config.xml @@ -42,4 +42,8 @@ <!-- Allow SystemUI to show the shutdown dialog --> <bool name="config_showSysuiShutdown">true</bool> + + <!-- Component name of the activity used to inform a user about a sensory being blocked because + of privacy settings. --> + <string name="config_sensorUseStartedActivity">com.android.systemui/com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity</string> </resources> diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 8c092ae37222..604310a9e905 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -454,6 +454,14 @@ android:finishOnCloseSystemDialogs="true"> </activity> + <!-- started from SensoryPrivacyService --> + <activity android:name=".sensorprivacy.television.TvUnblockSensorActivity" + android:exported="true" + android:permission="android.permission.MANAGE_SENSOR_PRIVACY" + android:theme="@style/BottomSheet" + android:finishOnCloseSystemDialogs="true"> + </activity> + <!-- started from UsbDeviceSettingsManager --> <activity android:name=".usb.UsbAccessoryUriActivity" diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java index 2dbf30fdd289..de8ed7013ab2 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java @@ -25,6 +25,7 @@ import com.android.systemui.people.widget.LaunchConversationActivity; import com.android.systemui.screenrecord.ScreenRecordDialog; import com.android.systemui.screenshot.LongScreenshotActivity; import com.android.systemui.sensorprivacy.SensorUseStartedActivity; +import com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity; import com.android.systemui.settings.brightness.BrightnessDialog; import com.android.systemui.statusbar.tv.notifications.TvNotificationPanelActivity; import com.android.systemui.tuner.TunerActivity; @@ -120,4 +121,10 @@ public abstract class DefaultActivityBinder { @IntoMap @ClassKey(SensorUseStartedActivity.class) public abstract Activity bindSensorUseStartedActivity(SensorUseStartedActivity activity); + + /** Inject into TvUnblockSensorActivity. */ + @Binds + @IntoMap + @ClassKey(TvUnblockSensorActivity.class) + public abstract Activity bindTvUnblockSensorActivity(TvUnblockSensorActivity activity); } diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java b/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java new file mode 100644 index 000000000000..9d101effa99f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.sensorprivacy.television; + +import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; +import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; + +import android.hardware.SensorPrivacyManager; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.systemui.R; +import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController; +import com.android.systemui.tv.TvBottomSheetActivity; + +import javax.inject.Inject; + +/** + * Bottom sheet that is shown when the camera/mic sensors are blocked by the global toggle and + * allows the user to re-enable them. + */ +public class TvUnblockSensorActivity extends TvBottomSheetActivity { + + private static final String TAG = TvUnblockSensorActivity.class.getSimpleName(); + + private static final int ALL_SENSORS = Integer.MAX_VALUE; + private int mSensor = -1; + + private final IndividualSensorPrivacyController mSensorPrivacyController; + private IndividualSensorPrivacyController.Callback mSensorPrivacyCallback; + + @Inject + public TvUnblockSensorActivity( + IndividualSensorPrivacyController individualSensorPrivacyController) { + mSensorPrivacyController = individualSensorPrivacyController; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + boolean allSensors = getIntent().getBooleanExtra(SensorPrivacyManager.EXTRA_ALL_SENSORS, + false); + if (allSensors) { + mSensor = ALL_SENSORS; + } else { + mSensor = getIntent().getIntExtra(SensorPrivacyManager.EXTRA_SENSOR, -1); + } + + if (mSensor == -1) { + Log.v(TAG, "Invalid extras"); + finish(); + return; + } + + mSensorPrivacyCallback = (sensor, blocked) -> { + if (mSensor == ALL_SENSORS) { + if (!mSensorPrivacyController.isSensorBlocked(CAMERA) + && !mSensorPrivacyController.isSensorBlocked(MICROPHONE)) { + finish(); + } + } else if (this.mSensor == sensor && !blocked) { + finish(); + } + }; + + initUI(); + } + + private void initUI() { + TextView title = findViewById(R.id.bottom_sheet_title); + TextView content = findViewById(R.id.bottom_sheet_body); + ImageView icon = findViewById(R.id.bottom_sheet_icon); + // mic icon if both icons are shown + ImageView secondIcon = findViewById(R.id.bottom_sheet_second_icon); + Button unblockButton = findViewById(R.id.bottom_sheet_positive_button); + Button cancelButton = findViewById(R.id.bottom_sheet_negative_button); + + switch (mSensor) { + case MICROPHONE: + title.setText(R.string.sensor_privacy_start_use_mic_dialog_title); + content.setText(R.string.sensor_privacy_start_use_mic_dialog_content); + icon.setImageResource(com.android.internal.R.drawable.perm_group_microphone); + secondIcon.setVisibility(View.GONE); + break; + case CAMERA: + title.setText(R.string.sensor_privacy_start_use_camera_dialog_title); + content.setText(R.string.sensor_privacy_start_use_camera_dialog_content); + icon.setImageResource(com.android.internal.R.drawable.perm_group_camera); + secondIcon.setVisibility(View.GONE); + break; + case ALL_SENSORS: + default: + title.setText(R.string.sensor_privacy_start_use_mic_camera_dialog_title); + content.setText(R.string.sensor_privacy_start_use_mic_camera_dialog_content); + icon.setImageResource(com.android.internal.R.drawable.perm_group_camera); + secondIcon.setImageResource(com.android.internal.R.drawable.perm_group_microphone); + break; + } + unblockButton.setText( + com.android.internal.R.string.sensor_privacy_start_use_dialog_turn_on_button); + unblockButton.setOnClickListener(v -> { + if (mSensor == ALL_SENSORS) { + mSensorPrivacyController.setSensorBlocked(CAMERA, false); + mSensorPrivacyController.setSensorBlocked(MICROPHONE, false); + } else { + mSensorPrivacyController.setSensorBlocked(mSensor, false); + } + }); + + cancelButton.setText(android.R.string.cancel); + cancelButton.setOnClickListener(v -> finish()); + } + + @Override + public void onResume() { + super.onResume(); + mSensorPrivacyController.addCallback(mSensorPrivacyCallback); + } + + @Override + public void onPause() { + mSensorPrivacyController.removeCallback(mSensorPrivacyCallback); + super.onPause(); + } + +} |