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:
Caitlin Cassidy
2021-11-08 16:13:01 +00:00
committed by Automerger Merge Worker
19 changed files with 321 additions and 284 deletions

View File

@@ -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());
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -447,7 +447,7 @@ public class NotificationShadeWindowViewController {
setDragDownHelper(mLockscreenShadeTransitionController.getTouchHelper());
mDepthController.setRoot(mView);
mPanelExpansionStateManager.addListener(mDepthController);
mPanelExpansionStateManager.addExpansionListener(mDepthController);
}
public NotificationShadeWindowView getView() {

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -271,7 +271,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
ScrimController.this.onThemeChanged();
}
});
panelExpansionStateManager.addListener(
panelExpansionStateManager.addExpansionListener(
(fraction, expanded, tracking) -> setRawPanelExpansionFraction(fraction)
);

View File

@@ -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),

View File

@@ -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;

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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();

View File

@@ -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,

View File

@@ -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 =

View File

@@ -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

View File

@@ -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
}
}
}