1 /*
2  * Copyright (C) 2022 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 static android.provider.Settings.Global.RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED;
20 
21 import static com.android.tv.settings.util.InstrumentationUtils.logToggleInteracted;
22 import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_SUMMARY;
23 import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_TEXT;
24 import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_TITLE_ICON;
25 
26 import android.app.tvsettings.TvSettingsEnums;
27 import android.content.Context;
28 import android.graphics.drawable.Icon;
29 import android.os.Bundle;
30 import android.provider.Settings;
31 
32 import androidx.annotation.Keep;
33 import androidx.preference.Preference;
34 import androidx.preference.PreferenceCategory;
35 import androidx.preference.PreferenceScreen;
36 import androidx.preference.SwitchPreference;
37 
38 import com.android.tv.settings.R;
39 import com.android.tv.settings.overlay.FlavorUtils;
40 import com.android.tv.twopanelsettings.TwoPanelSettingsFragment;
41 import com.android.tv.twopanelsettings.slices.InfoFragment;
42 
43 /**
44  * The microphone settings screen in TV settings.
45  */
46 @Keep
47 public class MicrophoneFragment extends SensorFragment {
48     private static final String MIC_REMOTE_CATEGORY_KEY = "mic_remote_category";
49     private static final String MIC_REMOTE_TOGGLE_KEY = "mic_remote_toggle";
50     private static final String MIC_REMOTE_TOGGLE_INFO_KEY = "mic_remote_toggle_info";
51     private SwitchPreference mMicRemoteToggle;
52     private static final int DEFAULT_MIC_REMOTE_TOGGLE_STATE = 1;
53 
54     @Override
addHardwareToggle(PreferenceScreen screen, Context themedContext)55     protected final void addHardwareToggle(PreferenceScreen screen, Context themedContext) {
56         PreferenceCategory category = new PreferenceCategory(themedContext);
57         category.setKey(MIC_REMOTE_CATEGORY_KEY);
58         category.setTitle(themedContext.getString(R.string.privacy_assistant_settings_title));
59         category.setVisible(false);
60         screen.addPreference(category);
61 
62         mMicRemoteToggle = new SwitchPreference(themedContext);
63         mMicRemoteToggle.setFragment(InfoFragment.class.getCanonicalName());
64         mMicRemoteToggle.setKey(MIC_REMOTE_TOGGLE_KEY);
65         mMicRemoteToggle.setTitle(themedContext.getString(R.string.mic_remote_toggle_title));
66         mMicRemoteToggle.setChecked(getMicRemoteToggleState());
67         Bundle b = mMicRemoteToggle.getExtras();
68         b.putParcelable(EXTRA_PREFERENCE_INFO_TITLE_ICON,
69                 Icon.createWithResource(themedContext, R.drawable.ic_info_outline_base));
70         category.addPreference(mMicRemoteToggle);
71         if (!FlavorUtils.isTwoPanel(themedContext)) {
72             // Show the toggle info text beneath instead.
73             Preference toggleInfo = new Preference(themedContext);
74             toggleInfo.setKey(MIC_REMOTE_TOGGLE_INFO_KEY);
75             toggleInfo.setLayoutResource(R.layout.sensor_toggle_info);
76             toggleInfo.setSelectable(false);
77             category.addPreference(toggleInfo);
78         }
79     }
80 
getMicRemoteToggleState()81     private boolean getMicRemoteToggleState() {
82         return Settings.Global.getInt(
83                 getActivity().getContentResolver(),
84                 RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED,
85                 DEFAULT_MIC_REMOTE_TOGGLE_STATE) == 1;
86     }
87 
setMicRemoteToggleState(boolean enabled)88     private void setMicRemoteToggleState(boolean enabled) {
89         Settings.Global.putInt(getActivity().getContentResolver(),
90                 RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED,
91                 enabled ? 1 : 0);
92     }
93 
94     @Override
updateHardwareToggle()95     protected final void updateHardwareToggle() {
96         if (mMicRemoteToggle == null) {
97             return;
98         }
99         Preference remoteCategory = findPreference(MIC_REMOTE_CATEGORY_KEY);
100         if (remoteCategory != null) {
101             remoteCategory.setVisible(!mSensorToggle.isChecked());
102         }
103         Context themedContext = getPreferenceManager().getContext();
104         Bundle b = mMicRemoteToggle.getExtras();
105         b.putCharSequence(EXTRA_PREFERENCE_INFO_TEXT,
106                 themedContext.getString(
107                         mMicRemoteToggle.isChecked() ? R.string.mic_remote_toggle_on_info_title
108                                 : R.string.mic_remote_toggle_off_info_title));
109         b.putCharSequence(EXTRA_PREFERENCE_INFO_SUMMARY,
110                 themedContext.getString(
111                         mMicRemoteToggle.isChecked() ? R.string.mic_remote_toggle_on_info_content
112                                 : R.string.mic_remote_toggle_off_info_content));
113         if (!FlavorUtils.isTwoPanel(themedContext)) {
114             Preference toggleInfo = findPreference(MIC_REMOTE_TOGGLE_INFO_KEY);
115             if (toggleInfo != null) {
116                 toggleInfo.setSummary(mMicRemoteToggle.isChecked()
117                         ? R.string.mic_remote_toggle_on_info_content
118                         : R.string.mic_remote_toggle_off_info_content);
119             }
120         }
121     }
122 
123     @Override
onPreferenceTreeClick(Preference preference)124     public boolean onPreferenceTreeClick(Preference preference) {
125         if (SENSOR_TOGGLE_KEY.equals(preference.getKey())) {
126             super.onPreferenceTreeClick(preference);
127             logToggleInteracted(
128                     TvSettingsEnums.PRIVACY_MICROPHONE_ACCESS,
129                     ((SwitchPreference) preference).isChecked());
130             return true;
131         } else if (MIC_REMOTE_TOGGLE_KEY.equals(preference.getKey())) {
132             setMicRemoteToggleState(mMicRemoteToggle.isChecked());
133             updateHardwareToggle();
134             if (getParentFragment() instanceof TwoPanelSettingsFragment) {
135                 ((TwoPanelSettingsFragment) getParentFragment()).refocusPreferenceForceRefresh(
136                         mMicRemoteToggle, this);
137             }
138             logToggleInteracted(
139                     TvSettingsEnums.PRIVACY_MICROPHONE_ACCESS_ON_REMOTE,
140                     ((SwitchPreference) preference).isChecked());
141             return true;
142         }
143         return super.onPreferenceTreeClick(preference);
144     }
145 
146     @Override
getPageId()147     public int getPageId() {
148         return TvSettingsEnums.PRIVACY_MICROPHONE;
149     }
150 }
151