Merge "Break VolumeDialogControllerImpl' dependency on StatusBar" into sc-dev

This commit is contained in:
Dave Mankoff
2021-05-26 14:59:51 +00:00
committed by Android (Google) Code Review
8 changed files with 199 additions and 125 deletions

View File

@@ -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);

View File

@@ -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;
@@ -165,6 +168,13 @@ public class FrameworkServicesModule {
return ActivityTaskManager.getService();
}
@Provides
@Singleton
static IAudioService provideIAudioService() {
return IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE));
}
@Provides
@Singleton
static IBatteryStats provideIBatteryStats() {
@@ -360,6 +370,12 @@ public class FrameworkServicesModule {
return context.getSystemService(Vibrator.class);
}
@Provides
@Singleton
static Optional<Vibrator> provideOptionalVibrator(Context context) {
return Optional.ofNullable(context.getSystemService(Vibrator.class));
}
@Provides
@Singleton
static ViewConfiguration provideViewConfiguration(Context context) {

View File

@@ -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);
}

View File

@@ -29,13 +29,21 @@ import java.util.concurrent.Executor;
* threads; there are no singletons here. Use responsibly.
*/
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.

View File

@@ -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

View File

@@ -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;
@Inject
public VolumeDialogControllerImpl(Context context, BroadcastDispatcher broadcastDispatcher,
Optional<Lazy<StatusBar>> statusBarOptionalLazy, RingerModeTracker ringerModeTracker) {
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;
private final WakefulnessLifecycle.Observer mWakefullnessLifecycleObserver =
new WakefulnessLifecycle.Observer() {
@Override
public void onStartedWakingUp() {
mDeviceInteractive = true;
}
mNotificationManager = (NotificationManager) mContext.getSystemService(
Context.NOTIFICATION_SERVICE);
@Override
public void onFinishedGoingToSleep() {
mDeviceInteractive = false;
}
};
@Inject
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();
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

View File

@@ -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 Handler builderHandlerOnNewThread(String threadName) {
public Looper buildLooperOnNewThread(String threadName) {
return mLooper;
}
@Override
public Handler buildHandlerOnNewThread(String threadName) {
return mHandler;
}

View File

@@ -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,44 +119,35 @@ 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);
@@ -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;
// }
// }
}