Merge changes Iac617598,I59fe4951,I374dc97a,Id882cff6,Ie3b4c571, ... into sc-v2-dev am: 3708e854a9 am: cc04eee6d8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16072876

Change-Id: I81274479ffbb42ace85995c744a0cb5b1ba1a767
This commit is contained in:
TreeHugger Robot
2021-10-19 20:21:06 +00:00
committed by Automerger Merge Worker
11 changed files with 308 additions and 314 deletions

View File

@@ -1668,6 +1668,24 @@ public class NotificationPanelViewController extends PanelViewController {
mNotificationStackScrollLayoutController.resetScrollPosition();
}
/** Collapses the panel. */
public void collapsePanel(boolean animate, boolean delayed, float speedUpFactor) {
boolean waiting = false;
if (animate && !isFullyCollapsed()) {
collapse(delayed, speedUpFactor);
waiting = true;
} else {
resetViews(false /* animate */);
setExpandedFraction(0); // just in case
}
if (!waiting) {
// it's possible that nothing animated, so we replicate the termination
// conditions of panelExpansionChanged here
// TODO(b/200063118): This can likely go away in a future refactor CL.
mBar.updateState(STATE_CLOSED);
}
}
@Override
public void collapse(boolean delayed, float speedUpFactor) {
if (!canPanelBeCollapsed()) {
@@ -3118,7 +3136,7 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
protected void onExpandingFinished() {
super.onExpandingFinished();
mScrimController.onExpandingFinished();
mNotificationStackScrollLayoutController.onExpansionStopped();
mHeadsUpManager.onExpandingFinished();
mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed());
@@ -3193,6 +3211,7 @@ public class NotificationPanelViewController extends PanelViewController {
protected void onTrackingStarted() {
mFalsingCollector.onTrackingStarted(!mKeyguardStateController.canDismissLockScreen());
super.onTrackingStarted();
mScrimController.onTrackingStarted();
if (mQsFullyExpanded) {
mQsExpandImmediate = true;
if (!mShouldUseSplitNotificationShade) {
@@ -3203,6 +3222,7 @@ public class NotificationPanelViewController extends PanelViewController {
mAffordanceHelper.animateHideLeftRightIcon();
}
mNotificationStackScrollLayoutController.onPanelTrackingStarted();
cancelPendingPanelCollapse();
}
@Override
@@ -3392,7 +3412,7 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
protected void onClosingFinished() {
super.onClosingFinished();
mStatusBar.onClosingFinished();
setClosingWithAlphaFadeout(false);
mMediaHierarchyManager.closeGuts();
}
@@ -3823,13 +3843,27 @@ public class NotificationPanelViewController extends PanelViewController {
mNotificationStackScrollLayoutController.setScrollingEnabled(b);
}
private Runnable mHideExpandedRunnable;
private final Runnable mMaybeHideExpandedRunnable = new Runnable() {
@Override
public void run() {
if (getExpansionFraction() == 0.0f) {
mView.post(mHideExpandedRunnable);
}
}
};
/**
* Initialize objects instead of injecting to avoid circular dependencies.
*
* @param hideExpandedRunnable a runnable to run when we need to hide the expanded panel.
*/
public void initDependencies(
StatusBar statusBar,
Runnable hideExpandedRunnable,
NotificationShelfController notificationShelfController) {
setStatusBar(statusBar);
mHideExpandedRunnable = hideExpandedRunnable;
mNotificationStackScrollLayoutController.setShelfController(notificationShelfController);
mNotificationShelfController = notificationShelfController;
mLockscreenShadeTransitionController.bindController(notificationShelfController);
@@ -3885,6 +3919,45 @@ public class NotificationPanelViewController extends PanelViewController {
private long mLastTouchDownTime = -1L;
@Override
public boolean onTouchForwardedFromStatusBar(MotionEvent event) {
// TODO(b/202981994): Move the touch debugging in this method to a central location.
// (Right now, it's split between StatusBar and here.)
// If panels aren't enabled, ignore the gesture and don't pass it down to the
// panel view.
if (!mCommandQueue.panelsEnabled()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.v(
TAG,
String.format(
"onTouchForwardedFromStatusBar: "
+ "panel disabled, ignoring touch at (%d,%d)",
(int) event.getX(),
(int) event.getY()
)
);
}
return false;
}
// If the view that would receive the touch is disabled, just have status bar eat
// the gesture.
if (event.getAction() == MotionEvent.ACTION_DOWN && !mView.isEnabled()) {
Log.v(TAG,
String.format(
"onTouchForwardedFromStatusBar: "
+ "panel view disabled, eating touch at (%d,%d)",
(int) event.getX(),
(int) event.getY()
)
);
return true;
}
return mView.dispatchTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (mBlockTouches || mQs.disallowPanelTouches()) {
@@ -3896,7 +3969,7 @@ public class NotificationPanelViewController extends PanelViewController {
if (mStatusBar.isBouncerShowing()) {
return true;
}
if (mBar.panelEnabled()
if (mCommandQueue.panelsEnabled()
&& !mNotificationStackScrollLayoutController.isLongPressInProgress()
&& mHeadsUpTouchHelper.onInterceptTouchEvent(event)) {
mMetricsLogger.count(COUNTER_PANEL_OPEN, 1);
@@ -4754,6 +4827,11 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
/** Removes any pending runnables that would collapse the panel. */
public void cancelPendingPanelCollapse() {
mView.removeCallbacks(mMaybeHideExpandedRunnable);
}
private final PanelBar.PanelStateChangeListener mPanelStateChangeListener =
new PanelBar.PanelStateChangeListener() {
@@ -4768,6 +4846,14 @@ public class NotificationPanelViewController extends PanelViewController {
if (state == STATE_OPEN && mCurrentState != state) {
mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
if (state == STATE_OPENING) {
mStatusBar.makeExpandedVisible(false);
}
if (state == STATE_CLOSED) {
// Close the status bar in the next frame so we can show the end of the
// animation.
mView.post(mMaybeHideExpandedRunnable);
}
mCurrentState = state;
}
};
@@ -4775,4 +4861,10 @@ public class NotificationPanelViewController extends PanelViewController {
public PanelBar.PanelStateChangeListener getPanelStateChangeListener() {
return mPanelStateChangeListener;
}
/** Returns the handler that the status bar should forward touches to. */
public PhoneStatusBarView.TouchEventHandler getStatusBarTouchEventHandler() {
return getTouchHandler()::onTouchForwardedFromStatusBar;
}
}

View File

@@ -25,7 +25,6 @@ import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import androidx.annotation.Nullable;
@@ -53,11 +52,18 @@ public abstract class PanelBar extends FrameLayout {
public static final int STATE_OPENING = 1;
public static final int STATE_OPEN = 2;
private PanelViewController mPanel;
@Nullable private PanelStateChangeListener mPanelStateChangeListener;
private int mState = STATE_CLOSED;
private boolean mTracking;
/** Updates the panel state if necessary. */
public void updateState(@PanelState int state) {
if (DEBUG) LOG("update state: %d -> %d", mState, state);
if (mState != state) {
go(state);
}
}
private void go(@PanelState int state) {
if (DEBUG) LOG("go state: %d -> %d", mState, state);
mState = state;
@@ -97,54 +103,11 @@ public abstract class PanelBar extends FrameLayout {
super.onFinishInflate();
}
/** Set the PanelViewController */
public void setPanel(PanelViewController pv) {
mPanel = pv;
pv.setBar(this);
}
/** Sets the listener that will be notified of panel state changes. */
public void setPanelStateChangeListener(PanelStateChangeListener listener) {
mPanelStateChangeListener = listener;
}
public boolean panelEnabled() {
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Allow subclasses to implement enable/disable semantics
if (!panelEnabled()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)",
(int) event.getX(), (int) event.getY()));
}
return false;
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
final PanelViewController panel = mPanel;
if (panel == null) {
// panel is not there, so we'll eat the gesture
Log.v(TAG, String.format("onTouch: no panel for touch at (%d,%d)",
(int) event.getX(), (int) event.getY()));
return true;
}
boolean enabled = panel.isEnabled();
if (DEBUG) LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %s %s", mState, panel,
(enabled ? "" : " (disabled)"));
if (!enabled) {
// panel is disabled, so we'll eat the gesture
Log.v(TAG, String.format(
"onTouch: panel (%s) is disabled, ignoring touch at (%d,%d)",
panel, (int) event.getX(), (int) event.getY()));
return true;
}
}
return mPanel == null || mPanel.getView().dispatchTouchEvent(event);
}
/**
* @param frac the fraction from the expansion in [0, 1]
* @param expanded whether the panel is currently expanded; this is independent from the
@@ -162,7 +125,6 @@ public abstract class PanelBar extends FrameLayout {
if (expanded) {
if (mState == STATE_CLOSED) {
go(STATE_OPENING);
onPanelPeeked();
}
fullyClosed = false;
fullyOpened = frac >= 1f;
@@ -171,44 +133,16 @@ public abstract class PanelBar extends FrameLayout {
go(STATE_OPEN);
} else if (fullyClosed && !mTracking && mState != STATE_CLOSED) {
go(STATE_CLOSED);
onPanelCollapsed();
}
if (SPEW) LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
fullyOpened?" fullyOpened":"", fullyClosed?" fullyClosed":"");
}
public void collapsePanel(boolean animate, boolean delayed, float speedUpFactor) {
boolean waiting = false;
PanelViewController pv = mPanel;
if (animate && !pv.isFullyCollapsed()) {
pv.collapse(delayed, speedUpFactor);
waiting = true;
} else {
pv.resetViews(false /* animate */);
pv.setExpandedFraction(0); // just in case
}
if (DEBUG) LOG("collapsePanel: animate=%s waiting=%s", animate, waiting);
if (!waiting && mState != STATE_CLOSED) {
// it's possible that nothing animated, so we replicate the termination
// conditions of panelExpansionChanged here
go(STATE_CLOSED);
onPanelCollapsed();
}
}
public void onPanelPeeked() {
if (DEBUG) LOG("onPanelPeeked");
}
public boolean isClosed() {
return mState == STATE_CLOSED;
}
public void onPanelCollapsed() {
if (DEBUG) LOG("onPanelCollapsed");
}
public void onTrackingStarted() {
mTracking = true;
}
@@ -217,14 +151,6 @@ public abstract class PanelBar extends FrameLayout {
mTracking = false;
}
public void onExpandingFinished() {
if (DEBUG) LOG("onExpandingFinished");
}
public void onClosingFinished() {
}
/** An interface that will be notified of panel state changes. */
public interface PanelStateChangeListener {
/** Called when the state changes. */

View File

@@ -185,10 +185,9 @@ public abstract class PanelViewController {
protected final SysuiStatusBarStateController mStatusBarStateController;
protected final AmbientState mAmbientState;
protected final LockscreenGestureLogger mLockscreenGestureLogger;
private final TouchHandler mTouchHandler;
protected void onExpandingFinished() {
mBar.onExpandingFinished();
}
protected abstract void onExpandingFinished();
protected void onExpandingStarted() {
}
@@ -226,6 +225,7 @@ public abstract class PanelViewController {
mView = view;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mLockscreenGestureLogger = lockscreenGestureLogger;
mTouchHandler = createTouchHandler();
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
@@ -238,7 +238,7 @@ public abstract class PanelViewController {
});
mView.addOnLayoutChangeListener(createLayoutChangeListener());
mView.setOnTouchListener(createTouchHandler());
mView.setOnTouchListener(mTouchHandler);
mView.setOnConfigurationChangedListener(createOnConfigurationChangedListener());
mResources = mView.getResources();
@@ -289,6 +289,10 @@ public abstract class PanelViewController {
: mTouchSlop;
}
protected TouchHandler getTouchHandler() {
return mTouchHandler;
}
private void addMovement(MotionEvent event) {
// Add movement to velocity tracker using raw screen X and Y coordinates instead
// of window coordinates because the window frame may be moving at the same time.
@@ -448,6 +452,7 @@ public abstract class PanelViewController {
protected void onTrackingStopped(boolean expand) {
mTracking = false;
mBar.onTrackingStopped(expand);
mStatusBar.onTrackingStopped(expand);
updatePanelExpansionAndVisibility();
}
@@ -455,6 +460,7 @@ public abstract class PanelViewController {
endClosing();
mTracking = true;
mBar.onTrackingStarted();
mStatusBar.onTrackingStarted();
notifyExpandingStarted();
updatePanelExpansionAndVisibility();
}
@@ -927,10 +933,7 @@ public abstract class PanelViewController {
mView.removeCallbacks(mFlingCollapseRunnable);
}
protected void onClosingFinished() {
mBar.onClosingFinished();
}
protected abstract void onClosingFinished();
protected void startUnlockHintAnimation() {
@@ -1153,23 +1156,28 @@ public abstract class PanelViewController {
return mView;
}
public boolean isEnabled() {
return mView.isEnabled();
}
public OnLayoutChangeListener createLayoutChangeListener() {
return new OnLayoutChangeListener();
}
protected TouchHandler createTouchHandler() {
return new TouchHandler();
}
protected abstract TouchHandler createTouchHandler();
protected OnConfigurationChangedListener createOnConfigurationChangedListener() {
return new OnConfigurationChangedListener();
}
public class TouchHandler implements View.OnTouchListener {
public abstract class TouchHandler implements View.OnTouchListener {
/**
* Method called when a touch has occurred on {@link PhoneStatusBarView}.
*
* Touches that occur on the status bar view may have ramifications for the notification
* panel (e.g. a touch that pulls down the shade could start on the status bar), so we need
* to notify the panel controller when these touches occur.
*
* Returns true if the event was handled and false otherwise.
*/
public abstract boolean onTouchForwardedFromStatusBar(MotionEvent event);
public boolean onInterceptTouchEvent(MotionEvent event) {
if (mInstantExpanding || !mNotificationsDragEnabled || mTouchDisabled || (mMotionAborted
&& event.getActionMasked() != MotionEvent.ACTION_DOWN)) {
@@ -1435,4 +1443,8 @@ public abstract class PanelViewController {
private void cancelJankMonitoring(int cuj) {
InteractionJankMonitor.getInstance().cancel(cuj);
}
protected float getExpansionFraction() {
return mExpandedFraction;
}
}

View File

@@ -24,7 +24,6 @@ import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
import android.view.DisplayCutout;
@@ -37,7 +36,6 @@ import android.view.accessibility.AccessibilityEvent;
import android.widget.LinearLayout;
import com.android.systemui.Dependency;
import com.android.systemui.EventLogTags;
import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
@@ -55,14 +53,6 @@ public class PhoneStatusBarView extends PanelBar {
StatusBar mBar;
private ScrimController mScrimController;
private Runnable mHideExpandedRunnable = new Runnable() {
@Override
public void run() {
if (mPanelFraction == 0.0f) {
mBar.makeExpandedInvisible();
}
}
};
private DarkReceiver mBattery;
private DarkReceiver mClock;
private int mRotationOrientation = -1;
@@ -76,15 +66,12 @@ public class PhoneStatusBarView extends PanelBar {
@Nullable
private List<StatusBar.ExpansionChangedListener> mExpansionChangedListeners;
@Nullable
private PanelExpansionStateChangedListener mPanelExpansionStateChangedListener;
private PanelEnabledProvider mPanelEnabledProvider;
private TouchEventHandler mTouchEventHandler;
/**
* Draw this many pixels into the left/right side of the cutout to optimally use the space
*/
private int mCutoutSideNudge = 0;
private boolean mHeadsUpVisible;
public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -100,8 +87,8 @@ public class PhoneStatusBarView extends PanelBar {
mExpansionChangedListeners = listeners;
}
void setPanelExpansionStateChangedListener(PanelExpansionStateChangedListener listener) {
mPanelExpansionStateChangedListener = listener;
void setTouchEventHandler(TouchEventHandler handler) {
mTouchEventHandler = handler;
}
public void setScrimController(ScrimController scrimController) {
@@ -177,15 +164,6 @@ public class PhoneStatusBarView extends PanelBar {
return changed;
}
@Override
public boolean panelEnabled() {
if (mPanelEnabledProvider == null) {
Log.e(TAG, "panelEnabledProvider is null; defaulting to super class.");
return super.panelEnabled();
}
return mPanelEnabledProvider.panelEnabled();
}
@Override
public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
if (super.onRequestSendAccessibilityEventInternal(child, event)) {
@@ -201,80 +179,32 @@ public class PhoneStatusBarView extends PanelBar {
return false;
}
@Override
public void onPanelPeeked() {
super.onPanelPeeked();
mBar.makeExpandedVisible(false);
}
@Override
public void onPanelCollapsed() {
super.onPanelCollapsed();
// Close the status bar in the next frame so we can show the end of the animation.
post(mHideExpandedRunnable);
}
public void removePendingHideExpandedRunnables() {
removeCallbacks(mHideExpandedRunnable);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean barConsumedEvent = mBar.interceptTouchEvent(event);
if (DEBUG_GESTURES) {
if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
EventLog.writeEvent(EventLogTags.SYSUI_PANELBAR_TOUCH,
event.getActionMasked(), (int) event.getX(), (int) event.getY(),
barConsumedEvent ? 1 : 0);
}
mBar.onTouchEvent(event);
if (mTouchEventHandler == null) {
Log.w(
TAG,
String.format(
"onTouch: No touch handler provided; eating gesture at (%d,%d)",
(int) event.getX(),
(int) event.getY()
)
);
return true;
}
return barConsumedEvent || super.onTouchEvent(event);
}
@Override
public void onTrackingStarted() {
super.onTrackingStarted();
mBar.onTrackingStarted();
mScrimController.onTrackingStarted();
removePendingHideExpandedRunnables();
}
@Override
public void onClosingFinished() {
super.onClosingFinished();
mBar.onClosingFinished();
}
@Override
public void onTrackingStopped(boolean expand) {
super.onTrackingStopped(expand);
mBar.onTrackingStopped(expand);
}
@Override
public void onExpandingFinished() {
super.onExpandingFinished();
mScrimController.onExpandingFinished();
return mTouchEventHandler.handleTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return mBar.interceptTouchEvent(event) || super.onInterceptTouchEvent(event);
mBar.onTouchEvent(event);
return super.onInterceptTouchEvent(event);
}
@Override
public void panelExpansionChanged(float frac, boolean expanded) {
super.panelExpansionChanged(frac, expanded);
if ((frac == 0 || frac == 1)) {
if (mPanelExpansionStateChangedListener != null) {
mPanelExpansionStateChangedListener.onPanelExpansionStateChanged();
} else {
Log.w(TAG, "No PanelExpansionStateChangedListener provided.");
}
}
if (mExpansionChangedListeners != null) {
for (StatusBar.ExpansionChangedListener listener : mExpansionChangedListeners) {
listener.onExpansionChanged(frac, expanded);
@@ -282,11 +212,6 @@ public class PhoneStatusBarView extends PanelBar {
}
}
/** Set the {@link PanelEnabledProvider} to use. */
public void setPanelEnabledProvider(PanelEnabledProvider panelEnabledProvider) {
mPanelEnabledProvider = panelEnabledProvider;
}
public void updateResources() {
mCutoutSideNudge = getResources().getDimensionPixelSize(
R.dimen.display_cutout_margin_consumption);
@@ -366,15 +291,14 @@ public class PhoneStatusBarView extends PanelBar {
getPaddingBottom());
}
/** An interface that will provide whether panel is enabled. */
interface PanelEnabledProvider {
/** Returns true if the panel is enabled and false otherwise. */
boolean panelEnabled();
}
/** A listener that will be notified when a panel's expansion state may have changed. */
public interface PanelExpansionStateChangedListener {
/** Called when a panel's expansion state may have changed. */
void onPanelExpansionStateChanged();
/**
* A handler repsonsible for all touch event handling on the status bar.
*
* The handler will be notified each time {@link this#onTouchEvent} is called, and the return
* value from the handler will be returned from {@link this#onTouchEvent}.
**/
public interface TouchEventHandler {
/** Called each time {@link this#onTouchEvent} is called. */
boolean handleTouchEvent(MotionEvent event);
}
}

View File

@@ -26,19 +26,15 @@ import com.android.systemui.util.ViewController
/** Controller for [PhoneStatusBarView]. */
class PhoneStatusBarViewController(
view: PhoneStatusBarView,
commandQueue: CommandQueue,
statusBarMoveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
panelExpansionStateChangedListener: PhoneStatusBarView.PanelExpansionStateChangedListener,
touchEventHandler: PhoneStatusBarView.TouchEventHandler,
) : ViewController<PhoneStatusBarView>(view) {
override fun onViewAttached() {}
override fun onViewDetached() {}
init {
mView.setPanelEnabledProvider {
commandQueue.panelsEnabled()
}
mView.setPanelExpansionStateChangedListener(panelExpansionStateChangedListener)
mView.setTouchEventHandler(touchEventHandler)
statusBarMoveFromCenterAnimationController?.let { animationController ->
val statusBarLeftSide: View = mView.findViewById(R.id.status_bar_left_side)

View File

@@ -128,7 +128,8 @@ public class ShadeControllerImpl implements ShadeController {
mNotificationShadeWindowController.setNotificationShadeFocusable(false);
getStatusBar().getNotificationShadeWindowViewController().cancelExpandHelper();
getStatusBarView().collapsePanel(true /* animate */, delayed, speedUpFactor);
getNotificationPanelViewController()
.collapsePanel(true /* animate */, delayed, speedUpFactor);
} else if (mBubblesOptional.isPresent()) {
mBubblesOptional.get().collapseStack();
}

View File

@@ -902,6 +902,7 @@ public class StatusBar extends SystemUI implements
mExpansionChangedListeners = new ArrayList<>();
addExpansionChangedListener(
(expansion, expanded) -> mScrimController.setRawPanelExpansionFraction(expansion));
addExpansionChangedListener(this::onPanelExpansionChanged);
mBubbleExpandListener =
(isExpanding, key) -> mContext.getMainExecutor().execute(() -> {
@@ -1167,7 +1168,6 @@ public class StatusBar extends SystemUI implements
PhoneStatusBarView oldStatusBarView = mStatusBarView;
mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView();
mStatusBarView.setBar(this);
mStatusBarView.setPanel(mNotificationPanelViewController);
mStatusBarView.setPanelStateChangeListener(
mNotificationPanelViewController.getPanelStateChangeListener());
mStatusBarView.setScrimController(mScrimController);
@@ -1176,6 +1176,8 @@ public class StatusBar extends SystemUI implements
sendInitialExpansionAmount(listener);
}
mNotificationPanelViewController.setBar(mStatusBarView);
StatusBarMoveFromCenterAnimationController moveFromCenterAnimation = null;
if (mUnfoldTransitionConfig.isEnabled()) {
moveFromCenterAnimation = mMoveFromCenterAnimation.get();
@@ -1183,9 +1185,9 @@ public class StatusBar extends SystemUI implements
mPhoneStatusBarViewController =
new PhoneStatusBarViewController(
mStatusBarView,
mCommandQueue,
moveFromCenterAnimation,
this::onPanelExpansionStateChanged);
mNotificationPanelViewController.getStatusBarTouchEventHandler()
);
mPhoneStatusBarViewController.init();
mBatteryMeterViewController = new BatteryMeterViewController(
@@ -1316,6 +1318,7 @@ public class StatusBar extends SystemUI implements
mNotificationPanelViewController.initDependencies(
this,
this::makeExpandedInvisible,
mNotificationShelfController);
BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
@@ -1453,12 +1456,14 @@ public class StatusBar extends SystemUI implements
}
}
private void onPanelExpansionStateChanged() {
if (getNavigationBarView() != null) {
getNavigationBarView().onStatusBarPanelStateChanged();
}
if (getNotificationPanelViewController() != null) {
getNotificationPanelViewController().updateSystemUiStateFlags();
private void onPanelExpansionChanged(float frac, boolean expanded) {
if (frac == 0 || frac == 1) {
if (getNavigationBarView() != null) {
getNavigationBarView().onStatusBarPanelStateChanged();
}
if (getNotificationPanelViewController() != null) {
getNotificationPanelViewController().updateSystemUiStateFlags();
}
}
}
@@ -2157,7 +2162,8 @@ public class StatusBar extends SystemUI implements
public void animateCollapseQuickSettings() {
if (mState == StatusBarState.SHADE) {
mStatusBarView.collapsePanel(true, false /* delayed */, 1.0f /* speedUpFactor */);
mNotificationPanelViewController.collapsePanel(
true, false /* delayed */, 1.0f /* speedUpFactor */);
}
}
@@ -2170,7 +2176,7 @@ public class StatusBar extends SystemUI implements
}
// Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/,
mNotificationPanelViewController.collapsePanel(/*animate=*/ false, false /* delayed*/,
1.0f /* speedUpFactor */);
mNotificationPanelViewController.closeQs();
@@ -2204,7 +2210,10 @@ public class StatusBar extends SystemUI implements
}
}
public boolean interceptTouchEvent(MotionEvent event) {
/** Called when a touch event occurred on {@link PhoneStatusBarView}. */
public void onTouchEvent(MotionEvent event) {
// TODO(b/202981994): Move this touch debugging to a central location. (Right now, it's
// split between NotificationPanelViewController and here.)
if (DEBUG_GESTURES) {
if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
@@ -2236,7 +2245,6 @@ public class StatusBar extends SystemUI implements
event.getAction() == MotionEvent.ACTION_CANCEL;
setInteracting(StatusBarManager.WINDOW_STATUS_BAR, !upOrCancel || mExpandedVisible);
}
return false;
}
boolean isSameStatusBarState(int state) {
@@ -4464,7 +4472,7 @@ public class StatusBar extends SystemUI implements
mNavigationBarController.touchAutoDim(mDisplayId);
Trace.beginSection("StatusBar#updateKeyguardState");
if (mState == StatusBarState.KEYGUARD && mStatusBarView != null) {
mStatusBarView.removePendingHideExpandedRunnables();
mNotificationPanelViewController.cancelPendingPanelCollapse();
}
updateDozingState();
checkBarModes();

View File

@@ -536,7 +536,7 @@ public class StatusBarCommandQueueCallbacks implements CommandQueue.Callbacks {
}
if (mStatusBar.getStatusBarView() != null) {
if (!showing && mStatusBarStateController.getState() == StatusBarState.SHADE) {
mStatusBar.getStatusBarView().collapsePanel(
mNotificationPanelViewController.collapsePanel(
false /* animate */, false /* delayed */, 1.0f /* speedUpFactor */);
}

View File

@@ -517,6 +517,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
mControlsComponent);
mNotificationPanelViewController.initDependencies(
mStatusBar,
() -> {},
mNotificationShelfController);
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
mNotificationPanelViewController.setBar(mPanelBar);
@@ -584,6 +585,51 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
assertThat(mNotificationPanelViewController.isTrackingBlocked()).isFalse();
}
@Test
public void onTouchForwardedFromStatusBar_panelsNotEnabled_returnsFalseAndNoViewEvent() {
when(mCommandQueue.panelsEnabled()).thenReturn(false);
boolean returnVal = mTouchHandler.onTouchForwardedFromStatusBar(
MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0));
assertThat(returnVal).isFalse();
verify(mView, never()).dispatchTouchEvent(any());
}
@Test
public void onTouchForwardedFromStatusBar_viewNotEnabled_returnsTrueAndNoViewEvent() {
when(mCommandQueue.panelsEnabled()).thenReturn(true);
when(mView.isEnabled()).thenReturn(false);
boolean returnVal = mTouchHandler.onTouchForwardedFromStatusBar(
MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0));
assertThat(returnVal).isTrue();
verify(mView, never()).dispatchTouchEvent(any());
}
@Test
public void onTouchForwardedFromStatusBar_viewNotEnabledButIsMoveEvent_viewReceivesEvent() {
when(mCommandQueue.panelsEnabled()).thenReturn(true);
when(mView.isEnabled()).thenReturn(false);
MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0);
mTouchHandler.onTouchForwardedFromStatusBar(event);
verify(mView).dispatchTouchEvent(event);
}
@Test
public void onTouchForwardedFromStatusBar_panelAndViewEnabled_viewReceivesEvent() {
when(mCommandQueue.panelsEnabled()).thenReturn(true);
when(mView.isEnabled()).thenReturn(true);
MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0);
mTouchHandler.onTouchForwardedFromStatusBar(event);
verify(mView).dispatchTouchEvent(event);
}
@Test
public void testA11y_initializeNode() {
AccessibilityNodeInfo nodeInfo = new AccessibilityNodeInfo();

View File

@@ -17,13 +17,13 @@
package com.android.systemui.statusbar.phone
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.util.mockito.any
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -31,15 +31,14 @@ import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.verify
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
@SmallTest
class PhoneStatusBarViewControllerTest : SysuiTestCase() {
private val stateChangeListener = TestStateChangedListener()
private val touchEventHandler = TestTouchEventHandler()
@Mock
private lateinit var commandQueue: CommandQueue
@Mock
private lateinit var panelViewController: PanelViewController
@Mock
@@ -63,58 +62,41 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
val parent = FrameLayout(mContext) // add parent to keep layout params
view = LayoutInflater.from(mContext)
.inflate(R.layout.status_bar, parent, false) as PhoneStatusBarView
view.setPanel(panelViewController)
view.setScrimController(scrimController)
view.setBar(mock(StatusBar::class.java))
}
controller = PhoneStatusBarViewController(
view,
commandQueue,
null,
stateChangeListener
touchEventHandler,
)
}
@Test
fun constructor_setsPanelEnabledProviderOnView() {
var providerUsed = false
`when`(commandQueue.panelsEnabled()).then {
providerUsed = true
true
}
fun constructor_setsTouchHandlerOnView() {
val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
// If the constructor correctly set a [PanelEnabledProvider], then it should be used
// when [PhoneStatusBarView.panelEnabled] is called.
view.panelEnabled()
view.onTouchEvent(event)
assertThat(providerUsed).isTrue()
assertThat(touchEventHandler.lastEvent).isEqualTo(event)
}
@Test
fun constructor_moveFromCenterAnimationIsNotNull_moveFromCenterAnimationInitialized() {
controller = PhoneStatusBarViewController(
view, commandQueue, moveFromCenterAnimation, stateChangeListener
view, moveFromCenterAnimation, touchEventHandler
)
verify(moveFromCenterAnimation).init(any(), any())
}
@Test
fun constructor_setsExpansionStateChangedListenerOnView() {
assertThat(stateChangeListener.stateChangeCalled).isFalse()
// If the constructor correctly set the listener, then it should be used when
// [PhoneStatusBarView.panelExpansionChanged] is called.
view.panelExpansionChanged(0f, false)
assertThat(stateChangeListener.stateChangeCalled).isTrue()
}
private class TestStateChangedListener : PhoneStatusBarView.PanelExpansionStateChangedListener {
var stateChangeCalled: Boolean = false
override fun onPanelExpansionStateChanged() {
stateChangeCalled = true
private class TestTouchEventHandler : PhoneStatusBarView.TouchEventHandler {
var lastEvent: MotionEvent? = null
override fun handleTouchEvent(event: MotionEvent?): Boolean {
lastEvent = event
return false
}
}
}

View File

@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone
import android.view.MotionEvent
import android.view.ViewGroup
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -48,63 +49,25 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
`when`(panelViewController.view).thenReturn(panelView)
view = PhoneStatusBarView(mContext, null)
view.setPanel(panelViewController)
view.setScrimController(scrimController)
view.setBar(statusBar)
}
@Test
fun panelEnabled_providerReturnsTrue_returnsTrue() {
view.setPanelEnabledProvider { true }
fun panelExpansionChanged_expansionChangeListenerNotified() {
val listener = TestExpansionChangedListener()
view.setExpansionChangedListeners(listOf(listener))
val fraction = 0.4f
val isExpanded = true
assertThat(view.panelEnabled()).isTrue()
view.panelExpansionChanged(fraction, isExpanded)
assertThat(listener.fraction).isEqualTo(fraction)
assertThat(listener.isExpanded).isEqualTo(isExpanded)
}
@Test
fun panelEnabled_providerReturnsFalse_returnsFalse() {
view.setPanelEnabledProvider { false }
assertThat(view.panelEnabled()).isFalse()
}
@Test
fun panelEnabled_noProvider_noCrash() {
view.panelEnabled()
// No assert needed, just testing no crash
}
@Test
fun panelExpansionChanged_fracZero_stateChangeListenerNotified() {
val listener = TestExpansionStateChangedListener()
view.setPanelExpansionStateChangedListener(listener)
view.panelExpansionChanged(0f, false)
assertThat(listener.stateChangeCalled).isTrue()
}
@Test
fun panelExpansionChanged_fracOne_stateChangeListenerNotified() {
val listener = TestExpansionStateChangedListener()
view.setPanelExpansionStateChangedListener(listener)
view.panelExpansionChanged(1f, false)
assertThat(listener.stateChangeCalled).isTrue()
}
@Test
fun panelExpansionChanged_fracHalf_stateChangeListenerNotNotified() {
val listener = TestExpansionStateChangedListener()
view.setPanelExpansionStateChangedListener(listener)
view.panelExpansionChanged(0.5f, false)
assertThat(listener.stateChangeCalled).isFalse()
}
@Test
fun panelExpansionChanged_noStateChangeListener_noCrash() {
fun panelExpansionChanged_noListeners_noCrash() {
view.panelExpansionChanged(1f, false)
// No assert needed, just testing no crash
}
@@ -144,17 +107,52 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
}
@Test
fun panelStateChanged_noListener_noCrash() {
view.panelExpansionChanged(1f, true)
fun onTouchEvent_listenerNotified() {
val handler = TestTouchEventHandler()
view.setTouchEventHandler(handler)
val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
view.onTouchEvent(event)
assertThat(handler.lastEvent).isEqualTo(event)
}
@Test
fun onTouchEvent_listenerReturnsTrue_viewReturnsTrue() {
val handler = TestTouchEventHandler()
view.setTouchEventHandler(handler)
val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
handler.returnValue = true
assertThat(view.onTouchEvent(event)).isTrue()
}
@Test
fun onTouchEvent_listenerReturnsFalse_viewReturnsFalse() {
val handler = TestTouchEventHandler()
view.setTouchEventHandler(handler)
val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
handler.returnValue = false
assertThat(view.onTouchEvent(event)).isFalse()
}
@Test
fun onTouchEvent_noListener_noCrash() {
view.onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0))
// No assert needed, just testing no crash
}
private class TestExpansionStateChangedListener
: PhoneStatusBarView.PanelExpansionStateChangedListener {
var stateChangeCalled: Boolean = false
private class TestExpansionChangedListener
: StatusBar.ExpansionChangedListener {
var fraction: Float = 0f
var isExpanded: Boolean = false
override fun onPanelExpansionStateChanged() {
stateChangeCalled = true
override fun onExpansionChanged(expansion: Float, expanded: Boolean) {
this.fraction = expansion
this.isExpanded = expanded
}
}
@@ -164,4 +162,13 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
this.state = state
}
}
private class TestTouchEventHandler : PhoneStatusBarView.TouchEventHandler {
var lastEvent: MotionEvent? = null
var returnValue: Boolean = false
override fun handleTouchEvent(event: MotionEvent?): Boolean {
lastEvent = event
return returnValue
}
}
}