Merge "[Status Bar Refactor] 3/N: Move PanelBar#onPanelExpansionChanged into PanelExpansionStateManager." into sc-v2-dev am: 19444c3a47
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16102500 Change-Id: Ib894a517c659887457a3dd82e366a491e695f2e4
This commit is contained in:
@@ -63,13 +63,13 @@ abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
mPanelExpansionStateManager.addListener(mPanelExpansionListener);
|
||||
mPanelExpansionStateManager.addExpansionListener(mPanelExpansionListener);
|
||||
mDumpManger.registerDumpable(getDumpTag(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
mPanelExpansionStateManager.removeListener(mPanelExpansionListener);
|
||||
mPanelExpansionStateManager.removeExpansionListener(mPanelExpansionListener);
|
||||
mDumpManger.unregisterDumpable(getDumpTag());
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
|
||||
mInputBouncerHiddenAmount = KeyguardBouncer.EXPANSION_HIDDEN;
|
||||
mIsBouncerVisible = mKeyguardViewManager.bouncerIsOrWillBeShowing();
|
||||
mConfigurationController.addCallback(mConfigurationListener);
|
||||
mPanelExpansionStateManager.addListener(mPanelExpansionListener);
|
||||
mPanelExpansionStateManager.addExpansionListener(mPanelExpansionListener);
|
||||
updateAlpha();
|
||||
updatePauseAuth();
|
||||
|
||||
@@ -145,7 +145,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
|
||||
mKeyguardViewManager.removeAlternateAuthInterceptor(mAlternateAuthInterceptor);
|
||||
mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false);
|
||||
mConfigurationController.removeCallback(mConfigurationListener);
|
||||
mPanelExpansionStateManager.removeListener(mPanelExpansionListener);
|
||||
mPanelExpansionStateManager.removeExpansionListener(mPanelExpansionListener);
|
||||
if (mLockScreenShadeTransitionController.getUdfpsKeyguardViewController() == this) {
|
||||
mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(null);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
|
||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
|
||||
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
|
||||
import com.android.systemui.statusbar.policy.EncryptionHelper;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
@@ -101,6 +102,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
||||
private final StatusBarLocationPublisher mLocationPublisher;
|
||||
private final FeatureFlags mFeatureFlags;
|
||||
private final NotificationIconAreaController mNotificationIconAreaController;
|
||||
private final PanelExpansionStateManager mPanelExpansionStateManager;
|
||||
private final StatusBarIconController mStatusBarIconController;
|
||||
|
||||
private List<String> mBlockedIcons = new ArrayList<>();
|
||||
@@ -126,6 +128,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
||||
SystemStatusAnimationScheduler animationScheduler,
|
||||
StatusBarLocationPublisher locationPublisher,
|
||||
NotificationIconAreaController notificationIconAreaController,
|
||||
PanelExpansionStateManager panelExpansionStateManager,
|
||||
FeatureFlags featureFlags,
|
||||
Lazy<Optional<StatusBar>> statusBarOptionalLazy,
|
||||
StatusBarIconController statusBarIconController,
|
||||
@@ -140,6 +143,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
||||
mAnimationScheduler = animationScheduler;
|
||||
mLocationPublisher = locationPublisher;
|
||||
mNotificationIconAreaController = notificationIconAreaController;
|
||||
mPanelExpansionStateManager = panelExpansionStateManager;
|
||||
mFeatureFlags = featureFlags;
|
||||
mStatusBarOptionalLazy = statusBarOptionalLazy;
|
||||
mStatusBarIconController = statusBarIconController;
|
||||
@@ -363,7 +367,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
||||
|
||||
private boolean shouldHideNotificationIcons() {
|
||||
final Optional<StatusBar> statusBarOptional = mStatusBarOptionalLazy.get();
|
||||
if (!mStatusBar.isClosed()
|
||||
if (!mPanelExpansionStateManager.isClosed()
|
||||
&& statusBarOptional.map(
|
||||
StatusBar::hideStatusBarIconsWhenExpanded).orElse(false)) {
|
||||
return true;
|
||||
@@ -409,7 +413,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
||||
* don't set the clock GONE otherwise it'll mess up the animation.
|
||||
*/
|
||||
private int clockHiddenMode() {
|
||||
if (!mStatusBar.isClosed() && !mKeyguardStateController.isShowing()
|
||||
if (!mPanelExpansionStateManager.isClosed() && !mKeyguardStateController.isShowing()
|
||||
&& !mStatusBarStateController.isDozing()) {
|
||||
return View.INVISIBLE;
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
|
||||
import static com.android.systemui.statusbar.StatusBarState.SHADE;
|
||||
import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
|
||||
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
|
||||
import static com.android.systemui.statusbar.phone.PanelBar.STATE_CLOSED;
|
||||
import static com.android.systemui.statusbar.phone.PanelBar.STATE_OPEN;
|
||||
import static com.android.systemui.statusbar.phone.PanelBar.STATE_OPENING;
|
||||
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED;
|
||||
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPEN;
|
||||
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPENING;
|
||||
|
||||
import static java.lang.Float.isNaN;
|
||||
|
||||
@@ -173,6 +173,7 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
|
||||
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
|
||||
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
|
||||
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
|
||||
import com.android.systemui.statusbar.phone.panelstate.PanelState;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
@@ -782,6 +783,8 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
new DynamicPrivacyControlListener();
|
||||
dynamicPrivacyController.addListener(dynamicPrivacyControlListener);
|
||||
|
||||
panelExpansionStateManager.addStateListener(this::onPanelStateChanged);
|
||||
|
||||
mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0);
|
||||
mBottomAreaShadeAlphaAnimator.addUpdateListener(animation -> {
|
||||
mBottomAreaShadeAlpha = (float) animation.getAnimatedValue();
|
||||
@@ -1561,7 +1564,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
// 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);
|
||||
getPanelExpansionStateManager().updateState(STATE_CLOSED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1646,7 +1649,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
|
||||
@Override
|
||||
public void fling(float vel, boolean expand) {
|
||||
GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder();
|
||||
GestureRecorder gr = mStatusBar.getGestureRecorder();
|
||||
if (gr != null) {
|
||||
gr.tag("fling " + ((vel > 0) ? "open" : "closed"), "notifications,v=" + vel);
|
||||
}
|
||||
@@ -4672,37 +4675,27 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
mView.removeCallbacks(mMaybeHideExpandedRunnable);
|
||||
}
|
||||
|
||||
private final PanelBar.PanelStateChangeListener mPanelStateChangeListener =
|
||||
new PanelBar.PanelStateChangeListener() {
|
||||
@PanelState
|
||||
private int mCurrentPanelState = STATE_CLOSED;
|
||||
|
||||
@PanelBar.PanelState
|
||||
private int mCurrentState = STATE_CLOSED;
|
||||
private void onPanelStateChanged(@PanelState int state) {
|
||||
mAmbientState.setIsShadeOpening(state == STATE_OPENING);
|
||||
updateQSExpansionEnabledAmbient();
|
||||
|
||||
@Override
|
||||
public void onStateChanged(@PanelBar.PanelState int state) {
|
||||
mAmbientState.setIsShadeOpening(state == STATE_OPENING);
|
||||
updateQSExpansionEnabledAmbient();
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
public PanelBar.PanelStateChangeListener getPanelStateChangeListener() {
|
||||
return mPanelStateChangeListener;
|
||||
if (state == STATE_OPEN && mCurrentPanelState != 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);
|
||||
}
|
||||
mCurrentPanelState = state;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the handler that the status bar should forward touches to. */
|
||||
public PhoneStatusBarView.TouchEventHandler getStatusBarTouchEventHandler() {
|
||||
return getTouchHandler()::onTouchForwardedFromStatusBar;
|
||||
|
||||
@@ -447,7 +447,7 @@ public class NotificationShadeWindowViewController {
|
||||
setDragDownHelper(mLockscreenShadeTransitionController.getTouchHelper());
|
||||
|
||||
mDepthController.setRoot(mView);
|
||||
mPanelExpansionStateManager.addListener(mDepthController);
|
||||
mPanelExpansionStateManager.addExpansionListener(mDepthController);
|
||||
}
|
||||
|
||||
public NotificationShadeWindowView getView() {
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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.statusbar.phone;
|
||||
|
||||
import static java.lang.Float.isNaN;
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
public abstract class PanelBar extends FrameLayout {
|
||||
public static final boolean DEBUG = false;
|
||||
public static final String TAG = PanelBar.class.getSimpleName();
|
||||
private static final boolean SPEW = false;
|
||||
private static final String PANEL_BAR_SUPER_PARCELABLE = "panel_bar_super_parcelable";
|
||||
private static final String STATE = "state";
|
||||
protected float mPanelFraction;
|
||||
|
||||
public static final void LOG(String fmt, Object... args) {
|
||||
if (!DEBUG) return;
|
||||
Log.v(TAG, String.format(fmt, args));
|
||||
}
|
||||
|
||||
/** Enum for the current state of the panel. */
|
||||
@Retention(SOURCE)
|
||||
@IntDef({STATE_CLOSED, STATE_OPENING, STATE_OPEN})
|
||||
@interface PanelState {}
|
||||
public static final int STATE_CLOSED = 0;
|
||||
public static final int STATE_OPENING = 1;
|
||||
public static final int STATE_OPEN = 2;
|
||||
|
||||
@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;
|
||||
if (mPanelStateChangeListener != null) {
|
||||
mPanelStateChangeListener.onStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Parcelable onSaveInstanceState() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(PANEL_BAR_SUPER_PARCELABLE, super.onSaveInstanceState());
|
||||
bundle.putInt(STATE, mState);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Parcelable state) {
|
||||
if (state == null || !(state instanceof Bundle)) {
|
||||
super.onRestoreInstanceState(state);
|
||||
return;
|
||||
}
|
||||
|
||||
Bundle bundle = (Bundle) state;
|
||||
super.onRestoreInstanceState(bundle.getParcelable(PANEL_BAR_SUPER_PARCELABLE));
|
||||
if (((Bundle) state).containsKey(STATE)) {
|
||||
go(bundle.getInt(STATE, STATE_CLOSED));
|
||||
}
|
||||
}
|
||||
|
||||
public PanelBar(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
}
|
||||
|
||||
/** Sets the listener that will be notified of panel state changes. */
|
||||
public void setPanelStateChangeListener(PanelStateChangeListener listener) {
|
||||
mPanelStateChangeListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param frac the fraction from the expansion in [0, 1]
|
||||
* @param expanded whether the panel is currently expanded; this is independent from the
|
||||
* fraction as the panel also might be expanded if the fraction is 0
|
||||
*/
|
||||
public void panelExpansionChanged(float frac, boolean expanded) {
|
||||
if (isNaN(frac)) {
|
||||
throw new IllegalArgumentException("frac cannot be NaN");
|
||||
}
|
||||
boolean fullyClosed = true;
|
||||
boolean fullyOpened = false;
|
||||
if (SPEW) LOG("panelExpansionChanged: start state=%d, f=%.1f", mState, frac);
|
||||
mPanelFraction = frac;
|
||||
// adjust any other panels that may be partially visible
|
||||
if (expanded) {
|
||||
if (mState == STATE_CLOSED) {
|
||||
go(STATE_OPENING);
|
||||
}
|
||||
fullyClosed = false;
|
||||
fullyOpened = frac >= 1f;
|
||||
}
|
||||
if (fullyOpened && !mTracking) {
|
||||
go(STATE_OPEN);
|
||||
} else if (fullyClosed && !mTracking && mState != STATE_CLOSED) {
|
||||
go(STATE_CLOSED);
|
||||
}
|
||||
|
||||
if (SPEW) LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
|
||||
fullyOpened?" fullyOpened":"", fullyClosed?" fullyClosed":"");
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return mState == STATE_CLOSED;
|
||||
}
|
||||
|
||||
public void onTrackingStarted() {
|
||||
mTracking = true;
|
||||
}
|
||||
|
||||
public void onTrackingStopped(boolean expand) {
|
||||
mTracking = false;
|
||||
}
|
||||
|
||||
/** An interface that will be notified of panel state changes. */
|
||||
public interface PanelStateChangeListener {
|
||||
/** Called when the state changes. */
|
||||
void onStateChanged(@PanelState int state);
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
public abstract class PanelView extends FrameLayout {
|
||||
public static final boolean DEBUG = PanelBar.DEBUG;
|
||||
public static final boolean DEBUG = false;
|
||||
public static final String TAG = PanelView.class.getSimpleName();
|
||||
private PanelViewController.TouchHandler mTouchHandler;
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public abstract class PanelViewController {
|
||||
public static final boolean DEBUG = PanelBar.DEBUG;
|
||||
public static final boolean DEBUG = PanelView.DEBUG;
|
||||
public static final String TAG = PanelView.class.getSimpleName();
|
||||
private static final int NO_FIXED_DURATION = -1;
|
||||
private static final long SHADE_OPEN_SPRING_OUT_DURATION = 350L;
|
||||
@@ -153,8 +153,6 @@ public abstract class PanelViewController {
|
||||
private boolean mAnimateAfterExpanding;
|
||||
private boolean mIsFlinging;
|
||||
|
||||
PanelBar mBar;
|
||||
|
||||
private String mViewName;
|
||||
private float mInitialTouchY;
|
||||
private float mInitialTouchX;
|
||||
@@ -462,7 +460,6 @@ public abstract class PanelViewController {
|
||||
|
||||
protected void onTrackingStopped(boolean expand) {
|
||||
mTracking = false;
|
||||
mBar.onTrackingStopped(expand);
|
||||
mStatusBar.onTrackingStopped(expand);
|
||||
updatePanelExpansionAndVisibility();
|
||||
}
|
||||
@@ -470,7 +467,6 @@ public abstract class PanelViewController {
|
||||
protected void onTrackingStarted() {
|
||||
endClosing();
|
||||
mTracking = true;
|
||||
mBar.onTrackingStarted();
|
||||
mStatusBar.onTrackingStarted();
|
||||
notifyExpandingStarted();
|
||||
updatePanelExpansionAndVisibility();
|
||||
@@ -848,10 +844,6 @@ public abstract class PanelViewController {
|
||||
return mTracking;
|
||||
}
|
||||
|
||||
public void setBar(PanelBar panelBar) {
|
||||
mBar = panelBar;
|
||||
}
|
||||
|
||||
public void collapse(boolean delayed, float speedUpFactor) {
|
||||
if (DEBUG) logf("collapse: " + this);
|
||||
if (canPanelBeCollapsed()) {
|
||||
@@ -1089,12 +1081,9 @@ public abstract class PanelViewController {
|
||||
* {@link #updateVisibility()}? That would allow us to make this method private.
|
||||
*/
|
||||
public void updatePanelExpansionAndVisibility() {
|
||||
if (mBar != null) {
|
||||
mBar.panelExpansionChanged(mExpandedFraction, isExpanded());
|
||||
}
|
||||
updateVisibility();
|
||||
mPanelExpansionStateManager.onPanelExpansionChanged(
|
||||
mExpandedFraction, isExpanded(), mTracking);
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
public boolean isExpanded() {
|
||||
@@ -1453,4 +1442,8 @@ public abstract class PanelViewController {
|
||||
protected float getExpansionFraction() {
|
||||
return mExpandedFraction;
|
||||
}
|
||||
|
||||
protected PanelExpansionStateManager getPanelExpansionStateManager() {
|
||||
return mPanelExpansionStateManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.internal.policy.SystemBarUtils;
|
||||
@@ -45,10 +46,8 @@ import com.android.systemui.util.leak.RotationUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class PhoneStatusBarView extends PanelBar {
|
||||
public class PhoneStatusBarView extends FrameLayout {
|
||||
private static final String TAG = "PhoneStatusBarView";
|
||||
private static final boolean DEBUG = StatusBar.DEBUG;
|
||||
private static final boolean DEBUG_GESTURES = false;
|
||||
private final StatusBarContentInsetsProvider mContentInsetsProvider;
|
||||
|
||||
StatusBar mBar;
|
||||
|
||||
@@ -271,7 +271,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
||||
ScrimController.this.onThemeChanged();
|
||||
}
|
||||
});
|
||||
panelExpansionStateManager.addListener(
|
||||
panelExpansionStateManager.addExpansionListener(
|
||||
(fraction, expanded, tracking) -> setRawPanelExpansionFraction(fraction)
|
||||
);
|
||||
|
||||
|
||||
@@ -887,7 +887,7 @@ public class StatusBar extends SystemUI implements
|
||||
mStartingSurfaceOptional = startingSurfaceOptional;
|
||||
lockscreenShadeTransitionController.setStatusbar(this);
|
||||
|
||||
mPanelExpansionStateManager.addListener(this::onPanelExpansionChanged);
|
||||
mPanelExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged);
|
||||
|
||||
mBubbleExpandListener =
|
||||
(isExpanding, key) -> mContext.getMainExecutor().execute(() -> {
|
||||
@@ -1128,7 +1128,7 @@ public class StatusBar extends SystemUI implements
|
||||
mNotificationLogger.setUpWithContainer(notifListContainer);
|
||||
|
||||
mNotificationIconAreaController.setupShelf(mNotificationShelfController);
|
||||
mPanelExpansionStateManager.addListener(mWakeUpCoordinator);
|
||||
mPanelExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
|
||||
|
||||
mUserSwitcherController.init(mNotificationShadeWindowView);
|
||||
|
||||
@@ -1143,12 +1143,8 @@ public class StatusBar extends SystemUI implements
|
||||
PhoneStatusBarView oldStatusBarView = mStatusBarView;
|
||||
mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView();
|
||||
mStatusBarView.setBar(this);
|
||||
mStatusBarView.setPanelStateChangeListener(
|
||||
mNotificationPanelViewController.getPanelStateChangeListener());
|
||||
mStatusBarView.setScrimController(mScrimController);
|
||||
|
||||
mNotificationPanelViewController.setBar(mStatusBarView);
|
||||
|
||||
mPhoneStatusBarViewController = mPhoneStatusBarViewControllerFactory
|
||||
.create(mStatusBarView, mNotificationPanelViewController
|
||||
.getStatusBarTouchEventHandler());
|
||||
@@ -1200,6 +1196,7 @@ public class StatusBar extends SystemUI implements
|
||||
mAnimationScheduler,
|
||||
mStatusBarLocationPublisher,
|
||||
mNotificationIconAreaController,
|
||||
mPanelExpansionStateManager,
|
||||
mFeatureFlags,
|
||||
|
||||
() -> Optional.of(this),
|
||||
|
||||
@@ -279,7 +279,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
mBouncer = mKeyguardBouncerFactory.create(container, mExpansionCallback);
|
||||
mNotificationPanelViewController = notificationPanelViewController;
|
||||
if (panelExpansionStateManager != null) {
|
||||
panelExpansionStateManager.addListener(this);
|
||||
panelExpansionStateManager.addExpansionListener(this);
|
||||
}
|
||||
mBypassController = bypassController;
|
||||
mNotificationContainer = notificationContainer;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui.statusbar.phone.panelstate
|
||||
|
||||
import android.annotation.IntDef
|
||||
import android.util.Log
|
||||
import androidx.annotation.FloatRange
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import javax.inject.Inject
|
||||
@@ -23,42 +25,136 @@ import javax.inject.Inject
|
||||
/**
|
||||
* A class responsible for managing the notification panel's current state.
|
||||
*
|
||||
* TODO(b/200063118): Move [PanelBar.panelExpansionChanged] logic to this class and make this class
|
||||
* the one source of truth for the state of panel expansion.
|
||||
* TODO(b/200063118): Make this class the one source of truth for the state of panel expansion.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class PanelExpansionStateManager @Inject constructor() {
|
||||
|
||||
private val listeners: MutableList<PanelExpansionListener> = mutableListOf()
|
||||
private val expansionListeners = mutableListOf<PanelExpansionListener>()
|
||||
private val stateListeners = mutableListOf<PanelStateListener>()
|
||||
|
||||
@PanelState private var state: Int = STATE_CLOSED
|
||||
@FloatRange(from = 0.0, to = 1.0) private var fraction: Float = 0f
|
||||
private var expanded: Boolean = false
|
||||
private var tracking: Boolean = false
|
||||
|
||||
/**
|
||||
* Adds a listener that will be notified when the panel expansion has changed.
|
||||
* Adds a listener that will be notified when the panel expansion fraction has changed.
|
||||
*
|
||||
* Listener will also be immediately notified with the current values.
|
||||
*/
|
||||
fun addListener(listener: PanelExpansionListener) {
|
||||
listeners.add(listener)
|
||||
fun addExpansionListener(listener: PanelExpansionListener) {
|
||||
expansionListeners.add(listener)
|
||||
listener.onPanelExpansionChanged(fraction, expanded, tracking)
|
||||
}
|
||||
|
||||
/** Removes a listener. */
|
||||
fun removeListener(listener: PanelExpansionListener) {
|
||||
listeners.remove(listener)
|
||||
/** Removes an expansion listener. */
|
||||
fun removeExpansionListener(listener: PanelExpansionListener) {
|
||||
expansionListeners.remove(listener)
|
||||
}
|
||||
|
||||
/** Called when the panel expansion has changed. Notifies all listeners of change. */
|
||||
/** Adds a listener that will be notified when the panel state has changed. */
|
||||
fun addStateListener(listener: PanelStateListener) {
|
||||
stateListeners.add(listener)
|
||||
}
|
||||
|
||||
/** Removes a state listener. */
|
||||
fun removeStateListener(listener: PanelStateListener) {
|
||||
stateListeners.remove(listener)
|
||||
}
|
||||
|
||||
/** Returns true if the panel is currently closed and false otherwise. */
|
||||
fun isClosed(): Boolean = state == STATE_CLOSED
|
||||
|
||||
/**
|
||||
* Called when the panel expansion has changed.
|
||||
*
|
||||
* @param fraction the fraction from the expansion in [0, 1]
|
||||
* @param expanded whether the panel is currently expanded; this is independent from the
|
||||
* fraction as the panel also might be expanded if the fraction is 0.
|
||||
* @param tracking whether we're currently tracking the user's gesture.
|
||||
*/
|
||||
fun onPanelExpansionChanged(
|
||||
@FloatRange(from = 0.0, to = 1.0) fraction: Float,
|
||||
expanded: Boolean,
|
||||
tracking: Boolean
|
||||
) {
|
||||
require(!fraction.isNaN()) { "fraction cannot be NaN" }
|
||||
val oldState = state
|
||||
|
||||
this.fraction = fraction
|
||||
this.expanded = expanded
|
||||
this.tracking = tracking
|
||||
listeners.forEach { it.onPanelExpansionChanged(fraction, expanded, tracking) }
|
||||
|
||||
var fullyClosed = true
|
||||
var fullyOpened = false
|
||||
|
||||
if (expanded) {
|
||||
if (this.state == STATE_CLOSED) {
|
||||
updateStateInternal(STATE_OPENING)
|
||||
}
|
||||
fullyClosed = false
|
||||
fullyOpened = fraction >= 1f
|
||||
}
|
||||
|
||||
if (fullyOpened && !tracking) {
|
||||
updateStateInternal(STATE_OPEN)
|
||||
} else if (fullyClosed && !tracking && this.state != STATE_CLOSED) {
|
||||
updateStateInternal(STATE_CLOSED)
|
||||
}
|
||||
|
||||
debugLog(
|
||||
"panelExpansionChanged:" +
|
||||
"start state=${oldState.stateToString()} " +
|
||||
"end state=${state.stateToString()} " +
|
||||
"f=$fraction " +
|
||||
"expanded=$expanded " +
|
||||
"tracking=$tracking" +
|
||||
"${if (fullyOpened) " fullyOpened" else ""} " +
|
||||
if (fullyClosed) " fullyClosed" else ""
|
||||
)
|
||||
|
||||
expansionListeners.forEach { it.onPanelExpansionChanged(fraction, expanded, tracking) }
|
||||
}
|
||||
|
||||
/** Updates the panel state if necessary. */
|
||||
fun updateState(@PanelState state: Int) {
|
||||
debugLog("update state: ${this.state.stateToString()} -> ${state.stateToString()}")
|
||||
if (this.state != state) {
|
||||
updateStateInternal(state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateStateInternal(@PanelState state: Int) {
|
||||
debugLog("go state: ${this.state.stateToString()} -> ${state.stateToString()}")
|
||||
this.state = state
|
||||
stateListeners.forEach { it.onPanelStateChanged(state) }
|
||||
}
|
||||
|
||||
private fun debugLog(msg: String) {
|
||||
if (!DEBUG) return
|
||||
Log.v(TAG, msg)
|
||||
}
|
||||
}
|
||||
|
||||
/** Enum for the current state of the panel. */
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@IntDef(value = [STATE_CLOSED, STATE_OPENING, STATE_OPEN])
|
||||
internal annotation class PanelState
|
||||
|
||||
const val STATE_CLOSED = 0
|
||||
const val STATE_OPENING = 1
|
||||
const val STATE_OPEN = 2
|
||||
|
||||
@PanelState
|
||||
private fun Int.stateToString(): String {
|
||||
return when (this) {
|
||||
STATE_CLOSED -> "CLOSED"
|
||||
STATE_OPENING -> "OPENING"
|
||||
STATE_OPEN -> "OPEN"
|
||||
else -> this.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private const val DEBUG = false
|
||||
private val TAG = PanelExpansionStateManager::class.simpleName
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.statusbar.phone.panelstate
|
||||
|
||||
/** A listener interface to be notified of state change events for the notification panel. */
|
||||
interface PanelStateListener {
|
||||
/** Called when the panel's expansion state has changed. */
|
||||
fun onPanelStateChanged(@PanelState state: Int)
|
||||
}
|
||||
@@ -171,7 +171,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
|
||||
|
||||
verify(mStatusBarStateController).removeCallback(mStatusBarStateListener);
|
||||
for (PanelExpansionListener listener : mExpansionListeners) {
|
||||
verify(mPanelExpansionStateManager).removeListener(listener);
|
||||
verify(mPanelExpansionStateManager).removeExpansionListener(listener);
|
||||
}
|
||||
verify(mKeyguardStateController).removeCallback(mKeyguardStateControllerCallback);
|
||||
}
|
||||
@@ -435,7 +435,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
|
||||
|
||||
private void captureExpansionListeners() {
|
||||
verify(mPanelExpansionStateManager, times(2))
|
||||
.addListener(mExpansionListenerCaptor.capture());
|
||||
.addExpansionListener(mExpansionListenerCaptor.capture());
|
||||
// first (index=0) is from super class, UdfpsAnimationViewController.
|
||||
// second (index=1) is from UdfpsKeyguardViewController
|
||||
mExpansionListeners = mExpansionListenerCaptor.getAllValues();
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.android.systemui.statusbar.OperatorNameViewController;
|
||||
import com.android.systemui.statusbar.connectivity.NetworkController;
|
||||
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
|
||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
||||
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -259,6 +260,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
||||
mAnimationScheduler,
|
||||
mLocationPublisher,
|
||||
mMockNotificationAreaController,
|
||||
new PanelExpansionStateManager(),
|
||||
mock(FeatureFlags.class),
|
||||
() -> Optional.of(mStatusBar),
|
||||
mStatusBarIconController,
|
||||
|
||||
@@ -176,8 +176,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private HeadsUpTouchHelper.Callback mHeadsUpCallback;
|
||||
@Mock
|
||||
private PanelBar mPanelBar;
|
||||
@Mock
|
||||
private KeyguardUpdateMonitor mUpdateMonitor;
|
||||
@Mock
|
||||
private KeyguardBypassController mKeyguardBypassController;
|
||||
@@ -460,7 +458,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
() -> {},
|
||||
mNotificationShelfController);
|
||||
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
|
||||
mNotificationPanelViewController.setBar(mPanelBar);
|
||||
mNotificationPanelViewController.setKeyguardIndicationController(
|
||||
mKeyguardIndicationController);
|
||||
ArgumentCaptor<View.OnAttachStateChangeListener> onAttachStateChangeListenerArgumentCaptor =
|
||||
|
||||
@@ -53,40 +53,6 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
|
||||
view.setBar(statusBar)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun panelStateChanged_toStateOpening_listenerNotified() {
|
||||
val listener = TestStateChangedListener()
|
||||
view.setPanelStateChangeListener(listener)
|
||||
|
||||
view.panelExpansionChanged(0.5f, true)
|
||||
|
||||
assertThat(listener.state).isEqualTo(PanelBar.STATE_OPENING)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun panelStateChanged_toStateOpen_listenerNotified() {
|
||||
val listener = TestStateChangedListener()
|
||||
view.setPanelStateChangeListener(listener)
|
||||
|
||||
view.panelExpansionChanged(1f, true)
|
||||
|
||||
assertThat(listener.state).isEqualTo(PanelBar.STATE_OPEN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun panelStateChanged_toStateClosed_listenerNotified() {
|
||||
val listener = TestStateChangedListener()
|
||||
view.setPanelStateChangeListener(listener)
|
||||
|
||||
// First, open the panel
|
||||
view.panelExpansionChanged(1f, true)
|
||||
|
||||
// Then, close it again
|
||||
view.panelExpansionChanged(0f, false)
|
||||
|
||||
assertThat(listener.state).isEqualTo(PanelBar.STATE_CLOSED)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onTouchEvent_listenerNotified() {
|
||||
val handler = TestTouchEventHandler()
|
||||
@@ -126,13 +92,6 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
|
||||
// No assert needed, just testing no crash
|
||||
}
|
||||
|
||||
private class TestStateChangedListener : PanelBar.PanelStateChangeListener {
|
||||
var state: Int = 0
|
||||
override fun onStateChanged(state: Int) {
|
||||
this.state = state
|
||||
}
|
||||
}
|
||||
|
||||
private class TestTouchEventHandler : PhoneStatusBarView.TouchEventHandler {
|
||||
var lastEvent: MotionEvent? = null
|
||||
var returnValue: Boolean = false
|
||||
|
||||
@@ -33,9 +33,9 @@ class PanelExpansionStateManagerTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPanelExpansionChanged_listenersNotified() {
|
||||
fun onPanelExpansionChanged_listenerNotified() {
|
||||
val listener = TestPanelExpansionListener()
|
||||
panelExpansionStateManager.addListener(listener)
|
||||
panelExpansionStateManager.addExpansionListener(listener)
|
||||
val fraction = 0.6f
|
||||
val expanded = true
|
||||
val tracking = true
|
||||
@@ -48,20 +48,143 @@ class PanelExpansionStateManagerTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun addPanelExpansionListener_listenerNotifiedOfCurrentValues() {
|
||||
fun addExpansionListener_listenerNotifiedOfCurrentValues() {
|
||||
val fraction = 0.6f
|
||||
val expanded = true
|
||||
val tracking = true
|
||||
panelExpansionStateManager.onPanelExpansionChanged(fraction, expanded, tracking)
|
||||
val listener = TestPanelExpansionListener()
|
||||
|
||||
panelExpansionStateManager.addListener(listener)
|
||||
panelExpansionStateManager.addExpansionListener(listener)
|
||||
|
||||
assertThat(listener.fraction).isEqualTo(fraction)
|
||||
assertThat(listener.expanded).isEqualTo(expanded)
|
||||
assertThat(listener.tracking).isEqualTo(tracking)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateState_listenerNotified() {
|
||||
val listener = TestPanelStateListener()
|
||||
panelExpansionStateManager.addStateListener(listener)
|
||||
|
||||
panelExpansionStateManager.updateState(STATE_OPEN)
|
||||
|
||||
assertThat(listener.state).isEqualTo(STATE_OPEN)
|
||||
}
|
||||
|
||||
/* ***** [PanelExpansionStateManager.onPanelExpansionChanged] test cases *******/
|
||||
|
||||
/* Fraction < 1 test cases */
|
||||
|
||||
@Test
|
||||
fun onPEC_fractionLessThanOne_expandedTrue_trackingFalse_becomesStateOpening() {
|
||||
val listener = TestPanelStateListener()
|
||||
panelExpansionStateManager.addStateListener(listener)
|
||||
|
||||
panelExpansionStateManager.onPanelExpansionChanged(
|
||||
fraction = 0.5f, expanded = true, tracking = false
|
||||
)
|
||||
|
||||
assertThat(listener.state).isEqualTo(STATE_OPENING)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPEC_fractionLessThanOne_expandedTrue_trackingTrue_becomesStateOpening() {
|
||||
val listener = TestPanelStateListener()
|
||||
panelExpansionStateManager.addStateListener(listener)
|
||||
|
||||
panelExpansionStateManager.onPanelExpansionChanged(
|
||||
fraction = 0.5f, expanded = true, tracking = true
|
||||
)
|
||||
|
||||
assertThat(listener.state).isEqualTo(STATE_OPENING)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPEC_fractionLessThanOne_expandedFalse_trackingFalse_becomesStateClosed() {
|
||||
val listener = TestPanelStateListener()
|
||||
panelExpansionStateManager.addStateListener(listener)
|
||||
// Start out on a different state
|
||||
panelExpansionStateManager.updateState(STATE_OPEN)
|
||||
|
||||
panelExpansionStateManager.onPanelExpansionChanged(
|
||||
fraction = 0.5f, expanded = false, tracking = false
|
||||
)
|
||||
|
||||
assertThat(listener.state).isEqualTo(STATE_CLOSED)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPEC_fractionLessThanOne_expandedFalse_trackingTrue_doesNotBecomeStateClosed() {
|
||||
val listener = TestPanelStateListener()
|
||||
panelExpansionStateManager.addStateListener(listener)
|
||||
// Start out on a different state
|
||||
panelExpansionStateManager.updateState(STATE_OPEN)
|
||||
|
||||
panelExpansionStateManager.onPanelExpansionChanged(
|
||||
fraction = 0.5f, expanded = false, tracking = true
|
||||
)
|
||||
|
||||
assertThat(listener.state).isEqualTo(STATE_OPEN)
|
||||
}
|
||||
|
||||
/* Fraction = 1 test cases */
|
||||
|
||||
@Test
|
||||
fun onPEC_fractionOne_expandedTrue_trackingFalse_becomesStateOpeningThenStateOpen() {
|
||||
val listener = TestPanelStateListener()
|
||||
panelExpansionStateManager.addStateListener(listener)
|
||||
|
||||
panelExpansionStateManager.onPanelExpansionChanged(
|
||||
fraction = 1f, expanded = true, tracking = false
|
||||
)
|
||||
|
||||
assertThat(listener.previousState).isEqualTo(STATE_OPENING)
|
||||
assertThat(listener.state).isEqualTo(STATE_OPEN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPEC_fractionOne_expandedTrue_trackingTrue_becomesStateOpening() {
|
||||
val listener = TestPanelStateListener()
|
||||
panelExpansionStateManager.addStateListener(listener)
|
||||
|
||||
panelExpansionStateManager.onPanelExpansionChanged(
|
||||
fraction = 1f, expanded = true, tracking = true
|
||||
)
|
||||
|
||||
assertThat(listener.state).isEqualTo(STATE_OPENING)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPEC_fractionOne_expandedFalse_trackingFalse_becomesStateClosed() {
|
||||
val listener = TestPanelStateListener()
|
||||
panelExpansionStateManager.addStateListener(listener)
|
||||
// Start out on a different state
|
||||
panelExpansionStateManager.updateState(STATE_OPEN)
|
||||
|
||||
panelExpansionStateManager.onPanelExpansionChanged(
|
||||
fraction = 1f, expanded = false, tracking = false
|
||||
)
|
||||
|
||||
assertThat(listener.state).isEqualTo(STATE_CLOSED)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPEC_fractionOne_expandedFalse_trackingTrue_doesNotBecomeStateClosed() {
|
||||
val listener = TestPanelStateListener()
|
||||
panelExpansionStateManager.addStateListener(listener)
|
||||
// Start out on a different state
|
||||
panelExpansionStateManager.updateState(STATE_OPEN)
|
||||
|
||||
panelExpansionStateManager.onPanelExpansionChanged(
|
||||
fraction = 1f, expanded = false, tracking = true
|
||||
)
|
||||
|
||||
assertThat(listener.state).isEqualTo(STATE_OPEN)
|
||||
}
|
||||
|
||||
/* ***** end [PanelExpansionStateManager.onPanelExpansionChanged] test cases ******/
|
||||
|
||||
class TestPanelExpansionListener : PanelExpansionListener {
|
||||
var fraction: Float = 0f
|
||||
var expanded: Boolean = false
|
||||
@@ -77,4 +200,14 @@ class PanelExpansionStateManagerTest : SysuiTestCase() {
|
||||
this.tracking = tracking
|
||||
}
|
||||
}
|
||||
|
||||
class TestPanelStateListener : PanelStateListener {
|
||||
@PanelState var previousState: Int = STATE_CLOSED
|
||||
@PanelState var state: Int = STATE_CLOSED
|
||||
|
||||
override fun onPanelStateChanged(state: Int) {
|
||||
this.previousState = this.state
|
||||
this.state = state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user