diff options
8 files changed, 198 insertions, 124 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index afda2a406e00..e9c565377530 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -236,7 +236,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { Log.i(TAG, "ScreenDecorations is disabled"); return; } - mHandler = mThreadFactory.builderHandlerOnNewThread("ScreenDecorations"); + mHandler = mThreadFactory.buildHandlerOnNewThread("ScreenDecorations"); mExecutor = mThreadFactory.buildDelayableExecutorOnHandler(mHandler); mExecutor.execute(this::startOnScreenDecorationsThread); mDotViewController.setUiExecutor(mExecutor); diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java index 26db33d6dea8..053d75d96720 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java @@ -46,6 +46,7 @@ import android.hardware.display.DisplayManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.media.AudioManager; +import android.media.IAudioService; import android.media.MediaRouter2Manager; import android.media.session.MediaSessionManager; import android.net.ConnectivityManager; @@ -77,6 +78,8 @@ import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.shared.system.PackageManagerWrapper; +import java.util.Optional; + import javax.inject.Singleton; import dagger.Module; @@ -167,6 +170,13 @@ public class FrameworkServicesModule { @Provides @Singleton + static IAudioService provideIAudioService() { + return IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE)); + } + + + @Provides + @Singleton static IBatteryStats provideIBatteryStats() { return IBatteryStats.Stub.asInterface( ServiceManager.getService(BatteryStats.SERVICE_NAME)); @@ -362,6 +372,12 @@ public class FrameworkServicesModule { @Provides @Singleton + static Optional<Vibrator> provideOptionalVibrator(Context context) { + return Optional.ofNullable(context.getSystemService(Vibrator.class)); + } + + @Provides + @Singleton static ViewConfiguration provideViewConfiguration(Context context) { return ViewConfiguration.get(context); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java index ebf2465f3bf3..b10e841e1bbb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java @@ -23,7 +23,6 @@ import android.util.ArraySet; import android.util.Log; import com.android.settingslib.mobile.TelephonyIcons; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.policy.NetworkController; @@ -63,6 +62,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba private final SecurityController mSecurityController; private final Handler mHandler = Handler.getMain(); private final CarrierConfigTracker mCarrierConfigTracker; + private final TunerService mTunerService; private boolean mHideAirplane; private boolean mHideMobile; @@ -83,9 +83,16 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba @Inject public StatusBarSignalPolicy(Context context, StatusBarIconController iconController, - CarrierConfigTracker carrierConfigTracker) { + CarrierConfigTracker carrierConfigTracker, NetworkController networkController, + SecurityController securityController, TunerService tunerService) { mContext = context; + mIconController = iconController; + mCarrierConfigTracker = carrierConfigTracker; + mNetworkController = networkController; + mSecurityController = securityController; + mTunerService = tunerService; + mSlotAirplane = mContext.getString(com.android.internal.R.string.status_bar_airplane); mSlotMobile = mContext.getString(com.android.internal.R.string.status_bar_mobile); mSlotWifi = mContext.getString(com.android.internal.R.string.status_bar_wifi); @@ -96,18 +103,14 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba mContext.getString(com.android.internal.R.string.status_bar_call_strength); mActivityEnabled = mContext.getResources().getBoolean(R.bool.config_showActivity); - mIconController = iconController; - mCarrierConfigTracker = carrierConfigTracker; - mNetworkController = Dependency.get(NetworkController.class); - mSecurityController = Dependency.get(SecurityController.class); - Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_HIDE_LIST); + tunerService.addTunable(this, StatusBarIconController.ICON_HIDE_LIST); mNetworkController.addCallback(this); mSecurityController.addCallback(this); } public void destroy() { - Dependency.get(TunerService.class).removeTunable(this); + mTunerService.removeTunable(this); mNetworkController.removeCallback(this); mSecurityController.removeCallback(this); } diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactory.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactory.java index 7a5ceb547d9e..fbec9e7b7f0c 100644 --- a/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactory.java +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactory.java @@ -30,12 +30,20 @@ import java.util.concurrent.Executor; */ public interface ThreadFactory { /** + * Returns a {@link Looper} running on a named thread. + * + * The thread is implicitly started and may be left running indefinitely, depending on the + * implementation. Assume this is the case and use responsibly. + */ + Looper buildLooperOnNewThread(String threadName); + + /** * Returns a {@link Handler} running on a named thread. * * The thread is implicitly started and may be left running indefinitely, depending on the * implementation. Assume this is the case and use responsibly. */ - Handler builderHandlerOnNewThread(String threadName); + Handler buildHandlerOnNewThread(String threadName); /** * Return an {@link java.util.concurrent.Executor} running on a named thread. diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactoryImpl.java index 184b83113d8d..051f4335e171 100644 --- a/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactoryImpl.java +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactoryImpl.java @@ -29,10 +29,15 @@ class ThreadFactoryImpl implements ThreadFactory { ThreadFactoryImpl() {} @Override - public Handler builderHandlerOnNewThread(String threadName) { + public Looper buildLooperOnNewThread(String threadName) { HandlerThread handlerThread = new HandlerThread(threadName); handlerThread.start(); - return new Handler(handlerThread.getLooper()); + return handlerThread.getLooper(); + } + + @Override + public Handler buildHandlerOnNewThread(String threadName) { + return new Handler(buildLooperOnNewThread(threadName)); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index 3aba7ca1ad7c..a5ccc47b8072 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -38,11 +38,9 @@ import android.media.session.MediaController.PlaybackInfo; import android.media.session.MediaSession.Token; import android.net.Uri; import android.os.Handler; -import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.UserHandle; import android.os.VibrationEffect; import android.os.Vibrator; @@ -66,9 +64,9 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.qs.tiles.DndTile; -import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.util.RingerModeLiveData; import com.android.systemui.util.RingerModeTracker; +import com.android.systemui.util.concurrency.ThreadFactory; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -80,8 +78,6 @@ import java.util.concurrent.ConcurrentHashMap; import javax.inject.Inject; -import dagger.Lazy; - /** * Source of truth for all state / events related to the volume dialog. No presentation. * @@ -118,12 +114,13 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa STREAMS.put(AudioSystem.STREAM_VOICE_CALL, R.string.stream_voice_call); } - private final HandlerThread mWorkerThread; private final W mWorker; private final Context mContext; + private final Looper mWorkerLooper; + private final PackageManager mPackageManager; + private final WakefulnessLifecycle mWakefulnessLifecycle; private AudioManager mAudio; private IAudioService mAudioService; - private final Optional<Lazy<StatusBar>> mStatusBarOptionalLazy; private final NotificationManager mNoMan; private final SettingObserver mObserver; private final Receiver mReceiver = new Receiver(); @@ -132,13 +129,13 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa protected C mCallbacks = new C(); private final State mState = new State(); protected final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks(); - private final Vibrator mVibrator; + private final Optional<Vibrator> mVibrator; private final boolean mHasVibrator; private boolean mShowA11yStream; private boolean mShowVolumeDialog; private boolean mShowSafetyWarning; private long mLastToggledRingerOn; - private final NotificationManager mNotificationManager; + private boolean mDeviceInteractive; private boolean mDestroyed; private VolumePolicy mVolumePolicy; @@ -149,26 +146,42 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa protected final VC mVolumeController = new VC(); protected final BroadcastDispatcher mBroadcastDispatcher; + private final WakefulnessLifecycle.Observer mWakefullnessLifecycleObserver = + new WakefulnessLifecycle.Observer() { + @Override + public void onStartedWakingUp() { + mDeviceInteractive = true; + } + + @Override + public void onFinishedGoingToSleep() { + mDeviceInteractive = false; + } + }; + @Inject - public VolumeDialogControllerImpl(Context context, BroadcastDispatcher broadcastDispatcher, - Optional<Lazy<StatusBar>> statusBarOptionalLazy, RingerModeTracker ringerModeTracker) { + public VolumeDialogControllerImpl( + Context context, + BroadcastDispatcher broadcastDispatcher, + RingerModeTracker ringerModeTracker, + ThreadFactory theadFactory, + AudioManager audioManager, + NotificationManager notificationManager, + Optional<Vibrator> optionalVibrator, + IAudioService iAudioService, + AccessibilityManager accessibilityManager, + PackageManager packageManager, + WakefulnessLifecycle wakefulnessLifecycle) { mContext = context.getApplicationContext(); - // TODO(b/150663459): remove this TV workaround once StatusBar is "unbound" on TVs - if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) { - mStatusBarOptionalLazy = Optional.empty(); - } else { - mStatusBarOptionalLazy = statusBarOptionalLazy; - } - mNotificationManager = (NotificationManager) mContext.getSystemService( - Context.NOTIFICATION_SERVICE); + mPackageManager = packageManager; + mWakefulnessLifecycle = wakefulnessLifecycle; Events.writeEvent(Events.EVENT_COLLECTION_STARTED); - mWorkerThread = new HandlerThread(VolumeDialogControllerImpl.class.getSimpleName()); - mWorkerThread.start(); - mWorker = new W(mWorkerThread.getLooper()); - mMediaSessions = createMediaSessions(mContext, mWorkerThread.getLooper(), - mMediaSessionsCallbacksW); - mAudio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - mNoMan = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + mWorkerLooper = theadFactory.buildLooperOnNewThread( + VolumeDialogControllerImpl.class.getSimpleName()); + mWorker = new W(mWorkerLooper); + mMediaSessions = createMediaSessions(mContext, mWorkerLooper, mMediaSessionsCallbacksW); + mAudio = audioManager; + mNoMan = notificationManager; mObserver = new SettingObserver(mWorker); mRingerModeObservers = new RingerModeObservers( (RingerModeLiveData) ringerModeTracker.getRingerMode(), @@ -178,16 +191,17 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa mBroadcastDispatcher = broadcastDispatcher; mObserver.init(); mReceiver.init(); - mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); - mHasVibrator = mVibrator != null && mVibrator.hasVibrator(); - mAudioService = IAudioService.Stub.asInterface( - ServiceManager.getService(Context.AUDIO_SERVICE)); + mVibrator = optionalVibrator; + mHasVibrator = mVibrator.isPresent() && mVibrator.get().hasVibrator(); + mAudioService = iAudioService; - boolean accessibilityVolumeStreamActive = context.getSystemService( - AccessibilityManager.class).isAccessibilityVolumeStreamActive(); + boolean accessibilityVolumeStreamActive = accessibilityManager + .isAccessibilityVolumeStreamActive(); mVolumeController.setA11yMode(accessibilityVolumeStreamActive ? VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME : VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME); + + mWakefulnessLifecycle.addObserver(mWakefullnessLifecycleObserver); } public AudioManager getAudioManager() { @@ -203,7 +217,6 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa mAudio.setVolumeController(mVolumeController); } catch (SecurityException e) { Log.w(TAG, "Unable to set the volume controller", e); - return; } } @@ -249,18 +262,6 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa return new MediaSessions(context, looper, callbacks); } - public void destroy() { - if (D.BUG) Log.d(TAG, "destroy"); - if (mDestroyed) return; - mDestroyed = true; - Events.writeEvent(Events.EVENT_COLLECTION_STOPPED); - mMediaSessions.destroy(); - mObserver.destroy(); - mReceiver.destroy(); - mRingerModeObservers.destroy(); - mWorkerThread.quitSafely(); - } - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println(VolumeDialogControllerImpl.class.getSimpleName() + " state:"); pw.print(" mDestroyed: "); pw.println(mDestroyed); @@ -383,9 +384,8 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa } public void vibrate(VibrationEffect effect) { - if (mHasVibrator) { - mVibrator.vibrate(effect, SONIFICIATION_VIBRATION_ATTRIBUTES); - } + mVibrator.ifPresent( + vibrator -> vibrator.vibrate(effect, SONIFICIATION_VIBRATION_ATTRIBUTES)); } public boolean hasVibrator() { @@ -437,9 +437,8 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa return; } - PackageManager packageManager = mContext.getPackageManager(); mCallbacks.onCaptionComponentStateChanged( - packageManager.getComponentEnabledSetting(componentName) + mPackageManager.getComponentEnabledSetting(componentName) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED, fromTooltip); } catch (Exception ex) { Log.e(TAG, @@ -466,17 +465,11 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa } private boolean shouldShowUI(int flags) { - // if status bar isn't null, check if phone is in AOD, else check flags - // since we could be using a different status bar - return mStatusBarOptionalLazy.map(statusBarLazy -> { - StatusBar statusBar = statusBarLazy.get(); - return statusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_ASLEEP - && statusBar.getWakefulnessState() - != WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP - && statusBar.isDeviceInteractive() && (flags & AudioManager.FLAG_SHOW_UI) != 0 - && mShowVolumeDialog; - }).orElse( - mShowVolumeDialog && (flags & AudioManager.FLAG_SHOW_UI) != 0); + int wakefulness = mWakefulnessLifecycle.getWakefulness(); + return wakefulness != WakefulnessLifecycle.WAKEFULNESS_ASLEEP + && wakefulness != WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP + && mDeviceInteractive && (flags & AudioManager.FLAG_SHOW_UI) != 0 + && mShowVolumeDialog; } boolean onVolumeChangedW(int stream, int flags) { @@ -600,15 +593,15 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa private boolean updateEffectsSuppressorW(ComponentName effectsSuppressor) { if (Objects.equals(mState.effectsSuppressor, effectsSuppressor)) return false; mState.effectsSuppressor = effectsSuppressor; - mState.effectsSuppressorName = getApplicationName(mContext, mState.effectsSuppressor); + mState.effectsSuppressorName = + getApplicationName(mPackageManager, mState.effectsSuppressor); Events.writeEvent(Events.EVENT_SUPPRESSOR_CHANGED, mState.effectsSuppressor, mState.effectsSuppressorName); return true; } - private static String getApplicationName(Context context, ComponentName component) { + private static String getApplicationName(PackageManager pm, ComponentName component) { if (component == null) return null; - final PackageManager pm = context.getPackageManager(); final String pkg = component.getPackageName(); try { final ApplicationInfo ai = pm.getApplicationInfo(pkg, 0); @@ -630,8 +623,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa } private boolean updateZenConfig() { - final NotificationManager.Policy policy = - mNotificationManager.getConsolidatedNotificationPolicy(); + final NotificationManager.Policy policy = mNoMan.getConsolidatedNotificationPolicy(); boolean disallowAlarms = (policy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_ALARMS) == 0; boolean disallowMedia = (policy.priorityCategories & NotificationManager.Policy diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java index 570e1d86574e..301a157bd42e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java @@ -27,6 +27,7 @@ import java.util.concurrent.Executor; public class FakeThreadFactory implements ThreadFactory { private final FakeExecutor mFakeExecutor; private Handler mHandler; + private Looper mLooper; public FakeThreadFactory(FakeExecutor fakeExecutor) { mFakeExecutor = fakeExecutor; @@ -36,8 +37,17 @@ public class FakeThreadFactory implements ThreadFactory { mHandler = handler; } + public void setLooper(Looper looper) { + mLooper = looper; + } + + @Override + public Looper buildLooperOnNewThread(String threadName) { + return mLooper; + } + @Override - public Handler builderHandlerOnNewThread(String threadName) { + public Handler buildHandlerOnNewThread(String threadName) { return mHandler; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java index 6166cd76e005..5c0efd36fcd1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java @@ -23,29 +23,37 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.media.AudioManager; +import android.media.IAudioService; import android.media.session.MediaSession; import android.os.Handler; import android.os.Process; +import android.os.Vibrator; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import android.view.accessibility.AccessibilityManager; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.keyguard.WakefulnessLifecycle; -import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.util.RingerModeLiveData; import com.android.systemui.util.RingerModeTracker; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.concurrency.FakeThreadFactory; +import com.android.systemui.util.concurrency.ThreadFactory; +import com.android.systemui.util.time.FakeSystemClock; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -58,7 +66,6 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { TestableVolumeDialogControllerImpl mVolumeController; VolumeDialogControllerImpl.C mCallback; - StatusBar mStatusBar; @Mock private BroadcastDispatcher mBroadcastDispatcher; @Mock @@ -67,6 +74,23 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { private RingerModeLiveData mRingerModeLiveData; @Mock private RingerModeLiveData mRingerModeInternalLiveData; + private final FakeThreadFactory mThreadFactory = new FakeThreadFactory( + new FakeExecutor(new FakeSystemClock())); + @Mock + private AudioManager mAudioManager; + @Mock + private NotificationManager mNotificationManager; + @Mock + private Vibrator mVibrator; + @Mock + private IAudioService mIAudioService; + @Mock + private AccessibilityManager mAccessibilityManager; + @Mock + private PackageManager mPackageManager; + @Mock + private WakefulnessLifecycle mWakefullnessLifcycle; + @Before public void setup() throws Exception { @@ -77,19 +101,15 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { // Initial non-set value when(mRingerModeLiveData.getValue()).thenReturn(-1); when(mRingerModeInternalLiveData.getValue()).thenReturn(-1); - mCallback = mock(VolumeDialogControllerImpl.C.class); - mStatusBar = mock(StatusBar.class); - mVolumeController = new TestableVolumeDialogControllerImpl(mContext, mCallback, mStatusBar, - mBroadcastDispatcher, mRingerModeTracker); + mThreadFactory.setLooper(TestableLooper.get(this).getLooper()); + mVolumeController = new TestableVolumeDialogControllerImpl(mContext, + mBroadcastDispatcher, mRingerModeTracker, mThreadFactory, mAudioManager, + mNotificationManager, Optional.of(mVibrator), mIAudioService, mAccessibilityManager, + mPackageManager, mWakefullnessLifcycle, mCallback); mVolumeController.setEnableDialogs(true, true); } - @After - public void tearDown() { - mVolumeController.destroy(); - } - @Test public void testRegisteredWithDispatcher() { verify(mBroadcastDispatcher).registerReceiverWithHandler(any(BroadcastReceiver.class), @@ -99,45 +119,36 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { @Test public void testVolumeChangeW_deviceNotInteractiveAOD() { - when(mStatusBar.isDeviceInteractive()).thenReturn(false); - when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE); + mVolumeController.setDeviceInteractive(false); + when(mWakefullnessLifcycle.getWakefulness()).thenReturn( + WakefulnessLifecycle.WAKEFULNESS_AWAKE); mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI); verify(mCallback, never()).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED); } @Test public void testVolumeChangeW_deviceInteractive() { - when(mStatusBar.isDeviceInteractive()).thenReturn(true); - when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE); + mVolumeController.setDeviceInteractive(true); + when(mWakefullnessLifcycle.getWakefulness()).thenReturn( + WakefulnessLifecycle.WAKEFULNESS_AWAKE); mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI); verify(mCallback, times(1)).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED); } @Test public void testVolumeChangeW_deviceInteractive_StartedSleeping() { - when(mStatusBar.isDeviceInteractive()).thenReturn(true); - when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE); + mVolumeController.setDeviceInteractive(true); + when(mWakefullnessLifcycle.getWakefulness()).thenReturn( + WakefulnessLifecycle.WAKEFULNESS_AWAKE); mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI); - when(mStatusBar.isDeviceInteractive()).thenReturn(false); - when(mStatusBar.getWakefulnessState()).thenReturn( + mVolumeController.setDeviceInteractive(false); + when(mWakefullnessLifcycle.getWakefulness()).thenReturn( WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP); mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI); verify(mCallback, times(1)).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED); } @Test - public void testVolumeChangeW_nullStatusBar() { - VolumeDialogControllerImpl.C callback = mock(VolumeDialogControllerImpl.C.class); - TestableVolumeDialogControllerImpl - nullStatusBarTestableDialog = - new TestableVolumeDialogControllerImpl( - mContext, callback, null, mBroadcastDispatcher, mRingerModeTracker); - nullStatusBarTestableDialog.setEnableDialogs(true, true); - nullStatusBarTestableDialog.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI); - verify(callback, times(1)).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED); - } - - @Test public void testOnRemoteVolumeChanged_newStream_noNullPointer() { MediaSession.Token token = new MediaSession.Token(Process.myUid(), null); mVolumeController.mMediaSessionsCallbacksW.onRemoteVolumeChanged(token, 0); @@ -155,22 +166,51 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { verify(mRingerModeInternalLiveData).observeForever(any()); } - @Test - public void testRingerModeOnDestroy_observersRemoved() { - mVolumeController.destroy(); - - verify(mRingerModeLiveData).removeObserver(any()); - verify(mRingerModeInternalLiveData).removeObserver(any()); - } - static class TestableVolumeDialogControllerImpl extends VolumeDialogControllerImpl { - TestableVolumeDialogControllerImpl(Context context, C callback, StatusBar s, - BroadcastDispatcher broadcastDispatcher, RingerModeTracker ringerModeTracker) { - super( - context, broadcastDispatcher, - s == null ? Optional.empty() : Optional.of(() -> s), ringerModeTracker); + private final WakefulnessLifecycle.Observer mWakefullessLifecycleObserver; + + TestableVolumeDialogControllerImpl( + Context context, + BroadcastDispatcher broadcastDispatcher, + RingerModeTracker ringerModeTracker, + ThreadFactory theadFactory, + AudioManager audioManager, + NotificationManager notificationManager, + Optional<Vibrator> optionalVibrator, + IAudioService iAudioService, + AccessibilityManager accessibilityManager, + PackageManager packageManager, + WakefulnessLifecycle wakefulnessLifecycle, + C callback) { + super(context, broadcastDispatcher, ringerModeTracker, theadFactory, audioManager, + notificationManager, optionalVibrator, iAudioService, accessibilityManager, + packageManager, wakefulnessLifecycle); mCallbacks = callback; + + ArgumentCaptor<WakefulnessLifecycle.Observer> observerCaptor = + ArgumentCaptor.forClass(WakefulnessLifecycle.Observer.class); + verify(wakefulnessLifecycle).addObserver(observerCaptor.capture()); + mWakefullessLifecycleObserver = observerCaptor.getValue(); + } + + public void setDeviceInteractive(boolean interactive) { + if (interactive) { + mWakefullessLifecycleObserver.onStartedWakingUp(); + } else { + mWakefullessLifecycleObserver.onFinishedGoingToSleep(); + } } } +// static class TestableVolumeDialogControllerImpl extends VolumeDialogControllerImpl { +// TestableVolumeDialogControllerImpl(Context context, C callback, +// BroadcastDispatcher broadcastDispatcher, RingerModeTracker ringerModeTracker, +// ThreadFactory threadFactory) { +// super( +// context, broadcastDispatcher, +// s == null ? Optional.empty() : Optional.of(() -> s), ringerModeTracker); +// mCallbacks = callback; +// } +// } + } |