diff --git a/res/xml/prevent_ringing_gesture_settings.xml b/res/xml/prevent_ringing_gesture_settings.xml index 62f022301a4..4b0edc36179 100644 --- a/res/xml/prevent_ringing_gesture_settings.xml +++ b/res/xml/prevent_ringing_gesture_settings.xml @@ -26,8 +26,11 @@ app:animation="@raw/gesture_prevent_ringing" app:preview="@drawable/gesture_prevent_ringing" /> + + - + android:title="@string/gesture_prevent_ringing_title" /> \ No newline at end of file diff --git a/src/com/android/settings/gestures/PreventRingingGesturePreferenceController.java b/src/com/android/settings/gestures/PreventRingingGesturePreferenceController.java index cb9bf4f5881..8f037ce45c4 100644 --- a/src/com/android/settings/gestures/PreventRingingGesturePreferenceController.java +++ b/src/com/android/settings/gestures/PreventRingingGesturePreferenceController.java @@ -46,7 +46,7 @@ public class PreventRingingGesturePreferenceController extends AbstractPreferenc OnResume, OnPause, OnCreate, PreferenceControllerMixin { @VisibleForTesting static final String KEY_VIBRATE = "prevent_ringing_option_vibrate"; - @VisibleForTesting static final String KEY_NONE = "prevent_ringing_option_none"; + @VisibleForTesting static final String KEY_MUTE = "prevent_ringing_option_mute"; private final String KEY_VIDEO_PAUSED = "key_video_paused"; @@ -57,9 +57,8 @@ public class PreventRingingGesturePreferenceController extends AbstractPreferenc private VideoPreference mVideoPreference; private boolean mVideoPaused; - private PreferenceCategory mPreferenceCategory; + @VisibleForTesting PreferenceCategory mPreferenceCategory; @VisibleForTesting RadioButtonPreference mVibratePref; - @VisibleForTesting RadioButtonPreference mNonePref; @VisibleForTesting RadioButtonPreference mMutePref; private SettingObserver mSettingObserver; @@ -80,7 +79,6 @@ public class PreventRingingGesturePreferenceController extends AbstractPreferenc mPreferenceCategory = (PreferenceCategory) screen.findPreference(getPreferenceKey()); mVibratePref = makeRadioPreference(KEY_VIBRATE, R.string.prevent_ringing_option_vibrate); mMutePref = makeRadioPreference(KEY_MUTE, R.string.prevent_ringing_option_mute); - mNonePref = makeRadioPreference(KEY_NONE, R.string.prevent_ringing_option_none); if (mPreferenceCategory != null) { mSettingObserver = new SettingObserver(mPreferenceCategory); @@ -124,19 +122,21 @@ public class PreventRingingGesturePreferenceController extends AbstractPreferenc public void updateState(Preference preference) { int preventRingingSetting = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE); - final boolean isVibrate = preventRingingSetting == Settings.Secure.VOLUME_HUSH_VIBRATE; final boolean isMute = preventRingingSetting == Settings.Secure.VOLUME_HUSH_MUTE; - final boolean isOff = preventRingingSetting == Settings.Secure.VOLUME_HUSH_OFF - || (!isVibrate && !isMute); if (mVibratePref != null && mVibratePref.isChecked() != isVibrate) { mVibratePref.setChecked(isVibrate); } if (mMutePref != null && mMutePref.isChecked() != isMute) { mMutePref.setChecked(isMute); } - if (mNonePref != null && mNonePref.isChecked() != isOff) { - mNonePref.setChecked(isOff); + + if (preventRingingSetting == Settings.Secure.VOLUME_HUSH_OFF) { + mVibratePref.setEnabled(false); + mMutePref.setEnabled(false); + } else { + mVibratePref.setEnabled(true); + mMutePref.setEnabled(true); } } @@ -173,13 +173,12 @@ public class PreventRingingGesturePreferenceController extends AbstractPreferenc private int keyToSetting(String key) { switch (key) { - case KEY_NONE: - return Settings.Secure.VOLUME_HUSH_OFF; case KEY_MUTE: return Settings.Secure.VOLUME_HUSH_MUTE; case KEY_VIBRATE: - default: return Settings.Secure.VOLUME_HUSH_VIBRATE; + default: + return Settings.Secure.VOLUME_HUSH_OFF; } } diff --git a/src/com/android/settings/gestures/PreventRingingGestureSettings.java b/src/com/android/settings/gestures/PreventRingingGestureSettings.java index 3e8ae855227..420a01985e3 100644 --- a/src/com/android/settings/gestures/PreventRingingGestureSettings.java +++ b/src/com/android/settings/gestures/PreventRingingGestureSettings.java @@ -35,7 +35,6 @@ import java.util.List; public class PreventRingingGestureSettings extends DashboardFragment { private static final String TAG = "RingingGestureSettings"; - private static final String KEY_PREVENT_RINGING = "gesture_prevent_ringing"; @Override public void onAttach(Context context) { @@ -51,6 +50,7 @@ public class PreventRingingGestureSettings extends DashboardFragment { Lifecycle lifecycle) { List controllers = new ArrayList<>(); controllers.add(new PreventRingingGesturePreferenceController(context, lifecycle)); + controllers.add(new PreventRingingSwitchPreferenceController(context)); return controllers; } diff --git a/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java b/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java new file mode 100644 index 00000000000..b94cfffdbca --- /dev/null +++ b/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2019 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. + */ + +package com.android.settings.gestures; + +import android.content.ContentResolver; +import android.content.Context; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.provider.Settings; +import android.widget.Switch; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.widget.SwitchBar; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.widget.LayoutPreference; + +public class PreventRingingSwitchPreferenceController extends AbstractPreferenceController + implements PreferenceControllerMixin, SwitchBar.OnSwitchChangeListener { + + private static final String KEY = "gesture_prevent_ringing_switch"; + private final Context mContext; + private SettingObserver mSettingObserver; + + @VisibleForTesting SwitchBar mSwitch; + + public PreventRingingSwitchPreferenceController(Context context) { + super(context); + mContext = context; + } + + @Override + public String getPreferenceKey() { + return KEY; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + if (isAvailable()) { + LayoutPreference pref = (LayoutPreference) screen.findPreference(getPreferenceKey()); + if (pref != null) { + mSettingObserver = new SettingObserver(pref); + mSwitch = pref.findViewById(R.id.switch_bar); + if (mSwitch != null) { + mSwitch.addOnSwitchChangeListener(this); + mSwitch.show(); + } + } + } + } + + public void setChecked(boolean isChecked) { + if (mSwitch != null) { + mSwitch.setChecked(isChecked); + } + } + + @Override + public void updateState(Preference preference) { + int preventRingingSetting = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE); + setChecked(preventRingingSetting != Settings.Secure.VOLUME_HUSH_OFF); + } + + @Override + public boolean isAvailable() { + return mContext.getResources().getBoolean( + com.android.internal.R.bool.config_volumeHushGestureEnabled); + } + + @Override + public void onSwitchChanged(Switch switchView, boolean isChecked) { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.VOLUME_HUSH_GESTURE, isChecked ? Settings.Secure.VOLUME_HUSH_VIBRATE + : Settings.Secure.VOLUME_HUSH_OFF); + } + + private class SettingObserver extends ContentObserver { + private final Uri VOLUME_HUSH_GESTURE = Settings.Secure.getUriFor( + Settings.Secure.VOLUME_HUSH_GESTURE); + + private final Preference mPreference; + + public SettingObserver(Preference preference) { + super(new Handler()); + mPreference = preference; + } + + public void register(ContentResolver cr) { + cr.registerContentObserver(VOLUME_HUSH_GESTURE, false, this); + } + + public void unregister(ContentResolver cr) { + cr.unregisterContentObserver(this); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + super.onChange(selfChange, uri); + if (uri == null || VOLUME_HUSH_GESTURE.equals(uri)) { + updateState(mPreference); + } + } + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/PreventRingingGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PreventRingingGesturePreferenceControllerTest.java index 84fef5d15c4..956d8bf52ed 100644 --- a/tests/robotests/src/com/android/settings/gestures/PreventRingingGesturePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/PreventRingingGesturePreferenceControllerTest.java @@ -18,44 +18,47 @@ package com.android.settings.gestures; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; import android.content.Context; import android.content.res.Resources; -import android.preference.PreferenceCategory; import android.provider.Settings; -import androidx.preference.PreferenceScreen; +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import com.android.settings.widget.RadioButtonPreference; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class PreventRingingGesturePreferenceControllerTest { - private Context mContext; private Resources mResources; private PreventRingingGesturePreferenceController mController; + @Mock + private Preference mPreference; + @Before public void setUp() { + MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); mResources = mock(Resources.class); when(mContext.getResources()).thenReturn(mResources); when(mResources.getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) .thenReturn(true); mController = new PreventRingingGesturePreferenceController(mContext, null); + mController.mPreferenceCategory = new PreferenceCategory(mContext); mController.mVibratePref = new RadioButtonPreference(mContext); - mController.mNonePref = new RadioButtonPreference(mContext); mController.mMutePref = new RadioButtonPreference(mContext); } @@ -79,9 +82,10 @@ public class PreventRingingGesturePreferenceControllerTest { public void testUpdateState_mute() { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_MUTE); - mController.updateState(null); + mController.updateState(mPreference); + assertThat(mController.mVibratePref.isEnabled()).isTrue(); + assertThat(mController.mMutePref.isEnabled()).isTrue(); assertThat(mController.mVibratePref.isChecked()).isFalse(); - assertThat(mController.mNonePref.isChecked()).isFalse(); assertThat(mController.mMutePref.isChecked()).isTrue(); } @@ -89,9 +93,21 @@ public class PreventRingingGesturePreferenceControllerTest { public void testUpdateState_vibrate() { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE); - mController.updateState(null); + mController.updateState(mPreference); + assertThat(mController.mVibratePref.isEnabled()).isTrue(); + assertThat(mController.mMutePref.isEnabled()).isTrue(); assertThat(mController.mVibratePref.isChecked()).isTrue(); - assertThat(mController.mNonePref.isChecked()).isFalse(); + assertThat(mController.mMutePref.isChecked()).isFalse(); + } + + @Test + public void testUpdateState_off() { + Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, + Settings.Secure.VOLUME_HUSH_OFF); + mController.updateState(mPreference); + assertThat(mController.mVibratePref.isEnabled()).isFalse(); + assertThat(mController.mMutePref.isEnabled()).isFalse(); + assertThat(mController.mVibratePref.isChecked()).isFalse(); assertThat(mController.mMutePref.isChecked()).isFalse(); } @@ -99,9 +115,8 @@ public class PreventRingingGesturePreferenceControllerTest { public void testUpdateState_other() { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, 7); - mController.updateState(null); + mController.updateState(mPreference); assertThat(mController.mVibratePref.isChecked()).isFalse(); - assertThat(mController.mNonePref.isChecked()).isTrue(); assertThat(mController.mMutePref.isChecked()).isFalse(); } @@ -132,19 +147,4 @@ public class PreventRingingGesturePreferenceControllerTest { Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_OFF)); } - - @Test - public void testRadioButtonClicked_off() { - RadioButtonPreference rbPref = new RadioButtonPreference(mContext); - rbPref.setKey(PreventRingingGesturePreferenceController.KEY_NONE); - - Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, - Settings.Secure.VOLUME_HUSH_MUTE); - - mController.onRadioButtonClicked(rbPref); - - assertThat(Settings.Secure.VOLUME_HUSH_OFF).isEqualTo( - Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE)); - } } diff --git a/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java new file mode 100644 index 00000000000..5f221f578f7 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2019 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. + */ + +package com.android.settings.gestures; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.res.Resources; +import android.provider.Settings; + +import androidx.preference.Preference; + +import com.android.settings.widget.SwitchBar; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class PreventRingingSwitchPreferenceControllerTest { + private Context mContext; + private Resources mResources; + private PreventRingingSwitchPreferenceController mController; + private Preference mPreference = mock(Preference.class); + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + mResources = mock(Resources.class); + when(mContext.getResources()).thenReturn(mResources); + when(mResources.getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) + .thenReturn(true); + mController = new PreventRingingSwitchPreferenceController(mContext); + mController.mSwitch = mock(SwitchBar.class); + } + + @Test + public void testIsAvailable_configIsTrue_shouldReturnTrue() { + when(mResources.getBoolean( + com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void testIsAvailable_configIsFalse_shouldReturnFalse() { + when(mResources.getBoolean( + com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void testOn_updateState_hushOff() { + Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, + Settings.Secure.VOLUME_HUSH_OFF); + mController.updateState(mPreference); + verify(mController.mSwitch, times(1)).setChecked(false); + } + + @Test + public void testOn_updateState_hushVibrate() { + Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, + Settings.Secure.VOLUME_HUSH_VIBRATE); + mController.updateState(mPreference); + verify(mController.mSwitch, times(1)).setChecked(true); + } + + @Test + public void testOn_updateState_hushMute() { + Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE, + Settings.Secure.VOLUME_HUSH_MUTE); + mController.updateState(mPreference); + verify(mController.mSwitch, times(1)).setChecked(true); + } +}