From 260142b49515f80ed49a692125046316a00d5455 Mon Sep 17 00:00:00 2001 From: Quang Anh Luong Date: Mon, 26 Jun 2023 16:19:49 +0900 Subject: [PATCH 1/6] Use speed string from WifiEntry Use speed string from WifiEntry.getTx/RxSpeedString() instead of creating it from the raw Mbps value. Bug: 286246206 Test: atest WifiDetailPReferenceController2Test, manually verify speed string is populated correctly in the Network Details page Change-Id: I89fa0e387d8ef4a5bbfa14871517273ed77bb0e0 --- .../WifiDetailPreferenceController2.java | 22 +++---- .../WifiDetailPreferenceController2Test.java | 60 ++++--------------- 2 files changed, 18 insertions(+), 64 deletions(-) diff --git a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java index 4c5a4bfe3de..2e1bc31ee4f 100644 --- a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java +++ b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java @@ -637,29 +637,23 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle } private void refreshTxSpeed() { - if (mWifiInfo == null - || mWifiEntry.getConnectedState() != WifiEntry.CONNECTED_STATE_CONNECTED) { + String summary = mWifiEntry.getTxSpeedString(); + if (TextUtils.isEmpty(summary)) { mTxLinkSpeedPref.setVisible(false); return; } - - int txLinkSpeedMbps = mWifiInfo.getTxLinkSpeedMbps(); - mTxLinkSpeedPref.setVisible(txLinkSpeedMbps >= 0); - mTxLinkSpeedPref.setSummary(mContext.getString( - R.string.tx_link_speed, mWifiInfo.getTxLinkSpeedMbps())); + mTxLinkSpeedPref.setVisible(true); + mTxLinkSpeedPref.setSummary(summary); } private void refreshRxSpeed() { - if (mWifiInfo == null - || mWifiEntry.getConnectedState() != WifiEntry.CONNECTED_STATE_CONNECTED) { + String summary = mWifiEntry.getRxSpeedString(); + if (TextUtils.isEmpty(summary)) { mRxLinkSpeedPref.setVisible(false); return; } - - int rxLinkSpeedMbps = mWifiInfo.getRxLinkSpeedMbps(); - mRxLinkSpeedPref.setVisible(rxLinkSpeedMbps >= 0); - mRxLinkSpeedPref.setSummary(mContext.getString( - R.string.rx_link_speed, mWifiInfo.getRxLinkSpeedMbps())); + mRxLinkSpeedPref.setVisible(true); + mRxLinkSpeedPref.setSummary(summary); } private void refreshSsid() { diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java index c86a0230351..dcd9b36bdc0 100644 --- a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java +++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java @@ -701,10 +701,10 @@ public class WifiDetailPreferenceController2Test { } @Test - public void linkSpeedPref_shouldNotShowIfNotSet() { + public void linkSpeedPref_shouldNotShowIfSpeedStringIsEmpty() { setUpForConnectedNetwork(); setUpSpyController(); - when(mMockWifiInfo.getTxLinkSpeedMbps()).thenReturn(WifiInfo.LINK_SPEED_UNKNOWN); + when(mMockWifiEntry.getTxSpeedString()).thenReturn(""); displayAndResume(); @@ -712,42 +712,22 @@ public class WifiDetailPreferenceController2Test { } @Test - public void linkSpeedPref_shouldVisibleForConnectedNetwork() { + public void linkSpeedPref_shouldBeVisibleIfSpeedStringIsNotEmpty() { setUpForConnectedNetwork(); setUpSpyController(); - String expectedLinkSpeed = mContext.getString(R.string.tx_link_speed, TX_LINK_SPEED); + when(mMockWifiEntry.getTxSpeedString()).thenReturn("100 Mbps"); displayAndResume(); verify(mMockTxLinkSpeedPref).setVisible(true); - verify(mMockTxLinkSpeedPref).setSummary(expectedLinkSpeed); + verify(mMockTxLinkSpeedPref).setSummary("100 Mbps"); } @Test - public void linkSpeedPref_shouldInvisibleForDisconnectedNetwork() { - setUpForDisconnectedNetwork(); - - displayAndResume(); - - verify(mMockTxLinkSpeedPref).setVisible(false); - verify(mMockTxLinkSpeedPref, never()).setSummary(any(String.class)); - } - - @Test - public void linkSpeedPref_shouldInvisibleForNotInRangeNetwork() { - setUpForNotInRangeNetwork(); - - displayAndResume(); - - verify(mMockTxLinkSpeedPref).setVisible(false); - verify(mMockTxLinkSpeedPref, never()).setSummary(any(String.class)); - } - - @Test - public void rxLinkSpeedPref_shouldNotShowIfNotSet() { + public void rxLinkSpeedPref_shouldNotShowIfSpeedStringIsEmpty() { setUpForConnectedNetwork(); setUpSpyController(); - when(mMockWifiInfo.getRxLinkSpeedMbps()).thenReturn(WifiInfo.LINK_SPEED_UNKNOWN); + when(mMockWifiEntry.getRxSpeedString()).thenReturn(""); displayAndResume(); @@ -755,35 +735,15 @@ public class WifiDetailPreferenceController2Test { } @Test - public void rxLinkSpeedPref_shouldVisibleForConnectedNetwork() { + public void rxLinkSpeedPref_shouldBeVisibleIfSpeedStringIsNotEmpty() { setUpForConnectedNetwork(); setUpSpyController(); - String expectedLinkSpeed = mContext.getString(R.string.rx_link_speed, RX_LINK_SPEED); + when(mMockWifiEntry.getRxSpeedString()).thenReturn("100 Mbps"); displayAndResume(); verify(mMockRxLinkSpeedPref).setVisible(true); - verify(mMockRxLinkSpeedPref).setSummary(expectedLinkSpeed); - } - - @Test - public void rxLinkSpeedPref_shouldInvisibleForDisconnectedNetwork() { - setUpForDisconnectedNetwork(); - - displayAndResume(); - - verify(mMockRxLinkSpeedPref).setVisible(false); - verify(mMockRxLinkSpeedPref, never()).setSummary(any(String.class)); - } - - @Test - public void rxLinkSpeedPref_shouldInvisibleForNotInRangeNetwork() { - setUpForNotInRangeNetwork(); - - displayAndResume(); - - verify(mMockRxLinkSpeedPref).setVisible(false); - verify(mMockRxLinkSpeedPref, never()).setSummary(any(String.class)); + verify(mMockRxLinkSpeedPref).setSummary("100 Mbps"); } @Test From 499f965c1c79cea14377c37028133a9f8717693d Mon Sep 17 00:00:00 2001 From: Michael Mikhail Date: Wed, 21 Jun 2023 16:58:20 +0000 Subject: [PATCH 2/6] Add content description to volume title in settings. Adds content description that is announced by talkback when a11y focus is on volume preference. This improves talkback announcement when view changes. Fixes: 285529113 Bug: 285455826 Fixes: 285487766 Test: atest VolumeSeekBarPreferenceControllerTest Test: atest VolumeSeekBarPreferenceTest Change-Id: Ibe80b4b1d489dc058df1cc79c96b034d5ddc6e56 --- res/values/strings.xml | 12 ++++++ .../MediaVolumePreferenceController.java | 13 ++++++ ...otificationVolumePreferenceController.java | 43 ++++++++++++------- ...odeAffectedVolumePreferenceController.java | 30 ++++++++++++- ...eparateRingVolumePreferenceController.java | 1 + .../notification/VolumeSeekBarPreference.java | 41 +++++++++++++++++- .../VolumeSeekBarPreferenceController.java | 2 + ...VolumeSeekBarPreferenceControllerTest.java | 12 ++++-- .../VolumeSeekBarPreferenceTest.java | 33 ++++++++++++++ 9 files changed, 164 insertions(+), 23 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 45b60265548..5e10a3770a7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7151,6 +7151,18 @@ Notification volume + + Ringer silent + + + Ringer vibrate + + + Notification volume muted, notifications will vibrate + + + %1$s muted + Unavailable because ring is muted diff --git a/src/com/android/settings/notification/MediaVolumePreferenceController.java b/src/com/android/settings/notification/MediaVolumePreferenceController.java index e40a2b4af98..79df55a0048 100644 --- a/src/com/android/settings/notification/MediaVolumePreferenceController.java +++ b/src/com/android/settings/notification/MediaVolumePreferenceController.java @@ -52,6 +52,7 @@ public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceCont public MediaVolumePreferenceController(Context context) { super(context, KEY_MEDIA_VOLUME); + mVolumePreferenceListener = this::updateContentDescription; } @Override @@ -109,6 +110,18 @@ public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceCont return false; } + private void updateContentDescription() { + if (mPreference != null) { + if (mPreference.isMuted()) { + mPreference.updateContentDescription( + mContext.getString(R.string.volume_content_description_silent_mode, + mPreference.getTitle())); + } else { + mPreference.updateContentDescription(mPreference.getTitle()); + } + } + } + @Override public SliceAction getSliceEndItem(Context context) { if (!isSupportEndItem()) { diff --git a/src/com/android/settings/notification/NotificationVolumePreferenceController.java b/src/com/android/settings/notification/NotificationVolumePreferenceController.java index cf8a33f765c..02dc96a2804 100644 --- a/src/com/android/settings/notification/NotificationVolumePreferenceController.java +++ b/src/com/android/settings/notification/NotificationVolumePreferenceController.java @@ -75,6 +75,7 @@ public class NotificationVolumePreferenceController extends updateEffectsSuppressor(); selectPreferenceIconState(); + updateContentDescription(); updateEnabledState(); } @@ -120,23 +121,32 @@ public class NotificationVolumePreferenceController extends } @Override - protected void selectPreferenceIconState() { + protected int getEffectiveRingerMode() { + if (mVibrator == null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { + return AudioManager.RINGER_MODE_SILENT; + } else if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) { + if (mHelper.getStreamVolume(AudioManager.STREAM_NOTIFICATION) == 0) { + // Ring is in normal, but notification is in silent. + return AudioManager.RINGER_MODE_SILENT; + } + } + return mRingerMode; + } + + @Override + protected void updateContentDescription() { if (mPreference != null) { - if (mVibrator != null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { - mMuteIcon = mVibrateIconId; - mPreference.showIcon(mVibrateIconId); - } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT - || mVibrator == null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { - mMuteIcon = mSilentIconId; - mPreference.showIcon(mSilentIconId); - } else { // ringmode normal: could be that we are still silent - if (mHelper.getStreamVolume(AudioManager.STREAM_NOTIFICATION) == 0) { - // ring is in normal, but notification is in silent - mMuteIcon = mSilentIconId; - mPreference.showIcon(mSilentIconId); - } else { - mPreference.showIcon(mNormalIconId); - } + int ringerMode = getEffectiveRingerMode(); + if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { + mPreference.updateContentDescription( + mContext.getString( + R.string.notification_volume_content_description_vibrate_mode)); + } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) { + mPreference.updateContentDescription( + mContext.getString(R.string.volume_content_description_silent_mode, + mPreference.getTitle())); + } else { + mPreference.updateContentDescription(mPreference.getTitle()); } } } @@ -169,6 +179,7 @@ public class NotificationVolumePreferenceController extends break; case NOTIFICATION_VOLUME_CHANGED: selectPreferenceIconState(); + updateContentDescription(); updateEnabledState(); break; } diff --git a/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java b/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java index 36877707257..ab65f8f5a9d 100644 --- a/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java +++ b/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java @@ -26,6 +26,7 @@ import android.os.Vibrator; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.settings.R; import java.util.Objects; @@ -54,6 +55,7 @@ public abstract class RingerModeAffectedVolumePreferenceController extends if (mVibrator != null && !mVibrator.hasVibrator()) { mVibrator = null; } + mVolumePreferenceListener = this::updateContentDescription; } protected void updateEffectsSuppressor() { @@ -123,6 +125,7 @@ public abstract class RingerModeAffectedVolumePreferenceController extends } mRingerMode = ringerMode; selectPreferenceIconState(); + updateContentDescription(); return true; } @@ -131,10 +134,11 @@ public abstract class RingerModeAffectedVolumePreferenceController extends */ protected void selectPreferenceIconState() { if (mPreference != null) { - if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) { + int ringerMode = getEffectiveRingerMode(); + if (ringerMode == AudioManager.RINGER_MODE_NORMAL) { mPreference.showIcon(mNormalIconId); } else { - if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE && mVibrator != null) { + if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { mMuteIcon = mVibrateIconId; } else { mMuteIcon = mSilentIconId; @@ -144,6 +148,28 @@ public abstract class RingerModeAffectedVolumePreferenceController extends } } + protected int getEffectiveRingerMode() { + if (mVibrator == null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { + return AudioManager.RINGER_MODE_SILENT; + } + return mRingerMode; + } + + protected void updateContentDescription() { + if (mPreference != null) { + int ringerMode = getEffectiveRingerMode(); + if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { + mPreference.updateContentDescription( + mContext.getString(R.string.ringer_content_description_vibrate_mode)); + } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) { + mPreference.updateContentDescription( + mContext.getString(R.string.ringer_content_description_silent_mode)); + } else { + mPreference.updateContentDescription(mPreference.getTitle()); + } + } + } + protected abstract boolean hintsMatch(int hints); } diff --git a/src/com/android/settings/notification/SeparateRingVolumePreferenceController.java b/src/com/android/settings/notification/SeparateRingVolumePreferenceController.java index b8a99085f6d..91926e3c977 100644 --- a/src/com/android/settings/notification/SeparateRingVolumePreferenceController.java +++ b/src/com/android/settings/notification/SeparateRingVolumePreferenceController.java @@ -65,6 +65,7 @@ public class SeparateRingVolumePreferenceController extends mReceiver.register(true); updateEffectsSuppressor(); selectPreferenceIconState(); + updateContentDescription(); if (mPreference != null) { mPreference.setVisible(getAvailabilityStatus() == AVAILABLE); diff --git a/src/com/android/settings/notification/VolumeSeekBarPreference.java b/src/com/android/settings/notification/VolumeSeekBarPreference.java index 14955c426e1..f3c1471be4f 100644 --- a/src/com/android/settings/notification/VolumeSeekBarPreference.java +++ b/src/com/android/settings/notification/VolumeSeekBarPreference.java @@ -47,10 +47,13 @@ public class VolumeSeekBarPreference extends SeekBarPreference { protected SeekBar mSeekBar; private int mStream; - private SeekBarVolumizer mVolumizer; + @VisibleForTesting + SeekBarVolumizer mVolumizer; private Callback mCallback; + private Listener mListener; private ImageView mIconView; private TextView mSuppressionTextView; + private TextView mTitle; private String mSuppressionText; private boolean mMuted; private boolean mZenMuted; @@ -98,6 +101,10 @@ public class VolumeSeekBarPreference extends SeekBarPreference { mCallback = callback; } + public void setListener(Listener listener) { + mListener = listener; + } + public void onActivityResume() { if (mStopped) { init(); @@ -118,6 +125,7 @@ public class VolumeSeekBarPreference extends SeekBarPreference { mSeekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); mIconView = (ImageView) view.findViewById(com.android.internal.R.id.icon); mSuppressionTextView = (TextView) view.findViewById(R.id.suppression_text); + mTitle = (TextView) view.findViewById(com.android.internal.R.id.title); init(); } @@ -142,6 +150,9 @@ public class VolumeSeekBarPreference extends SeekBarPreference { mMuted = muted; mZenMuted = zenMuted; updateIconView(); + if (mListener != null) { + mListener.onUpdateMuteState(); + } } @Override public void onStartTrackingTouch(SeekBarVolumizer sbv) { @@ -165,6 +176,9 @@ public class VolumeSeekBarPreference extends SeekBarPreference { mVolumizer.setSeekBar(mSeekBar); updateIconView(); updateSuppressionText(); + if (mListener != null) { + mListener.onUpdateMuteState(); + } if (!isEnabled()) { mSeekBar.setEnabled(false); mVolumizer.stop(); @@ -175,7 +189,7 @@ public class VolumeSeekBarPreference extends SeekBarPreference { if (mIconView == null) return; if (mIconResId != 0) { mIconView.setImageResource(mIconResId); - } else if (mMuteIconResId != 0 && mMuted && !mZenMuted) { + } else if (mMuteIconResId != 0 && isMuted()) { mIconView.setImageResource(mMuteIconResId); } else { mIconView.setImageDrawable(getIcon()); @@ -208,6 +222,10 @@ public class VolumeSeekBarPreference extends SeekBarPreference { updateSuppressionText(); } + protected boolean isMuted() { + return mMuted && !mZenMuted; + } + protected void updateSuppressionText() { if (mSuppressionTextView != null && mSeekBar != null) { mSuppressionTextView.setText(mSuppressionText); @@ -216,6 +234,14 @@ public class VolumeSeekBarPreference extends SeekBarPreference { } } + /** + * Update content description of title to improve talkback announcements. + */ + protected void updateContentDescription(CharSequence contentDescription) { + if (mTitle == null) return; + mTitle.setContentDescription(contentDescription); + } + public interface Callback { void onSampleStarting(SeekBarVolumizer sbv); void onStreamValueChanged(int stream, int progress); @@ -225,4 +251,15 @@ public class VolumeSeekBarPreference extends SeekBarPreference { */ void onStartTrackingTouch(SeekBarVolumizer sbv); } + + /** + * Listener to view updates in volumeSeekbarPreference. + */ + public interface Listener { + + /** + * Listener to mute state updates. + */ + void onUpdateMuteState(); + } } diff --git a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java index 0414565721e..285e8ddbeb9 100644 --- a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java +++ b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java @@ -36,6 +36,7 @@ public abstract class VolumeSeekBarPreferenceController extends protected VolumeSeekBarPreference mPreference; protected VolumeSeekBarPreference.Callback mVolumePreferenceCallback; protected AudioHelper mHelper; + protected VolumeSeekBarPreference.Listener mVolumePreferenceListener; public VolumeSeekBarPreferenceController(Context context, String key) { super(context, key); @@ -62,6 +63,7 @@ public abstract class VolumeSeekBarPreferenceController extends protected void setupVolPreference(PreferenceScreen screen) { mPreference = screen.findPreference(getPreferenceKey()); mPreference.setCallback(mVolumePreferenceCallback); + mPreference.setListener(mVolumePreferenceListener); mPreference.setStream(getAudioStream()); mPreference.setMuteIcon(getMuteIcon()); } diff --git a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java index 2d54c38e249..f7e32a2c9d9 100644 --- a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java @@ -49,6 +49,8 @@ public class VolumeSeekBarPreferenceControllerTest { @Mock private VolumeSeekBarPreference.Callback mCallback; @Mock + private VolumeSeekBarPreference.Listener mListener; + @Mock private AudioHelper mHelper; private VolumeSeekBarPreferenceControllerTestable mController; @@ -59,7 +61,7 @@ public class VolumeSeekBarPreferenceControllerTest { when(mScreen.findPreference(nullable(String.class))).thenReturn(mPreference); when(mPreference.getKey()).thenReturn("key"); mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback, true, - mPreference.getKey()); + mPreference.getKey(), mListener); mController.setAudioHelper(mHelper); } @@ -70,18 +72,20 @@ public class VolumeSeekBarPreferenceControllerTest { verify(mPreference).setCallback(mCallback); verify(mPreference).setStream(VolumeSeekBarPreferenceControllerTestable.AUDIO_STREAM); verify(mPreference).setMuteIcon(VolumeSeekBarPreferenceControllerTestable.MUTE_ICON); + verify(mPreference).setListener(mListener); } @Test public void displayPreference_notAvailable_shouldNotUpdatePreference() { mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback, false, - mPreference.getKey()); + mPreference.getKey(), mListener); mController.displayPreference(mScreen); verify(mPreference, never()).setCallback(any(VolumeSeekBarPreference.Callback.class)); verify(mPreference, never()).setStream(anyInt()); verify(mPreference, never()).setMuteIcon(anyInt()); + verify(mPreference, never()).setListener(mListener); } @Test @@ -157,10 +161,12 @@ public class VolumeSeekBarPreferenceControllerTest { private boolean mAvailable; VolumeSeekBarPreferenceControllerTestable(Context context, - VolumeSeekBarPreference.Callback callback, boolean available, String key) { + VolumeSeekBarPreference.Callback callback, boolean available, String key, + VolumeSeekBarPreference.Listener listener) { super(context, key); setCallback(callback); mAvailable = available; + mVolumePreferenceListener = listener; } @Override diff --git a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceTest.java index d74f76a7cea..59f0bcb91b9 100644 --- a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceTest.java @@ -18,11 +18,14 @@ package com.android.settings.notification; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.media.AudioManager; +import android.preference.SeekBarVolumizer; +import android.widget.SeekBar; import org.junit.Before; import org.junit.Test; @@ -34,18 +37,28 @@ import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) public class VolumeSeekBarPreferenceTest { + private static final CharSequence CONTENT_DESCRIPTION = "TEST"; @Mock private AudioManager mAudioManager; @Mock private VolumeSeekBarPreference mPreference; @Mock private Context mContext; + @Mock + private SeekBar mSeekBar; + @Mock + private SeekBarVolumizer mVolumizer; + private VolumeSeekBarPreference.Listener mListener; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); + doCallRealMethod().when(mPreference).updateContentDescription(CONTENT_DESCRIPTION); + mPreference.mSeekBar = mSeekBar; mPreference.mAudioManager = mAudioManager; + mPreference.mVolumizer = mVolumizer; + mListener = () -> mPreference.updateContentDescription(CONTENT_DESCRIPTION); } @Test @@ -65,4 +78,24 @@ public class VolumeSeekBarPreferenceTest { verify(mPreference).setMin(min); verify(mPreference).setProgress(progress); } + + @Test + public void init_listenerIsCalled() { + doCallRealMethod().when(mPreference).setListener(mListener); + doCallRealMethod().when(mPreference).init(); + + mPreference.setListener(mListener); + mPreference.init(); + + verify(mPreference).updateContentDescription(CONTENT_DESCRIPTION); + } + + @Test + public void init_listenerNotSet_noException() { + doCallRealMethod().when(mPreference).init(); + + mPreference.init(); + + verify(mPreference, never()).updateContentDescription(CONTENT_DESCRIPTION); + } } From 6308e3fb2a3ff6bf00bb02b133678fe4fee37f5d Mon Sep 17 00:00:00 2001 From: Michael Mikhail Date: Mon, 26 Jun 2023 20:16:30 +0000 Subject: [PATCH 3/6] Trigger talkback for notification volume change Triggers talkback to say the content description of the title of notification volume when notification volume is set to vibrate or silent mode. Fixes: 285453719 Fixes: 285455826 Test: manually checked when the ring volume is set to 0% and when the notification volume is set to 0%. Check the video in the bug link. Change-Id: I4bd65bdbfa41793fc8e32c295185363ca36cc0d7 --- .../NotificationVolumePreferenceController.java | 6 ++++++ .../settings/notification/VolumeSeekBarPreference.java | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/com/android/settings/notification/NotificationVolumePreferenceController.java b/src/com/android/settings/notification/NotificationVolumePreferenceController.java index 02dc96a2804..fe7b70bf129 100644 --- a/src/com/android/settings/notification/NotificationVolumePreferenceController.java +++ b/src/com/android/settings/notification/NotificationVolumePreferenceController.java @@ -26,6 +26,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.service.notification.NotificationListenerService; +import android.view.View; import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.PreferenceScreen; @@ -138,14 +139,19 @@ public class NotificationVolumePreferenceController extends if (mPreference != null) { int ringerMode = getEffectiveRingerMode(); if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { + mPreference.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); mPreference.updateContentDescription( mContext.getString( R.string.notification_volume_content_description_vibrate_mode)); } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) { + mPreference.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); mPreference.updateContentDescription( mContext.getString(R.string.volume_content_description_silent_mode, mPreference.getTitle())); } else { + // Set a11y mode to none in order not to trigger talkback while changing + // notification volume in normal mode. + mPreference.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_NONE); mPreference.updateContentDescription(mPreference.getTitle()); } } diff --git a/src/com/android/settings/notification/VolumeSeekBarPreference.java b/src/com/android/settings/notification/VolumeSeekBarPreference.java index f3c1471be4f..0000eba2ba7 100644 --- a/src/com/android/settings/notification/VolumeSeekBarPreference.java +++ b/src/com/android/settings/notification/VolumeSeekBarPreference.java @@ -242,6 +242,11 @@ public class VolumeSeekBarPreference extends SeekBarPreference { mTitle.setContentDescription(contentDescription); } + protected void setAccessibilityLiveRegion(int mode) { + if (mTitle == null) return; + mTitle.setAccessibilityLiveRegion(mode); + } + public interface Callback { void onSampleStarting(SeekBarVolumizer sbv); void onStreamValueChanged(int stream, int progress); From fefda226f7cefef2149835c869a28b6649efde94 Mon Sep 17 00:00:00 2001 From: Hao Dong Date: Fri, 30 Jun 2023 20:48:57 +0000 Subject: [PATCH 4/6] Add super call in FingerprintEnrollEnrolling onConfigurationChanged. Test: N/A - fix a crash Bug: 289458339 Change-Id: Id34b1036fe12079b14cd3aaa0a85eecc138e6b17 --- .../biometrics/fingerprint/FingerprintEnrollEnrolling.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java index dbdb024973a..a62bd6723ec 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java @@ -1101,9 +1101,9 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { } } - @SuppressWarnings("MissingSuperCall") // TODO: Fix me @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); maybeHideSfpsText(newConfig); switch(newConfig.orientation) { case Configuration.ORIENTATION_LANDSCAPE: { From 6c7e4560a2393c34899b35489a4f9eecadc60802 Mon Sep 17 00:00:00 2001 From: Rhed Jao Date: Tue, 4 Jul 2023 09:44:50 +0000 Subject: [PATCH 5/6] Update strings for the repair mode lock password screen Bug: 289325981 Test: build Change-Id: I347397fa0445436a231bc82529215c6031e4d80d --- res/values/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 927035d3095..198208fb231 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3493,18 +3493,18 @@ Also use password to unlock this device - + Verify pattern - + Verify PIN - + Verify password - - Enter your device pattern enrolled in normal mode to continue - - Enter your device PIN enrolled in normal mode to continue - - Enter your device password enrolled in normal mode to continue + + Use your device pattern to continue + + Enter your device PIN to continue + + Enter your device password to continue From b88bad678dd5ba64344d643866bf81a8813d5bfb Mon Sep 17 00:00:00 2001 From: Tetiana Meronyk Date: Tue, 4 Jul 2023 13:43:36 +0000 Subject: [PATCH 6/6] Fix "Allow guest to use telephony" toggle not updating its value Bug: 283004333 Test: atest GuestTelephonyPreferenceControllerTest Change-Id: I2f13a989bbe6a925c0e88350dbc215f6f188fe17 --- .../GuestTelephonyPreferenceController.java | 16 ++++++++-------- .../GuestTelephonyPreferenceControllerTest.java | 4 ++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/com/android/settings/users/GuestTelephonyPreferenceController.java b/src/com/android/settings/users/GuestTelephonyPreferenceController.java index 2aa808f4e5c..83e4bfc5310 100644 --- a/src/com/android/settings/users/GuestTelephonyPreferenceController.java +++ b/src/com/android/settings/users/GuestTelephonyPreferenceController.java @@ -34,14 +34,11 @@ public class GuestTelephonyPreferenceController extends TogglePreferenceControll private final UserManager mUserManager; private final UserCapabilities mUserCaps; - private Bundle mDefaultGuestRestrictions; public GuestTelephonyPreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); mUserManager = context.getSystemService(UserManager.class); mUserCaps = UserCapabilities.create(context); - mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions(); - mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true); } @Override @@ -55,13 +52,16 @@ public class GuestTelephonyPreferenceController extends TogglePreferenceControll @Override public boolean isChecked() { - return !mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS, false); + return !mUserManager.getDefaultGuestRestrictions() + .getBoolean(UserManager.DISALLOW_OUTGOING_CALLS, false); } @Override public boolean setChecked(boolean isChecked) { - mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, !isChecked); - mUserManager.setDefaultGuestRestrictions(mDefaultGuestRestrictions); + Bundle guestRestrictions = mUserManager.getDefaultGuestRestrictions(); + guestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true); + guestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, !isChecked); + mUserManager.setDefaultGuestRestrictions(guestRestrictions); return true; } @@ -74,7 +74,7 @@ public class GuestTelephonyPreferenceController extends TogglePreferenceControll public void updateState(Preference preference) { super.updateState(preference); mUserCaps.updateAddUserCapabilities(mContext); - preference.setVisible(isAvailable() && mUserCaps.mUserSwitcherEnabled && mContext - .getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)); + preference.setVisible(isAvailable() && mUserCaps.mUserSwitcherEnabled + && mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)); } } diff --git a/tests/robotests/src/com/android/settings/users/GuestTelephonyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/users/GuestTelephonyPreferenceControllerTest.java index aa84cb66576..c4b514cad13 100644 --- a/tests/robotests/src/com/android/settings/users/GuestTelephonyPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/users/GuestTelephonyPreferenceControllerTest.java @@ -18,12 +18,14 @@ package com.android.settings.users; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assume.assumeTrue; import static org.mockito.Answers.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.content.pm.PackageManager; import android.os.SystemProperties; import android.os.UserManager; @@ -103,6 +105,8 @@ public class GuestTelephonyPreferenceControllerTest { @Test public void updateState_Admin_shouldDisplayPreference() { + assumeTrue("Device does not have telephony feature ", + mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)); SystemProperties.set("fw.max_users", Long.toBinaryString(4)); mDpm.setDeviceOwner(null); mUserManager.setIsAdminUser(true);