1 /* 2 * Copyright (C) 2018 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.settings.gestures; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.database.ContentObserver; 22 import android.net.Uri; 23 import android.os.Bundle; 24 import android.os.Handler; 25 import android.provider.Settings; 26 27 import androidx.preference.Preference; 28 import androidx.preference.PreferenceCategory; 29 import androidx.preference.PreferenceScreen; 30 31 import com.android.internal.annotations.VisibleForTesting; 32 import com.android.settings.R; 33 import com.android.settings.core.PreferenceControllerMixin; 34 import com.android.settings.widget.RadioButtonPreference; 35 import com.android.settings.widget.VideoPreference; 36 import com.android.settingslib.core.AbstractPreferenceController; 37 import com.android.settingslib.core.lifecycle.Lifecycle; 38 import com.android.settingslib.core.lifecycle.LifecycleObserver; 39 import com.android.settingslib.core.lifecycle.events.OnCreate; 40 import com.android.settingslib.core.lifecycle.events.OnPause; 41 import com.android.settingslib.core.lifecycle.events.OnResume; 42 import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; 43 44 public class PreventRingingGesturePreferenceController extends AbstractPreferenceController 45 implements RadioButtonPreference.OnClickListener, LifecycleObserver, OnSaveInstanceState, 46 OnResume, OnPause, OnCreate, PreferenceControllerMixin { 47 48 @VisibleForTesting 49 static final String KEY_VIBRATE = "prevent_ringing_option_vibrate"; 50 51 @VisibleForTesting 52 static final String KEY_MUTE = "prevent_ringing_option_mute"; 53 54 private final String KEY_VIDEO_PAUSED = "key_video_paused"; 55 private final String PREF_KEY_VIDEO = "gesture_prevent_ringing_video"; 56 private final String KEY = "gesture_prevent_ringing_category"; 57 private final Context mContext; 58 59 private VideoPreference mVideoPreference; 60 private boolean mVideoPaused; 61 62 @VisibleForTesting 63 PreferenceCategory mPreferenceCategory; 64 @VisibleForTesting 65 RadioButtonPreference mVibratePref; 66 @VisibleForTesting 67 RadioButtonPreference mMutePref; 68 69 private SettingObserver mSettingObserver; 70 PreventRingingGesturePreferenceController(Context context, Lifecycle lifecycle)71 public PreventRingingGesturePreferenceController(Context context, Lifecycle lifecycle) { 72 super(context); 73 mContext = context; 74 75 if (lifecycle != null) { 76 lifecycle.addObserver(this); 77 } 78 } 79 80 @Override displayPreference(PreferenceScreen screen)81 public void displayPreference(PreferenceScreen screen) { 82 super.displayPreference(screen); 83 if (!isAvailable()) { 84 return; 85 } 86 mPreferenceCategory = screen.findPreference(getPreferenceKey()); 87 mVibratePref = makeRadioPreference(KEY_VIBRATE, R.string.prevent_ringing_option_vibrate); 88 mMutePref = makeRadioPreference(KEY_MUTE, R.string.prevent_ringing_option_mute); 89 90 if (mPreferenceCategory != null) { 91 mSettingObserver = new SettingObserver(mPreferenceCategory); 92 } 93 94 mVideoPreference = screen.findPreference(getVideoPrefKey()); 95 } 96 97 @Override isAvailable()98 public boolean isAvailable() { 99 return mContext.getResources().getBoolean( 100 com.android.internal.R.bool.config_volumeHushGestureEnabled); 101 } 102 103 @Override getPreferenceKey()104 public String getPreferenceKey() { 105 return KEY; 106 } 107 getVideoPrefKey()108 public String getVideoPrefKey() { 109 return PREF_KEY_VIDEO; 110 } 111 112 @Override onSaveInstanceState(Bundle outState)113 public void onSaveInstanceState(Bundle outState) { 114 outState.putBoolean(KEY_VIDEO_PAUSED, mVideoPaused); 115 } 116 117 @Override onRadioButtonClicked(RadioButtonPreference preference)118 public void onRadioButtonClicked(RadioButtonPreference preference) { 119 int preventRingingSetting = keyToSetting(preference.getKey()); 120 if (preventRingingSetting != Settings.Secure.getInt(mContext.getContentResolver(), 121 Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE)) { 122 Settings.Secure.putInt(mContext.getContentResolver(), 123 Settings.Secure.VOLUME_HUSH_GESTURE, preventRingingSetting); 124 } 125 } 126 127 @Override updateState(Preference preference)128 public void updateState(Preference preference) { 129 int preventRingingSetting = Settings.Secure.getInt(mContext.getContentResolver(), 130 Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE); 131 final boolean isVibrate = preventRingingSetting == Settings.Secure.VOLUME_HUSH_VIBRATE; 132 final boolean isMute = preventRingingSetting == Settings.Secure.VOLUME_HUSH_MUTE; 133 if (mVibratePref != null && mVibratePref.isChecked() != isVibrate) { 134 mVibratePref.setChecked(isVibrate); 135 } 136 if (mMutePref != null && mMutePref.isChecked() != isMute) { 137 mMutePref.setChecked(isMute); 138 } 139 140 if (preventRingingSetting == Settings.Secure.VOLUME_HUSH_OFF) { 141 mVibratePref.setEnabled(false); 142 mMutePref.setEnabled(false); 143 } else { 144 mVibratePref.setEnabled(true); 145 mMutePref.setEnabled(true); 146 } 147 } 148 149 @Override onCreate(Bundle savedInstanceState)150 public void onCreate(Bundle savedInstanceState) { 151 if (savedInstanceState != null) { 152 mVideoPaused = savedInstanceState.getBoolean(KEY_VIDEO_PAUSED, false); 153 } 154 } 155 156 @Override onResume()157 public void onResume() { 158 if (mSettingObserver != null) { 159 mSettingObserver.register(mContext.getContentResolver()); 160 mSettingObserver.onChange(false, null); 161 } 162 163 if (mVideoPreference != null) { 164 mVideoPreference.onViewVisible(mVideoPaused); 165 } 166 } 167 168 @Override onPause()169 public void onPause() { 170 if (mSettingObserver != null) { 171 mSettingObserver.unregister(mContext.getContentResolver()); 172 } 173 174 if (mVideoPreference != null) { 175 mVideoPaused = mVideoPreference.isVideoPaused(); 176 mVideoPreference.onViewInvisible(); 177 } 178 } 179 keyToSetting(String key)180 private int keyToSetting(String key) { 181 switch (key) { 182 case KEY_MUTE: 183 return Settings.Secure.VOLUME_HUSH_MUTE; 184 case KEY_VIBRATE: 185 return Settings.Secure.VOLUME_HUSH_VIBRATE; 186 default: 187 return Settings.Secure.VOLUME_HUSH_OFF; 188 } 189 } 190 makeRadioPreference(String key, int titleId)191 private RadioButtonPreference makeRadioPreference(String key, int titleId) { 192 RadioButtonPreference pref = new RadioButtonPreference(mPreferenceCategory.getContext()); 193 pref.setKey(key); 194 pref.setTitle(titleId); 195 pref.setOnClickListener(this); 196 mPreferenceCategory.addPreference(pref); 197 return pref; 198 } 199 200 private class SettingObserver extends ContentObserver { 201 private final Uri VOLUME_HUSH_GESTURE = Settings.Secure.getUriFor( 202 Settings.Secure.VOLUME_HUSH_GESTURE); 203 204 private final Preference mPreference; 205 SettingObserver(Preference preference)206 public SettingObserver(Preference preference) { 207 super(new Handler()); 208 mPreference = preference; 209 } 210 register(ContentResolver cr)211 public void register(ContentResolver cr) { 212 cr.registerContentObserver(VOLUME_HUSH_GESTURE, false, this); 213 } 214 unregister(ContentResolver cr)215 public void unregister(ContentResolver cr) { 216 cr.unregisterContentObserver(this); 217 } 218 219 @Override onChange(boolean selfChange, Uri uri)220 public void onChange(boolean selfChange, Uri uri) { 221 super.onChange(selfChange, uri); 222 if (uri == null || VOLUME_HUSH_GESTURE.equals(uri)) { 223 updateState(mPreference); 224 } 225 } 226 } 227 } 228