Loading packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java +35 −3 Original line number Diff line number Diff line Loading @@ -58,9 +58,26 @@ public interface VolumeDialogController { void userActivity(); void getState(); boolean areCaptionsEnabled(); void setCaptionsEnabled(boolean isEnabled); /** * Get Captions enabled state * * @param checkForSwitchState set true when we'd like to switch captions enabled state after * getting the latest captions state. */ void getCaptionsEnabledState(boolean checkForSwitchState); /** * Set Captions enabled state * * @param enabled the captions enabled state we'd like to update. */ void setCaptionsEnabledState(boolean enabled); /** * Get Captions component state * * @param fromTooltip if it's triggered from tooltip. */ void getCaptionsComponentState(boolean fromTooltip); @ProvidesInterface(version = StreamState.VERSION) Loading Loading @@ -192,7 +209,22 @@ public interface VolumeDialogController { void onScreenOff(); void onShowSafetyWarning(int flags); void onAccessibilityModeChanged(Boolean showA11yStream); /** * Callback function for captions component state changed event * * @param isComponentEnabled the lateset captions component state. * @param fromTooltip if it's triggered from tooltip. */ void onCaptionComponentStateChanged(Boolean isComponentEnabled, Boolean fromTooltip); /** * Callback function for captions enabled state changed event * * @param isEnabled the lateset captions enabled state. * @param checkBeforeSwitch intend to switch captions enabled state after the callback. */ void onCaptionEnabledStateChanged(Boolean isEnabled, Boolean checkBeforeSwitch); // requires version 2 void onShowCsdWarning(@AudioManager.CsdWarning int csdWarning, int durationMs); } Loading packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +90 −24 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.media.session.MediaController.PlaybackInfo; import android.media.session.MediaSession.Token; import android.net.Uri; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; import android.os.Message; import android.os.RemoteException; Loading @@ -57,6 +58,7 @@ import android.util.Slog; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.CaptioningManager; import androidx.annotation.NonNull; import androidx.lifecycle.Observer; import com.android.internal.annotations.GuardedBy; Loading @@ -81,6 +83,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; Loading Loading @@ -131,7 +134,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa private final Receiver mReceiver = new Receiver(); private final RingerModeObservers mRingerModeObservers; private final MediaSessions mMediaSessions; private final CaptioningManager mCaptioningManager; private final AtomicReference<CaptioningManager> mCaptioningManager = new AtomicReference<>(); private final KeyguardManager mKeyguardManager; private final ActivityManager mActivityManager; private final UserTracker mUserTracker; Loading Loading @@ -179,7 +182,6 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa AccessibilityManager accessibilityManager, PackageManager packageManager, WakefulnessLifecycle wakefulnessLifecycle, CaptioningManager captioningManager, KeyguardManager keyguardManager, ActivityManager activityManager, UserTracker userTracker, Loading Loading @@ -209,10 +211,12 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa mVibrator = vibrator; mHasVibrator = mVibrator.hasVibrator(); mAudioService = iAudioService; mCaptioningManager = captioningManager; mKeyguardManager = keyguardManager; mActivityManager = activityManager; mUserTracker = userTracker; mUserTracker.addCallback(mUserChangedCallback, new HandlerExecutor(mWorker)); createCaptioningManagerServiceByUserContext(mUserTracker.getUserContext()); dumpManager.registerDumpable("VolumeDialogControllerImpl", this); boolean accessibilityVolumeStreamActive = accessibilityManager Loading Loading @@ -316,12 +320,31 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa mWorker.sendEmptyMessage(W.GET_STATE); } public boolean areCaptionsEnabled() { return mCaptioningManager.isSystemAudioCaptioningEnabled(); /** * We met issues about the wrong state of System Caption in multi-user mode. * It happened in the usage of CaptioningManager Service from SysUI process * that is a global system process of User 0. * Therefore, we have to add callback on UserTracker that allows us to get the Context of * active User and then get the corresponding CaptioningManager Service for further usages. */ private final UserTracker.Callback mUserChangedCallback = new UserTracker.Callback() { @Override public void onUserChanged(int newUser, @NonNull Context userContext) { createCaptioningManagerServiceByUserContext(userContext); } }; private void createCaptioningManagerServiceByUserContext(@NonNull Context userContext) { mCaptioningManager.set(userContext.getSystemService(CaptioningManager.class)); } public void setCaptionsEnabled(boolean isEnabled) { mCaptioningManager.setSystemAudioCaptioningEnabled(isEnabled); public void getCaptionsEnabledState(boolean checkForSwitchState) { mWorker.obtainMessage(W.GET_CAPTIONS_ENABLED_STATE, checkForSwitchState).sendToTarget(); } public void setCaptionsEnabledState(boolean enabled) { mWorker.obtainMessage(W.SET_CAPTIONS_ENABLED_STATE, enabled).sendToTarget(); } public void getCaptionsComponentState(boolean fromTooltip) { Loading Loading @@ -418,8 +441,34 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa } private void onGetCaptionsComponentStateW(boolean fromTooltip) { CaptioningManager captioningManager = mCaptioningManager.get(); if (null != captioningManager) { mCallbacks.onCaptionComponentStateChanged( mCaptioningManager.isSystemAudioCaptioningUiEnabled(), fromTooltip); captioningManager.isSystemAudioCaptioningUiEnabled(), fromTooltip); } else { Log.e(TAG, "onGetCaptionsComponentStateW(), null captioningManager"); } } private void onGetCaptionsEnabledStateW(boolean checkForSwitchState) { CaptioningManager captioningManager = mCaptioningManager.get(); if (null != captioningManager) { mCallbacks.onCaptionEnabledStateChanged( captioningManager.isSystemAudioCaptioningEnabled(), checkForSwitchState); } else { Log.e(TAG, "onGetCaptionsEnabledStateW(), null captioningManager"); } } private void onSetCaptionsEnabledStateW(boolean enabled) { CaptioningManager captioningManager = mCaptioningManager.get(); if (null != captioningManager) { captioningManager.setSystemAudioCaptioningEnabled(enabled); mCallbacks.onCaptionEnabledStateChanged( captioningManager.isSystemAudioCaptioningEnabled(), false); } else { Log.e(TAG, "onGetCaptionsEnabledStateW(), null captioningManager"); } } private void onAccessibilityModeChanged(Boolean showA11yStream) { Loading Loading @@ -719,7 +768,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa * This method will never be called if the CSD (Computed Sound Dose) feature is * not enabled. See com.android.android.server.audio.SoundDoseHelper for the state of * the feature. * @param warning the type of warning to display, values are one of * @param csdWarning the type of warning to display, values are one of * {@link android.media.AudioManager#CSD_WARNING_DOSE_REACHED_1X}, * {@link android.media.AudioManager#CSD_WARNING_DOSE_REPEATED_5X}, * {@link android.media.AudioManager#CSD_WARNING_MOMENTARY_EXPOSURE}, Loading Loading @@ -798,6 +847,8 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa private static final int ACCESSIBILITY_MODE_CHANGED = 15; private static final int GET_CAPTIONS_COMPONENT_STATE = 16; private static final int SHOW_CSD_WARNING = 17; private static final int GET_CAPTIONS_ENABLED_STATE = 18; private static final int SET_CAPTIONS_ENABLED_STATE = 19; W(Looper looper) { super(looper); Loading Loading @@ -825,6 +876,10 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa case ACCESSIBILITY_MODE_CHANGED: onAccessibilityModeChanged((Boolean) msg.obj); break; case SHOW_CSD_WARNING: onShowCsdWarningW(msg.arg1, msg.arg2); break; case GET_CAPTIONS_ENABLED_STATE: onGetCaptionsEnabledStateW((Boolean) msg.obj); break; case SET_CAPTIONS_ENABLED_STATE: onSetCaptionsEnabledStateW((Boolean) msg.obj); break; } } } Loading Loading @@ -993,6 +1048,17 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa componentEnabled, fromTooltip)); } } @Override public void onCaptionEnabledStateChanged(Boolean isEnabled, Boolean checkBeforeSwitch) { boolean captionsEnabled = isEnabled != null && isEnabled; for (final Map.Entry<Callbacks, Handler> entry : mCallbackMap.entrySet()) { entry.getValue().post( () -> entry.getKey().onCaptionEnabledStateChanged( captionsEnabled, checkBeforeSwitch)); } } } private final class RingerModeObservers { Loading packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +22 −9 Original line number Diff line number Diff line Loading @@ -1333,21 +1333,30 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, if (!isServiceComponentEnabled) return; updateCaptionsIcon(); checkEnabledStateForCaptionsIconUpdate(); if (fromTooltip) showCaptionsTooltip(); } private void updateCaptionsIcon() { boolean captionsEnabled = mController.areCaptionsEnabled(); if (mODICaptionsIcon.getCaptionsEnabled() != captionsEnabled) { mHandler.post(mODICaptionsIcon.setCaptionsEnabled(captionsEnabled)); private void updateCaptionsEnabledH(boolean isCaptionsEnabled, boolean checkForSwitchState) { if (checkForSwitchState) { mController.setCaptionsEnabledState(!isCaptionsEnabled); } else { updateCaptionsIcon(isCaptionsEnabled); } } private void checkEnabledStateForCaptionsIconUpdate() { mController.getCaptionsEnabledState(false); } private void updateCaptionsIcon(boolean isCaptionsEnabled) { if (mODICaptionsIcon.getCaptionsEnabled() != isCaptionsEnabled) { mHandler.post(mODICaptionsIcon.setCaptionsEnabled(isCaptionsEnabled)); } } private void onCaptionIconClicked() { boolean isEnabled = mController.areCaptionsEnabled(); mController.setCaptionsEnabled(!isEnabled); updateCaptionsIcon(); mController.getCaptionsEnabledState(true); } private void incrementManualToggleCount() { Loading Loading @@ -2363,7 +2372,6 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, } else { updateRowsH(activeRow); } } @Override Loading @@ -2371,6 +2379,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, Boolean isComponentEnabled, Boolean fromTooltip) { updateODICaptionsH(isComponentEnabled, fromTooltip); } @Override public void onCaptionEnabledStateChanged(Boolean isEnabled, Boolean checkForSwitchState) { updateCaptionsEnabledH(isEnabled, checkForSwitchState); } }; @VisibleForTesting void onPostureChanged(int posture) { Loading packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java +10 −6 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import android.os.Process; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.CaptioningManager; import androidx.test.filters.SmallTest; Loading @@ -64,6 +63,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.concurrent.Executor; @RunWith(AndroidTestingRunner.class) @SmallTest @TestableLooper.RunWithLooper Loading Loading @@ -96,8 +97,6 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { @Mock private WakefulnessLifecycle mWakefullnessLifcycle; @Mock private CaptioningManager mCaptioningManager; @Mock private KeyguardManager mKeyguardManager; @Mock private ActivityManager mActivityManager; Loading @@ -117,6 +116,7 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { when(mRingerModeLiveData.getValue()).thenReturn(-1); when(mRingerModeInternalLiveData.getValue()).thenReturn(-1); when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser()); when(mUserTracker.getUserContext()).thenReturn(mContext); // Enable group volume adjustments mContext.getOrCreateTestableResources().addOverride( com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions, Loading @@ -127,7 +127,7 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { mVolumeController = new TestableVolumeDialogControllerImpl(mContext, mBroadcastDispatcher, mRingerModeTracker, mThreadFactory, mAudioManager, mNotificationManager, mVibrator, mIAudioService, mAccessibilityManager, mPackageManager, mWakefullnessLifcycle, mCaptioningManager, mKeyguardManager, mPackageManager, mWakefullnessLifcycle, mKeyguardManager, mActivityManager, mUserTracker, mDumpManager, mCallback); mVolumeController.setEnableDialogs(true, true); } Loading Loading @@ -219,6 +219,11 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { verify(mRingerModeInternalLiveData).observeForever(any()); } @Test public void testAddCallbackWithUserTracker() { verify(mUserTracker).addCallback(any(UserTracker.Callback.class), any(Executor.class)); } static class TestableVolumeDialogControllerImpl extends VolumeDialogControllerImpl { private final WakefulnessLifecycle.Observer mWakefullessLifecycleObserver; Loading @@ -234,7 +239,6 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { AccessibilityManager accessibilityManager, PackageManager packageManager, WakefulnessLifecycle wakefulnessLifecycle, CaptioningManager captioningManager, KeyguardManager keyguardManager, ActivityManager activityManager, UserTracker userTracker, Loading @@ -242,7 +246,7 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { C callback) { super(context, broadcastDispatcher, ringerModeTracker, theadFactory, audioManager, notificationManager, optionalVibrator, iAudioService, accessibilityManager, packageManager, wakefulnessLifecycle, captioningManager, keyguardManager, packageManager, wakefulnessLifecycle, keyguardManager, activityManager, userTracker, dumpManager); mCallbacks = callback; Loading packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static junit.framework.Assert.assertTrue; import static org.junit.Assume.assumeNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; Loading Loading @@ -93,6 +94,8 @@ public class VolumeDialogImplTest extends SysuiTestCase { View mDrawerVibrate; View mDrawerMute; View mDrawerNormal; CaptionsToggleImageButton mODICaptionsIcon; private TestableLooper mTestableLooper; private ConfigurationController mConfigurationController; private int mOriginalOrientation; Loading Loading @@ -180,6 +183,7 @@ public class VolumeDialogImplTest extends SysuiTestCase { mDrawerVibrate = mDrawerContainer.findViewById(R.id.volume_drawer_vibrate); mDrawerMute = mDrawerContainer.findViewById(R.id.volume_drawer_mute); mDrawerNormal = mDrawerContainer.findViewById(R.id.volume_drawer_normal); mODICaptionsIcon = mDialog.getDialogView().findViewById(R.id.odi_captions_icon); Prefs.putInt(mContext, Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT, Loading Loading @@ -688,6 +692,28 @@ public class VolumeDialogImplTest extends SysuiTestCase { assertRingerContainerDescribesItsState(RINGER_MODE_VIBRATE, RingerDrawerState.CLOSE); } @Test public void testOnCaptionEnabledStateChanged_checkBeforeSwitchTrue_setCaptionsEnabledState() { ArgumentCaptor<VolumeDialogController.Callbacks> controllerCallbackCapture = ArgumentCaptor.forClass(VolumeDialogController.Callbacks.class); verify(mVolumeDialogController).addCallback(controllerCallbackCapture.capture(), any()); VolumeDialogController.Callbacks callbacks = controllerCallbackCapture.getValue(); callbacks.onCaptionEnabledStateChanged(true, true); verify(mVolumeDialogController).setCaptionsEnabledState(eq(false)); } @Test public void testOnCaptionEnabledStateChanged_checkBeforeSwitchFalse_getCaptionsEnabledTrue() { ArgumentCaptor<VolumeDialogController.Callbacks> controllerCallbackCapture = ArgumentCaptor.forClass(VolumeDialogController.Callbacks.class); verify(mVolumeDialogController).addCallback(controllerCallbackCapture.capture(), any()); VolumeDialogController.Callbacks callbacks = controllerCallbackCapture.getValue(); callbacks.onCaptionEnabledStateChanged(true, false); assertTrue(mODICaptionsIcon.getCaptionsEnabled()); } /** * The content description should include ringer state, and the correct one. */ Loading Loading
packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java +35 −3 Original line number Diff line number Diff line Loading @@ -58,9 +58,26 @@ public interface VolumeDialogController { void userActivity(); void getState(); boolean areCaptionsEnabled(); void setCaptionsEnabled(boolean isEnabled); /** * Get Captions enabled state * * @param checkForSwitchState set true when we'd like to switch captions enabled state after * getting the latest captions state. */ void getCaptionsEnabledState(boolean checkForSwitchState); /** * Set Captions enabled state * * @param enabled the captions enabled state we'd like to update. */ void setCaptionsEnabledState(boolean enabled); /** * Get Captions component state * * @param fromTooltip if it's triggered from tooltip. */ void getCaptionsComponentState(boolean fromTooltip); @ProvidesInterface(version = StreamState.VERSION) Loading Loading @@ -192,7 +209,22 @@ public interface VolumeDialogController { void onScreenOff(); void onShowSafetyWarning(int flags); void onAccessibilityModeChanged(Boolean showA11yStream); /** * Callback function for captions component state changed event * * @param isComponentEnabled the lateset captions component state. * @param fromTooltip if it's triggered from tooltip. */ void onCaptionComponentStateChanged(Boolean isComponentEnabled, Boolean fromTooltip); /** * Callback function for captions enabled state changed event * * @param isEnabled the lateset captions enabled state. * @param checkBeforeSwitch intend to switch captions enabled state after the callback. */ void onCaptionEnabledStateChanged(Boolean isEnabled, Boolean checkBeforeSwitch); // requires version 2 void onShowCsdWarning(@AudioManager.CsdWarning int csdWarning, int durationMs); } Loading
packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +90 −24 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.media.session.MediaController.PlaybackInfo; import android.media.session.MediaSession.Token; import android.net.Uri; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; import android.os.Message; import android.os.RemoteException; Loading @@ -57,6 +58,7 @@ import android.util.Slog; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.CaptioningManager; import androidx.annotation.NonNull; import androidx.lifecycle.Observer; import com.android.internal.annotations.GuardedBy; Loading @@ -81,6 +83,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; Loading Loading @@ -131,7 +134,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa private final Receiver mReceiver = new Receiver(); private final RingerModeObservers mRingerModeObservers; private final MediaSessions mMediaSessions; private final CaptioningManager mCaptioningManager; private final AtomicReference<CaptioningManager> mCaptioningManager = new AtomicReference<>(); private final KeyguardManager mKeyguardManager; private final ActivityManager mActivityManager; private final UserTracker mUserTracker; Loading Loading @@ -179,7 +182,6 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa AccessibilityManager accessibilityManager, PackageManager packageManager, WakefulnessLifecycle wakefulnessLifecycle, CaptioningManager captioningManager, KeyguardManager keyguardManager, ActivityManager activityManager, UserTracker userTracker, Loading Loading @@ -209,10 +211,12 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa mVibrator = vibrator; mHasVibrator = mVibrator.hasVibrator(); mAudioService = iAudioService; mCaptioningManager = captioningManager; mKeyguardManager = keyguardManager; mActivityManager = activityManager; mUserTracker = userTracker; mUserTracker.addCallback(mUserChangedCallback, new HandlerExecutor(mWorker)); createCaptioningManagerServiceByUserContext(mUserTracker.getUserContext()); dumpManager.registerDumpable("VolumeDialogControllerImpl", this); boolean accessibilityVolumeStreamActive = accessibilityManager Loading Loading @@ -316,12 +320,31 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa mWorker.sendEmptyMessage(W.GET_STATE); } public boolean areCaptionsEnabled() { return mCaptioningManager.isSystemAudioCaptioningEnabled(); /** * We met issues about the wrong state of System Caption in multi-user mode. * It happened in the usage of CaptioningManager Service from SysUI process * that is a global system process of User 0. * Therefore, we have to add callback on UserTracker that allows us to get the Context of * active User and then get the corresponding CaptioningManager Service for further usages. */ private final UserTracker.Callback mUserChangedCallback = new UserTracker.Callback() { @Override public void onUserChanged(int newUser, @NonNull Context userContext) { createCaptioningManagerServiceByUserContext(userContext); } }; private void createCaptioningManagerServiceByUserContext(@NonNull Context userContext) { mCaptioningManager.set(userContext.getSystemService(CaptioningManager.class)); } public void setCaptionsEnabled(boolean isEnabled) { mCaptioningManager.setSystemAudioCaptioningEnabled(isEnabled); public void getCaptionsEnabledState(boolean checkForSwitchState) { mWorker.obtainMessage(W.GET_CAPTIONS_ENABLED_STATE, checkForSwitchState).sendToTarget(); } public void setCaptionsEnabledState(boolean enabled) { mWorker.obtainMessage(W.SET_CAPTIONS_ENABLED_STATE, enabled).sendToTarget(); } public void getCaptionsComponentState(boolean fromTooltip) { Loading Loading @@ -418,8 +441,34 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa } private void onGetCaptionsComponentStateW(boolean fromTooltip) { CaptioningManager captioningManager = mCaptioningManager.get(); if (null != captioningManager) { mCallbacks.onCaptionComponentStateChanged( mCaptioningManager.isSystemAudioCaptioningUiEnabled(), fromTooltip); captioningManager.isSystemAudioCaptioningUiEnabled(), fromTooltip); } else { Log.e(TAG, "onGetCaptionsComponentStateW(), null captioningManager"); } } private void onGetCaptionsEnabledStateW(boolean checkForSwitchState) { CaptioningManager captioningManager = mCaptioningManager.get(); if (null != captioningManager) { mCallbacks.onCaptionEnabledStateChanged( captioningManager.isSystemAudioCaptioningEnabled(), checkForSwitchState); } else { Log.e(TAG, "onGetCaptionsEnabledStateW(), null captioningManager"); } } private void onSetCaptionsEnabledStateW(boolean enabled) { CaptioningManager captioningManager = mCaptioningManager.get(); if (null != captioningManager) { captioningManager.setSystemAudioCaptioningEnabled(enabled); mCallbacks.onCaptionEnabledStateChanged( captioningManager.isSystemAudioCaptioningEnabled(), false); } else { Log.e(TAG, "onGetCaptionsEnabledStateW(), null captioningManager"); } } private void onAccessibilityModeChanged(Boolean showA11yStream) { Loading Loading @@ -719,7 +768,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa * This method will never be called if the CSD (Computed Sound Dose) feature is * not enabled. See com.android.android.server.audio.SoundDoseHelper for the state of * the feature. * @param warning the type of warning to display, values are one of * @param csdWarning the type of warning to display, values are one of * {@link android.media.AudioManager#CSD_WARNING_DOSE_REACHED_1X}, * {@link android.media.AudioManager#CSD_WARNING_DOSE_REPEATED_5X}, * {@link android.media.AudioManager#CSD_WARNING_MOMENTARY_EXPOSURE}, Loading Loading @@ -798,6 +847,8 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa private static final int ACCESSIBILITY_MODE_CHANGED = 15; private static final int GET_CAPTIONS_COMPONENT_STATE = 16; private static final int SHOW_CSD_WARNING = 17; private static final int GET_CAPTIONS_ENABLED_STATE = 18; private static final int SET_CAPTIONS_ENABLED_STATE = 19; W(Looper looper) { super(looper); Loading Loading @@ -825,6 +876,10 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa case ACCESSIBILITY_MODE_CHANGED: onAccessibilityModeChanged((Boolean) msg.obj); break; case SHOW_CSD_WARNING: onShowCsdWarningW(msg.arg1, msg.arg2); break; case GET_CAPTIONS_ENABLED_STATE: onGetCaptionsEnabledStateW((Boolean) msg.obj); break; case SET_CAPTIONS_ENABLED_STATE: onSetCaptionsEnabledStateW((Boolean) msg.obj); break; } } } Loading Loading @@ -993,6 +1048,17 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa componentEnabled, fromTooltip)); } } @Override public void onCaptionEnabledStateChanged(Boolean isEnabled, Boolean checkBeforeSwitch) { boolean captionsEnabled = isEnabled != null && isEnabled; for (final Map.Entry<Callbacks, Handler> entry : mCallbackMap.entrySet()) { entry.getValue().post( () -> entry.getKey().onCaptionEnabledStateChanged( captionsEnabled, checkBeforeSwitch)); } } } private final class RingerModeObservers { Loading
packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +22 −9 Original line number Diff line number Diff line Loading @@ -1333,21 +1333,30 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, if (!isServiceComponentEnabled) return; updateCaptionsIcon(); checkEnabledStateForCaptionsIconUpdate(); if (fromTooltip) showCaptionsTooltip(); } private void updateCaptionsIcon() { boolean captionsEnabled = mController.areCaptionsEnabled(); if (mODICaptionsIcon.getCaptionsEnabled() != captionsEnabled) { mHandler.post(mODICaptionsIcon.setCaptionsEnabled(captionsEnabled)); private void updateCaptionsEnabledH(boolean isCaptionsEnabled, boolean checkForSwitchState) { if (checkForSwitchState) { mController.setCaptionsEnabledState(!isCaptionsEnabled); } else { updateCaptionsIcon(isCaptionsEnabled); } } private void checkEnabledStateForCaptionsIconUpdate() { mController.getCaptionsEnabledState(false); } private void updateCaptionsIcon(boolean isCaptionsEnabled) { if (mODICaptionsIcon.getCaptionsEnabled() != isCaptionsEnabled) { mHandler.post(mODICaptionsIcon.setCaptionsEnabled(isCaptionsEnabled)); } } private void onCaptionIconClicked() { boolean isEnabled = mController.areCaptionsEnabled(); mController.setCaptionsEnabled(!isEnabled); updateCaptionsIcon(); mController.getCaptionsEnabledState(true); } private void incrementManualToggleCount() { Loading Loading @@ -2363,7 +2372,6 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, } else { updateRowsH(activeRow); } } @Override Loading @@ -2371,6 +2379,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, Boolean isComponentEnabled, Boolean fromTooltip) { updateODICaptionsH(isComponentEnabled, fromTooltip); } @Override public void onCaptionEnabledStateChanged(Boolean isEnabled, Boolean checkForSwitchState) { updateCaptionsEnabledH(isEnabled, checkForSwitchState); } }; @VisibleForTesting void onPostureChanged(int posture) { Loading
packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java +10 −6 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import android.os.Process; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.CaptioningManager; import androidx.test.filters.SmallTest; Loading @@ -64,6 +63,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.concurrent.Executor; @RunWith(AndroidTestingRunner.class) @SmallTest @TestableLooper.RunWithLooper Loading Loading @@ -96,8 +97,6 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { @Mock private WakefulnessLifecycle mWakefullnessLifcycle; @Mock private CaptioningManager mCaptioningManager; @Mock private KeyguardManager mKeyguardManager; @Mock private ActivityManager mActivityManager; Loading @@ -117,6 +116,7 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { when(mRingerModeLiveData.getValue()).thenReturn(-1); when(mRingerModeInternalLiveData.getValue()).thenReturn(-1); when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser()); when(mUserTracker.getUserContext()).thenReturn(mContext); // Enable group volume adjustments mContext.getOrCreateTestableResources().addOverride( com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions, Loading @@ -127,7 +127,7 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { mVolumeController = new TestableVolumeDialogControllerImpl(mContext, mBroadcastDispatcher, mRingerModeTracker, mThreadFactory, mAudioManager, mNotificationManager, mVibrator, mIAudioService, mAccessibilityManager, mPackageManager, mWakefullnessLifcycle, mCaptioningManager, mKeyguardManager, mPackageManager, mWakefullnessLifcycle, mKeyguardManager, mActivityManager, mUserTracker, mDumpManager, mCallback); mVolumeController.setEnableDialogs(true, true); } Loading Loading @@ -219,6 +219,11 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { verify(mRingerModeInternalLiveData).observeForever(any()); } @Test public void testAddCallbackWithUserTracker() { verify(mUserTracker).addCallback(any(UserTracker.Callback.class), any(Executor.class)); } static class TestableVolumeDialogControllerImpl extends VolumeDialogControllerImpl { private final WakefulnessLifecycle.Observer mWakefullessLifecycleObserver; Loading @@ -234,7 +239,6 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { AccessibilityManager accessibilityManager, PackageManager packageManager, WakefulnessLifecycle wakefulnessLifecycle, CaptioningManager captioningManager, KeyguardManager keyguardManager, ActivityManager activityManager, UserTracker userTracker, Loading @@ -242,7 +246,7 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { C callback) { super(context, broadcastDispatcher, ringerModeTracker, theadFactory, audioManager, notificationManager, optionalVibrator, iAudioService, accessibilityManager, packageManager, wakefulnessLifecycle, captioningManager, keyguardManager, packageManager, wakefulnessLifecycle, keyguardManager, activityManager, userTracker, dumpManager); mCallbacks = callback; Loading
packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static junit.framework.Assert.assertTrue; import static org.junit.Assume.assumeNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; Loading Loading @@ -93,6 +94,8 @@ public class VolumeDialogImplTest extends SysuiTestCase { View mDrawerVibrate; View mDrawerMute; View mDrawerNormal; CaptionsToggleImageButton mODICaptionsIcon; private TestableLooper mTestableLooper; private ConfigurationController mConfigurationController; private int mOriginalOrientation; Loading Loading @@ -180,6 +183,7 @@ public class VolumeDialogImplTest extends SysuiTestCase { mDrawerVibrate = mDrawerContainer.findViewById(R.id.volume_drawer_vibrate); mDrawerMute = mDrawerContainer.findViewById(R.id.volume_drawer_mute); mDrawerNormal = mDrawerContainer.findViewById(R.id.volume_drawer_normal); mODICaptionsIcon = mDialog.getDialogView().findViewById(R.id.odi_captions_icon); Prefs.putInt(mContext, Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT, Loading Loading @@ -688,6 +692,28 @@ public class VolumeDialogImplTest extends SysuiTestCase { assertRingerContainerDescribesItsState(RINGER_MODE_VIBRATE, RingerDrawerState.CLOSE); } @Test public void testOnCaptionEnabledStateChanged_checkBeforeSwitchTrue_setCaptionsEnabledState() { ArgumentCaptor<VolumeDialogController.Callbacks> controllerCallbackCapture = ArgumentCaptor.forClass(VolumeDialogController.Callbacks.class); verify(mVolumeDialogController).addCallback(controllerCallbackCapture.capture(), any()); VolumeDialogController.Callbacks callbacks = controllerCallbackCapture.getValue(); callbacks.onCaptionEnabledStateChanged(true, true); verify(mVolumeDialogController).setCaptionsEnabledState(eq(false)); } @Test public void testOnCaptionEnabledStateChanged_checkBeforeSwitchFalse_getCaptionsEnabledTrue() { ArgumentCaptor<VolumeDialogController.Callbacks> controllerCallbackCapture = ArgumentCaptor.forClass(VolumeDialogController.Callbacks.class); verify(mVolumeDialogController).addCallback(controllerCallbackCapture.capture(), any()); VolumeDialogController.Callbacks callbacks = controllerCallbackCapture.getValue(); callbacks.onCaptionEnabledStateChanged(true, false); assertTrue(mODICaptionsIcon.getCaptionsEnabled()); } /** * The content description should include ringer state, and the correct one. */ Loading