Extract most QS code from NPVC

Moved QS-related code from NPVC to a new class that handles QS panel expansion

Bug: 254870148
Test: manual, atest
Change-Id: Ic1cbdc6c02e25cd3efaea4badbf2b8835895459b
This commit is contained in:
Shawn Lee
2022-12-15 21:34:25 -08:00
parent 934de388ec
commit 206360a694
15 changed files with 2910 additions and 2010 deletions

View File

@@ -39,6 +39,7 @@ public class DebugDrawable extends Drawable {
private final NotificationPanelView mView;
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
private final LockIconViewController mLockIconViewController;
private final QuickSettingsController mQsController;
private final Set<Integer> mDebugTextUsedYPositions;
private final Paint mDebugPaint;
@@ -46,12 +47,14 @@ public class DebugDrawable extends Drawable {
NotificationPanelViewController notificationPanelViewController,
NotificationPanelView notificationPanelView,
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
LockIconViewController lockIconViewController
LockIconViewController lockIconViewController,
QuickSettingsController quickSettingsController
) {
mNotificationPanelViewController = notificationPanelViewController;
mView = notificationPanelView;
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
mLockIconViewController = lockIconViewController;
mQsController = quickSettingsController;
mDebugTextUsedYPositions = new HashSet<>();
mDebugPaint = new Paint();
}
@@ -71,12 +74,19 @@ public class DebugDrawable extends Drawable {
Color.RED, "getMaxPanelHeight()");
drawDebugInfo(canvas, (int) mNotificationPanelViewController.getExpandedHeight(),
Color.BLUE, "getExpandedHeight()");
drawDebugInfo(canvas, mNotificationPanelViewController.calculatePanelHeightQsExpanded(),
drawDebugInfo(canvas, mQsController.calculatePanelHeightExpanded(
mNotificationPanelViewController.getClockPositionResult()
.stackScrollerPadding),
Color.GREEN, "calculatePanelHeightQsExpanded()");
drawDebugInfo(canvas, mNotificationPanelViewController.calculatePanelHeightQsExpanded(),
drawDebugInfo(canvas, mQsController.calculatePanelHeightExpanded(
mNotificationPanelViewController.getClockPositionResult()
.stackScrollerPadding),
Color.YELLOW, "calculatePanelHeightShade()");
drawDebugInfo(canvas,
(int) mNotificationPanelViewController.calculateNotificationsTopPadding(),
(int) mQsController.calculateNotificationsTopPadding(
mNotificationPanelViewController.isExpanding(),
mNotificationPanelViewController.getKeyguardNotificationStaticPadding(),
mNotificationPanelViewController.getExpandedFraction()),
Color.MAGENTA, "calculateNotificationsTopPadding()");
drawDebugInfo(canvas, mNotificationPanelViewController.getClockPositionResult().clockY,
Color.GRAY, "mClockPositionResult.clockY");

File diff suppressed because it is too large Load Diff

View File

@@ -50,7 +50,6 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) {
h: Float,
touchSlop: Float,
qsExpanded: Boolean,
collapsedOnDown: Boolean,
keyguardShowing: Boolean,
qsExpansionEnabled: Boolean
) {
@@ -63,13 +62,12 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) {
long1 = h.toLong()
double1 = touchSlop.toDouble()
bool1 = qsExpanded
bool2 = collapsedOnDown
bool3 = keyguardShowing
bool4 = qsExpansionEnabled
bool2 = keyguardShowing
bool3 = qsExpansionEnabled
},
{
"QsTrackingNotStarted: initTouchY=$int1,y=$int2,h=$long1,slop=$double1,qsExpanded" +
"=$bool1,collapsedDown=$bool2,keyguardShowing=$bool3,qsExpansion=$bool4"
"=$bool1,keyguardShowing=$bool2,qsExpansion=$bool3"
}
)
}
@@ -158,7 +156,6 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) {
qsMinExpansionHeight: Int,
qsMaxExpansionHeight: Int,
stackScrollerOverscrolling: Boolean,
dozing: Boolean,
qsAnimatorExpand: Boolean,
animatingQs: Boolean
) {
@@ -171,14 +168,13 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) {
int1 = qsMinExpansionHeight
int2 = qsMaxExpansionHeight
bool2 = stackScrollerOverscrolling
bool3 = dozing
bool4 = qsAnimatorExpand
bool3 = qsAnimatorExpand
// 0 = false, 1 = true
long1 = animatingQs.compareTo(false).toLong()
},
{
"$str1 qsExpanded=$bool1,qsMinExpansionHeight=$int1,qsMaxExpansionHeight=$int2," +
"stackScrollerOverscrolling=$bool2,dozing=$bool3,qsAnimatorExpand=$bool4," +
"stackScrollerOverscrolling=$bool2,qsAnimatorExpand=$bool3," +
"animatingQs=$long1"
}
)

View File

