From 70c9f89e6f082f12edb0e3d02fb6b42f4f3a4379 Mon Sep 17 00:00:00 2001 From: Etienne Ruffieux Date: Thu, 6 Jan 2022 17:24:09 +0000 Subject: [PATCH 1/5] Replaced use of Bluetooth resource by SystemApi Bluetooth resources are moved to the Bluetooth module, we need to clear all existing usages of these resources. Updated existing tests. Tag: #feature Test: make RunSettingsRoboTests Bug: 211570675 Change-Id: I0f76df5043e69ed33cca40af3c32ac5b922b79ef --- ...ConnectedAudioDevicesPreferenceController.java | 6 ++++-- ...ectedAudioDevicesPreferenceControllerTest.java | 15 ++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java b/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java index ee6af1c8785..fb756955d25 100644 --- a/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java +++ b/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java @@ -16,6 +16,7 @@ package com.android.settings.development; +import android.bluetooth.BluetoothManager; import android.content.Context; import android.os.SystemProperties; @@ -42,8 +43,9 @@ public class BluetoothMaxConnectedAudioDevicesPreferenceController extends public BluetoothMaxConnectedAudioDevicesPreferenceController(Context context) { super(context); - mDefaultMaxConnectedAudioDevices = mContext.getResources().getInteger( - com.android.internal.R.integer.config_bluetooth_max_connected_audio_devices); + BluetoothManager mBluetoothManager = context.getSystemService(BluetoothManager.class); + mDefaultMaxConnectedAudioDevices = mBluetoothManager.getAdapter() + .getMaxConnectedAudioDevices(); } @Override diff --git a/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java index 98dc656d5f5..e5fbd655304 100644 --- a/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java @@ -24,8 +24,9 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; import android.content.Context; -import android.content.res.Resources; import android.os.SystemProperties; import androidx.preference.ListPreference; @@ -52,7 +53,10 @@ public class BluetoothMaxConnectedAudioDevicesPreferenceControllerTest { @Spy private Context mSpyContext = RuntimeEnvironment.application; @Spy - private Resources mSpyResources = RuntimeEnvironment.application.getResources(); + private BluetoothManager mBluetoothManager = + mSpyContext.getSystemService(BluetoothManager.class); + @Spy + private BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter(); private ListPreference mPreference; private BluetoothMaxConnectedAudioDevicesPreferenceController mController; @@ -63,15 +67,16 @@ public class BluetoothMaxConnectedAudioDevicesPreferenceControllerTest { @Before public void setup() { MockitoAnnotations.initMocks(this); - doReturn(mSpyResources).when(mSpyContext).getResources(); + doReturn(mBluetoothManager).when(mSpyContext).getSystemService(BluetoothManager.class); + doReturn(mBluetoothAdapter).when(mBluetoothManager).getAdapter(); // Get XML values without mock // Setup test list preference using XML values mPreference = new ListPreference(mSpyContext); mPreference.setEntries(R.array.bluetooth_max_connected_audio_devices); mPreference.setEntryValues(R.array.bluetooth_max_connected_audio_devices_values); // Stub default max connected audio devices to a test controlled value - doReturn(TEST_MAX_CONNECTED_AUDIO_DEVICES).when(mSpyResources).getInteger( - com.android.internal.R.integer.config_bluetooth_max_connected_audio_devices); + doReturn(TEST_MAX_CONNECTED_AUDIO_DEVICES).when(mBluetoothAdapter) + .getMaxConnectedAudioDevices(); // Init the actual controller mController = new BluetoothMaxConnectedAudioDevicesPreferenceController(mSpyContext); // Construct preference in the controller via a mocked preference screen object From a9a1bb374793203eb8c2736ba3db14f4513db3f2 Mon Sep 17 00:00:00 2001 From: Weng Su Date: Sat, 22 Jan 2022 14:05:32 +0000 Subject: [PATCH 2/5] Mock UserManager.class for WifiSettingsTest Bug: 214938188 Test: manual test make RunSettingsRoboTests ROBOTEST_FILTER=WifiSettingsTest Change-Id: I1b8faba6348b6dfddbd7eb6ccfaa35ca32366c91 --- .../src/com/android/settings/wifi/WifiSettingsTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java index d442d4e4bc9..c83ec49a40a 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java @@ -60,7 +60,6 @@ import com.android.wifitrackerlib.WifiEntry; import com.android.wifitrackerlib.WifiPickerTracker; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -71,7 +70,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowToast; @RunWith(RobolectricTestRunner.class) -@Ignore public class WifiSettingsTest { private static final int NUM_NETWORKS = 4; @@ -94,6 +92,7 @@ public class WifiSettingsTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + when(mContext.getSystemService(UserManager.class)).thenReturn(mock(UserManager.class)); mWifiSettings = spy(new WifiSettings()); doReturn(mContext).when(mWifiSettings).getContext(); From 3a15d6cab1e885af471ab117666f1c3055b0bc6d Mon Sep 17 00:00:00 2001 From: Junyu Lai Date: Mon, 10 Jan 2022 10:39:00 +0000 Subject: [PATCH 3/5] [MS48.2] Remove NetworkStatsHistory from CycleAdaptor While the ChartData changes the types of stored data. Modify CycleAdaptor accordlingly for the compatibility. Test: atest clockwork-settings-robotests make RunSettingsRoboTests -j40 make RunSettingsLibRoboTests ROBOTEST_FILTER=DataUsageControllerTest make RunSettingsLibRoboTests ROBOTEST_FILTER=NetworkCycleChartDataLoaderTest make RunSettingsLibRoboTests ROBOTEST_FILTER=NetworkCycleDataForUidLoaderTest make RunSettingsLibRoboTests ROBOTEST_FILTER=NetworkCycleDataLoaderTest make RunSettingsLibRoboTests ROBOTEST_FILTER=DataUsageUtilsTest Bug: 204830222 Ignore-AOSP-First: Related API conflict, need master first. Change-Id: Ia778d680d5354fb67476db0763dfab017284dc4a --- Android.bp | 1 + .../settings/datausage/CycleAdapter.java | 72 ++++++++++++++----- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/Android.bp b/Android.bp index 0116237a1e4..fd669741a3e 100644 --- a/Android.bp +++ b/Android.bp @@ -63,6 +63,7 @@ android_library { "androidx.lifecycle_lifecycle-extensions", "guava", "jsr305", + "net-utils-framework-common", "settings-contextual-card-protos-lite", "settings-log-bridge-protos-lite", "contextualcards", diff --git a/src/com/android/settings/datausage/CycleAdapter.java b/src/com/android/settings/datausage/CycleAdapter.java index 74d27be7e67..1292d001435 100644 --- a/src/com/android/settings/datausage/CycleAdapter.java +++ b/src/com/android/settings/datausage/CycleAdapter.java @@ -13,14 +13,17 @@ */ package com.android.settings.datausage; +import android.annotation.NonNull; +import android.app.usage.NetworkStats; import android.content.Context; import android.net.NetworkPolicy; import android.net.NetworkPolicyManager; -import android.net.NetworkStatsHistory; import android.text.format.DateUtils; import android.util.Pair; +import android.util.Range; import android.widget.AdapterView; +import com.android.net.module.util.NetworkStatsUtils; import com.android.settings.Utils; import com.android.settingslib.net.ChartData; import com.android.settingslib.net.NetworkCycleData; @@ -62,9 +65,43 @@ public class CycleAdapter extends SettingsSpinnerAdapter return 0; } + protected static long getTotalBytesForTimeRange(List stats, + Range range) { + long bytes = 0L; + for (NetworkStats.Bucket bucket : stats) { + final Range bucketSpan = new Range<>( + bucket.getStartTimeStamp(), bucket.getEndTimeStamp()); + // Only record bytes that overlapped with the given time range. For partially + // overlapped bucket, record rational bytes assuming the traffic is uniform + // distributed within the bucket. + try { + final Range overlapped = range.intersect(bucketSpan); + final long totalOfBucket = bucket.getRxBytes() + bucket.getTxBytes(); + bytes += NetworkStatsUtils.multiplySafeByRational(totalOfBucket, + overlapped.getUpper() - overlapped.getLower(), + bucketSpan.getUpper() - bucketSpan.getLower()); + } catch (IllegalArgumentException e) { + // Range disjoint, ignore. + continue; + } + } + return bytes; + } + + @NonNull + private Range getTimeRangeOf(@NonNull List stats) { + long start = Long.MAX_VALUE; + long end = Long.MIN_VALUE; + for (NetworkStats.Bucket bucket : stats) { + start = Math.min(start, bucket.getStartTimeStamp()); + end = Math.max(end, bucket.getEndTimeStamp()); + } + return new Range(start, end); + } + /** * Rebuild list based on {@link NetworkPolicy} and available - * {@link NetworkStatsHistory} data. Always selects the newest item, + * {@link List} data. Always selects the newest item, * updating the inspection range on chartData. */ @Deprecated @@ -75,19 +112,20 @@ public class CycleAdapter extends SettingsSpinnerAdapter clear(); final Context context = getContext(); - NetworkStatsHistory.Entry entry = null; - long historyStart = Long.MAX_VALUE; - long historyEnd = Long.MIN_VALUE; - if (chartData != null) { - historyStart = chartData.network.getStart(); - historyEnd = chartData.network.getEnd(); + long historyStart; + long historyEnd; + try { + final Range historyTimeRange = getTimeRangeOf(chartData.network); + historyStart = historyTimeRange.getLower(); + historyEnd = historyTimeRange.getUpper(); + } catch (IllegalArgumentException e) { + // Empty history. + final long now = System.currentTimeMillis(); + historyStart = now; + historyEnd = now + 1; } - final long now = System.currentTimeMillis(); - if (historyStart == Long.MAX_VALUE) historyStart = now; - if (historyEnd == Long.MIN_VALUE) historyEnd = now + 1; - boolean hasCycles = false; if (policy != null) { final Iterator> it = NetworkPolicyManager @@ -99,8 +137,9 @@ public class CycleAdapter extends SettingsSpinnerAdapter final boolean includeCycle; if (chartData != null) { - entry = chartData.network.getValues(cycleStart, cycleEnd, entry); - includeCycle = (entry.rxBytes + entry.txBytes) > 0; + final long bytesInCycle = getTotalBytesForTimeRange(chartData.network, + new Range<>(cycleStart, cycleEnd)); + includeCycle = bytesInCycle > 0; } else { includeCycle = true; } @@ -120,8 +159,9 @@ public class CycleAdapter extends SettingsSpinnerAdapter final boolean includeCycle; if (chartData != null) { - entry = chartData.network.getValues(cycleStart, cycleEnd, entry); - includeCycle = (entry.rxBytes + entry.txBytes) > 0; + final long bytesInCycle = getTotalBytesForTimeRange(chartData.network, + new Range<>(cycleStart, cycleEnd)); + includeCycle = bytesInCycle > 0; } else { includeCycle = true; } From 76b2cd60e5363f22aa4d150aba6beee0a5a53ac8 Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Fri, 14 Jan 2022 16:58:48 +0000 Subject: [PATCH 4/5] 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); From ff810c3a8a4ff59dd8552a20d8b3983d2c8b3ef3 Mon Sep 17 00:00:00 2001 From: Tsung-Mao Fang Date: Tue, 25 Jan 2022 12:21:42 +0800 Subject: [PATCH 5/5] Ignore broken tests Bug: 216213206 Test: run robo test Change-Id: I4538465480595524f5d49861f822572842f503ae --- .../AccessibilityHearingAidPreferenceControllerTest.java | 2 ++ .../bluetooth/BluetoothDetailsButtonsControllerTest.java | 2 ++ .../bluetooth/BluetoothDetailsControllerEventsTest.java | 2 ++ .../bluetooth/BluetoothDetailsHeaderControllerTest.java | 2 ++ .../bluetooth/BluetoothDetailsMacAddressControllerTest.java | 2 ++ .../bluetooth/BluetoothDetailsProfilesControllerTest.java | 2 ++ .../sound/AudioOutputSwitchPreferenceControllerTest.java | 2 ++ .../sound/HandsFreeProfileOutputPreferenceControllerTest.java | 1 + .../settings/sound/MediaOutputPreferenceControllerTest.java | 1 + 9 files changed, 16 insertions(+) diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java index 0b739f49743..f59545236fa 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java @@ -48,6 +48,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -62,6 +63,7 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Ignore @Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class}) public class AccessibilityHearingAidPreferenceControllerTest { private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"; diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsButtonsControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsButtonsControllerTest.java index 17b824c88e8..df743959b2c 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsButtonsControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsButtonsControllerTest.java @@ -35,6 +35,7 @@ import androidx.fragment.app.FragmentTransaction; import com.android.settings.R; import com.android.settingslib.widget.ActionButtonsPreference; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -42,6 +43,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) +@Ignore public class BluetoothDetailsButtonsControllerTest extends BluetoothDetailsControllerTestBase { private BluetoothDetailsButtonsController mController; private ActionButtonsPreference mButtonsPref; diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerEventsTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerEventsTest.java index 36efcbdf5cc..7f3ab628bca 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerEventsTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerEventsTest.java @@ -29,11 +29,13 @@ import androidx.preference.PreferenceScreen; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.core.lifecycle.Lifecycle; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) +@Ignore public class BluetoothDetailsControllerEventsTest extends BluetoothDetailsControllerTestBase { @Test diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java index 94f8cc52dc7..a28c4f5010c 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java @@ -37,6 +37,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.widget.LayoutPreference; import org.junit.After; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; @@ -46,6 +47,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) +@Ignore @Config(shadows = {ShadowEntityHeaderController.class, ShadowDeviceConfig.class}) public class BluetoothDetailsHeaderControllerTest extends BluetoothDetailsControllerTestBase { diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressControllerTest.java index 749a18278ee..6e9da781114 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressControllerTest.java @@ -21,11 +21,13 @@ import static com.google.common.truth.Truth.assertThat; import com.android.settingslib.widget.FooterPreference; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) +@Ignore public class BluetoothDetailsMacAddressControllerTest extends BluetoothDetailsControllerTestBase { private BluetoothDetailsMacAddressController mController; diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java index c5b0a6a0630..3bc9a05acbc 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java @@ -42,6 +42,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.bluetooth.MapProfile; import com.android.settingslib.bluetooth.PbapServerProfile; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -56,6 +57,7 @@ import java.util.Map; import java.util.Set; @RunWith(RobolectricTestRunner.class) +@Ignore @Config(shadows = ShadowBluetoothDevice.class) public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsControllerTestBase { diff --git a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java index 9c916028c1e..b73e1c9ae4c 100644 --- a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java @@ -58,6 +58,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -73,6 +74,7 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Ignore @Config(shadows = { ShadowAudioManager.class, ShadowBluetoothUtils.class, diff --git a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java index fec70dc096b..39109065b80 100644 --- a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java @@ -66,6 +66,7 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Ignore @Config(shadows = { ShadowAudioManager.class, ShadowBluetoothUtils.class, diff --git a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java index f604193debc..306c4c1a4da 100644 --- a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java @@ -79,6 +79,7 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Ignore @Config(shadows = { ShadowAudioManager.class, ShadowBluetoothUtils.class,