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