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