Fixed a bug where the HUN would interfere with the normal touches
When a hun came in or went away, the touchable regions were not
enforced correctly due to a race condition. This lead to the user
grabing the notification panel unintentionally and ripping him
out of the normal touch state.
Also fixed a small bug where the alpha was not correctly animating
sometimes and the HUN shadow would still draw.
Bug: 20956211
Change-Id: Iae1fef5825b3d2b8b4128cc8c3272019194cd819
(cherry picked from commit 8b4a06e9e2)
This commit is contained in:
@@ -619,7 +619,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
R.color.notification_panel_solid_background)));
|
||||
}
|
||||
|
||||
mHeadsUpManager = new HeadsUpManager(context, mNotificationPanel.getViewTreeObserver());
|
||||
mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow);
|
||||
mHeadsUpManager.setBar(this);
|
||||
mHeadsUpManager.addListener(this);
|
||||
mHeadsUpManager.addListener(mNotificationPanel);
|
||||
@@ -1869,21 +1869,34 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
@Override
|
||||
public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
|
||||
if (inPinnedMode) {
|
||||
// We need to ensure that the touchable region is updated before the window will be
|
||||
// resized, in order to not catch any touches. A layout will ensure that
|
||||
// onComputeInternalInsets will be called and after that we can resize the layout. Let's
|
||||
// make sure that the window stays small for one frame until the touchableRegion is set.
|
||||
mNotificationPanel.requestLayout();
|
||||
mStatusBarWindowManager.setHeadsUpShowing(true);
|
||||
mStatusBarWindowManager.setForceStatusBarVisible(true);
|
||||
} else {
|
||||
Runnable endRunnable = new Runnable() {
|
||||
mStatusBarWindowManager.setForceWindowCollapsed(true);
|
||||
mNotificationPanel.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!mHeadsUpManager.hasPinnedHeadsUp()) {
|
||||
mStatusBarWindowManager.setHeadsUpShowing(false);
|
||||
}
|
||||
mStatusBarWindowManager.setForceWindowCollapsed(false);
|
||||
}
|
||||
};
|
||||
});
|
||||
} else {
|
||||
if (!mNotificationPanel.isFullyCollapsed()) {
|
||||
endRunnable.run();
|
||||
mStatusBarWindowManager.setHeadsUpShowing(false);
|
||||
} else {
|
||||
mStackScroller.runAfterAnimationFinished(endRunnable);
|
||||
mHeadsUpManager.setHeadsUpGoingAway(true);
|
||||
mStackScroller.runAfterAnimationFinished(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!mHeadsUpManager.hasPinnedHeadsUp()) {
|
||||
mStatusBarWindowManager.setHeadsUpShowing(false);
|
||||
mHeadsUpManager.setHeadsUpGoingAway(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,8 +378,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
|
||||
if (previousAnimator != null) {
|
||||
if (animate || alpha == mCurrentHeadsUpAlpha) {
|
||||
previousAnimator.cancel();
|
||||
} else {
|
||||
animEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim, TAG_HUN_END_ALPHA);
|
||||
}
|
||||
animEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim, TAG_HUN_START_ALPHA);
|
||||
}
|
||||
if (alpha != mCurrentHeadsUpAlpha && alpha != animEndValue) {
|
||||
if (animate) {
|
||||
|
||||
@@ -129,8 +129,9 @@ public class StatusBarWindowManager {
|
||||
}
|
||||
|
||||
private void applyHeight(State state) {
|
||||
boolean expanded = state.isKeyguardShowingAndNotOccluded() || state.statusBarExpanded
|
||||
|| state.keyguardFadingAway || state.bouncerShowing || state.headsUpShowing;
|
||||
boolean expanded = !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
|
||||
|| state.statusBarExpanded || state.keyguardFadingAway || state.bouncerShowing
|
||||
|| state.headsUpShowing);
|
||||
if (expanded) {
|
||||
mLpChanged.height = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
} else {
|
||||
@@ -256,6 +257,16 @@ public class StatusBarWindowManager {
|
||||
apply(mCurrentState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the window to be collapsed, even if it should theoretically be expanded.
|
||||
* Used for when a heads-up comes in but we still need to wait for the touchable regions to
|
||||
* be computed.
|
||||
*/
|
||||
public void setForceWindowCollapsed(boolean force) {
|
||||
mCurrentState.forceCollapsed = force;
|
||||
apply(mCurrentState);
|
||||
}
|
||||
|
||||
private static class State {
|
||||
boolean keyguardShowing;
|
||||
boolean keyguardOccluded;
|
||||
@@ -267,6 +278,7 @@ public class StatusBarWindowManager {
|
||||
boolean qsExpanded;
|
||||
boolean headsUpShowing;
|
||||
boolean forceStatusBarVisible;
|
||||
boolean forceCollapsed;
|
||||
|
||||
/**
|
||||
* The {@link BaseStatusBar} state from the status bar.
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.Pools;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
@@ -78,6 +79,8 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
|
||||
}
|
||||
};
|
||||
|
||||
private final View mStatusBarWindowView;
|
||||
private final int mStatusBarHeight;
|
||||
private PhoneStatusBar mBar;
|
||||
private int mSnoozeLengthMs;
|
||||
private ContentObserver mSettingsObserver;
|
||||
@@ -92,8 +95,11 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
|
||||
private boolean mIsExpanded;
|
||||
private boolean mHasPinnedNotification;
|
||||
private int[] mTmpTwoArray = new int[2];
|
||||
private boolean mHeadsUpGoingAway;
|
||||
private boolean mWaitingOnCollapseWhenGoingAway;
|
||||
private boolean mIsObserving;
|
||||
|
||||
public HeadsUpManager(final Context context, ViewTreeObserver observer) {
|
||||
public HeadsUpManager(final Context context, View statusBarWindowView) {
|
||||
Resources resources = context.getResources();
|
||||
mTouchAcceptanceDelay = resources.getInteger(R.integer.touch_acceptance_delay);
|
||||
mSnoozedPackages = new ArrayMap<>();
|
||||
@@ -119,7 +125,24 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
|
||||
context.getContentResolver().registerContentObserver(
|
||||
Settings.Global.getUriFor(SETTING_HEADS_UP_SNOOZE_LENGTH_MS), false,
|
||||
mSettingsObserver);
|
||||
observer.addOnComputeInternalInsetsListener(this);
|
||||
mStatusBarWindowView = statusBarWindowView;
|
||||
mStatusBarHeight = resources.getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.status_bar_height);
|
||||
}
|
||||
|
||||
private void updateTouchableRegionListener() {
|
||||
boolean shouldObserve = mHasPinnedNotification || mHeadsUpGoingAway
|
||||
|| mWaitingOnCollapseWhenGoingAway;
|
||||
if (shouldObserve == mIsObserving) {
|
||||
return;
|
||||
}
|
||||
if (shouldObserve) {
|
||||
mStatusBarWindowView.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
|
||||
mStatusBarWindowView.requestLayout();
|
||||
} else {
|
||||
mStatusBarWindowView.getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
|
||||
}
|
||||
mIsObserving = shouldObserve;
|
||||
}
|
||||
|
||||
public void setBar(PhoneStatusBar bar) {
|
||||
@@ -207,6 +230,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
|
||||
return;
|
||||
}
|
||||
mHasPinnedNotification = hasPinnedNotification;
|
||||
updateTouchableRegionListener();
|
||||
for (OnHeadsUpChangedListener listener : mListeners) {
|
||||
listener.onHeadsUpPinnedModeChanged(hasPinnedNotification);
|
||||
}
|
||||
@@ -326,7 +350,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
|
||||
}
|
||||
|
||||
public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
|
||||
if (!mIsExpanded && mHasPinnedNotification) {
|
||||
if (mHasPinnedNotification) {
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int maxX = 0;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
@@ -344,6 +368,9 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
|
||||
|
||||
info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
|
||||
info.touchableRegion.set(minX, minY, maxX, maxY);
|
||||
} else if (mHeadsUpGoingAway || mWaitingOnCollapseWhenGoingAway) {
|
||||
info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
|
||||
info.touchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,6 +446,10 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
|
||||
mIsExpanded = isExpanded;
|
||||
if (isExpanded) {
|
||||
unpinAll();
|
||||
// make sure our state is sane
|
||||
mWaitingOnCollapseWhenGoingAway = false;
|
||||
mHeadsUpGoingAway = false;
|
||||
updateTouchableRegionListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -443,6 +474,40 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
|
||||
return aEntry.compareTo(bEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that we are exiting the headsUp pinned mode, but some notifications might still be
|
||||
* animating out. This is used to keep the touchable regions in a sane state.
|
||||
*/
|
||||
public void setHeadsUpGoingAway(boolean headsUpGoingAway) {
|
||||
if (headsUpGoingAway != mHeadsUpGoingAway) {
|
||||
mHeadsUpGoingAway = headsUpGoingAway;
|
||||
if (!headsUpGoingAway) {
|
||||
waitForStatusBarLayout();
|
||||
}
|
||||
updateTouchableRegionListener();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to wait on the whole panel to collapse, before we can remove the touchable region
|
||||
* listener.
|
||||
*/
|
||||
private void waitForStatusBarLayout() {
|
||||
mWaitingOnCollapseWhenGoingAway = true;
|
||||
mStatusBarWindowView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
|
||||
@Override
|
||||
public void onLayoutChange(View v, int left, int top, int right, int bottom,
|
||||
int oldLeft,
|
||||
int oldTop, int oldRight, int oldBottom) {
|
||||
if (mStatusBarWindowView.getHeight() <= mStatusBarHeight) {
|
||||
mStatusBarWindowView.removeOnLayoutChangeListener(this);
|
||||
mWaitingOnCollapseWhenGoingAway = false;
|
||||
updateTouchableRegionListener();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This represents a notification and how long it is in a heads up mode. It also manages its
|
||||
|
||||
Reference in New Issue
Block a user