@@ -187,6 +187,8 @@ class LockscreenShadeTransitionController @Inject constructor(
private val qsTransitionController = qsTransitionControllerFactory.create { qS }
private val callbacks = mutableListOf<Callback>()
/** See [LockscreenShadeQsTransitionController.qsTransitionFraction].*/
@get:FloatRange(from = 0.0, to = 1.0)
val qSDragProgress: Float
@@ -320,8 +322,8 @@ class LockscreenShadeTransitionController @Inject constructor(
true /* drag down is always an open */)
}
notificationPanelController.animateToFullShade(delay)
notificationPanelController.setTransitionToFullShadeAmount(0f,
true /* animated */, delay)
callbacks.forEach { it.setTransitionToFullShadeAmount(0f,
true /* animated */, delay) }
// Let's reset ourselves, ready for the next animation
@@ -425,8 +427,8 @@ class LockscreenShadeTransitionController @Inject constructor(
qsTransitionController.dragDownAmount = value
notificationPanelController.setTransitionToFullShadeAmount(field,
false /* animate */, 0 /* delay */)
callbacks.forEach { it.setTransitionToFullShadeAmount(field,
false /* animate */, 0 /* delay */) }
mediaHierarchyManager.setTransitionToFullShadeAmount(field)
scrimTransitionController.dragDownAmount = value
@@ -689,7 +691,7 @@ class LockscreenShadeTransitionController @Inject constructor(
if (cancelled) {
setPulseHeight(0f, animate = true)
} else {
notificationPanelController.onPulseExpansionFinished()
callbacks.forEach { it.onPulseExpansionFinished() }
setPulseHeight(0f, animate = false)
}
}
@@ -721,6 +723,27 @@ class LockscreenShadeTransitionController @Inject constructor(
"${animationHandlerOnKeyguardDismiss != null}")
}
}
fun addCallback(callback: Callback) {
if (!callbacks.contains(callback)) {
callbacks.add(callback)
}
}
/**
* Callback for authentication events.
*/
interface Callback {
/** TODO: comment here */
fun onPulseExpansionFinished() {}
/**
* Sets the amount of pixels we have currently dragged down if we're transitioning
* to the full shade. 0.0f means we're not transitioning yet.
*/
fun setTransitionToFullShadeAmount(pxAmount: Float, animate: Boolean, delay: Long) {}
}
}
/**

View File

@@ -57,6 +57,7 @@ import com.android.systemui.qs.QSPanelController;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.CameraLauncher;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
@@ -104,6 +105,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
private final VibrationEffect mCameraLaunchGestureVibrationEffect;
private final SystemBarAttributesListener mSystemBarAttributesListener;
private final Lazy<CameraLauncher> mCameraLauncherLazy;
private final QuickSettingsController mQsController;
private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
@@ -111,6 +113,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
@Inject
CentralSurfacesCommandQueueCallbacks(
CentralSurfaces centralSurfaces,
QuickSettingsController quickSettingsController,
Context context,
@Main Resources resources,
ShadeController shadeController,
@@ -137,6 +140,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
Lazy<CameraLauncher> cameraLauncherLazy,
UserTracker userTracker) {
mCentralSurfaces = centralSurfaces;
mQsController = quickSettingsController;
mContext = context;
mShadeController = shadeController;
mCommandQueue = commandQueue;
@@ -334,9 +338,9 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
mNotificationStackScrollLayoutController.setWillExpand(true);
mHeadsUpManager.unpinAll(true /* userUnpinned */);
mMetricsLogger.count("panel_open", 1);
} else if (!mNotificationPanelViewController.isInSettings()
} else if (!mQsController.getExpanded()
&& !mNotificationPanelViewController.isExpanding()) {
mNotificationPanelViewController.flingSettings(0 /* velocity */,
mQsController.flingQs(0 /* velocity */,
NotificationPanelViewController.FLING_EXPAND);
mMetricsLogger.count("panel_open_qs", 1);
}

View File

@@ -185,6 +185,7 @@ import com.android.systemui.shade.CameraLauncher;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.NotificationShadeWindowViewController;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.shade.ShadeExpansionStateManager;
@@ -488,6 +489,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
// settings
private QSPanelController mQSPanelController;
@VisibleForTesting
QuickSettingsController mQsController;
KeyguardIndicationController mKeyguardIndicationController;
@@ -1419,7 +1422,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|| isOccluded()
|| !mKeyguardStateController.canDismissLockScreen()
|| mKeyguardViewMediator.isAnySimPinSecure()
|| (mNotificationPanelViewController.isQsExpanded() && trackingTouch)
|| (mQsController.getExpanded() && trackingTouch)
|| mNotificationPanelViewController.getBarState() == StatusBarState.SHADE_LOCKED) {
return;
}
@@ -1580,6 +1583,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mCentralSurfacesComponent.getLockIconViewController().init();
mStackScrollerController =
mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
mQsController = mCentralSurfacesComponent.getQuickSettingsController();
mStackScroller = mStackScrollerController.getView();
mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer();
mPresenter = mCentralSurfacesComponent.getNotificationPresenter();
@@ -1699,7 +1703,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
&& !isShadeDisabled()
&& ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
&& !mDozing;
mNotificationPanelViewController.setQsExpansionEnabledPolicy(expandEnabled);
mQsController.setExpansionEnabledPolicy(expandEnabled);
Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled);
}
@@ -3234,12 +3238,12 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mStatusBarKeyguardViewManager.onBackPressed();
return true;
}
if (mNotificationPanelViewController.isQsCustomizing()) {
mNotificationPanelViewController.closeQsCustomizer();
if (mQsController.isCustomizing()) {
mQsController.closeQsCustomizer();
return true;
}
if (mNotificationPanelViewController.isQsExpanded()) {
mNotificationPanelViewController.animateCloseQs(false /* animateAway */);
if (mQsController.getExpanded()) {
mNotificationPanelViewController.animateCloseQs(false);
return true;
}
if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) {
@@ -3600,7 +3604,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mFalsingCollector.onScreenOff();
mScrimController.onScreenTurnedOff();
if (mCloseQsBeforeScreenOff) {
mNotificationPanelViewController.closeQs();
mQsController.closeQs();
mCloseQsBeforeScreenOff = false;
}
updateIsKeyguard();

View File

@@ -40,6 +40,7 @@ import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -102,6 +103,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
private final IStatusBarService mBarService;
private final DynamicPrivacyController mDynamicPrivacyController;
private final NotificationListContainer mNotifListContainer;
private final QuickSettingsController mQsController;
protected boolean mVrMode;
@@ -109,6 +111,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
StatusBarNotificationPresenter(
Context context,
NotificationPanelViewController panel,
QuickSettingsController quickSettingsController,
HeadsUpManagerPhone headsUp,
NotificationShadeWindowView statusBarWindow,
ActivityStarter activityStarter,
@@ -136,6 +139,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
mActivityStarter = activityStarter;
mKeyguardStateController = keyguardStateController;
mNotificationPanel = panel;
mQsController = quickSettingsController;
mHeadsUpManager = headsUp;
mDynamicPrivacyController = dynamicPrivacyController;
mKeyguardIndicationController = keyguardIndicationController;
@@ -191,7 +195,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
private void maybeClosePanelForShadeEmptied() {
if (CLOSE_PANEL_WHEN_EMPTIED
&& !mNotificationPanel.isTracking()
&& !mNotificationPanel.isQsExpanded()
&& !mQsController.getExpanded()
&& mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
&& !isCollapsing()) {
mStatusBarStateController.setState(StatusBarState.KEYGUARD);

View File

@@ -26,6 +26,7 @@ import com.android.systemui.shade.LargeScreenShadeHeaderController;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.NotificationShadeWindowViewController;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.core.StatusBarInitializer;
@@ -113,6 +114,9 @@ public interface CentralSurfacesComponent {
*/
NotificationPanelViewController getNotificationPanelViewController();
/** Creates a QuickSettingsController. */
QuickSettingsController getQuickSettingsController();
/**
* Creates a LockIconViewController. Must be init after creation.
*/

View File

@@ -196,6 +196,7 @@ import org.mockito.stubbing.Answer;
import java.util.List;
import java.util.Optional;
import dagger.Lazy;
import kotlinx.coroutines.CoroutineDispatcher;
@SmallTest
@@ -270,6 +271,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
@Mock private KeyguardMediaController mKeyguardMediaController;
@Mock private NavigationModeController mNavigationModeController;
@Mock private NavigationBarController mNavigationBarController;
@Mock private QuickSettingsController mQsController;
@Mock private LargeScreenShadeHeaderController mLargeScreenShadeHeaderController;
@Mock private ContentResolver mContentResolver;
@Mock private TapAgainViewController mTapAgainViewController;
@@ -329,6 +331,10 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
private final ShadeExpansionStateManager mShadeExpansionStateManager =
new ShadeExpansionStateManager();
private QuickSettingsController mQuickSettingsController;
@Mock private Lazy<NotificationPanelViewController> mNotificationPanelViewControllerLazy;
private FragmentHostManager.FragmentListener mFragmentListener;
@Before
@@ -506,6 +512,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
mTapAgainViewController,
mNavigationModeController,
mNavigationBarController,
mQsController,
mFragmentService,
mContentResolver,
mRecordingController,
@@ -515,8 +522,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
mShadeExpansionStateManager,
mNotificationRemoteInputManager,
mSysUIUnfoldComponent,
mInteractionJankMonitor,
mQsFrameTranslateController,
mSysUiState,
() -> mKeyguardBottomAreaViewController,
mKeyguardUnlockAnimationController,
@@ -572,6 +577,40 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
.setOnEmptySpaceClickListener(mEmptySpaceClickListenerCaptor.capture());
verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true);
reset(mKeyguardStatusViewController);
when(mNotificationPanelViewControllerLazy.get())
.thenReturn(mNotificationPanelViewController);
mQuickSettingsController = new QuickSettingsController(
mNotificationPanelViewControllerLazy,
mView,
mQsFrameTranslateController,
mShadeTransitionController,
expansionHandler,
mNotificationRemoteInputManager,
mShadeExpansionStateManager,
mStatusBarKeyguardViewManager,
mNotificationStackScrollLayoutController,
mLockscreenShadeTransitionController,
mNotificationShadeDepthController,
mLargeScreenShadeHeaderController,
mStatusBarTouchableRegionManager,
mKeyguardStateController,
mKeyguardBypassController,
mUpdateMonitor,
mScrimController,
mMediaDataManager,
mMediaHierarchyManager,
mAmbientState,
mRecordingController,
mFalsingManager,
new FalsingCollectorFake(),
mAccessibilityManager,
mLockscreenGestureLogger,
mMetricsLogger,
mFeatureFlags,
mInteractionJankMonitor,
mShadeLog
);
}
@After
@@ -755,27 +794,14 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
@Test
public void testOnTouchEvent_expansionCanBeBlocked() {
onTouchEvent(MotionEvent.obtain(0L /* downTime */,
0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */,
0 /* metaState */));
onTouchEvent(MotionEvent.obtain(0L /* downTime */,
0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 200f /* y */,
0 /* metaState */));
onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0));
onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 200f, 0));
assertThat((int) mNotificationPanelViewController.getExpandedHeight()).isEqualTo(200);
assertThat(mNotificationPanelViewController.isTrackingBlocked()).isFalse();
mNotificationPanelViewController.blockExpansionForCurrentTouch();
onTouchEvent(MotionEvent.obtain(0L /* downTime */,
0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 300f /* y */,
0 /* metaState */));
onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 300f, 0));
// Expansion should not have changed because it was blocked
assertThat((int) mNotificationPanelViewController.getExpandedHeight()).isEqualTo(200);
assertThat(mNotificationPanelViewController.isTrackingBlocked()).isTrue();
onTouchEvent(MotionEvent.obtain(0L /* downTime */,
0L /* eventTime */, MotionEvent.ACTION_UP, 0f /* x */, 300f /* y */,
0 /* metaState */));
assertThat(mNotificationPanelViewController.isTrackingBlocked()).isFalse();
}
@Test
@@ -1045,7 +1071,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
@Test
public void testCanCollapsePanelOnTouch_trueWhenInSettings() {
mStatusBarStateController.setState(SHADE);
mNotificationPanelViewController.setQsExpanded(true);
when(mQsController.getExpanded()).thenReturn(true);
assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isTrue();
}
@@ -1054,7 +1080,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
public void testCanCollapsePanelOnTouch_falseInDualPaneShade() {
mStatusBarStateController.setState(SHADE);
enableSplitShade(/* enabled= */ true);
mNotificationPanelViewController.setQsExpanded(true);
when(mQsController.getExpanded()).thenReturn(true);
assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isFalse();
}
@@ -1125,7 +1151,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
@Test
public void testRotatingToSplitShadeWithQsExpanded_transitionsToShadeLocked() {
mStatusBarStateController.setState(KEYGUARD);
mNotificationPanelViewController.setQsExpanded(true);
when(mQsController.getExpanded()).thenReturn(true);
enableSplitShade(true);
@@ -1136,24 +1162,18 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
public void testUnlockedSplitShadeTransitioningToKeyguard_closesQS() {
enableSplitShade(true);
mStatusBarStateController.setState(SHADE);
mNotificationPanelViewController.setQsExpanded(true);
mStatusBarStateController.setState(KEYGUARD);
assertThat(mNotificationPanelViewController.isQsExpanded()).isEqualTo(false);
assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isEqualTo(false);
verify(mQsController).closeQs();
}
@Test
public void testLockedSplitShadeTransitioningToKeyguard_closesQS() {
enableSplitShade(true);
mStatusBarStateController.setState(SHADE_LOCKED);
mNotificationPanelViewController.setQsExpanded(true);
mStatusBarStateController.setState(KEYGUARD);
assertThat(mNotificationPanelViewController.isQsExpanded()).isEqualTo(false);
assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isEqualTo(false);
verify(mQsController).closeQs();
}
@Test
@@ -1165,7 +1185,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true);
when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(1);
mNotificationPanelViewController.closeQs();
triggerPositionClockAndNotifications();
verify(mKeyguardStatusViewController).displayClock(SMALL, /* animate */ true);
}
@@ -1292,18 +1312,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
verify(mKeyguardStatusViewController, never()).displayClock(LARGE, /* animate */ true);
}
@Test
public void testLargeScreenHeaderMadeActiveForLargeScreen() {
mStatusBarStateController.setState(SHADE);
when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(true);
mNotificationPanelViewController.updateResources();
verify(mLargeScreenShadeHeaderController).setLargeScreenActive(true);
when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(false);
mNotificationPanelViewController.updateResources();
verify(mLargeScreenShadeHeaderController).setLargeScreenActive(false);
}
@Test
public void testExpandWithQsMethodIsUsingLockscreenTransitionController() {
enableSplitShade(/* enabled= */ true);
@@ -1358,12 +1366,14 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
@Test
public void testQsToBeImmediatelyExpandedWhenOpeningPanelInSplitShade() {
enableSplitShade(/* enabled= */ true);
mShadeExpansionStateManager.updateState(STATE_OPEN);
verify(mQsController).setExpandImmediate(false);
mShadeExpansionStateManager.updateState(STATE_CLOSED);
assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse();
verify(mQsController, times(2)).setExpandImmediate(false);
mShadeExpansionStateManager.updateState(STATE_OPENING);
assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isTrue();
verify(mQsController).setExpandImmediate(true);
}
@Test
@@ -1375,33 +1385,28 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
// going to lockscreen would trigger STATE_OPENING
mShadeExpansionStateManager.updateState(STATE_OPENING);
assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse();
verify(mQsController, never()).setExpandImmediate(true);
}
@Test
public void testQsImmediateResetsWhenPanelOpensOrCloses() {
mNotificationPanelViewController.setQsExpandImmediate(true);
mShadeExpansionStateManager.updateState(STATE_OPEN);
assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse();
mNotificationPanelViewController.setQsExpandImmediate(true);
mShadeExpansionStateManager.updateState(STATE_CLOSED);
assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse();
verify(mQsController, times(2)).setExpandImmediate(false);
}
@Test
public void testQsExpansionChangedToDefaultWhenRotatingFromOrToSplitShade() {
// to make sure shade is in expanded state
mNotificationPanelViewController.startWaitingForOpenPanelGesture();
assertThat(mNotificationPanelViewController.isQsExpanded()).isFalse();
// switch to split shade from portrait (default state)
enableSplitShade(/* enabled= */ true);
assertThat(mNotificationPanelViewController.isQsExpanded()).isTrue();
verify(mQsController).setExpanded(true);
// switch to portrait from split shade
enableSplitShade(/* enabled= */ false);
assertThat(mNotificationPanelViewController.isQsExpanded()).isFalse();
verify(mQsController).setExpanded(false);
}
@Test
@@ -1413,59 +1418,10 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
assertThat(mNotificationPanelViewController.isClosing()).isFalse();
mNotificationPanelViewController.animateCloseQs(false);
assertThat(mNotificationPanelViewController.isClosing()).isTrue();
}
@Test
public void testPanelStaysOpenWhenClosingQs() {
mShadeExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
/* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0);
mNotificationPanelViewController.setExpandedFraction(1f);
assertThat(mNotificationPanelViewController.isClosing()).isFalse();
mNotificationPanelViewController.animateCloseQs(false);
assertThat(mNotificationPanelViewController.isClosing()).isFalse();
}
@Test
public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() {
mNotificationPanelViewController.setQs(mQs);
when(mQsFrame.getX()).thenReturn(0f);
when(mQsFrame.getWidth()).thenReturn(1000);
when(mQsHeader.getTop()).thenReturn(0);
when(mQsHeader.getBottom()).thenReturn(1000);
NotificationPanelViewController.TouchHandler touchHandler =
mNotificationPanelViewController.createTouchHandler();
mNotificationPanelViewController.setExpandedFraction(1f);
touchHandler.onInterceptTouchEvent(
createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN));
touchHandler.onInterceptTouchEvent(
createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE));
assertThat(mNotificationPanelViewController.isQsTracking()).isTrue();
}
@Test
public void interceptTouchEvent_withinQs_shadeExpanded_inSplitShade_doesNotStartQsTracking() {
enableSplitShade(true);
mNotificationPanelViewController.setQs(mQs);
when(mQsFrame.getX()).thenReturn(0f);
when(mQsFrame.getWidth()).thenReturn(1000);
when(mQsHeader.getTop()).thenReturn(0);
when(mQsHeader.getBottom()).thenReturn(1000);
NotificationPanelViewController.TouchHandler touchHandler =
mNotificationPanelViewController.createTouchHandler();
mNotificationPanelViewController.setExpandedFraction(1f);
touchHandler.onInterceptTouchEvent(
createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN));
touchHandler.onInterceptTouchEvent(
createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE));
assertThat(mNotificationPanelViewController.isQsTracking()).isFalse();
}
@Test
public void testOnAttachRefreshStatusBarState() {
mStatusBarStateController.setState(KEYGUARD);
@@ -1494,11 +1450,14 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
enableSplitShade(true);
mNotificationPanelViewController.expandWithQs();
when(mHeadsUpManager.isTrackingHeadsUp()).thenReturn(true);
when(mQsController.calculatePanelHeightExpanded(anyInt())).thenReturn(10000);
mNotificationPanelViewController.setHeadsUpDraggingStartingHeight(
SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
int maxDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance();
// make sure we're ignoring the placeholder value for Qs max height
assertThat(maxDistance).isLessThan(10000);
assertThat(maxDistance).isGreaterThan(SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
}
@@ -1525,94 +1484,25 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
@Test
public void onLayoutChange_fullWidth_updatesQSWithFullWithTrue() {
mNotificationPanelViewController.setQs(mQs);
setIsFullWidth(true);
verify(mQs).setIsNotificationPanelFullWidth(true);
verify(mQsController).setNotificationPanelFullWidth(true);
}
@Test
public void onLayoutChange_notFullWidth_updatesQSWithFullWithFalse() {
mNotificationPanelViewController.setQs(mQs);
setIsFullWidth(false);
verify(mQs).setIsNotificationPanelFullWidth(false);
verify(mQsController).setNotificationPanelFullWidth(false);
}
@Test
public void onLayoutChange_qsNotSet_doesNotCrash() {
mNotificationPanelViewController.setQs(null);
mQuickSettingsController.setQs(null);
triggerLayoutChange();
}
@Test
public void onQsFragmentAttached_fullWidth_setsFullWidthTrueOnQS() {
setIsFullWidth(true);
givenViewAttached();
mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
verify(mQSFragment).setIsNotificationPanelFullWidth(true);
}
@Test
public void onQsFragmentAttached_notFullWidth_setsFullWidthFalseOnQS() {
setIsFullWidth(false);
givenViewAttached();
mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
verify(mQSFragment).setIsNotificationPanelFullWidth(false);
}
@Test
public void setQsExpansion_lockscreenShadeTransitionInProgress_usesLockscreenSquishiness() {
float squishinessFraction = 0.456f;
mNotificationPanelViewController.setQs(mQs);
when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
.thenReturn(squishinessFraction);
when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
.thenReturn(0.987f);
// Call setTransitionToFullShadeAmount to get into the full shade transition in progress
// state.
mNotificationPanelViewController.setTransitionToFullShadeAmount(
/* pxAmount= */ 234,
/* animate= */ false,
/* delay= */ 0
);
mNotificationPanelViewController.setQsExpansionHeight(/* height= */ 123);
// First for setTransitionToFullShadeAmount and then setQsExpansion
verify(mQs, times(2)).setQsExpansion(
/* expansion= */ anyFloat(),
/* panelExpansionFraction= */ anyFloat(),
/* proposedTranslation= */ anyFloat(),
eq(squishinessFraction)
);
}
@Test
public void setQsExpansion_lockscreenShadeTransitionNotInProgress_usesStandardSquishiness() {
float lsSquishinessFraction = 0.456f;
float nsslSquishinessFraction = 0.987f;
mNotificationPanelViewController.setQs(mQs);
when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
.thenReturn(lsSquishinessFraction);
when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
.thenReturn(nsslSquishinessFraction);
mNotificationPanelViewController.setQsExpansionHeight(/* height= */ 123);
verify(mQs).setQsExpansion(
/* expansion= */ anyFloat(),
/* panelExpansionFraction= */ anyFloat(),
/* proposedTranslation= */ anyFloat(),
eq(nsslSquishinessFraction)
);
}
@Test
public void onEmptySpaceClicked_notDozingAndOnKeyguard_requestsFaceAuth() {
StatusBarStateController.StateListener statusBarStateListener =
@@ -1738,15 +1628,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
int transitionDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance();
mNotificationPanelViewController.setExpandedHeight(transitionDistance);
assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isFalse();
// set maxQsExpansion in NPVC
int maxQsExpansion = 123;
mNotificationPanelViewController.setQs(mQs);
when(mQs.getDesiredHeight()).thenReturn(maxQsExpansion);
triggerLayoutChange();
mNotificationPanelViewController.setQsExpansionHeight(maxQsExpansion);
assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue();
}
@Test
@@ -1761,7 +1642,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
}
private void triggerPositionClockAndNotifications() {
mNotificationPanelViewController.closeQs();
mNotificationPanelViewController.onQsSetExpansionHeightCalled(false);
}
private FalsingManager.FalsingTapListener getFalsingTapListener() {

View File

@@ -0,0 +1,415 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.shade;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.media.controls.pipeline.MediaDataManager;
import com.android.systemui.media.controls.ui.MediaHierarchyManager;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.QSFragment;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.shade.transition.ShadeTransitionController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.QsFrameTranslateController;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import dagger.Lazy;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class QuickSettingsControllerTest extends SysuiTestCase {
private static final int SPLIT_SHADE_FULL_TRANSITION_DISTANCE = 400;
private QuickSettingsController mQsController;
@Mock private Resources mResources;
@Mock private KeyguardBottomAreaView mQsFrame;
@Mock private KeyguardStatusBarView mKeyguardStatusBar;
@Mock private QS mQs;
@Mock private QSFragment mQSFragment;
@Mock private Lazy<NotificationPanelViewController> mPanelViewControllerLazy;
@Mock private NotificationPanelViewController mNotificationPanelViewController;
@Mock private NotificationPanelView mPanelView;
@Mock private ViewGroup mQsHeader;
@Mock private ViewParent mPanelViewParent;
@Mock private QsFrameTranslateController mQsFrameTranslateController;
@Mock private ShadeTransitionController mShadeTransitionController;
@Mock private PulseExpansionHandler mPulseExpansionHandler;
@Mock private NotificationRemoteInputManager mNotificationRemoteInputManager;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Mock private NotificationShadeDepthController mNotificationShadeDepthController;
@Mock private LargeScreenShadeHeaderController mLargeScreenShadeHeaderController;
@Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
@Mock private KeyguardStateController mKeyguardStateController;
@Mock private KeyguardBypassController mKeyguardBypassController;
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock private ScrimController mScrimController;
@Mock private MediaDataManager mMediaDataManager;
@Mock private MediaHierarchyManager mMediaHierarchyManager;
@Mock private AmbientState mAmbientState;
@Mock private RecordingController mRecordingController;
@Mock private FalsingManager mFalsingManager;
@Mock private FalsingCollector mFalsingCollector;
@Mock private AccessibilityManager mAccessibilityManager;
@Mock private LockscreenGestureLogger mLockscreenGestureLogger;
@Mock private MetricsLogger mMetricsLogger;
@Mock private FeatureFlags mFeatureFlags;
@Mock private InteractionJankMonitor mInteractionJankMonitor;
@Mock private ShadeLogger mShadeLogger;
@Mock private DumpManager mDumpManager;
@Mock private DozeParameters mDozeParameters;
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
@Mock private HeadsUpManagerPhone mHeadsUpManager;
@Mock private UiEventLogger mUiEventLogger;
private SysuiStatusBarStateController mStatusBarStateController;
private Handler mMainHandler;
private LockscreenShadeTransitionController.Callback mLockscreenShadeTransitionCallback;
private final ShadeExpansionStateManager mShadeExpansionStateManager =
new ShadeExpansionStateManager();
private FragmentHostManager.FragmentListener mFragmentListener;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(mPanelViewControllerLazy.get()).thenReturn(mNotificationPanelViewController);
mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
mInteractionJankMonitor, mShadeExpansionStateManager);
KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
keyguardStatusView.setId(R.id.keyguard_status_view);
when(mPanelView.getResources()).thenReturn(mResources);
when(mPanelView.getContext()).thenReturn(getContext());
when(mPanelView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
when(mPanelView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
when(mPanelView.findViewById(R.id.keyguard_status_view))
.thenReturn(mock(KeyguardStatusView.class));
when(mQs.getView()).thenReturn(mPanelView);
when(mQSFragment.getView()).thenReturn(mPanelView);
when(mNotificationRemoteInputManager.isRemoteInputActive())
.thenReturn(false);
when(mInteractionJankMonitor.begin(any(), anyInt()))
.thenReturn(true);
when(mInteractionJankMonitor.end(anyInt()))
.thenReturn(true);
when(mPanelView.getParent()).thenReturn(mPanelViewParent);
when(mQs.getHeader()).thenReturn(mQsHeader);
doAnswer(invocation -> {
mLockscreenShadeTransitionCallback = invocation.getArgument(0);
return null;
}).when(mLockscreenShadeTransitionController).addCallback(any());
mMainHandler = new Handler(Looper.getMainLooper());
mQsController = new QuickSettingsController(
mPanelViewControllerLazy,
mPanelView,
mQsFrameTranslateController,
mShadeTransitionController,
mPulseExpansionHandler,
mNotificationRemoteInputManager,
mShadeExpansionStateManager,
mStatusBarKeyguardViewManager,
mNotificationStackScrollLayoutController,
mLockscreenShadeTransitionController,
mNotificationShadeDepthController,
mLargeScreenShadeHeaderController,
mStatusBarTouchableRegionManager,
mKeyguardStateController,
mKeyguardBypassController,
mKeyguardUpdateMonitor,
mScrimController,
mMediaDataManager,
mMediaHierarchyManager,
mAmbientState,
mRecordingController,
mFalsingManager,
mFalsingCollector,
mAccessibilityManager,
mLockscreenGestureLogger,
mMetricsLogger,
mFeatureFlags,
mInteractionJankMonitor,
mShadeLogger
);
mFragmentListener = mQsController.getQsFragmentListener();
}
@After
public void tearDown() {
mNotificationPanelViewController.cancelHeightAnimator();
mMainHandler.removeCallbacksAndMessages(null);
}
@Test
public void testOnTouchEvent_isConflictingExpansionGestureSet() {
assertThat(mQsController.isConflictingExpansionGesture()).isFalse();
mShadeExpansionStateManager.onPanelExpansionChanged(1f, true, false, 0f);
mQsController.handleTouch(MotionEvent.obtain(0L /* downTime */,
0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */,
0 /* metaState */), false, false);
assertThat(mQsController.isConflictingExpansionGesture()).isTrue();
}
@Test
public void testCloseQsSideEffects() {
enableSplitShade(true);
mQsController.setExpandImmediate(true);
mQsController.setExpanded(true);
mQsController.closeQs();
assertThat(mQsController.getExpanded()).isEqualTo(false);
assertThat(mQsController.isExpandImmediate()).isEqualTo(false);
}
@Test
public void testLargeScreenHeaderMadeActiveForLargeScreen() {
mStatusBarStateController.setState(SHADE);
when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(true);
mQsController.updateResources();
verify(mLargeScreenShadeHeaderController).setLargeScreenActive(true);
when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(false);
mQsController.updateResources();
verify(mLargeScreenShadeHeaderController).setLargeScreenActive(false);
}
@Test
public void testPanelStaysOpenWhenClosingQs() {
mShadeExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
/* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0);
mNotificationPanelViewController.setExpandedFraction(1f);
float shadeExpandedHeight = mQsController.getShadeExpandedHeight();
mQsController.animateCloseQs(false);
assertThat(mQsController.getShadeExpandedHeight()).isEqualTo(shadeExpandedHeight);
}
@Test
public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() {
mQsController.setQs(mQs);
when(mQsFrame.getX()).thenReturn(0f);
when(mQsFrame.getWidth()).thenReturn(1000);
when(mQsHeader.getTop()).thenReturn(0);
when(mQsHeader.getBottom()).thenReturn(1000);
mQsController.setShadeExpandedHeight(1f);
mQsController.onIntercept(
createMotionEvent(0, 0, MotionEvent.ACTION_DOWN));
mQsController.onIntercept(
createMotionEvent(0, 500, MotionEvent.ACTION_MOVE));
assertThat(mQsController.isTracking()).isTrue();
}
@Test
public void interceptTouchEvent_withinQs_shadeExpanded_inSplitShade_doesNotStartQsTracking() {
enableSplitShade(true);
mQsController.setQs(mQs);
when(mQsFrame.getX()).thenReturn(0f);
when(mQsFrame.getWidth()).thenReturn(1000);
when(mQsHeader.getTop()).thenReturn(0);
when(mQsHeader.getBottom()).thenReturn(1000);
mQsController.setShadeExpandedHeight(1f);
mQsController.onIntercept(
createMotionEvent(0, 0, MotionEvent.ACTION_DOWN));
mQsController.onIntercept(
createMotionEvent(0, 500, MotionEvent.ACTION_MOVE));
assertThat(mQsController.isTracking()).isFalse();
}
@Test
public void onQsFragmentAttached_fullWidth_setsFullWidthTrueOnQS() {
setIsFullWidth(true);
mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
verify(mQSFragment).setIsNotificationPanelFullWidth(true);
}
@Test
public void onQsFragmentAttached_notFullWidth_setsFullWidthFalseOnQS() {
setIsFullWidth(false);
mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
verify(mQSFragment).setIsNotificationPanelFullWidth(false);
}
@Test
public void getMaxPanelTransitionDistance_inSplitShade_withHeadsUp_returnsBiggerValue() {
enableSplitShade(true);
mNotificationPanelViewController.expandWithQs();
when(mHeadsUpManager.isTrackingHeadsUp()).thenReturn(true);
mNotificationPanelViewController.setHeadsUpDraggingStartingHeight(
SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
assertThat(mQsController.calculatePanelHeightExpanded(0))
.isGreaterThan(SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
}
@Test
public void setQsExpansion_lockscreenShadeTransitionInProgress_usesLockscreenSquishiness() {
float squishinessFraction = 0.456f;
mQsController.setQs(mQs);
when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
.thenReturn(squishinessFraction);
when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
.thenReturn(0.987f);
// Call setTransitionToFullShadeAmount to get into the full shade transition in progress
// state.
mLockscreenShadeTransitionCallback.setTransitionToFullShadeAmount(234, false, 0);
mQsController.setExpansionHeight(123);
// First for setTransitionToFullShadeAmount and then setQsExpansion
verify(mQs, times(2)).setQsExpansion(anyFloat(), anyFloat(), anyFloat(),
eq(squishinessFraction)
);
}
@Test
public void setQsExpansion_lockscreenShadeTransitionNotInProgress_usesStandardSquishiness() {
float lsSquishinessFraction = 0.456f;
float nsslSquishinessFraction = 0.987f;
mQsController.setQs(mQs);
when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
.thenReturn(lsSquishinessFraction);
when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
.thenReturn(nsslSquishinessFraction);
mQsController.setExpansionHeight(123);
verify(mQs).setQsExpansion(anyFloat(), anyFloat(), anyFloat(), eq(nsslSquishinessFraction)
);
}
@Test
public void shadeExpanded_onKeyguard() {
mStatusBarStateController.setState(KEYGUARD);
// set maxQsExpansion in NPVC
int maxQsExpansion = 123;
mQsController.setQs(mQs);
when(mQs.getDesiredHeight()).thenReturn(maxQsExpansion);
int oldMaxHeight = mQsController.updateHeightsOnShadeLayoutChange();
mQsController.handleShadeLayoutChanged(oldMaxHeight);
mQsController.setExpansionHeight(maxQsExpansion);
assertThat(mQsController.computeExpansionFraction()).isEqualTo(1f);
}
private static MotionEvent createMotionEvent(int x, int y, int action) {
return MotionEvent.obtain(
/* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0);
}
private void enableSplitShade(boolean enabled) {
when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(enabled);
mQsController.updateResources();
}
private void setIsFullWidth(boolean fullWidth) {
mQsController.setNotificationPanelFullWidth(fullWidth);
triggerLayoutChange();
}
private void triggerLayoutChange() {
int oldMaxHeight = mQsController.updateHeightsOnShadeLayoutChange();
mQsController.handleShadeLayoutChanged(oldMaxHeight);
}
}

View File

@@ -79,6 +79,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
@Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller
@Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller
@Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController
@Mock lateinit var transitionControllerCallback: LockscreenShadeTransitionController.Callback
@JvmField @Rule val mockito = MockitoJUnit.rule()
private val configurationController = FakeConfigurationController()
@@ -124,6 +125,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
},
qsTransitionControllerFactory = { qsTransitionController },
)
transitionController.addCallback(transitionControllerCallback)
whenever(nsslController.view).thenReturn(stackscroller)
whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
transitionController.notificationPanelController = notificationPanelController
@@ -258,7 +260,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat())
verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat())
verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
verify(notificationPanelController, never()).setTransitionToFullShadeAmount(anyFloat(),
verify(transitionControllerCallback, never()).setTransitionToFullShadeAmount(anyFloat(),
anyBoolean(), anyLong())
verify(qsTransitionController, never()).dragDownAmount = anyFloat()
}
@@ -269,7 +271,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
verify(nsslController).setTransitionToFullShadeAmount(anyFloat())
verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat())
verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
verify(notificationPanelController).setTransitionToFullShadeAmount(anyFloat(),
verify(transitionControllerCallback).setTransitionToFullShadeAmount(anyFloat(),
anyBoolean(), anyLong())
verify(qsTransitionController).dragDownAmount = 10f
verify(depthController).transitionToFullShadeProgress = anyFloat()

View File

@@ -46,6 +46,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.CameraLauncher;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
@@ -73,6 +74,7 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
@Mock private CentralSurfaces mCentralSurfaces;
@Mock private ShadeController mShadeController;
@Mock private CommandQueue mCommandQueue;
@Mock private QuickSettingsController mQuickSettingsController;
@Mock private NotificationPanelViewController mNotificationPanelViewController;
@Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
private final MetricsLogger mMetricsLogger = new FakeMetricsLogger();
@@ -101,6 +103,7 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
mSbcqCallbacks = new CentralSurfacesCommandQueueCallbacks(
mCentralSurfaces,
mQuickSettingsController,
mContext,
mContext.getResources(),
mShadeController,

View File

@@ -126,6 +126,7 @@ import com.android.systemui.shade.NotificationPanelView;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.NotificationShadeWindowViewController;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeControllerImpl;
import com.android.systemui.shade.ShadeExpansionStateManager;
@@ -218,6 +219,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
@Mock private HeadsUpManagerPhone mHeadsUpManager;
@Mock private NotificationPanelViewController mNotificationPanelViewController;
@Mock private NotificationPanelView mNotificationPanelView;
@Mock private QuickSettingsController mQuickSettingsController;
@Mock private IStatusBarService mBarService;
@Mock private IDreamManager mDreamManager;
@Mock private LightRevealScrimViewModel mLightRevealScrimViewModel;
@@ -546,6 +548,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
// initialized automatically and make NPVC private.
mCentralSurfaces.mNotificationShadeWindowView = mNotificationShadeWindowView;
mCentralSurfaces.mNotificationPanelViewController = mNotificationPanelViewController;
mCentralSurfaces.mQsController = mQuickSettingsController;
mCentralSurfaces.mDozeScrimController = mDozeScrimController;
mCentralSurfaces.mPresenter = mNotificationPresenter;
mCentralSurfaces.mKeyguardIndicationController = mKeyguardIndicationController;

View File

@@ -43,6 +43,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -112,6 +113,7 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(
mContext,
mock(NotificationPanelViewController.class),
mock(QuickSettingsController.class),
mock(HeadsUpManagerPhone.class),
notificationShadeWindowView,
mock(ActivityStarter.class),