Merge "Move volume dialog away from the hinge" into udc-dev

This commit is contained in:
Behnam Heydarshahi
2023-05-08 18:53:32 +00:00
committed by Android (Google) Code Review
4 changed files with 259 additions and 17 deletions

View File

@@ -98,6 +98,8 @@ public class Events {
public static final int DISMISS_REASON_OUTPUT_CHOOSER = 8; public static final int DISMISS_REASON_OUTPUT_CHOOSER = 8;
public static final int DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED = 9; public static final int DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED = 9;
public static final int DISMISS_REASON_CSD_WARNING_TIMEOUT = 10; public static final int DISMISS_REASON_CSD_WARNING_TIMEOUT = 10;
public static final int DISMISS_REASON_POSTURE_CHANGED = 11;
public static final String[] DISMISS_REASONS = { public static final String[] DISMISS_REASONS = {
"unknown", "unknown",
"touch_outside", "touch_outside",
@@ -109,7 +111,8 @@ public class Events {
"a11y_stream_changed", "a11y_stream_changed",
"output_chooser", "output_chooser",
"usb_temperature_below_threshold", "usb_temperature_below_threshold",
"csd_warning_timeout" "csd_warning_timeout",
"posture_changed"
}; };
public static final int SHOW_REASON_UNKNOWN = 0; public static final int SHOW_REASON_UNKNOWN = 0;

View File

@@ -34,6 +34,7 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_VOLUME_CONTROL; import static com.android.internal.jank.InteractionJankMonitor.CUJ_VOLUME_CONTROL;
import static com.android.internal.jank.InteractionJankMonitor.Configuration.Builder; import static com.android.internal.jank.InteractionJankMonitor.Configuration.Builder;
import static com.android.systemui.volume.Events.DISMISS_REASON_POSTURE_CHANGED;
import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED; import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED;
import android.animation.Animator; import android.animation.Animator;
@@ -129,6 +130,7 @@ import com.android.systemui.plugins.VolumeDialogController.State;
import com.android.systemui.plugins.VolumeDialogController.StreamState; import com.android.systemui.plugins.VolumeDialogController.StreamState;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.AlphaTintDrawableWrapper; import com.android.systemui.util.AlphaTintDrawableWrapper;
import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.DeviceConfigProxy;
@@ -184,7 +186,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private final boolean mChangeVolumeRowTintWhenInactive; private final boolean mChangeVolumeRowTintWhenInactive;
private final Context mContext; private final Context mContext;
private final H mHandler = new H(); private final H mHandler;
private final VolumeDialogController mController; private final VolumeDialogController mController;
private final DeviceProvisionedController mDeviceProvisionedController; private final DeviceProvisionedController mDeviceProvisionedController;
private final Region mTouchableRegion = new Region(); private final Region mTouchableRegion = new Region();
@@ -259,16 +261,13 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private final AccessibilityManagerWrapper mAccessibilityMgr; private final AccessibilityManagerWrapper mAccessibilityMgr;
private final Object mSafetyWarningLock = new Object(); private final Object mSafetyWarningLock = new Object();
private final Accessibility mAccessibility = new Accessibility(); private final Accessibility mAccessibility = new Accessibility();
private final ConfigurationController mConfigurationController; private final ConfigurationController mConfigurationController;
private final MediaOutputDialogFactory mMediaOutputDialogFactory; private final MediaOutputDialogFactory mMediaOutputDialogFactory;
private final VolumePanelFactory mVolumePanelFactory; private final VolumePanelFactory mVolumePanelFactory;
private final CsdWarningDialog.Factory mCsdWarningDialogFactory; private final CsdWarningDialog.Factory mCsdWarningDialogFactory;
private final ActivityStarter mActivityStarter; private final ActivityStarter mActivityStarter;
private boolean mShowing; private boolean mShowing;
private boolean mShowA11yStream; private boolean mShowA11yStream;
private int mActiveStream; private int mActiveStream;
private int mPrevActiveStream; private int mPrevActiveStream;
private boolean mAutomute = VolumePrefs.DEFAULT_ENABLE_AUTOMUTE; private boolean mAutomute = VolumePrefs.DEFAULT_ENABLE_AUTOMUTE;
@@ -300,6 +299,12 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
@VisibleForTesting @VisibleForTesting
int mVolumeRingerMuteIconDrawableId; int mVolumeRingerMuteIconDrawableId;
private int mOriginalGravity;
private final DevicePostureController.Callback mDevicePostureControllerCallback;
private final DevicePostureController mDevicePostureController;
private @DevicePostureController.DevicePostureInt int mDevicePosture;
private int mOrientation;
public VolumeDialogImpl( public VolumeDialogImpl(
Context context, Context context,
VolumeDialogController volumeDialogController, VolumeDialogController volumeDialogController,
@@ -313,9 +318,12 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
DeviceConfigProxy deviceConfigProxy, DeviceConfigProxy deviceConfigProxy,
Executor executor, Executor executor,
CsdWarningDialog.Factory csdWarningDialogFactory, CsdWarningDialog.Factory csdWarningDialogFactory,
DevicePostureController devicePostureController,
Looper looper,
DumpManager dumpManager) { DumpManager dumpManager) {
mContext = mContext =
new ContextThemeWrapper(context, R.style.volume_dialog_theme); new ContextThemeWrapper(context, R.style.volume_dialog_theme);
mHandler = new H(looper);
mController = volumeDialogController; mController = volumeDialogController;
mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
@@ -357,6 +365,16 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
initDimens(); initDimens();
mOrientation = mContext.getResources().getConfiguration().orientation;
mDevicePostureController = devicePostureController;
if (mDevicePostureController != null) {
int initialPosture = mDevicePostureController.getDevicePosture();
mDevicePosture = initialPosture;
mDevicePostureControllerCallback = this::onPostureChanged;
} else {
mDevicePostureControllerCallback = null;
}
mDeviceConfigProxy = deviceConfigProxy; mDeviceConfigProxy = deviceConfigProxy;
mExecutor = executor; mExecutor = executor;
mSeparateNotification = mDeviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, mSeparateNotification = mDeviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -364,6 +382,25 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
updateRingerModeIconSet(); updateRingerModeIconSet();
} }
/**
* Adjust the dialog location on the screen in order to avoid drawing on the hinge.
*/
private void adjustPositionOnScreen() {
final boolean isPortrait = mOrientation == Configuration.ORIENTATION_PORTRAIT;
final boolean isHalfOpen =
mDevicePosture == DevicePostureController.DEVICE_POSTURE_HALF_OPENED;
final boolean isTabletop = isPortrait && isHalfOpen;
WindowManager.LayoutParams lp = mWindow.getAttributes();
int gravity = isTabletop ? (mOriginalGravity | Gravity.TOP) : mOriginalGravity;
mWindowGravity = Gravity.getAbsoluteGravity(gravity,
mContext.getResources().getConfiguration().getLayoutDirection());
lp.gravity = mWindowGravity;
}
@VisibleForTesting int getWindowGravity() {
return mWindowGravity;
}
/** /**
* If ringer and notification are the same stream (T and earlier), use notification-like bell * If ringer and notification are the same stream (T and earlier), use notification-like bell
* icon set. * icon set.
@@ -419,6 +456,10 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mDeviceConfigProxy.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, mDeviceConfigProxy.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
mExecutor, this::onDeviceConfigChange); mExecutor, this::onDeviceConfigChange);
if (mDevicePostureController != null) {
mDevicePostureController.addCallback(mDevicePostureControllerCallback);
}
} }
@Override @Override
@@ -427,6 +468,9 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mHandler.removeCallbacksAndMessages(null); mHandler.removeCallbacksAndMessages(null);
mConfigurationController.removeCallback(this); mConfigurationController.removeCallback(this);
mDeviceConfigProxy.removeOnPropertiesChangedListener(this::onDeviceConfigChange); mDeviceConfigProxy.removeOnPropertiesChangedListener(this::onDeviceConfigChange);
if (mDevicePostureController != null) {
mDevicePostureController.removeCallback(mDevicePostureControllerCallback);
}
} }
/** /**
@@ -441,7 +485,6 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mSeparateNotification = newVal; mSeparateNotification = newVal;
updateRingerModeIconSet(); updateRingerModeIconSet();
updateRingRowIcon(); updateRingRowIcon();
} }
} }
} }
@@ -500,7 +543,6 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private void initDialog(int lockTaskModeState) { private void initDialog(int lockTaskModeState) {
mDialog = new CustomDialog(mContext); mDialog = new CustomDialog(mContext);
initDimens(); initDimens();
mConfigurableTexts = new ConfigurableTexts(mContext); mConfigurableTexts = new ConfigurableTexts(mContext);
@@ -524,14 +566,13 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
lp.setTitle(VolumeDialogImpl.class.getSimpleName()); lp.setTitle(VolumeDialogImpl.class.getSimpleName());
lp.windowAnimations = -1; lp.windowAnimations = -1;
mWindowGravity = Gravity.getAbsoluteGravity( mOriginalGravity = mContext.getResources().getInteger(R.integer.volume_dialog_gravity);
mContext.getResources().getInteger(R.integer.volume_dialog_gravity), mWindowGravity = Gravity.getAbsoluteGravity(mOriginalGravity,
mContext.getResources().getConfiguration().getLayoutDirection()); mContext.getResources().getConfiguration().getLayoutDirection());
lp.gravity = mWindowGravity; lp.gravity = mWindowGravity;
mWindow.setAttributes(lp); mWindow.setAttributes(lp);
mWindow.setLayout(WRAP_CONTENT, WRAP_CONTENT); mWindow.setLayout(WRAP_CONTENT, WRAP_CONTENT);
mDialog.setContentView(R.layout.volume_dialog); mDialog.setContentView(R.layout.volume_dialog);
mDialogView = mDialog.findViewById(R.id.volume_dialog); mDialogView = mDialog.findViewById(R.id.volume_dialog);
mDialogView.setAlpha(0); mDialogView.setAlpha(0);
@@ -1539,8 +1580,10 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
animator.translationX( animator.translationX(
(isWindowGravityLeft() ? -1 : 1) * mDialogView.getWidth() / 2.0f); (isWindowGravityLeft() ? -1 : 1) * mDialogView.getWidth() / 2.0f);
} }
animator.setListener(getJankListener(getDialogView(), TYPE_DISMISS, animator.setListener(getJankListener(getDialogView(), TYPE_DISMISS,
mDialogHideAnimationDurationMs)).start(); mDialogHideAnimationDurationMs)).start();
checkODICaptionsTooltip(true); checkODICaptionsTooltip(true);
synchronized (mSafetyWarningLock) { synchronized (mSafetyWarningLock) {
if (mSafetyWarning != null) { if (mSafetyWarning != null) {
@@ -2237,6 +2280,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mTopContainer.setBackground(background); mTopContainer.setBackground(background);
} }
@Override
public void onConfigChanged(Configuration config) {
mOrientation = config.orientation;
}
private final VolumeDialogController.Callbacks mControllerCallbackH private final VolumeDialogController.Callbacks mControllerCallbackH
= new VolumeDialogController.Callbacks() { = new VolumeDialogController.Callbacks() {
@Override @Override
@@ -2313,6 +2361,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
} }
}; };
@VisibleForTesting void onPostureChanged(int posture) {
dismiss(DISMISS_REASON_POSTURE_CHANGED);
mDevicePosture = posture;
}
private final class H extends Handler { private final class H extends Handler {
private static final int SHOW = 1; private static final int SHOW = 1;
private static final int DISMISS = 2; private static final int DISMISS = 2;
@@ -2323,8 +2376,8 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private static final int STATE_CHANGED = 7; private static final int STATE_CHANGED = 7;
private static final int CSD_TIMEOUT = 8; private static final int CSD_TIMEOUT = 8;
public H() { H(Looper looper) {
super(Looper.getMainLooper()); super(looper);
} }
@Override @Override
@@ -2370,6 +2423,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
protected void onStart() { protected void onStart() {
super.setCanceledOnTouchOutside(true); super.setCanceledOnTouchOutside(true);
super.onStart(); super.onStart();
adjustPositionOnScreen();
} }
@Override @Override

View File

@@ -18,6 +18,7 @@ package com.android.systemui.volume.dagger;
import android.content.Context; import android.content.Context;
import android.media.AudioManager; import android.media.AudioManager;
import android.os.Looper;
import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.jank.InteractionJankMonitor;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
@@ -28,6 +29,7 @@ import com.android.systemui.plugins.VolumeDialog;
import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.volume.CsdWarningDialog; import com.android.systemui.volume.CsdWarningDialog;
@@ -42,7 +44,6 @@ import dagger.Provides;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** Dagger Module for code in the volume package. */ /** Dagger Module for code in the volume package. */
@Module @Module
public interface VolumeModule { public interface VolumeModule {
@@ -65,6 +66,7 @@ public interface VolumeModule {
DeviceConfigProxy deviceConfigProxy, DeviceConfigProxy deviceConfigProxy,
@Main Executor executor, @Main Executor executor,
CsdWarningDialog.Factory csdFactory, CsdWarningDialog.Factory csdFactory,
DevicePostureController devicePostureController,
DumpManager dumpManager) { DumpManager dumpManager) {
VolumeDialogImpl impl = new VolumeDialogImpl( VolumeDialogImpl impl = new VolumeDialogImpl(
context, context,
@@ -79,6 +81,8 @@ public interface VolumeModule {
deviceConfigProxy, deviceConfigProxy,
executor, executor,
csdFactory, csdFactory,
devicePostureController,
Looper.getMainLooper(),
dumpManager); dumpManager);
impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false); impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
impl.setAutomute(true); impl.setAutomute(true);

View File

@@ -17,22 +17,28 @@
package com.android.systemui.volume; package com.android.systemui.volume;
import static com.android.systemui.volume.Events.DISMISS_REASON_UNKNOWN; import static com.android.systemui.volume.Events.DISMISS_REASON_UNKNOWN;
import static com.android.systemui.volume.Events.SHOW_REASON_UNKNOWN;
import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS; import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS;
import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times; 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 android.app.KeyguardManager; import android.app.KeyguardManager;
import android.content.res.Configuration;
import android.media.AudioManager; import android.media.AudioManager;
import android.os.SystemClock; import android.os.SystemClock;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper; import android.testing.TestableLooper;
import android.view.Gravity;
import android.view.InputDevice; import android.view.InputDevice;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
@@ -53,7 +59,9 @@ import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.plugins.VolumeDialogController.State; import com.android.systemui.plugins.VolumeDialogController.State;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.FakeConfigurationController;
import com.android.systemui.util.DeviceConfigProxyFake; import com.android.systemui.util.DeviceConfigProxyFake;
import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock; import com.android.systemui.util.time.FakeSystemClock;
@@ -82,6 +90,9 @@ public class VolumeDialogImplTest extends SysuiTestCase {
View mDrawerNormal; View mDrawerNormal;
private DeviceConfigProxyFake mDeviceConfigProxy; private DeviceConfigProxyFake mDeviceConfigProxy;
private FakeExecutor mExecutor; private FakeExecutor mExecutor;
private TestableLooper mTestableLooper;
private ConfigurationController mConfigurationController;
private int mOriginalOrientation;
@Mock @Mock
VolumeDialogController mVolumeDialogController; VolumeDialogController mVolumeDialogController;
@@ -92,8 +103,6 @@ public class VolumeDialogImplTest extends SysuiTestCase {
@Mock @Mock
DeviceProvisionedController mDeviceProvisionedController; DeviceProvisionedController mDeviceProvisionedController;
@Mock @Mock
ConfigurationController mConfigurationController;
@Mock
MediaOutputDialogFactory mMediaOutputDialogFactory; MediaOutputDialogFactory mMediaOutputDialogFactory;
@Mock @Mock
VolumePanelFactory mVolumePanelFactory; VolumePanelFactory mVolumePanelFactory;
@@ -104,6 +113,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
@Mock @Mock
private DumpManager mDumpManager; private DumpManager mDumpManager;
@Mock CsdWarningDialog mCsdWarningDialog; @Mock CsdWarningDialog mCsdWarningDialog;
@Mock
DevicePostureController mPostureController;
private final CsdWarningDialog.Factory mCsdWarningDialogFactory = private final CsdWarningDialog.Factory mCsdWarningDialogFactory =
new CsdWarningDialog.Factory() { new CsdWarningDialog.Factory() {
@@ -119,9 +130,17 @@ public class VolumeDialogImplTest extends SysuiTestCase {
getContext().addMockSystemService(KeyguardManager.class, mKeyguard); getContext().addMockSystemService(KeyguardManager.class, mKeyguard);
mTestableLooper = TestableLooper.get(this);
mDeviceConfigProxy = new DeviceConfigProxyFake(); mDeviceConfigProxy = new DeviceConfigProxyFake();
mExecutor = new FakeExecutor(new FakeSystemClock()); mExecutor = new FakeExecutor(new FakeSystemClock());
when(mPostureController.getDevicePosture())
.thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED);
mOriginalOrientation = mContext.getResources().getConfiguration().orientation;
mConfigurationController = new FakeConfigurationController();
mDialog = new VolumeDialogImpl( mDialog = new VolumeDialogImpl(
getContext(), getContext(),
mVolumeDialogController, mVolumeDialogController,
@@ -135,8 +154,9 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mDeviceConfigProxy, mDeviceConfigProxy,
mExecutor, mExecutor,
mCsdWarningDialogFactory, mCsdWarningDialogFactory,
mDumpManager mPostureController,
); mTestableLooper.getLooper(),
mDumpManager);
mDialog.init(0, null); mDialog.init(0, null);
State state = createShellState(); State state = createShellState();
mDialog.onStateChangedH(state); mDialog.onStateChangedH(state);
@@ -227,6 +247,7 @@ public class VolumeDialogImplTest extends SysuiTestCase {
ArgumentCaptor.forClass(VolumeDialogController.Callbacks.class); ArgumentCaptor.forClass(VolumeDialogController.Callbacks.class);
verify(mVolumeDialogController).addCallback(controllerCallbackCapture.capture(), any()); verify(mVolumeDialogController).addCallback(controllerCallbackCapture.capture(), any());
VolumeDialogController.Callbacks callbacks = controllerCallbackCapture.getValue(); VolumeDialogController.Callbacks callbacks = controllerCallbackCapture.getValue();
callbacks.onShowSafetyWarning(AudioManager.FLAG_SHOW_UI); callbacks.onShowSafetyWarning(AudioManager.FLAG_SHOW_UI);
verify(mAccessibilityMgr).getRecommendedTimeoutMillis( verify(mAccessibilityMgr).getRecommendedTimeoutMillis(
VolumeDialogImpl.DIALOG_SAFETYWARNING_TIMEOUT_MILLIS, VolumeDialogImpl.DIALOG_SAFETYWARNING_TIMEOUT_MILLIS,
@@ -371,11 +392,171 @@ public class VolumeDialogImplTest extends SysuiTestCase {
verify(mCsdWarningDialog).show(); verify(mCsdWarningDialog).show();
} }
@Test
public void ifPortraitHalfOpen_drawVerticallyTop() {
DevicePostureController devicePostureController = mock(DevicePostureController.class);
when(devicePostureController.getDevicePosture())
.thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED);
VolumeDialogImpl dialog = new VolumeDialogImpl(
getContext(),
mVolumeDialogController,
mAccessibilityMgr,
mDeviceProvisionedController,
mConfigurationController,
mMediaOutputDialogFactory,
mVolumePanelFactory,
mActivityStarter,
mInteractionJankMonitor,
mDeviceConfigProxy,
mExecutor,
mCsdWarningDialogFactory,
devicePostureController,
mTestableLooper.getLooper(),
mDumpManager
);
dialog.init(0 , null);
verify(devicePostureController).addCallback(any());
dialog.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED);
mTestableLooper.processAllMessages(); // let dismiss() finish
setOrientation(Configuration.ORIENTATION_PORTRAIT);
// Call show() to trigger layout updates before verifying position
dialog.show(SHOW_REASON_UNKNOWN);
mTestableLooper.processAllMessages(); // let show() finish before assessing its side-effect
int gravity = dialog.getWindowGravity();
assertEquals(Gravity.TOP, gravity & Gravity.VERTICAL_GRAVITY_MASK);
}
@Test
public void ifPortraitAndOpen_drawCenterVertically() {
DevicePostureController devicePostureController = mock(DevicePostureController.class);
when(devicePostureController.getDevicePosture())
.thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED);
VolumeDialogImpl dialog = new VolumeDialogImpl(
getContext(),
mVolumeDialogController,
mAccessibilityMgr,
mDeviceProvisionedController,
mConfigurationController,
mMediaOutputDialogFactory,
mVolumePanelFactory,
mActivityStarter,
mInteractionJankMonitor,
mDeviceConfigProxy,
mExecutor,
mCsdWarningDialogFactory,
devicePostureController,
mTestableLooper.getLooper(),
mDumpManager
);
dialog.init(0, null);
verify(devicePostureController).addCallback(any());
dialog.onPostureChanged(DevicePostureController.DEVICE_POSTURE_OPENED);
mTestableLooper.processAllMessages(); // let dismiss() finish
setOrientation(Configuration.ORIENTATION_PORTRAIT);
dialog.show(SHOW_REASON_UNKNOWN);
mTestableLooper.processAllMessages(); // let show() finish before assessing its side-effect
int gravity = dialog.getWindowGravity();
assertEquals(Gravity.CENTER_VERTICAL, gravity & Gravity.VERTICAL_GRAVITY_MASK);
}
@Test
public void ifLandscapeAndHalfOpen_drawCenterVertically() {
DevicePostureController devicePostureController = mock(DevicePostureController.class);
when(devicePostureController.getDevicePosture())
.thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED);
VolumeDialogImpl dialog = new VolumeDialogImpl(
getContext(),
mVolumeDialogController,
mAccessibilityMgr,
mDeviceProvisionedController,
mConfigurationController,
mMediaOutputDialogFactory,
mVolumePanelFactory,
mActivityStarter,
mInteractionJankMonitor,
mDeviceConfigProxy,
mExecutor,
mCsdWarningDialogFactory,
devicePostureController,
mTestableLooper.getLooper(),
mDumpManager
);
dialog.init(0, null);
verify(devicePostureController).addCallback(any());
dialog.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED);
mTestableLooper.processAllMessages(); // let dismiss() finish
setOrientation(Configuration.ORIENTATION_LANDSCAPE);
dialog.show(SHOW_REASON_UNKNOWN);
mTestableLooper.processAllMessages(); // let show() finish before assessing its side-effect
int gravity = dialog.getWindowGravity();
assertEquals(Gravity.CENTER_VERTICAL, gravity & Gravity.VERTICAL_GRAVITY_MASK);
}
@Test
public void dialogInit_addsPostureControllerCallback() {
// init is already called in setup
verify(mPostureController).addCallback(any());
}
@Test
public void dialogDestroy_removesPostureControllerCallback() {
VolumeDialogImpl dialog = new VolumeDialogImpl(
getContext(),
mVolumeDialogController,
mAccessibilityMgr,
mDeviceProvisionedController,
mConfigurationController,
mMediaOutputDialogFactory,
mVolumePanelFactory,
mActivityStarter,
mInteractionJankMonitor,
mDeviceConfigProxy,
mExecutor,
mCsdWarningDialogFactory,
mPostureController,
mTestableLooper.getLooper(),
mDumpManager
);
dialog.init(0, null);
verify(mPostureController, never()).removeCallback(any());
dialog.destroy();
verify(mPostureController).removeCallback(any());
}
private void setOrientation(int orientation) {
Configuration config = new Configuration();
config.orientation = orientation;
if (mConfigurationController != null) {
mConfigurationController.onConfigurationChanged(config);
}
}
@After @After
public void teardown() { public void teardown() {
if (mDialog != null) { if (mDialog != null) {
mDialog.clearInternalHandlerAfterTest(); mDialog.clearInternalHandlerAfterTest();
} }
setOrientation(mOriginalOrientation);
mTestableLooper.processAllMessages();
reset(mPostureController);
} }
/* /*