Merge "Update mic/cam toggles to the latest UI mocks" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
81a64e22f9
@@ -73,6 +73,13 @@ public final class SensorPrivacyManager {
|
||||
public static final String EXTRA_SENSOR = SensorPrivacyManager.class.getName()
|
||||
+ ".extra.sensor";
|
||||
|
||||
/**
|
||||
* An extra indicating if all sensors are affected
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_ALL_SENSORS = SensorPrivacyManager.class.getName()
|
||||
+ ".extra.all_sensors";
|
||||
|
||||
/**
|
||||
* Individual sensors not listed in {@link Sensors}
|
||||
* @hide
|
||||
|
||||
25
core/res/res/drawable/ic_camera_allowed.xml
Normal file
25
core/res/res/drawable/ic_camera_allowed.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M18,10.48L18,6c0,-1.1 -0.9,-2 -2,-2L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2v-4.48l4,3.98v-11l-4,3.98zM16,9.69L16,18L4,18L4,6h12v3.69z"/>
|
||||
</vector>
|
||||
@@ -1,29 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="m18,12c-2.75,0 -5,2.25 -5,5 0,2.75 2.25,5 5,5 2.75,0 5,-2.25 5,-5 0,-2.75 -2.1667,-5 -5,-5zM15.5,17.8333h5v-1.6666h-5z"
|
||||
android:fillColor="#30302a"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="m16.4,5.5004h-2.536l-1.464,-1.6H7.6l-1.464,1.6H3.6c-0.88,0 -1.6,0.72 -1.6,1.6v9.6c0,0.88 0.72,1.6 1.6,1.6h8.5413C12.0488,17.8817 12,17.4465 12,17c0,-0.1005 0.0025,-0.2004 0.0073,-0.2996H3.6V7.1004H16.4V11.2157C16.9094,11.0751 17.4459,11 18,11V7.1004c0,-0.88 -0.72,-1.6 -1.6,-1.6zM6.8,11.9004c0,-1.768 1.432,-3.2 3.2,-3.2 1.768,0 3.2,1.432 3.2,3.2 0,1.768 -1.432,3.2 -3.2,3.2 -1.768,0 -3.2,-1.432 -3.2,-3.2z"
|
||||
android:fillColor="#30302a"
|
||||
android:fillType="evenOdd"/>
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M18,10.48V6c0,-1.1 -0.9,-2 -2,-2H6.83l2,2H16v7.17l2,2v-1.65l4,3.98v-11l-4,3.98zM16,16L6,6 4,4 2.81,2.81 1.39,4.22l0.85,0.85C2.09,5.35 2,5.66 2,6v12c0,1.1 0.9,2 2,2h12c0.34,0 0.65,-0.09 0.93,-0.24l2.85,2.85 1.41,-1.41L18,18l-2,-2zM4,18V6.83L15.17,18H4z"/>
|
||||
</vector>
|
||||
|
||||
25
core/res/res/drawable/ic_mic_allowed.xml
Normal file
25
core/res/res/drawable/ic_mic_allowed.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M12,14c1.66,0 3,-1.34 3,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM11,5c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v6c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1L11,5zM17,11c0,2.76 -2.24,5 -5,5s-5,-2.24 -5,-5L5,11c0,3.53 2.61,6.43 6,6.92L11,21h2v-3.08c3.39,-0.49 6,-3.39 6,-6.92h-2z"/>
|
||||
</vector>
|
||||
@@ -1,29 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="m17,12c-2.75,0 -5,2.25 -5,5 0,2.75 2.25,5 5,5 2.75,0 5,-2.25 5,-5 0,-2.75 -2.1667,-5 -5,-5zM14.5,17.8333h5v-1.6666h-5z"
|
||||
android:fillColor="#30302a"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="m12,12c0,1.66 -1.34,3 -3,3C7.34,15 6,13.66 6,12L6,6C6,4.34 7.34,3 9,3c1.66,0 3,1.34 3,3zM9,5C8.45,5 8,5.45 8,6v6c0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1L10,6C10,5.45 9.55,5 9,5ZM11.0147,16.577C10.3983,16.849 9.7167,17 9,17 6.24,17 4,14.76 4,12L2,12c0,3.53 2.61,6.43 6,6.92L8,22h2v-3.08c0.4212,-0.0609 0.8303,-0.1589 1.2238,-0.2908C11.078,18.1111 11,17.5647 11,17c0,-0.1422 0.0049,-0.2832 0.0147,-0.423z"
|
||||
android:fillColor="#30302a"
|
||||
android:fillType="evenOdd"/>
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M11,5c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v5.17l1.82,1.82c0.11,-0.31 0.18,-0.64 0.18,-0.99V5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v1.17l2,2V5zM2.81,2.81L1.39,4.22l11.65,11.65c-0.33,0.08 -0.68,0.13 -1.04,0.13 -2.76,0 -5,-2.24 -5,-5H5c0,3.53 2.61,6.43 6,6.92V21h2v-3.08c0.57,-0.08 1.12,-0.24 1.64,-0.46l5.14,5.14 1.41,-1.41L2.81,2.81zM19,11h-2c0,0.91 -0.26,1.75 -0.69,2.48l1.46,1.46C18.54,13.82 19,12.47 19,11z"/>
|
||||
</vector>
|
||||
|
||||
@@ -5941,12 +5941,14 @@ ul.</string>
|
||||
<!-- Notification action to dismiss. [CHAR LIMIT=50] -->
|
||||
<string name="dismiss_action">Dismiss</string>
|
||||
|
||||
<!--- Content of notification triggered if the microphone is disabled but an app tried to access it. [CHAR LIMIT=NONE] -->
|
||||
<string name="sensor_privacy_start_use_mic_notification_content">To continue, <b><xliff:g id="app" example="Gmail">%s</xliff:g></b> needs access to your device microphone.</string>
|
||||
<!--- Title of notification triggered if the microphone is disabled but an app tried to access it. [CHAR LIMIT=NONE] -->
|
||||
<string name="sensor_privacy_start_use_mic_notification_content_title">Unblock device microphone</string>
|
||||
<!--- Title of notification triggered if the camera is disabled but an app tried to access it. [CHAR LIMIT=NONE] -->
|
||||
<string name="sensor_privacy_start_use_camera_notification_content_title">Unblock device camera</string>
|
||||
<!--- Content of notification triggered if the camera is disabled but an app tried to access it. [CHAR LIMIT=NONE] -->
|
||||
<string name="sensor_privacy_start_use_camera_notification_content">To continue, <b><xliff:g id="app" example="Gmail">%s</xliff:g></b> needs access to your device’s camera.</string>
|
||||
<string name="sensor_privacy_start_use_notification_content_text">For <b><xliff:g id="app" example="Gmail">%s</xliff:g></b> and all apps and services</string>
|
||||
<!--- Action button in the dialog triggered if a sensor (e.g. microphone or camera) is disabled but an app tried to access it. [CHAR LIMIT=60] -->
|
||||
<string name="sensor_privacy_start_use_dialog_turn_on_button">Turn on</string>
|
||||
<string name="sensor_privacy_start_use_dialog_turn_on_button">Unblock</string>
|
||||
<!--- Label for notification channel for all sensor privacy related notifications. [CHAR LIMIT=NONE] -->
|
||||
<string name="sensor_privacy_notification_channel_label">Sensor Privacy</string>
|
||||
|
||||
|
||||
@@ -4202,8 +4202,11 @@
|
||||
|
||||
<java-symbol type="drawable" name="ic_camera_blocked" />
|
||||
<java-symbol type="drawable" name="ic_mic_blocked" />
|
||||
<java-symbol type="string" name="sensor_privacy_start_use_mic_notification_content" />
|
||||
<java-symbol type="string" name="sensor_privacy_start_use_camera_notification_content" />
|
||||
<java-symbol type="drawable" name="ic_camera_allowed" />
|
||||
<java-symbol type="drawable" name="ic_mic_allowed" />
|
||||
<java-symbol type="string" name="sensor_privacy_start_use_mic_notification_content_title" />
|
||||
<java-symbol type="string" name="sensor_privacy_start_use_camera_notification_content_title" />
|
||||
<java-symbol type="string" name="sensor_privacy_start_use_notification_content_text" />
|
||||
<java-symbol type="string" name="sensor_privacy_start_use_dialog_turn_on_button" />
|
||||
<java-symbol type="string" name="sensor_privacy_notification_channel_label" />
|
||||
|
||||
|
||||
53
packages/SystemUI/res/layout/sensor_use_started_title.xml
Normal file
53
packages/SystemUI/res/layout/sensor_use_started_title.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingTop="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center">
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:id="@+id/sensor_use_camera_icon"
|
||||
android:src="@*android:drawable/perm_group_camera"
|
||||
android:tint="?android:attr/colorAccent"
|
||||
android:visibility="gone" />
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:id="@+id/sensor_use_microphone_icon"
|
||||
android:src="@*android:drawable/perm_group_microphone"
|
||||
android:tint="?android:attr/colorAccent"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
<com.android.internal.widget.DialogTitle
|
||||
android:id="@+id/sensor_use_started_title_message"
|
||||
style="@android:style/TextAppearance.DeviceDefault.WindowTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center" />
|
||||
</LinearLayout>
|
||||
@@ -832,9 +832,13 @@
|
||||
<!-- QuickSettings: Location (Off) [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_location_off_label">Location Off</string>
|
||||
<!-- QuickSettings: Camera [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_camera_label">Block Camera</string>
|
||||
<string name="quick_settings_camera_label">Camera access</string>
|
||||
<!-- QuickSettings: Microphone [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_mic_label">Mute Microphone</string>
|
||||
<string name="quick_settings_mic_label">Mic access</string>
|
||||
<!-- QuickSettings: Camera or microphone access is allowed [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_camera_mic_available">Available</string>
|
||||
<!-- QuickSettings: Camera or microphone access is blocked [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_camera_mic_blocked">Blocked</string>
|
||||
<!-- QuickSettings: Media device [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_media_device_label">Media device</string>
|
||||
<!-- QuickSettings: RSSI [CHAR LIMIT=NONE] -->
|
||||
@@ -981,10 +985,19 @@
|
||||
<!-- QuickSettings: Text to prompt the user to stop an ongoing recording [CHAR LIMIT=20] -->
|
||||
<string name="quick_settings_screen_record_stop">Stop</string>
|
||||
|
||||
<!--- Title of dialog triggered if the microphone is disabled but an app tried to access it. [CHAR LIMIT=150] -->
|
||||
<string name="sensor_privacy_start_use_mic_dialog_title">Unblock device microphone?</string>
|
||||
<!--- Title of dialog triggered if the camera is disabled but an app tried to access it. [CHAR LIMIT=150] -->
|
||||
<string name="sensor_privacy_start_use_camera_dialog_title">Unblock device camera?</string>
|
||||
<!--- Title of dialog triggered if the camera is disabled but an app tried to access it. [CHAR LIMIT=150] -->
|
||||
<string name="sensor_privacy_start_use_mic_camera_dialog_title">Unblock device camera and microphone?</string>
|
||||
|
||||
<!--- Content of dialog triggered if the microphone is disabled but an app tried to access it. [CHAR LIMIT=NONE] -->
|
||||
<string name="sensor_privacy_start_use_mic_dialog_content">To continue, <b><xliff:g id="app" example="Gmail">%s</xliff:g></b> needs access to your device microphone.</string>
|
||||
<string name="sensor_privacy_start_use_mic_dialog_content">This unblocks access for all apps and services allowed to use your microphone.</string>
|
||||
<!--- Content of dialog triggered if the camera is disabled but an app tried to access it. [CHAR LIMIT=NONE] -->
|
||||
<string name="sensor_privacy_start_use_camera_dialog_content">To continue, <b><xliff:g id="app" example="Gmail">%s</xliff:g></b> needs access to your device’s camera.</string>
|
||||
<string name="sensor_privacy_start_use_camera_dialog_content">This unblocks access for all apps and services allowed to use your camera.</string>
|
||||
<!--- Content of dialog triggered if the camera is disabled but an app tried to access it. [CHAR LIMIT=NONE] -->
|
||||
<string name="sensor_privacy_start_use_mic_camera_dialog_content">This unblocks access for all apps and services allowed to use your camera or microphone.</string>
|
||||
|
||||
<!-- Default name for the media device shown in the output switcher when the name is not available [CHAR LIMIT=30] -->
|
||||
<string name="media_seamless_remote_device">Device</string>
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.android.systemui.people.PeopleSpaceActivity;
|
||||
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.settings.brightness.BrightnessDialog;
|
||||
import com.android.systemui.statusbar.tv.notifications.TvNotificationPanelActivity;
|
||||
import com.android.systemui.tuner.TunerActivity;
|
||||
@@ -113,4 +114,10 @@ public abstract class DefaultActivityBinder {
|
||||
@IntoMap
|
||||
@ClassKey(LaunchConversationActivity.class)
|
||||
public abstract Activity bindLaunchConversationActivity(LaunchConversationActivity activity);
|
||||
|
||||
/** Inject into SensorUseStartedActivity. */
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(SensorUseStartedActivity.class)
|
||||
public abstract Activity bindSensorUseStartedActivity(SensorUseStartedActivity activity);
|
||||
}
|
||||
|
||||
@@ -70,8 +70,12 @@ public class CameraToggleTile extends SensorPrivacyToggleTile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @DrawableRes int getIconRes() {
|
||||
return com.android.internal.R.drawable.ic_camera_blocked;
|
||||
public @DrawableRes int getIconRes(boolean isBlocked) {
|
||||
if (isBlocked) {
|
||||
return com.android.internal.R.drawable.ic_camera_blocked;
|
||||
} else {
|
||||
return com.android.internal.R.drawable.ic_camera_allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,8 +71,12 @@ public class MicrophoneToggleTile extends SensorPrivacyToggleTile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @DrawableRes int getIconRes() {
|
||||
return com.android.internal.R.drawable.ic_mic_blocked;
|
||||
public @DrawableRes int getIconRes(boolean isBlocked) {
|
||||
if (isBlocked) {
|
||||
return com.android.internal.R.drawable.ic_mic_blocked;
|
||||
} else {
|
||||
return com.android.internal.R.drawable.ic_mic_allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,10 +26,12 @@ import android.widget.Switch;
|
||||
import androidx.annotation.DrawableRes;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.plugins.qs.DetailAdapter;
|
||||
import com.android.systemui.plugins.qs.QSTile;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.qs.QSHost;
|
||||
@@ -55,7 +57,7 @@ public abstract class SensorPrivacyToggleTile extends QSTileImpl<QSTile.BooleanS
|
||||
/**
|
||||
* @return icon for the QS tile
|
||||
*/
|
||||
public abstract @DrawableRes int getIconRes();
|
||||
public abstract @DrawableRes int getIconRes(boolean isBlocked);
|
||||
|
||||
protected SensorPrivacyToggleTile(QSHost host,
|
||||
@Background Looper backgroundLooper,
|
||||
@@ -97,10 +99,15 @@ public abstract class SensorPrivacyToggleTile extends QSTileImpl<QSTile.BooleanS
|
||||
boolean isBlocked = arg == null ? mSensorPrivacyController.isSensorBlocked(getSensorId())
|
||||
: (boolean) arg;
|
||||
|
||||
state.icon = ResourceIcon.get(getIconRes());
|
||||
state.state = isBlocked ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
|
||||
state.value = isBlocked;
|
||||
state.icon = ResourceIcon.get(getIconRes(isBlocked));
|
||||
state.state = isBlocked ? Tile.STATE_INACTIVE : Tile.STATE_ACTIVE;
|
||||
state.value = !isBlocked;
|
||||
state.label = getTileLabel();
|
||||
if (isBlocked) {
|
||||
state.secondaryLabel = mContext.getString(R.string.quick_settings_camera_mic_blocked);
|
||||
} else {
|
||||
state.secondaryLabel = mContext.getString(R.string.quick_settings_camera_mic_available);
|
||||
}
|
||||
state.handlesLongClick = false;
|
||||
state.contentDescription = state.label;
|
||||
state.expandedAccessibilityClassName = Switch.class.getName();
|
||||
@@ -116,6 +123,11 @@ public abstract class SensorPrivacyToggleTile extends QSTileImpl<QSTile.BooleanS
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DetailAdapter getDetailAdapter() {
|
||||
return super.getDetailAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorBlockedChanged(int sensor, boolean blocked) {
|
||||
if (sensor == getSensorId()) {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.systemui.sensorprivacy
|
||||
|
||||
import android.app.AppOpsManager
|
||||
import android.app.KeyguardManager
|
||||
import android.app.KeyguardManager.KeyguardDismissCallback
|
||||
import android.content.DialogInterface
|
||||
@@ -24,15 +23,22 @@ import android.content.Intent.EXTRA_PACKAGE_NAME
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
import android.hardware.SensorPrivacyManager
|
||||
import android.hardware.SensorPrivacyManager.EXTRA_ALL_SENSORS
|
||||
import android.hardware.SensorPrivacyManager.EXTRA_SENSOR
|
||||
import android.hardware.SensorPrivacyManager.Sensors.CAMERA
|
||||
import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.text.Html
|
||||
import android.util.Log
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.widget.ImageView
|
||||
import com.android.internal.app.AlertActivity
|
||||
import com.android.internal.widget.DialogTitle
|
||||
import com.android.keyguard.KeyguardUpdateMonitor
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Dialog to be shown on top of apps that are attempting to use a sensor (e.g. microphone) which is
|
||||
@@ -40,21 +46,27 @@ import com.android.systemui.R
|
||||
*
|
||||
* <p>The dialog is started for the user the app is running for which might be a secondary users.
|
||||
*/
|
||||
class SensorUseStartedActivity : AlertActivity(), DialogInterface.OnClickListener {
|
||||
class SensorUseStartedActivity @Inject constructor(
|
||||
private val sensorPrivacyController: IndividualSensorPrivacyController,
|
||||
private val keyguardManager: KeyguardManager,
|
||||
private val keyguardUpdateMonitor: KeyguardUpdateMonitor
|
||||
) : AlertActivity(), DialogInterface.OnClickListener {
|
||||
|
||||
companion object {
|
||||
private val LOG_TAG = SensorUseStartedActivity::class.java.simpleName
|
||||
|
||||
private const val SUPPRESS_REMINDERS_REMOVAL_DELAY_MILLIS = 2000L
|
||||
|
||||
private const val CAMERA = SensorPrivacyManager.Sensors.CAMERA
|
||||
private const val MICROPHONE = SensorPrivacyManager.Sensors.MICROPHONE
|
||||
private const val ALL_SENSORS = Integer.MAX_VALUE
|
||||
}
|
||||
|
||||
private var sensor = -1
|
||||
private lateinit var sensorUsePackageName: String
|
||||
private var unsuppressImmediately = false
|
||||
|
||||
private lateinit var sensorPrivacyManager: SensorPrivacyManager
|
||||
private lateinit var appOpsManager: AppOpsManager
|
||||
private lateinit var keyguardManager: KeyguardManager
|
||||
private lateinit var sensorPrivacyListener: IndividualSensorPrivacyController.Callback
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -64,35 +76,81 @@ class SensorUseStartedActivity : AlertActivity(), DialogInterface.OnClickListene
|
||||
setFinishOnTouchOutside(false)
|
||||
|
||||
setResult(RESULT_CANCELED)
|
||||
sensorPrivacyManager = getSystemService(SensorPrivacyManager::class.java)!!
|
||||
appOpsManager = getSystemService(AppOpsManager::class.java)!!
|
||||
keyguardManager = getSystemService(KeyguardManager::class.java)!!
|
||||
|
||||
sensorUsePackageName = intent.getStringExtra(EXTRA_PACKAGE_NAME) ?: return
|
||||
sensor = intent.getIntExtra(EXTRA_SENSOR, -1).also {
|
||||
if (it == -1) {
|
||||
|
||||
if (intent.getBooleanExtra(EXTRA_ALL_SENSORS, false)) {
|
||||
sensor = ALL_SENSORS
|
||||
sensorPrivacyListener =
|
||||
IndividualSensorPrivacyController.Callback { _, _ ->
|
||||
if (!sensorPrivacyController.isSensorBlocked(MICROPHONE) &&
|
||||
!sensorPrivacyController.isSensorBlocked(CAMERA)) {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
sensorPrivacyController.addCallback(sensorPrivacyListener)
|
||||
if (!sensorPrivacyController.isSensorBlocked(MICROPHONE) &&
|
||||
!sensorPrivacyController.isSensorBlocked(CAMERA)) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
sensor = intent.getIntExtra(EXTRA_SENSOR, -1).also {
|
||||
if (it == -1) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
}
|
||||
sensorPrivacyListener =
|
||||
IndividualSensorPrivacyController.Callback {
|
||||
whichSensor: Int, isBlocked: Boolean ->
|
||||
if (whichSensor == sensor && !isBlocked) {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
sensorPrivacyController.addCallback(sensorPrivacyListener)
|
||||
|
||||
if (!sensorPrivacyController.isSensorBlocked(sensor)) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sensorPrivacyManager.addSensorPrivacyListener(sensor) { isBlocked ->
|
||||
if (!isBlocked) {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
if (!sensorPrivacyManager.isSensorPrivacyEnabled(sensor)) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
mAlertParams.apply {
|
||||
try {
|
||||
mCustomTitleView = mInflater.inflate(R.layout.sensor_use_started_title, null)
|
||||
mCustomTitleView.findViewById<DialogTitle>(R.id.sensor_use_started_title_message)!!
|
||||
.setText(when (sensor) {
|
||||
MICROPHONE ->
|
||||
R.string.sensor_privacy_start_use_mic_dialog_title
|
||||
CAMERA ->
|
||||
R.string.sensor_privacy_start_use_camera_dialog_title
|
||||
ALL_SENSORS ->
|
||||
R.string.sensor_privacy_start_use_mic_camera_dialog_title
|
||||
else -> Resources.ID_NULL
|
||||
})
|
||||
|
||||
mCustomTitleView.findViewById<ImageView>(R.id.sensor_use_microphone_icon)!!
|
||||
.visibility = if (sensor == MICROPHONE || sensor == ALL_SENSORS) {
|
||||
VISIBLE
|
||||
} else {
|
||||
GONE
|
||||
}
|
||||
mCustomTitleView.findViewById<ImageView>(R.id.sensor_use_camera_icon)!!
|
||||
.visibility = if (sensor == CAMERA || sensor == ALL_SENSORS) {
|
||||
VISIBLE
|
||||
} else {
|
||||
GONE
|
||||
}
|
||||
|
||||
mMessage = Html.fromHtml(getString(when (sensor) {
|
||||
MICROPHONE ->
|
||||
R.string.sensor_privacy_start_use_mic_dialog_content
|
||||
CAMERA ->
|
||||
R.string.sensor_privacy_start_use_camera_dialog_content
|
||||
ALL_SENSORS ->
|
||||
R.string.sensor_privacy_start_use_mic_camera_dialog_content
|
||||
else -> Resources.ID_NULL
|
||||
}, packageManager.getApplicationInfo(sensorUsePackageName, 0)
|
||||
.loadLabel(packageManager)), 0)
|
||||
@@ -101,13 +159,6 @@ class SensorUseStartedActivity : AlertActivity(), DialogInterface.OnClickListene
|
||||
return
|
||||
}
|
||||
|
||||
mIconId = when (sensor) {
|
||||
MICROPHONE ->
|
||||
com.android.internal.R.drawable.perm_group_microphone
|
||||
CAMERA -> com.android.internal.R.drawable.perm_group_camera
|
||||
else -> Resources.ID_NULL
|
||||
}
|
||||
|
||||
mPositiveButtonText = getString(
|
||||
com.android.internal.R.string.sensor_privacy_start_use_dialog_turn_on_button)
|
||||
mNegativeButtonText = getString(android.R.string.cancel)
|
||||
@@ -121,14 +172,14 @@ class SensorUseStartedActivity : AlertActivity(), DialogInterface.OnClickListene
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
sensorPrivacyManager.suppressSensorPrivacyReminders(sensorUsePackageName, true)
|
||||
sensorPrivacyController.suppressSensorPrivacyReminders(sensorUsePackageName, true)
|
||||
unsuppressImmediately = false
|
||||
}
|
||||
|
||||
override fun onClick(dialog: DialogInterface?, which: Int) {
|
||||
when (which) {
|
||||
BUTTON_POSITIVE -> {
|
||||
if (keyguardManager.isDeviceLocked) {
|
||||
if (keyguardUpdateMonitor.getUserHasTrust(userId)) {
|
||||
keyguardManager
|
||||
.requestDismissKeyguard(this, object : KeyguardDismissCallback() {
|
||||
override fun onDismissError() {
|
||||
@@ -152,25 +203,30 @@ class SensorUseStartedActivity : AlertActivity(), DialogInterface.OnClickListene
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onDestroy()
|
||||
super.onStop()
|
||||
|
||||
if (unsuppressImmediately) {
|
||||
sensorPrivacyManager
|
||||
sensorPrivacyController
|
||||
.suppressSensorPrivacyReminders(sensorUsePackageName, false)
|
||||
} else {
|
||||
Handler(mainLooper).postDelayed({
|
||||
sensorPrivacyManager
|
||||
sensorPrivacyController
|
||||
.suppressSensorPrivacyReminders(sensorUsePackageName, false)
|
||||
}, SUPPRESS_REMINDERS_REMOVAL_DELAY_MILLIS)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
sensorPrivacyController.removeCallback(sensorPrivacyListener)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
// do not allow backing out
|
||||
}
|
||||
|
||||
private fun disableSensorPrivacy() {
|
||||
sensorPrivacyManager.setSensorPrivacyForProfileGroup(sensor, false)
|
||||
sensorPrivacyController.setSensorBlocked(sensor, false)
|
||||
unsuppressImmediately = true
|
||||
setResult(RESULT_OK)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ public interface IndividualSensorPrivacyController extends
|
||||
|
||||
void setSensorBlocked(@Sensor int sensor, boolean blocked);
|
||||
|
||||
void suppressSensorPrivacyReminders(String packageName, boolean suppress);
|
||||
|
||||
interface Callback {
|
||||
void onSensorBlockedChanged(@Sensor int sensor, boolean blocked);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,11 @@ public class IndividualSensorPrivacyControllerImpl implements IndividualSensorPr
|
||||
mSensorPrivacyManager.setSensorPrivacyForProfileGroup(sensor, blocked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suppressSensorPrivacyReminders(String packageName, boolean suppress) {
|
||||
mSensorPrivacyManager.suppressSensorPrivacyReminders(packageName, suppress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCallback(@NonNull Callback listener) {
|
||||
mCallbacks.add(listener);
|
||||
|
||||
@@ -63,6 +63,7 @@ import android.os.ResultReceiver;
|
||||
import android.os.ShellCallback;
|
||||
import android.os.ShellCommand;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.SensorPrivacyIndividualEnabledSensorProto;
|
||||
import android.service.SensorPrivacyServiceDumpProto;
|
||||
import android.service.SensorPrivacyUserProto;
|
||||
@@ -368,10 +369,10 @@ public final class SensorPrivacyService extends SystemService {
|
||||
|
||||
if (sensor == MICROPHONE) {
|
||||
iconRes = R.drawable.ic_mic_blocked;
|
||||
messageRes = R.string.sensor_privacy_start_use_mic_notification_content;
|
||||
messageRes = R.string.sensor_privacy_start_use_mic_notification_content_title;
|
||||
} else {
|
||||
iconRes = R.drawable.ic_camera_blocked;
|
||||
messageRes = R.string.sensor_privacy_start_use_camera_notification_content;
|
||||
messageRes = R.string.sensor_privacy_start_use_camera_notification_content_title;
|
||||
}
|
||||
|
||||
NotificationManager notificationManager =
|
||||
@@ -390,10 +391,11 @@ public final class SensorPrivacyService extends SystemService {
|
||||
Icon icon = Icon.createWithResource(getUiContext().getResources(), iconRes);
|
||||
notificationManager.notify(sensor,
|
||||
new Notification.Builder(mContext, SENSOR_PRIVACY_CHANNEL_ID)
|
||||
.setContentTitle(Html.fromHtml(getUiContext().getString(messageRes,
|
||||
.setContentTitle(getUiContext().getString(messageRes))
|
||||
.setContentText(Html.fromHtml(getUiContext().getString(
|
||||
R.string.sensor_privacy_start_use_notification_content_text,
|
||||
packageLabel),0))
|
||||
.setSmallIcon(icon)
|
||||
.setLargeIcon(icon)
|
||||
.addAction(new Notification.Action.Builder(icon,
|
||||
getUiContext().getString(
|
||||
R.string.sensor_privacy_start_use_dialog_turn_on_button),
|
||||
@@ -405,6 +407,10 @@ public final class SensorPrivacyService extends SystemService {
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
| PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.build())
|
||||
.setContentIntent(PendingIntent.getActivity(mContext, sensor,
|
||||
new Intent(Settings.ACTION_PRIVACY_SETTINGS),
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
| PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user