From 76b2cd60e5363f22aa4d150aba6beee0a5a53ac8 Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Fri, 14 Jan 2022 16:58:48 +0000 Subject: [PATCH] Disable ring, notification and touch vibration in silent mode Disable haptic settings for ring, notification and touch feedback when the phone ringer mode is set to silent. Preserve the setting values and display message explaining why those settings are disabled. Bug: 203188852 Test: *Vibration[Intensity|Toggle]PreferenceControllerTest Change-Id: I6c24079ece9d637f2feb487f756937888a92caa7 --- res/values/strings.xml | 2 + ...FeedbackIntensityPreferenceController.java | 6 ++ ...ibrationIntensityPreferenceController.java | 6 ++ .../RingVibrationPreferenceConfig.java | 6 ++ ...ibrationIntensityPreferenceController.java | 5 +- .../VibrationPreferenceConfig.java | 91 ++++++++++++++++--- ...mpingRingerTogglePreferenceController.java | 4 +- .../VibrationTogglePreferenceController.java | 5 +- ...backIntensityPreferenceControllerTest.java | 55 ++++++++++- ...eedbackTogglePreferenceControllerTest.java | 56 +++++++++++- ...tionIntensityPreferenceControllerTest.java | 35 ++++++- ...brationTogglePreferenceControllerTest.java | 34 ++++++- ...tionIntensityPreferenceControllerTest.java | 57 +++++++++++- ...brationTogglePreferenceControllerTest.java | 56 +++++++++++- ...gRingerTogglePreferenceControllerTest.java | 1 + 15 files changed, 393 insertions(+), 26 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index ec72321ced8..70a47fe66da 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5457,6 +5457,8 @@ Vibration & haptics Control the vibration strength for different usages + + Setting disabled because device is set to silent Calls diff --git a/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java b/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java index 98fd5f2315c..05dc7840155 100644 --- a/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java +++ b/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java @@ -37,6 +37,12 @@ public class HapticFeedbackIntensityPreferenceController VibrationAttributes.USAGE_TOUCH); } + @Override + public boolean isRestrictedByRingerModeSilent() { + // Touch feedback is disabled when the phone is in silent mode. + return true; + } + @Override public int readIntensity() { final int hapticFeedbackEnabled = Settings.System.getInt(mContentResolver, diff --git a/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java index cee45f6065d..951d322b98e 100644 --- a/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java +++ b/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java @@ -32,6 +32,12 @@ public class NotificationVibrationIntensityPreferenceController super(context, Settings.System.NOTIFICATION_VIBRATION_INTENSITY, VibrationAttributes.USAGE_NOTIFICATION); } + + @Override + public boolean isRestrictedByRingerModeSilent() { + // Notifications never vibrate when the phone is in silent mode. + return true; + } } public NotificationVibrationIntensityPreferenceController(Context context, diff --git a/src/com/android/settings/accessibility/RingVibrationPreferenceConfig.java b/src/com/android/settings/accessibility/RingVibrationPreferenceConfig.java index da446d77ac8..f4ec7473d16 100644 --- a/src/com/android/settings/accessibility/RingVibrationPreferenceConfig.java +++ b/src/com/android/settings/accessibility/RingVibrationPreferenceConfig.java @@ -35,6 +35,12 @@ public class RingVibrationPreferenceConfig extends VibrationPreferenceConfig { mAudioManager = context.getSystemService(AudioManager.class); } + @Override + public boolean isRestrictedByRingerModeSilent() { + // Incoming calls never vibrate when the phone is in silent mode. + return true; + } + @Override public int readIntensity() { final int vibrateWhenRinging = Settings.System.getInt(mContentResolver, diff --git a/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java index b3e8168af87..6441eeb4571 100644 --- a/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java +++ b/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java @@ -58,12 +58,12 @@ public abstract class VibrationIntensityPreferenceController extends SliderPrefe @Override public void onStart() { - mSettingsContentObserver.register(mContext.getContentResolver()); + mSettingsContentObserver.register(mContext); } @Override public void onStop() { - mSettingsContentObserver.unregister(mContext.getContentResolver()); + mSettingsContentObserver.unregister(mContext); } @Override @@ -72,6 +72,7 @@ public abstract class VibrationIntensityPreferenceController extends SliderPrefe final SeekBarPreference preference = screen.findPreference(getPreferenceKey()); mSettingsContentObserver.onDisplayPreference(this, preference); preference.setEnabled(mPreferenceConfig.isPreferenceEnabled()); + preference.setSummaryProvider(unused -> mPreferenceConfig.getSummary()); // TODO: remove setContinuousUpdates and replace with a different way to play the haptic // preview without relying on the setting being propagated to the service. preference.setContinuousUpdates(true); diff --git a/src/com/android/settings/accessibility/VibrationPreferenceConfig.java b/src/com/android/settings/accessibility/VibrationPreferenceConfig.java index 1b0b1635456..9208b188c49 100644 --- a/src/com/android/settings/accessibility/VibrationPreferenceConfig.java +++ b/src/com/android/settings/accessibility/VibrationPreferenceConfig.java @@ -18,9 +18,13 @@ package com.android.settings.accessibility; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; +import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.database.ContentObserver; +import android.media.AudioManager; import android.net.Uri; import android.os.Handler; import android.os.VibrationAttributes; @@ -28,8 +32,10 @@ import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; +import androidx.annotation.Nullable; import androidx.preference.Preference; +import com.android.settings.R; import com.android.settingslib.core.AbstractPreferenceController; /** @@ -45,8 +51,10 @@ public abstract class VibrationPreferenceConfig { public static final String MAIN_SWITCH_SETTING_KEY = Settings.System.VIBRATE_ON; protected final ContentResolver mContentResolver; + private final AudioManager mAudioManager; private final Vibrator mVibrator; private final String mSettingKey; + private final String mRingerModeSilentSummary; private final int mDefaultIntensity; private final VibrationAttributes mVibrationAttributes; @@ -58,6 +66,9 @@ public abstract class VibrationPreferenceConfig { public VibrationPreferenceConfig(Context context, String settingKey, int vibrationUsage) { mContentResolver = context.getContentResolver(); mVibrator = context.getSystemService(Vibrator.class); + mAudioManager = context.getSystemService(AudioManager.class); + mRingerModeSilentSummary = context.getString( + R.string.accessibility_vibration_setting_disabled_for_silent_mode_summary); mSettingKey = settingKey; mDefaultIntensity = mVibrator.getDefaultVibrationIntensity(vibrationUsage); mVibrationAttributes = new VibrationAttributes.Builder() @@ -70,9 +81,24 @@ public abstract class VibrationPreferenceConfig { return mSettingKey; } + /** Returns the summary string for this setting preference. */ + @Nullable + public CharSequence getSummary() { + return isRestrictedByRingerModeSilent() && isRingerModeSilent() + ? mRingerModeSilentSummary : null; + } + /** Returns true if this setting preference is enabled for user update. */ public boolean isPreferenceEnabled() { - return isMainVibrationSwitchEnabled(mContentResolver); + return isMainVibrationSwitchEnabled(mContentResolver) + && (!isRestrictedByRingerModeSilent() || !isRingerModeSilent()); + } + + /** + * Returns true if this setting preference should be disabled when the device is in silent mode. + */ + public boolean isRestrictedByRingerModeSilent() { + return false; } /** Returns the default intensity to be displayed when the setting value is not set. */ @@ -96,12 +122,23 @@ public abstract class VibrationPreferenceConfig { mVibrationAttributes); } + private boolean isRingerModeSilent() { + // AudioManager.isSilentMode() also returns true when ringer mode is VIBRATE. + // The vibration preferences are only disabled when the ringer mode is SILENT. + return mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT; + } + /** {@link ContentObserver} for a setting described by a {@link VibrationPreferenceConfig}. */ public static final class SettingObserver extends ContentObserver { private static final Uri MAIN_SWITCH_SETTING_URI = Settings.System.getUriFor(MAIN_SWITCH_SETTING_KEY); + private static final IntentFilter INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER = + new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION); private final Uri mUri; + @Nullable + private final BroadcastReceiver mRingerModeChangeReceiver; + private AbstractPreferenceController mPreferenceController; private Preference mPreference; @@ -109,35 +146,63 @@ public abstract class VibrationPreferenceConfig { public SettingObserver(VibrationPreferenceConfig preferenceConfig) { super(new Handler(/* async= */ true)); mUri = Settings.System.getUriFor(preferenceConfig.getSettingKey()); + + if (preferenceConfig.isRestrictedByRingerModeSilent()) { + // If this preference is restricted by AudioManager.getRingerModeInternal() result + // for the device mode, then listen to changes in that value using the broadcast + // intent action INTERNAL_RINGER_MODE_CHANGED_ACTION. + mRingerModeChangeReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) { + notifyChange(); + } + } + }; + } else { + // No need to register a receiver if this preference is not affected by ringer mode. + mRingerModeChangeReceiver = null; + } } @Override public void onChange(boolean selfChange, Uri uri) { - if (mPreferenceController == null || mPreference == null) { - // onDisplayPreference not triggered yet, nothing to update. - return; - } if (mUri.equals(uri) || MAIN_SWITCH_SETTING_URI.equals(uri)) { + notifyChange(); + } + } + + private void notifyChange() { + if (mPreferenceController != null && mPreference != null) { mPreferenceController.updateState(mPreference); } } /** - * Register this observer to given {@link ContentResolver}, to be called from lifecycle + * Register this observer to given {@link Context}, to be called from lifecycle * {@code onStart} method. */ - public void register(ContentResolver contentResolver) { - contentResolver.registerContentObserver(mUri, /* notifyForDescendants= */ false, this); - contentResolver.registerContentObserver(MAIN_SWITCH_SETTING_URI, - /* notifyForDescendants= */ false, this); + public void register(Context context) { + if (mRingerModeChangeReceiver != null) { + context.registerReceiver(mRingerModeChangeReceiver, + INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER); + } + context.getContentResolver().registerContentObserver( + mUri, /* notifyForDescendants= */ false, this); + context.getContentResolver().registerContentObserver( + MAIN_SWITCH_SETTING_URI, /* notifyForDescendants= */ false, this); } /** - * Unregister this observer from given {@link ContentResolver}, to be called from lifecycle + * Unregister this observer from given {@link Context}, to be called from lifecycle * {@code onStop} method. */ - public void unregister(ContentResolver contentResolver) { - contentResolver.unregisterContentObserver(this); + public void unregister(Context context) { + if (mRingerModeChangeReceiver != null) { + context.unregisterReceiver(mRingerModeChangeReceiver); + } + context.getContentResolver().unregisterContentObserver(this); } /** diff --git a/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java b/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java index 37a0257cb20..8d1b43ee926 100644 --- a/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java +++ b/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java @@ -93,7 +93,7 @@ public class VibrationRampingRingerTogglePreferenceController @Override public void onStart() { - mRingSettingObserver.register(mContext.getContentResolver()); + mRingSettingObserver.register(mContext); mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.APPLY_RAMPING_RINGER), /* notifyForDescendants= */ false, @@ -102,7 +102,7 @@ public class VibrationRampingRingerTogglePreferenceController @Override public void onStop() { - mRingSettingObserver.unregister(mContext.getContentResolver()); + mRingSettingObserver.unregister(mContext); mContext.getContentResolver().unregisterContentObserver(mSettingObserver); } diff --git a/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java index 8f158cc04b5..c60158daac1 100644 --- a/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java +++ b/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java @@ -45,12 +45,12 @@ public abstract class VibrationTogglePreferenceController extends TogglePreferen @Override public void onStart() { - mSettingsContentObserver.register(mContext.getContentResolver()); + mSettingsContentObserver.register(mContext); } @Override public void onStop() { - mSettingsContentObserver.unregister(mContext.getContentResolver()); + mSettingsContentObserver.unregister(mContext); } @Override @@ -66,6 +66,7 @@ public abstract class VibrationTogglePreferenceController extends TogglePreferen super.updateState(preference); if (preference != null) { preference.setEnabled(mPreferenceConfig.isPreferenceEnabled()); + preference.setSummary(mPreferenceConfig.getSummary()); } } diff --git a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java index 2273a3ed2fd..9d87c93c1df 100644 --- a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java @@ -18,9 +18,11 @@ package com.android.settings.accessibility; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.media.AudioManager; import android.os.VibrationAttributes; import android.os.Vibrator; import android.provider.Settings; @@ -48,6 +50,7 @@ public class HapticFeedbackIntensityPreferenceControllerTest { private static final int ON = 1; @Mock private PreferenceScreen mScreen; + @Mock private AudioManager mAudioManager; private Lifecycle mLifecycle; private Context mContext; @@ -59,7 +62,9 @@ public class HapticFeedbackIntensityPreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mLifecycle = new Lifecycle(() -> mLifecycle); - mContext = ApplicationProvider.getApplicationContext(); + mContext = spy(ApplicationProvider.getApplicationContext()); + when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); mVibrator = mContext.getSystemService(Vibrator.class); mController = new HapticFeedbackIntensityPreferenceController(mContext, PREFERENCE_KEY, Vibrator.VIBRATION_INTENSITY_HIGH); @@ -88,6 +93,54 @@ public class HapticFeedbackIntensityPreferenceControllerTest { .isEqualTo(mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH)); } + @Test + public void updateState_ringerModeUpdates_shouldPreserveSettingAndDisplaySummary() { + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + // TODO(b/136805769): summary is broken in SeekBarPreference, enable this once fixed +// assertThat(mPreference.getSummary()).isNotNull(); +// assertThat(mPreference.getSummary().toString()).isEqualTo(mContext.getString( +// R.string.accessibility_vibration_setting_disabled_for_silent_mode_summary)); + assertThat(mPreference.isEnabled()).isFalse(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + } + + @Test + public void updateState_hapticFeedbackDisabled_shouldDisplayAlwaysOff() { + updateSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, OFF); + + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, + Vibrator.VIBRATION_INTENSITY_MEDIUM); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + } + @Test public void updateState_shouldDisplayIntensityInSliderPosition() { updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH); diff --git a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java index f992b0ef029..3e8aeac6b59 100644 --- a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java @@ -18,9 +18,11 @@ package com.android.settings.accessibility; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.media.AudioManager; import android.os.VibrationAttributes; import android.os.Vibrator; import android.provider.Settings; @@ -29,6 +31,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.R; import com.android.settings.core.BasePreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; @@ -48,6 +51,7 @@ public class HapticFeedbackTogglePreferenceControllerTest { private static final int ON = 1; @Mock private PreferenceScreen mScreen; + @Mock AudioManager mAudioManager; private Lifecycle mLifecycle; private Context mContext; @@ -59,7 +63,9 @@ public class HapticFeedbackTogglePreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mLifecycle = new Lifecycle(() -> mLifecycle); - mContext = ApplicationProvider.getApplicationContext(); + mContext = spy(ApplicationProvider.getApplicationContext()); + when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); mVibrator = mContext.getSystemService(Vibrator.class); mController = new HapticFeedbackTogglePreferenceController(mContext, PREFERENCE_KEY); mLifecycle.addObserver(mController); @@ -84,6 +90,54 @@ public class HapticFeedbackTogglePreferenceControllerTest { assertThat(mPreference.isChecked()).isTrue(); } + + @Test + public void updateState_ringerModeUpdates_shouldPreserveSettingAndDisplaySummary() { + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + assertThat(mPreference.getSummary()).isNotNull(); + assertThat(mPreference.getSummary().toString()).isEqualTo(mContext.getString( + R.string.accessibility_vibration_setting_disabled_for_silent_mode_summary)); + assertThat(mPreference.isEnabled()).isFalse(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + } + + @Test + public void updateState_hapticFeedbackDisabled_shouldDisplayAlwaysOff() { + updateSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, OFF); + + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, + Vibrator.VIBRATION_INTENSITY_MEDIUM); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + + updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + } + @Test public void updateState_shouldDisplayOnOffState() { updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH); diff --git a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java index d0be8b57c6a..9533c5389de 100644 --- a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java @@ -18,9 +18,11 @@ package com.android.settings.accessibility; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.media.AudioManager; import android.os.VibrationAttributes; import android.os.Vibrator; import android.provider.Settings; @@ -46,6 +48,7 @@ public class NotificationVibrationIntensityPreferenceControllerTest { private static final String PREFERENCE_KEY = "preference_key"; @Mock private PreferenceScreen mScreen; + @Mock private AudioManager mAudioManager; private Lifecycle mLifecycle; private Context mContext; @@ -57,7 +60,9 @@ public class NotificationVibrationIntensityPreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mLifecycle = new Lifecycle(() -> mLifecycle); - mContext = ApplicationProvider.getApplicationContext(); + mContext = spy(ApplicationProvider.getApplicationContext()); + when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); mVibrator = mContext.getSystemService(Vibrator.class); mController = new NotificationVibrationIntensityPreferenceController(mContext, PREFERENCE_KEY, Vibrator.VIBRATION_INTENSITY_HIGH); @@ -86,6 +91,34 @@ public class NotificationVibrationIntensityPreferenceControllerTest { mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION)); } + + @Test + public void updateState_ringerModeUpdates_shouldPreserveSettingAndDisplaySummary() { + updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, + Vibrator.VIBRATION_INTENSITY_LOW); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + // TODO(b/136805769): summary is broken in SeekBarPreference, enable this once fixed +// assertThat(mPreference.getSummary()).isNotNull(); +// assertThat(mPreference.getSummary().toString()).isEqualTo(mContext.getString( +// R.string.accessibility_vibration_setting_disabled_for_silent_mode_summary)); + assertThat(mPreference.isEnabled()).isFalse(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + } + @Test public void updateState_shouldDisplayIntensityInSliderPosition() { updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, diff --git a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java index adf94361b3c..4b6f686fa1b 100644 --- a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java @@ -18,9 +18,11 @@ package com.android.settings.accessibility; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.media.AudioManager; import android.os.VibrationAttributes; import android.os.Vibrator; import android.provider.Settings; @@ -29,6 +31,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.R; import com.android.settings.core.BasePreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; @@ -46,6 +49,7 @@ public class NotificationVibrationTogglePreferenceControllerTest { private static final String PREFERENCE_KEY = "preference_key"; @Mock private PreferenceScreen mScreen; + @Mock private AudioManager mAudioManager; private Lifecycle mLifecycle; private Context mContext; @@ -57,7 +61,9 @@ public class NotificationVibrationTogglePreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mLifecycle = new Lifecycle(() -> mLifecycle); - mContext = ApplicationProvider.getApplicationContext(); + mContext = spy(ApplicationProvider.getApplicationContext()); + when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); mVibrator = mContext.getSystemService(Vibrator.class); mController = new NotificationVibrationTogglePreferenceController(mContext, PREFERENCE_KEY); mLifecycle.addObserver(mController); @@ -82,6 +88,32 @@ public class NotificationVibrationTogglePreferenceControllerTest { assertThat(mPreference.isChecked()).isTrue(); } + @Test + public void updateState_ringerModeUpdates_shouldPreserveSettingAndDisplaySummary() { + updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, + Vibrator.VIBRATION_INTENSITY_LOW); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + assertThat(mPreference.getSummary()).isNotNull(); + assertThat(mPreference.getSummary().toString()).isEqualTo(mContext.getString( + R.string.accessibility_vibration_setting_disabled_for_silent_mode_summary)); + assertThat(mPreference.isEnabled()).isFalse(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + } + @Test public void updateState_shouldDisplayOnOffState() { updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java index d891926c418..2bffaf4d011 100644 --- a/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java @@ -18,9 +18,11 @@ package com.android.settings.accessibility; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.media.AudioManager; import android.os.VibrationAttributes; import android.os.Vibrator; import android.provider.Settings; @@ -49,6 +51,7 @@ public class RingVibrationIntensityPreferenceControllerTest { private static final int ON = 1; @Mock private PreferenceScreen mScreen; + @Mock private AudioManager mAudioManager; private Lifecycle mLifecycle; private Context mContext; @@ -60,7 +63,9 @@ public class RingVibrationIntensityPreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mLifecycle = new Lifecycle(() -> mLifecycle); - mContext = ApplicationProvider.getApplicationContext(); + mContext = spy(ApplicationProvider.getApplicationContext()); + when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); mVibrator = mContext.getSystemService(Vibrator.class); mController = new RingVibrationIntensityPreferenceController(mContext, PREFERENCE_KEY, Vibrator.VIBRATION_INTENSITY_HIGH); @@ -89,6 +94,55 @@ public class RingVibrationIntensityPreferenceControllerTest { mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE)); } + @Test + public void updateState_ringerModeUpdates_shouldPreserveSettingAndDisplaySummary() { + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + // TODO(b/136805769): summary is broken in SeekBarPreference, enable this once fixed +// assertThat(mPreference.getSummary()).isNotNull(); +// assertThat(mPreference.getSummary().toString()).isEqualTo(mContext.getString( +// R.string.accessibility_vibration_setting_disabled_for_silent_mode_summary)); + assertThat(mPreference.isEnabled()).isFalse(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + } + + @Test + public void updateState_vibrateWhenRingingAndRampingRingerOff_shouldDisplayAlwaysOff() { + when(mAudioManager.isRampingRingerEnabled()).thenReturn(false); + updateSetting(Settings.System.VIBRATE_WHEN_RINGING, OFF); + + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, + Vibrator.VIBRATION_INTENSITY_MEDIUM); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF); + mController.updateState(mPreference); + assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); + } + @Test public void updateState_shouldDisplayIntensityInSliderPosition() { updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH); @@ -109,7 +163,6 @@ public class RingVibrationIntensityPreferenceControllerTest { assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF); } - @Test @Ignore public void setProgress_updatesIntensityAndDependentSettings() throws Exception { diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java index 8e85c86d901..08ad1cdade1 100644 --- a/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java @@ -18,9 +18,11 @@ package com.android.settings.accessibility; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.media.AudioManager; import android.os.VibrationAttributes; import android.os.Vibrator; import android.provider.Settings; @@ -29,6 +31,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.R; import com.android.settings.core.BasePreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; @@ -48,6 +51,7 @@ public class RingVibrationTogglePreferenceControllerTest { private static final int ON = 1; @Mock private PreferenceScreen mScreen; + @Mock private AudioManager mAudioManager; private Lifecycle mLifecycle; private Context mContext; @@ -59,7 +63,9 @@ public class RingVibrationTogglePreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mLifecycle = new Lifecycle(() -> mLifecycle); - mContext = ApplicationProvider.getApplicationContext(); + mContext = spy(ApplicationProvider.getApplicationContext()); + when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); mVibrator = mContext.getSystemService(Vibrator.class); mController = new RingVibrationTogglePreferenceController(mContext, PREFERENCE_KEY); mLifecycle.addObserver(mController); @@ -84,6 +90,54 @@ public class RingVibrationTogglePreferenceControllerTest { assertThat(mPreference.isChecked()).isTrue(); } + @Test + public void updateState_ringerModeUpdates_shouldPreserveSettingAndDisplaySummary() { + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + assertThat(mPreference.getSummary()).isNotNull(); + assertThat(mPreference.getSummary().toString()).isEqualTo(mContext.getString( + R.string.accessibility_vibration_setting_disabled_for_silent_mode_summary)); + assertThat(mPreference.isEnabled()).isFalse(); + + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + assertThat(mPreference.getSummary()).isNull(); + assertThat(mPreference.isEnabled()).isTrue(); + } + + @Test + public void updateState_vibrateWhenRingingAndRampingRingerOff_shouldDisplayAlwaysOff() { + when(mAudioManager.isRampingRingerEnabled()).thenReturn(false); + updateSetting(Settings.System.VIBRATE_WHEN_RINGING, OFF); + + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, + Vibrator.VIBRATION_INTENSITY_MEDIUM); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + + updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF); + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + } + @Test public void updateState_shouldDisplayOnOffState() { updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH); diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java index 1f2c0d9fcf5..9e3113053cc 100644 --- a/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java @@ -70,6 +70,7 @@ public class VibrationRampingRingerTogglePreferenceControllerTest { mContext = spy(ApplicationProvider.getApplicationContext()); when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); mController = new VibrationRampingRingerTogglePreferenceController(mContext, PREFERENCE_KEY, mDeviceConfigProvider); mLifecycle.addObserver(mController);