1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tv.settings.privacy;
18 
19 import android.annotation.DrawableRes;
20 import android.annotation.Nullable;
21 import android.annotation.StringRes;
22 import android.app.AppOpsManager;
23 import android.content.Context;
24 import android.hardware.SensorPrivacyManager;
25 import android.hardware.SensorPrivacyManager.Sensors.Sensor;
26 import android.provider.DeviceConfig;
27 
28 import androidx.preference.Preference;
29 
30 import com.android.tv.settings.R;
31 
32 public enum PrivacyToggle {
33     CAMERA_TOGGLE(
34             R.string.camera,
35             R.string.camera_toggle_title,
36             R.string.camera_toggle_info_title,
37             R.string.camera_toggle_info_content,
38             R.string.camera_physical_privacy_enabled_title,
39             R.string.camera_physical_privacy_enabled_text,
40             R.drawable.ic_camera_off_base,
41             R.drawable.camera_physical_privacy_enabled_panel_image,
42             R.string.camera_physical_privacy_enabled_panel_text,
43             R.string.open_camera_permissions,
44             "android.permission-group.CAMERA",
45             SensorPrivacyManager.Sensors.CAMERA,
46             new int[]{AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA},
47             "camera_toggle_enabled"
48     ),
49 
50     MIC_TOGGLE(
51             R.string.microphone,
52             R.string.mic_toggle_title,
53             R.string.mic_toggle_info_title,
54             R.string.mic_toggle_info_content,
55             R.string.microphone_physical_privacy_enabled_title,
56             R.string.microphone_physical_privacy_enabled_text,
57             R.drawable.ic_mic_off_base,
58             R.drawable.microphone_physical_privacy_enabled_panel_image,
59             R.string.microphone_physical_privacy_enabled_panel_text,
60             R.string.open_mic_permissions,
61             "android.permission-group.MICROPHONE",
62             SensorPrivacyManager.Sensors.MICROPHONE,
63             new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_PHONE_CALL_MICROPHONE,
64                     AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO},
65             "mic_toggle_enabled"
66     );
67 
68     @StringRes
69     public final int screenTitle;
70     @StringRes
71     public final int toggleTitle;
72     @StringRes
73     public final int toggleInfoTitle;
74     @StringRes
75     public final int toggleInfoText;
76     @StringRes
77     public final int appPermissionsTitle;
78     @StringRes
79     public final int physicalPrivacyEnabledInfoTitle;
80     @StringRes
81     public final int physicalPrivacyEnabledInfoText;
82     @DrawableRes
83     public final int physicalPrivacyEnabledIcon;
84     @DrawableRes
85     public final int physicalPrivacyEnabledInfoPanelImage;
86     @StringRes
87     public final int physicalPrivacyEnabledInfoPanelText;
88 
89     public final String permissionsGroupName;
90     @Sensor
91     public final int sensor;
92     public final int[] appOps;
93     public final String deviceConfigName;
94 
95 
PrivacyToggle(@tringRes int screenTitle, @StringRes int toggleTitle, @StringRes int toggleInfoTitle, @StringRes int toggleInfoText, @StringRes int physicalPrivacyEnabledInfoTitle, @StringRes int physicalPrivacyEnabledInfoText, @DrawableRes int physicalPrivacyEnabledIcon, @DrawableRes int physicalPrivacyEnabledInfoPanelImage, @StringRes int physicalPrivacyEnabledInfoPanelText, @StringRes int appPermissionsTitle, String permissionsGroupName, @Sensor int sensor, int[] appOps, String deviceConfigName)96     PrivacyToggle(@StringRes int screenTitle, @StringRes int toggleTitle,
97             @StringRes int toggleInfoTitle, @StringRes int toggleInfoText,
98             @StringRes int physicalPrivacyEnabledInfoTitle,
99             @StringRes int physicalPrivacyEnabledInfoText,
100             @DrawableRes int physicalPrivacyEnabledIcon,
101             @DrawableRes int physicalPrivacyEnabledInfoPanelImage,
102             @StringRes int physicalPrivacyEnabledInfoPanelText, @StringRes int appPermissionsTitle,
103             String permissionsGroupName, @Sensor int sensor, int[] appOps,
104             String deviceConfigName) {
105         this.screenTitle = screenTitle;
106         this.toggleTitle = toggleTitle;
107         this.toggleInfoTitle = toggleInfoTitle;
108         this.toggleInfoText = toggleInfoText;
109         this.physicalPrivacyEnabledInfoTitle = physicalPrivacyEnabledInfoTitle;
110         this.physicalPrivacyEnabledInfoText = physicalPrivacyEnabledInfoText;
111         this.physicalPrivacyEnabledIcon = physicalPrivacyEnabledIcon;
112         this.physicalPrivacyEnabledInfoPanelImage = physicalPrivacyEnabledInfoPanelImage;
113         this.physicalPrivacyEnabledInfoPanelText = physicalPrivacyEnabledInfoPanelText;
114         this.appPermissionsTitle = appPermissionsTitle;
115         this.permissionsGroupName = permissionsGroupName;
116         this.sensor = sensor;
117         this.appOps = appOps;
118         this.deviceConfigName = deviceConfigName;
119     }
120 
121     /**
122      * Checks if the privacy toggle should be shown.
123      */
isPresentAndEnabled(Context context)124     public boolean isPresentAndEnabled(Context context) {
125         return context.getSystemService(SensorPrivacyManager.class).supportsSensorToggle(
126                 sensor) && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
127                 deviceConfigName, /* defaultValue= */ true);
128     }
129 
130     /**
131      * Hides the preference if the toggle shouldn't be shown and adds the toggle to the extras so
132      * the SensorFragment knows which sensor is meant.
133      */
preparePreferenceWithSensorFragment(Context context, @Nullable Preference preference, String extrasKey)134     public void preparePreferenceWithSensorFragment(Context context,
135             @Nullable Preference preference, String extrasKey) {
136         if (preference == null) {
137             return;
138         }
139         if (isPresentAndEnabled(context)) {
140             preference.getExtras().putObject(extrasKey, this);
141         } else {
142             preference.setVisible(false);
143         }
144     }
145 }
146