summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java12
-rw-r--r--packages/SystemUI/res/layout/super_notification_shade.xml6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java (renamed from core/java/com/android/internal/colorextraction/drawable/ScrimDrawable.java)59
-rw-r--r--packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java)57
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java140
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java)7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java121
20 files changed, 527 insertions, 117 deletions
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
index fffcafbf88fb..4d4c909d2894 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
@@ -14,7 +14,6 @@
package com.android.systemui.plugins.qs;
-import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
@@ -57,7 +56,6 @@ public interface QS extends FragmentBase {
void setQsExpansion(float qsExpansionFraction, float headerTranslation);
void setHeaderListening(boolean listening);
void notifyCustomizeChanged();
-
void setContainer(ViewGroup container);
void setExpandClickListener(OnClickListener onClickListener);
@@ -75,6 +73,16 @@ public interface QS extends FragmentBase {
return isShowingDetail();
}
+ /**
+ * If QS should translate as we pull it down, or if it should be static.
+ */
+ void setTranslateWhileExpanding(boolean shouldTranslate);
+
+ /**
+ * A rounded corner clipping that makes QS feel as if it were behind everything.
+ */
+ void setFancyClipping(int top, int bottom, int cornerRadius, boolean visible);
+
@ProvidesInterface(version = HeightListener.VERSION)
interface HeightListener {
int VERSION = 1;
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index 12c864cfcad3..bea50e87a29a 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -43,7 +43,7 @@
android:visibility="invisible" />
</com.android.systemui.statusbar.BackDropView>
- <com.android.systemui.statusbar.ScrimView
+ <com.android.systemui.scrim.ScrimView
android:id="@+id/scrim_behind"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -51,7 +51,7 @@
sysui:ignoreRightInset="true"
/>
- <com.android.systemui.statusbar.ScrimView
+ <com.android.systemui.scrim.ScrimView
android:id="@+id/scrim_notifications"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -72,7 +72,7 @@
<include layout="@layout/brightness_mirror_container" />
- <com.android.systemui.statusbar.ScrimView
+ <com.android.systemui.scrim.ScrimView
android:id="@+id/scrim_in_front"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index fc80dbe021a7..588f4bb20340 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -16,6 +16,7 @@
package com.android.keyguard;
+import android.graphics.Rect;
import android.os.UserHandle;
import android.util.Slog;
@@ -48,6 +49,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
private final ConfigurationController mConfigurationController;
private final DozeParameters mDozeParameters;
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
+ private final Rect mClipBounds = new Rect();
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
@@ -299,4 +301,17 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mView.updateLogoutView(shouldShowLogout());
}
};
+
+ /**
+ * Rect that specifies how KSV should be clipped, on its parent's coordinates.
+ */
+ public void setClipBounds(Rect clipBounds) {
+ if (clipBounds != null) {
+ mClipBounds.set(clipBounds.left, (int) (clipBounds.top - mView.getY()),
+ clipBounds.right, (int) (clipBounds.bottom - mView.getY()));
+ mView.setClipBounds(mClipBounds);
+ } else {
+ mView.setClipBounds(null);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index e44e305b6120..19edeb80c10c 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -98,7 +98,6 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
-import com.android.internal.colorextraction.drawable.ScrimDrawable;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
@@ -117,6 +116,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
+import com.android.systemui.scrim.ScrimDrawable;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 767d7ab5a490..411e0f07f2be 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -30,11 +30,11 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import com.android.internal.R;
-import com.android.internal.colorextraction.drawable.ScrimDrawable;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.GlobalActions;
+import com.android.systemui.scrim.ScrimDrawable;
import com.android.systemui.statusbar.BlurUtils;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.ScrimController;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java b/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java
index 309b32fc85d2..cd3609108c28 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java
@@ -29,6 +29,7 @@ public class NonInterceptingScrollView extends ScrollView {
private final int mTouchSlop;
private float mDownY;
+ private boolean mScrollEnabled = true;
public NonInterceptingScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -85,6 +86,16 @@ public class NonInterceptingScrollView extends ScrollView {
return super.onInterceptTouchEvent(ev);
}
+ @Override
+ public boolean canScrollVertically(int direction) {
+ return mScrollEnabled && super.canScrollVertically(direction);
+ }
+
+ @Override
+ public boolean canScrollHorizontally(int direction) {
+ return mScrollEnabled && super.canScrollHorizontally(direction);
+ }
+
public int getScrollRange() {
int scrollRange = 0;
if (getChildCount() > 0) {
@@ -94,4 +105,12 @@ public class NonInterceptingScrollView extends ScrollView {
}
return scrollRange;
}
+
+ /**
+ * Enable scrolling for this view. Needed because the view might be clipped but still intercepts
+ * touches on the lockscreen.
+ */
+ public void setScrollingEnabled(boolean enabled) {
+ mScrollEnabled = enabled;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index cefcd4a5194c..294d76590fed 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -54,6 +54,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
private static final String MOVE_FULL_ROWS = "sysui_qs_move_whole_rows";
public static final float EXPANDED_TILE_DELAY = .86f;
+ public static final float SHORT_PARALLAX_AMOUNT = 0.1f;
private static final long QQS_FADE_IN_DURATION = 200L;
// Fade out faster than fade in to finish before QQS hides.
private static final long QQS_FADE_OUT_DURATION = 50L;
@@ -101,6 +102,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
private final Executor mExecutor;
private final TunerService mTunerService;
private boolean mShowCollapsedOnKeyguard;
+ private boolean mTranslateWhileExpanding;
@Inject
public QSAnimator(QS qs, QuickQSPanel quickPanel, QuickStatusBarHeader quickStatusBarHeader,
@@ -242,6 +244,9 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
int width = mQs.getView() != null ? mQs.getView().getMeasuredWidth() : 0;
int heightDiff = height - mQs.getHeader().getBottom()
+ mQs.getHeader().getPaddingBottom();
+ if (!mTranslateWhileExpanding) {
+ heightDiff *= SHORT_PARALLAX_AMOUNT;
+ }
firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0);
int qqsTileHeight = 0;
@@ -570,6 +575,13 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
setCurrentPosition();
};
+ /**
+ * True whe QS will be pulled from the top, false when it will be clipped.
+ */
+ public void setTranslateWhileExpanding(boolean shouldTranslate) {
+ mTranslateWhileExpanding = shouldTranslate;
+ }
+
static class HeightExpansionAnimator {
private final List<View> mViews = new ArrayList<>();
private final ValueAnimator mAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 6b09e2eb7b8b..e89803d16779 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -20,6 +20,8 @@ import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Canvas;
+import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.View;
@@ -54,6 +56,10 @@ public class QSContainerImpl extends FrameLayout {
private static final PhysicsAnimator.SpringConfig BACKGROUND_SPRING
= new PhysicsAnimator.SpringConfig(SpringForce.STIFFNESS_MEDIUM,
SpringForce.DAMPING_RATIO_LOW_BOUNCY);
+ private int mFancyClippingTop;
+ private int mFancyClippingBottom;
+ private final float[] mFancyClippingRadii = new float[] {0, 0, 0, 0, 0, 0, 0, 0};
+ private final Path mFancyClippingPath = new Path();
private int mBackgroundBottom = -1;
private int mHeightOverride = -1;
private View mQSDetail;
@@ -70,6 +76,7 @@ public class QSContainerImpl extends FrameLayout {
private int mContentPadding = -1;
private boolean mAnimateBottomOnNextLayout;
private int mNavBarInset = 0;
+ private boolean mClippingEnabled;
public QSContainerImpl(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -169,6 +176,15 @@ public class QSContainerImpl extends FrameLayout {
MeasureSpec.makeMeasureSpec(getDisplayHeight(), MeasureSpec.EXACTLY));
}
+ @Override
+ public void dispatchDraw(Canvas canvas) {
+ if (!mFancyClippingPath.isEmpty()) {
+ canvas.translate(0, -getTranslationY());
+ canvas.clipOutPath(mFancyClippingPath);
+ canvas.translate(0, getTranslationY());
+ }
+ super.dispatchDraw(canvas);
+ }
@Override
protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed,
@@ -187,6 +203,7 @@ public class QSContainerImpl extends FrameLayout {
super.onLayout(changed, left, top, right, bottom);
updateExpansion(mAnimateBottomOnNextLayout /* animate */);
mAnimateBottomOnNextLayout = false;
+ updateClippingPath();
}
public void disable(int state1, int state2, boolean animate) {
@@ -281,6 +298,7 @@ public class QSContainerImpl extends FrameLayout {
public void setExpansion(float expansion) {
mQsExpansion = expansion;
+ mQSPanelContainer.setScrollingEnabled(expansion > 0.0f);
updateExpansion();
}
@@ -318,4 +336,46 @@ public class QSContainerImpl extends FrameLayout {
}
return mSizePoint.y;
}
+
+ /**
+ * Clip QS bottom using a concave shape.
+ */
+ public void setFancyClipping(int top, int bottom, int radius, boolean enabled) {
+ boolean updatePath = false;
+ if (mFancyClippingRadii[0] != radius) {
+ mFancyClippingRadii[0] = radius;
+ mFancyClippingRadii[1] = radius;
+ mFancyClippingRadii[2] = radius;
+ mFancyClippingRadii[3] = radius;
+ updatePath = true;
+ }
+ if (mFancyClippingTop != top) {
+ mFancyClippingTop = top;
+ updatePath = true;
+ }
+ if (mFancyClippingBottom != bottom) {
+ mFancyClippingBottom = bottom;
+ updatePath = true;
+ }
+ if (mClippingEnabled != enabled) {
+ mClippingEnabled = enabled;
+ updatePath = true;
+ }
+
+ if (updatePath) {
+ updateClippingPath();
+ }
+ }
+
+ private void updateClippingPath() {
+ mFancyClippingPath.reset();
+ if (!mClippingEnabled) {
+ invalidate();
+ return;
+ }
+
+ mFancyClippingPath.addRoundRect(0, mFancyClippingTop, getWidth(),
+ mFancyClippingBottom, mFancyClippingRadii, Path.Direction.CW);
+ invalidate();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index b95194adb9cc..d5cb777416a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -107,6 +107,11 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private QuickQSPanelController mQuickQSPanelController;
private QSCustomizerController mQSCustomizerController;
private FeatureFlags mFeatureFlags;
+ /**
+ * When true, QS will translate from outside the screen. It will be clipped with parallax
+ * otherwise.
+ */
+ private boolean mTranslateWhileExpanding;
@Inject
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
@@ -254,6 +259,13 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
}
+ @Override
+ public void setFancyClipping(int top, int bottom, int cornerRadius, boolean visible) {
+ if (getView() instanceof QSContainerImpl) {
+ ((QSContainerImpl) getView()).setFancyClipping(top, bottom, cornerRadius, visible);
+ }
+ }
+
private void setEditLocation(View view) {
View edit = view.findViewById(android.R.id.edit);
int[] loc = edit.getLocationOnScreen();
@@ -394,16 +406,23 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
@Override
+ public void setTranslateWhileExpanding(boolean shouldTranslate) {
+ mTranslateWhileExpanding = shouldTranslate;
+ mQSAnimator.setTranslateWhileExpanding(shouldTranslate);
+ }
+
+ @Override
public void setQsExpansion(float expansion, float headerTranslation) {
if (DEBUG) Log.d(TAG, "setQSExpansion " + expansion + " " + headerTranslation);
if (mQSAnimator != null) {
final boolean showQSOnLockscreen = expansion > 0;
- final boolean showQSUnlocked = headerTranslation == 0;
+ final boolean showQSUnlocked = headerTranslation == 0 || !mTranslateWhileExpanding;
mQSAnimator.startAlphaAnimation(showQSOnLockscreen || showQSUnlocked);
}
mContainer.setExpansion(expansion);
- final float translationScaleY = expansion - 1;
+ final float translationScaleY = (mTranslateWhileExpanding
+ ? 1 : QSAnimator.SHORT_PARALLAX_AMOUNT) * (expansion - 1);
boolean onKeyguardAndExpanded = isKeyguardShowing() && !mShowCollapsedOnKeyguard;
if (!mHeaderAnimating && !headerWillBeAnimating()) {
getView().setTranslationY(
diff --git a/core/java/com/android/internal/colorextraction/drawable/ScrimDrawable.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
index 1fc126eb161d..0a55fbe8bf75 100644
--- a/core/java/com/android/internal/colorextraction/drawable/ScrimDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.colorextraction.drawable;
+package com.android.systemui.scrim;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -49,6 +49,7 @@ public class ScrimDrawable extends Drawable {
private float mCornerRadius;
private Rect mBounds;
private ConcaveInfo mConcaveInfo;
+ private int mBottomEdgePosition;
public ScrimDrawable() {
mPaint = new Paint();
@@ -143,21 +144,43 @@ public class ScrimDrawable extends Drawable {
* Make bottom edge concave with provided corner radius
*/
public void setBottomEdgeConcave(float radius) {
+ if (radius == 0) {
+ // Disable clipping completely when there's no radius.
+ mConcaveInfo = null;
+ return;
+ }
// only rounding top corners for clip out path
float[] cornerRadii = new float[]{radius, radius, radius, radius, 0, 0, 0, 0};
mConcaveInfo = new ConcaveInfo(radius, cornerRadii);
}
+ /**
+ * Location of concave edge.
+ * @see #setBottomEdgeConcave(float)
+ */
+ public void setBottomEdgePosition(int y) {
+ if (mBottomEdgePosition == y) {
+ return;
+ }
+ mBottomEdgePosition = y;
+ if (mConcaveInfo == null) {
+ return;
+ }
+ updatePath();
+ invalidateSelf();
+ }
+
@Override
public void draw(@NonNull Canvas canvas) {
mPaint.setColor(mMainColor);
mPaint.setAlpha(mAlpha);
if (mConcaveInfo != null) {
drawConcave(canvas);
+ } else {
+ canvas.drawRoundRect(getBounds().left, getBounds().top, getBounds().right,
+ getBounds().bottom + mCornerRadius,
+ /* x radius*/ mCornerRadius, /* y radius*/ mCornerRadius, mPaint);
}
- canvas.drawRoundRect(getBounds().left, getBounds().top, getBounds().right,
- getBounds().bottom + mCornerRadius,
- /* x radius*/ mCornerRadius, /* y radius*/ mCornerRadius, mPaint);
}
private void drawConcave(Canvas canvas) {
@@ -165,19 +188,23 @@ public class ScrimDrawable extends Drawable {
if (mBounds == null
|| getBounds().right != mBounds.right
|| getBounds().left != mBounds.left) {
- mConcaveInfo.mPath.reset();
- float left = getBounds().left;
- float right = getBounds().right;
- float top = 0f;
- float bottom = mConcaveInfo.mPathOverlap;
- mConcaveInfo.mPath.addRoundRect(left, top, right, bottom,
- mConcaveInfo.mCornerRadii, Path.Direction.CW);
+ mBounds = getBounds();
+ updatePath();
}
- mBounds = getBounds();
- int translation = (int) (mBounds.bottom - mConcaveInfo.mPathOverlap);
- canvas.translate(0, translation);
canvas.clipOutPath(mConcaveInfo.mPath);
- canvas.translate(0, -translation);
+ canvas.drawRect(getBounds().left, getBounds().top, getBounds().right,
+ mBottomEdgePosition + mConcaveInfo.mPathOverlap, mPaint);
+ }
+
+ private void updatePath() {
+ mConcaveInfo.mPath.reset();
+ if (mBounds == null) {
+ mBounds = getBounds();
+ }
+ float top = mBottomEdgePosition;
+ float bottom = mBottomEdgePosition + mConcaveInfo.mPathOverlap;
+ mConcaveInfo.mPath.addRoundRect(mBounds.left, top, mBounds.right, bottom,
+ mConcaveInfo.mCornerRadii, Path.Direction.CW);
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
index a537299d4979..0d9ade6da49c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.scrim;
import static java.lang.Float.isNaN;
@@ -38,7 +38,6 @@ import androidx.core.graphics.ColorUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
-import com.android.internal.colorextraction.drawable.ScrimDrawable;
import com.android.systemui.R;
import java.util.concurrent.Executor;
@@ -96,6 +95,9 @@ public class ScrimView extends View {
});
}
+ /**
+ * Needed for WM Shell, which has its own thread structure.
+ */
public void setExecutor(Executor executor, Looper looper) {
mExecutor = executor;
mExecutorLooper = looper;
@@ -108,7 +110,8 @@ public class ScrimView extends View {
}
}
- public void setDrawable(Drawable drawable) {
+ @VisibleForTesting
+ void setDrawable(Drawable drawable) {
executeOnExecutor(() -> {
mDrawable = drawable;
mDrawable.setCallback(this);
@@ -144,16 +147,24 @@ public class ScrimView extends View {
});
}
+ /**
+ * Sets the color of the scrim, without animating them.
+ */
public void setColors(@NonNull ColorExtractor.GradientColors colors) {
setColors(colors, false);
}
+ /**
+ * Sets the scrim colors, optionally animating them.
+ * @param colors The colors.
+ * @param animated If we should animate the transition.
+ */
public void setColors(@NonNull ColorExtractor.GradientColors colors, boolean animated) {
if (colors == null) {
throw new IllegalArgumentException("Colors cannot be null");
}
executeOnExecutor(() -> {
- synchronized(mColorLock) {
+ synchronized (mColorLock) {
if (mColors.equals(colors)) {
return;
}
@@ -168,17 +179,28 @@ public class ScrimView extends View {
return mDrawable;
}
+ /**
+ * Returns current scrim colors.
+ */
public ColorExtractor.GradientColors getColors() {
- synchronized(mColorLock) {
+ synchronized (mColorLock) {
mTmpColors.set(mColors);
}
return mTmpColors;
}
+ /**
+ * Applies tint to this view, without animations.
+ */
public void setTint(int color) {
setTint(color, false);
}
+ /**
+ * Tints this view, optionally animating it.
+ * @param color The color.
+ * @param animated If we should animate.
+ */
public void setTint(int color, boolean animated) {
executeOnExecutor(() -> {
if (mTintColor == color) {
@@ -200,8 +222,8 @@ public class ScrimView extends View {
} else {
boolean hasAlpha = Color.alpha(mTintColor) != 0;
if (hasAlpha) {
- PorterDuff.Mode targetMode = mColorFilter == null ? Mode.SRC_OVER :
- mColorFilter.getMode();
+ PorterDuff.Mode targetMode = mColorFilter == null
+ ? Mode.SRC_OVER : mColorFilter.getMode();
if (mColorFilter == null || mColorFilter.getColor() != mTintColor) {
mColorFilter = new PorterDuffColorFilter(mTintColor, targetMode);
}
@@ -254,6 +276,9 @@ public class ScrimView extends View {
return mViewAlpha;
}
+ /**
+ * Sets a callback that is invoked whenever the alpha, color, or tint change.
+ */
public void setChangeRunnable(Runnable changeRunnable, Executor changeRunnableExecutor) {
mChangeRunnable = changeRunnable;
mChangeRunnableExecutor = changeRunnableExecutor;
@@ -276,9 +301,9 @@ public class ScrimView extends View {
* Make bottom edge concave so overlap between layers is not visible for alphas between 0 and 1
* @return height of concavity
*/
- public float enableBottomEdgeConcave() {
+ public float enableBottomEdgeConcave(boolean clipScrim) {
if (mDrawable instanceof ScrimDrawable) {
- float radius = getResources().getDimensionPixelSize(CORNER_RADIUS);
+ float radius = clipScrim ? getResources().getDimensionPixelSize(CORNER_RADIUS) : 0;
((ScrimDrawable) mDrawable).setBottomEdgeConcave(radius);
return radius;
}
@@ -286,6 +311,16 @@ public class ScrimView extends View {
}
/**
+ * The position of the bottom of the scrim, used for clipping.
+ * @see #enableBottomEdgeConcave(boolean)
+ */
+ public void setBottomEdgePosition(int y) {
+ if (mDrawable instanceof ScrimDrawable) {
+ ((ScrimDrawable) mDrawable).setBottomEdgePosition(y);
+ }
+ }
+
+ /**
* Enable view to have rounded corners with radius of {@link #CORNER_RADIUS}
*/
public void enableRoundedCorners() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 4fc49ed26f64..36a370c71216 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -780,7 +780,7 @@ public class NotificationStackScrollLayoutController {
return mView.isLayoutRtl();
}
- public float getLeft() {
+ public int getLeft() {
return mView.getLeft();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 961699e9e600..e2af940e66a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -515,6 +515,7 @@ public class NotificationPanelViewController extends PanelViewController {
private boolean mDelayShowingKeyguardStatusBar;
private boolean mAnimatingQS;
+ private final Rect mKeyguardStatusAreaClipBounds = new Rect();
private int mOldLayoutDirection;
private NotificationShelfController mNotificationShelfController;
@@ -522,6 +523,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final Executor mUiExecutor;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
+ private int mScrimCornerRadius;
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@Override
@@ -628,6 +630,7 @@ public class NotificationPanelViewController extends PanelViewController {
mDozeParameters = dozeParameters;
mBiometricUnlockController = biometricUnlockController;
mScrimController = scrimController;
+ mScrimController.setClipsQsScrim(!mShouldUseSplitNotificationShade);
mUserManager = userManager;
mMediaDataManager = mediaDataManager;
mQuickAccessWalletClient = quickAccessWalletClient;
@@ -852,10 +855,16 @@ public class NotificationPanelViewController extends PanelViewController {
public void updateResources() {
mSplitShadeNotificationsTopPadding =
mResources.getDimensionPixelSize(R.dimen.notifications_top_padding_split_shade);
+ mScrimCornerRadius =
+ mResources.getDimensionPixelSize(R.dimen.notification_scrim_corner_radius);
int qsWidth = mResources.getDimensionPixelSize(R.dimen.qs_panel_width);
int panelWidth = mResources.getDimensionPixelSize(R.dimen.notification_panel_width);
mShouldUseSplitNotificationShade =
Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources);
+ mScrimController.setClipsQsScrim(!mShouldUseSplitNotificationShade);
+ if (mQs != null) {
+ mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade);
+ }
// To change the constraints at runtime, all children of the ConstraintLayout must have ids
ensureAllViewsHaveIds(mNotificationContainerParent);
ConstraintSet constraintSet = new ConstraintSet();
@@ -2003,15 +2012,23 @@ public class NotificationPanelViewController extends PanelViewController {
mDepthController.setQsPanelExpansion(qsExpansionFraction);
}
- private void setNotificationBounds(float qsExpansionFraction, int qsPanelBottomY) {
- float top = 0;
- float bottom = 0;
- float left = 0;
- float right = 0;
- if (qsPanelBottomY > 0) {
- // notification shade is expanding/expanded
+ /**
+ * Updates scrim bounds, QS clipping, and KSV clipping as well based on the bounds of the shade
+ * and QS state.
+ *
+ * @param qsFraction QS expansion fraction, from getQsExpansionFraction().
+ * @param qsPanelBottomY Absolute y position of the bottom of QS as it's being pulled.
+ */
+ private void setNotificationBounds(float qsFraction, int qsPanelBottomY) {
+ int top = 0;
+ int bottom = 0;
+ int left = 0;
+ int right = 0;
+ boolean visible = qsFraction > 0 || qsPanelBottomY > 0;
+ if (visible || !mShouldUseSplitNotificationShade) {
if (!mShouldUseSplitNotificationShade) {
- top = qsPanelBottomY;
+ float notificationTop = mAmbientState.getStackY() - mQsNotificationTopPadding;
+ top = (int) Math.min(qsPanelBottomY, notificationTop);
bottom = getView().getBottom();
left = getView().getLeft();
right = getView().getRight();
@@ -2022,6 +2039,17 @@ public class NotificationPanelViewController extends PanelViewController {
right = mNotificationStackScrollLayoutController.getRight();
}
}
+
+ if (!mShouldUseSplitNotificationShade) {
+ // Fancy clipping for quick settings
+ if (mQs != null) {
+ mQs.setFancyClipping(top, bottom, mScrimCornerRadius, visible);
+ }
+ // The padding on this area is large enough that we can use a cheaper clipping strategy
+ mKeyguardStatusAreaClipBounds.set(left, top, right, bottom);
+ mKeyguardStatusViewController.setClipBounds(visible
+ ? mKeyguardStatusAreaClipBounds : null);
+ }
mScrimController.setNotificationsBounds(left, top, right, bottom);
}
@@ -2493,6 +2521,10 @@ public class NotificationPanelViewController extends PanelViewController {
float appearAmount = mNotificationStackScrollLayoutController
.calculateAppearFraction(mExpandedHeight);
float startHeight = -mQsExpansionHeight;
+ if (!mShouldUseSplitNotificationShade && mBarState == StatusBarState.SHADE) {
+ // Small parallax as we pull down and clip QS
+ startHeight = -mQsExpansionHeight * 0.2f;
+ }
if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()
&& mNotificationStackScrollLayoutController.isPulseExpanding()) {
if (!mPulseExpansionHandler.isExpanding()
@@ -3128,8 +3160,10 @@ public class NotificationPanelViewController extends PanelViewController {
mQs.setPanelView(mHeightListener);
mQs.setExpandClickListener(mOnClickListener);
mQs.setHeaderClickable(mQsExpansionEnabled);
+ mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade);
updateQSPulseExpansion();
mQs.setOverscrolling(mStackScrollerOverscrolling);
+ mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade);
// recompute internal state when qspanel height changes
mQs.getView().addOnLayoutChangeListener(
@@ -3925,7 +3959,10 @@ public class NotificationPanelViewController extends PanelViewController {
// animate out
// the top of QS
if (!mQsExpanded) {
- mQs.animateHeaderSlidingOut();
+ // TODO(b/185683835) Nicer clipping when using new spacial model
+ if (mShouldUseSplitNotificationShade) {
+ mQs.animateHeaderSlidingOut();
+ }
}
} else {
mKeyguardStatusBar.setAlpha(1f);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 064086a828cb..5a2a6f21f94a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -147,9 +147,6 @@ public abstract class PanelViewController {
private float mInitialTouchX;
private boolean mTouchDisabled;
- // AmbientState will never be null since it provides an @Inject constructor for Dagger to call.
- private AmbientState mAmbientState;
-
/**
* Whether or not the PanelView can be expanded or collapsed with a drag.
*/
@@ -172,6 +169,7 @@ public abstract class PanelViewController {
protected final Resources mResources;
protected final KeyguardStateController mKeyguardStateController;
protected final SysuiStatusBarStateController mStatusBarStateController;
+ protected final AmbientState mAmbientState;
protected void onExpandingFinished() {
mBar.onExpandingFinished();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 5e9c758da07a..0d96ead964f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -48,8 +48,8 @@ import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
+import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.FeatureFlags;
-import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -96,6 +96,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
* When at least 1 scrim is fully opaque (alpha set to 1.)
*/
public static final int OPAQUE = 2;
+ private boolean mClipsQsScrim;
@IntDef(prefix = {"VISIBILITY_"}, value = {
TRANSPARENT,
@@ -165,6 +166,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
// Assuming the shade is expanded during initialization
private float mExpansionFraction = 1f;
private float mQsExpansion;
+ private boolean mQsBottomVisible;
private boolean mDarkenWhileDragging;
private boolean mExpansionAffectsAlpha = true;
@@ -183,6 +185,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private int mInFrontTint;
private int mBehindTint;
+ private int mNotificationsTint;
private int mBubbleTint;
private boolean mWallpaperVisibilityTimedOut;
@@ -265,6 +268,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mScrimForBubble = scrimForBubble;
updateThemeColors();
+ behindScrim.enableBottomEdgeConcave(mClipsQsScrim);
mNotificationsScrim.enableRoundedCorners();
if (mScrimBehindChangeRunnable != null) {
@@ -331,14 +335,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mInFrontTint = state.getFrontTint();
mBehindTint = state.getBehindTint();
+ mNotificationsTint = state.getNotifTint();
mBubbleTint = state.getBubbleTint();
mInFrontAlpha = state.getFrontAlpha();
mBehindAlpha = state.getBehindAlpha();
mBubbleAlpha = state.getBubbleAlpha();
- if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha)) {
+ mNotificationsAlpha = state.getNotifAlpha();
+ if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha) || isNaN(mNotificationsAlpha)) {
throw new IllegalStateException("Scrim opacity is NaN for state: " + state + ", front: "
- + mInFrontAlpha + ", back: " + mBehindAlpha);
+ + mInFrontAlpha + ", back: " + mBehindAlpha + ", notif: "
+ + mNotificationsAlpha);
}
applyExpansionToAlpha();
@@ -397,7 +404,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
scheduleUpdate();
}
- dispatchScrimState(mScrimBehind.getViewAlpha());
+ dispatchBackScrimState(mScrimBehind.getViewAlpha());
}
private boolean shouldFadeAwayWallpaper() {
@@ -491,21 +498,25 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
*/
public void setNotificationsBounds(float left, float top, float right, float bottom) {
mNotificationsScrim.setDrawableBounds(left, top, right, bottom);
+ if (mClipsQsScrim) {
+ mScrimBehind.setBottomEdgePosition((int) top);
+ }
}
/**
* Current state of the QuickSettings when pulling it from the top.
*
* @param expansionFraction From 0 to 1 where 0 means collapsed and 1 expanded.
- * @param qsPanelBottomY absolute Y position of qs panel bottom
+ * @param qsPanelBottomY Absolute Y position of qs panel bottom
*/
public void setQsPosition(float expansionFraction, int qsPanelBottomY) {
if (isNaN(expansionFraction)) {
return;
}
- updateNotificationsScrimAlpha(expansionFraction, qsPanelBottomY);
- if (mQsExpansion != expansionFraction) {
+ boolean qsBottomVisible = qsPanelBottomY > 0;
+ if (mQsExpansion != expansionFraction || mQsBottomVisible != qsBottomVisible) {
mQsExpansion = expansionFraction;
+ mQsBottomVisible = qsBottomVisible;
boolean relevantState = (mState == ScrimState.SHADE_LOCKED
|| mState == ScrimState.KEYGUARD
|| mState == ScrimState.PULSING
@@ -517,31 +528,36 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
}
- private void updateNotificationsScrimAlpha(float qsExpansion, int qsPanelBottomY) {
- float newAlpha = 0;
- if (qsPanelBottomY > 0) {
- float interpolator = 0;
- if (mState == ScrimState.UNLOCKED || mState == ScrimState.SHADE_LOCKED) {
- interpolator = getInterpolatedFraction();
- } else {
- interpolator = qsExpansion;
- }
- newAlpha = MathUtils.lerp(0, 1, interpolator);
+ /**
+ * If QS and notification scrims should not overlap, and should be clipped to each other's
+ * bounds instead.
+ */
+ public void setClipsQsScrim(boolean clipScrim) {
+ if (clipScrim == mClipsQsScrim) {
+ return;
}
- if (newAlpha != mNotificationsAlpha) {
- mNotificationsAlpha = newAlpha;
- // update alpha without animating
- mNotificationsScrim.setViewAlpha(newAlpha);
+ mClipsQsScrim = clipScrim;
+ for (ScrimState state : ScrimState.values()) {
+ state.setClipQsScrim(mClipsQsScrim);
+ }
+ if (mScrimBehind != null) {
+ mScrimBehind.enableBottomEdgeConcave(mClipsQsScrim);
}
}
+ @VisibleForTesting
+ public boolean getClipQsScrim() {
+ return mClipsQsScrim;
+ }
+
private void setOrAdaptCurrentAnimation(@Nullable View scrim) {
if (scrim == null) {
return;
}
float alpha = getCurrentScrimAlpha(scrim);
- if (isAnimating(scrim)) {
+ boolean qsScrimPullingDown = scrim == mScrimBehind && mQsBottomVisible;
+ if (isAnimating(scrim) && !qsScrimPullingDown) {
// Adapt current animation.
ValueAnimator previousAnimator = (ValueAnimator) scrim.getTag(TAG_KEY_ANIM);
float previousEndValue = (Float) scrim.getTag(TAG_END_ALPHA);
@@ -562,7 +578,19 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
return;
}
- if (mState == ScrimState.UNLOCKED || mState == ScrimState.BUBBLE_EXPANDED) {
+ if (mState == ScrimState.UNLOCKED) {
+ // Darken scrim as you pull down the shade when unlocked
+ float behindFraction = getInterpolatedFraction();
+ behindFraction = (float) Math.pow(behindFraction, 0.8f);
+ if (mClipsQsScrim) {
+ mBehindAlpha = 1;
+ mNotificationsAlpha = behindFraction * mDefaultScrimAlpha;
+ } else {
+ mBehindAlpha = behindFraction * mDefaultScrimAlpha;
+ mNotificationsAlpha = mBehindAlpha;
+ }
+ mInFrontAlpha = 0;
+ } else if (mState == ScrimState.BUBBLE_EXPANDED) {
// Darken scrim as you pull down the shade when unlocked
float behindFraction = getInterpolatedFraction();
behindFraction = (float) Math.pow(behindFraction, 0.8f);
@@ -573,27 +601,45 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
// Either darken of make the scrim transparent when you
// pull down the shade
float interpolatedFract = getInterpolatedFraction();
- float alphaBehind = mState.getBehindAlpha();
+ float stateBehind = mClipsQsScrim ? mState.getNotifAlpha() : mState.getBehindAlpha();
+ float backAlpha;
if (mDarkenWhileDragging) {
- mBehindAlpha = MathUtils.lerp(mDefaultScrimAlpha, alphaBehind,
+ backAlpha = MathUtils.lerp(mDefaultScrimAlpha, stateBehind,
interpolatedFract);
- mInFrontAlpha = mState.getFrontAlpha();
} else {
- mBehindAlpha = MathUtils.lerp(0 /* start */, alphaBehind,
+ backAlpha = MathUtils.lerp(0 /* start */, stateBehind,
interpolatedFract);
- mInFrontAlpha = mState.getFrontAlpha();
}
- mBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(),
- mState.getBehindTint(), interpolatedFract);
+ mInFrontAlpha = mState.getFrontAlpha();
+ int backTint;
+ if (mClipsQsScrim) {
+ backTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getNotifTint(),
+ mState.getNotifTint(), interpolatedFract);
+ } else {
+ backTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(),
+ mState.getBehindTint(), interpolatedFract);
+ }
if (mQsExpansion > 0) {
- mBehindAlpha = MathUtils.lerp(mBehindAlpha, mDefaultScrimAlpha, mQsExpansion);
- mBehindTint = ColorUtils.blendARGB(mBehindTint,
- ScrimState.SHADE_LOCKED.getBehindTint(), mQsExpansion);
+ backAlpha = MathUtils.lerp(backAlpha, mDefaultScrimAlpha, mQsExpansion);
+ int stateTint = mClipsQsScrim ? ScrimState.SHADE_LOCKED.getNotifTint()
+ : ScrimState.SHADE_LOCKED.getBehindTint();
+ backTint = ColorUtils.blendARGB(backTint, stateTint, mQsExpansion);
+ }
+ if (mClipsQsScrim) {
+ mNotificationsAlpha = backAlpha;
+ mNotificationsTint = backTint;
+ mBehindAlpha = 1;
+ mBehindTint = Color.BLACK;
+ } else {
+ mBehindAlpha = backAlpha;
+ mNotificationsAlpha = Math.max(1.0f - getInterpolatedFraction(), mQsExpansion);
+ mBehindTint = backTint;
}
}
- if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha)) {
+ if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha) || isNaN(mNotificationsAlpha)) {
throw new IllegalStateException("Scrim opacity is NaN for state: " + mState
- + ", front: " + mInFrontAlpha + ", back: " + mBehindAlpha);
+ + ", front: " + mInFrontAlpha + ", back: " + mBehindAlpha + ", notif: "
+ + mNotificationsAlpha);
}
}
@@ -606,7 +652,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
setOrAdaptCurrentAnimation(mNotificationsScrim);
setOrAdaptCurrentAnimation(mScrimInFront);
setOrAdaptCurrentAnimation(mScrimForBubble);
- dispatchScrimState(mScrimBehind.getViewAlpha());
+ dispatchBackScrimState(mScrimBehind.getViewAlpha());
// Reset wallpaper timeout if it's already timeout like expanding panel while PULSING
// and docking.
@@ -693,10 +739,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
&& !mBlankScreen;
mScrimInFront.setColors(mColors, animateScrimInFront);
- mScrimBehind.setColors(mColors, animateScrimNotifications);
+ mScrimBehind.setColors(mColors, animateBehindScrim);
mNotificationsScrim.setColors(mColors, animateScrimNotifications);
- dispatchScrimState(mScrimBehind.getViewAlpha());
+ dispatchBackScrimState(mScrimBehind.getViewAlpha());
}
// We want to override the back scrim opacity for the AOD state
@@ -723,15 +769,21 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
dispatchScrimsVisible();
}
- private void dispatchScrimState(float alpha) {
+ private void dispatchBackScrimState(float alpha) {
+ // When clipping QS, the notification scrim is the one that feels behind.
+ // mScrimBehind will be drawing black and its opacity will always be 1.
+ if (mClipsQsScrim && mQsBottomVisible) {
+ alpha = mNotificationsAlpha;
+ }
mScrimStateListener.accept(mState, alpha, mScrimInFront.getColors());
}
private void dispatchScrimsVisible() {
+ final ScrimView backScrim = mClipsQsScrim ? mNotificationsScrim : mScrimBehind;
final int currentScrimVisibility;
- if (mScrimInFront.getViewAlpha() == 1 || mScrimBehind.getViewAlpha() == 1) {
+ if (mScrimInFront.getViewAlpha() == 1 || backScrim.getViewAlpha() == 1) {
currentScrimVisibility = OPAQUE;
- } else if (mScrimInFront.getViewAlpha() == 0 && mScrimBehind.getViewAlpha() == 0) {
+ } else if (mScrimInFront.getViewAlpha() == 0 && backScrim.getViewAlpha() == 0) {
currentScrimVisibility = TRANSPARENT;
} else {
currentScrimVisibility = SEMI_TRANSPARENT;
@@ -859,7 +911,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
} else if (scrim == mScrimBehind) {
return mBehindTint;
} else if (scrim == mNotificationsScrim) {
- return Color.TRANSPARENT;
+ return mNotificationsTint;
} else if (scrim == mScrimForBubble) {
return mBubbleTint;
} else {
@@ -917,9 +969,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
if (mState == ScrimState.UNLOCKED) {
mInFrontTint = Color.TRANSPARENT;
mBehindTint = mState.getBehindTint();
+ mNotificationsTint = mState.getNotifTint();
mBubbleTint = Color.TRANSPARENT;
updateScrimColor(mScrimInFront, mInFrontAlpha, mInFrontTint);
updateScrimColor(mScrimBehind, mBehindAlpha, mBehindTint);
+ updateScrimColor(mNotificationsScrim, mNotificationsAlpha, mNotificationsTint);
if (mScrimForBubble != null) {
updateScrimColor(mScrimForBubble, mBubbleAlpha, mBubbleTint);
}
@@ -964,7 +1018,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
if (scrim == mScrimBehind) {
- dispatchScrimState(alpha);
+ dispatchBackScrimState(alpha);
}
final boolean wantsAlphaUpdate = alpha != currentAlpha;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index a9774d850fd9..66cc26f5d295 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -22,7 +22,7 @@ import android.os.Trace;
import androidx.annotation.Nullable;
import com.android.systemui.dock.DockManager;
-import com.android.systemui.statusbar.ScrimView;
+import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
/**
@@ -80,11 +80,16 @@ public enum ScrimState {
}
mFrontTint = Color.BLACK;
mBehindTint = Color.BLACK;
+ mNotifTint = mClipQsScrim ? Color.BLACK : Color.TRANSPARENT;
mBubbleTint = Color.TRANSPARENT;
mFrontAlpha = 0;
- mBehindAlpha = mScrimBehindAlphaKeyguard;
+ mBehindAlpha = mClipQsScrim ? 1 : mScrimBehindAlphaKeyguard;
+ mNotifAlpha = mClipQsScrim ? mScrimBehindAlphaKeyguard : 0;
mBubbleAlpha = 0;
+ if (mClipQsScrim) {
+ updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK);
+ }
}
},
@@ -105,7 +110,10 @@ public enum ScrimState {
BOUNCER {
@Override
public void prepare(ScrimState previousState) {
- mBehindAlpha = mDefaultScrimAlpha;
+ mBehindAlpha = mClipQsScrim ? 1 : mDefaultScrimAlpha;
+ mBehindTint = mClipQsScrim ? Color.BLACK : Color.TRANSPARENT;
+ mNotifAlpha = mClipQsScrim ? mDefaultScrimAlpha : 0;
+ mNotifTint = Color.TRANSPARENT;
mFrontAlpha = 0f;
mBubbleAlpha = 0f;
}
@@ -126,10 +134,15 @@ public enum ScrimState {
SHADE_LOCKED {
@Override
public void prepare(ScrimState previousState) {
- mBehindAlpha = mDefaultScrimAlpha;
+ mBehindAlpha = mClipQsScrim ? 1 : mDefaultScrimAlpha;
+ mNotifAlpha = 1f;
mBubbleAlpha = 0f;
mFrontAlpha = 0f;
mBehindTint = Color.BLACK;
+
+ if (mClipQsScrim) {
+ updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK);
+ }
}
// to make sure correct color is returned before "prepare" is called
@@ -224,7 +237,8 @@ public enum ScrimState {
@Override
public void prepare(ScrimState previousState) {
// State that UI will sync to.
- mBehindAlpha = 0;
+ mBehindAlpha = mClipQsScrim ? 1 : 0;
+ mNotifAlpha = 0;
mFrontAlpha = 0;
mBubbleAlpha = 0;
@@ -253,6 +267,10 @@ public enum ScrimState {
mBubbleTint = Color.BLACK;
mBlankScreen = true;
}
+
+ if (mClipQsScrim) {
+ updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK);
+ }
}
},
@@ -279,12 +297,14 @@ public enum ScrimState {
int mFrontTint = Color.TRANSPARENT;
int mBehindTint = Color.TRANSPARENT;
int mBubbleTint = Color.TRANSPARENT;
+ int mNotifTint = Color.TRANSPARENT;
boolean mAnimateChange = true;
float mAodFrontScrimAlpha;
float mFrontAlpha;
float mBehindAlpha;
float mBubbleAlpha;
+ float mNotifAlpha;
float mScrimBehindAlphaKeyguard;
float mDefaultScrimAlpha;
@@ -301,6 +321,7 @@ public enum ScrimState {
boolean mWakeLockScreenSensorActive;
boolean mKeyguardFadingAway;
long mKeyguardFadingAwayDuration;
+ boolean mClipQsScrim;
public void init(ScrimView scrimInFront, ScrimView scrimBehind, ScrimView scrimForBubble,
DozeParameters dozeParameters, DockManager dockManager) {
@@ -325,6 +346,10 @@ public enum ScrimState {
return mBehindAlpha;
}
+ public float getNotifAlpha() {
+ return mNotifAlpha;
+ }
+
public float getBubbleAlpha() {
return mBubbleAlpha;
}
@@ -337,6 +362,10 @@ public enum ScrimState {
return mBehindTint;
}
+ public int getNotifTint() {
+ return mNotifTint;
+ }
+
public int getBubbleTint() {
return mBubbleTint;
}
@@ -406,4 +435,8 @@ public enum ScrimState {
mKeyguardFadingAway = fadingAway;
mKeyguardFadingAwayDuration = duration;
}
+
+ public void setClipQsScrim(boolean clipsQsScrim) {
+ mClipQsScrim = clipsQsScrim;
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 026072bf0d6a..de448100d33f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -21,7 +21,6 @@ import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.WindowType;
import static android.app.StatusBarManager.WindowVisibleState;
import static android.app.StatusBarManager.windowStateToString;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.InsetsState.containsType;
@@ -180,6 +179,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSFragment;
import com.android.systemui.qs.QSPanelController;
import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.scrim.ScrimView;
import com.android.systemui.settings.brightness.BrightnessSlider;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.AutoHideUiElement;
@@ -202,7 +202,6 @@ import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.PowerButtonReveal;
import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index b823534c2813..b95545576e56 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -63,11 +63,11 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.scrim.ScrimView;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.notification.NotificationChannelHelper;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java
index c2e58efe1328..a345f7804ae9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.scrim;
import static junit.framework.Assert.assertEquals;
@@ -31,7 +31,6 @@ import android.view.View;
import androidx.test.filters.SmallTest;
import com.android.internal.colorextraction.ColorExtractor;
-import com.android.internal.colorextraction.drawable.ScrimDrawable;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.utils.leaks.LeakCheckedTest;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 8633eb466b6c..559ee6f29bb6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -49,8 +49,8 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.DejankUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
+import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.FeatureFlags;
-import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -69,6 +69,7 @@ import org.mockito.stubbing.Answer;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -91,7 +92,7 @@ public class ScrimControllerTest extends SysuiTestCase {
@Mock
private AlarmManager mAlarmManager;
@Mock
- private DozeParameters mDozeParamenters;
+ private DozeParameters mDozeParameters;
@Mock
LightBarController mLightBarController;
@Mock
@@ -200,8 +201,8 @@ public class ScrimControllerTest extends SysuiTestCase {
return null;
}).when(mScrimBehind).postOnAnimationDelayed(any(Runnable.class), anyLong());
- when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
- when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
+ when(mDozeParameters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
+ when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true);
doAnswer((Answer<Void>) invocation -> {
mScrimState = invocation.getArgument(0);
@@ -220,7 +221,7 @@ public class ScrimControllerTest extends SysuiTestCase {
when(mDockManager.isDocked()).thenReturn(false);
mScrimController = new ScrimController(mLightBarController,
- mDozeParamenters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder,
+ mDozeParameters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder,
new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
mDockManager, mConfigurationController, mFeatureFlags,
new FakeExecutor(new FakeSystemClock()));
@@ -238,6 +239,10 @@ public class ScrimControllerTest extends SysuiTestCase {
@After
public void tearDown() {
finishAnimationsImmediately();
+ Arrays.stream(ScrimState.values()).forEach((scrim) -> {
+ scrim.setAodFrontScrimAlpha(0f);
+ scrim.setClipQsScrim(false);
+ });
DejankUtils.setImmediate(false);
}
@@ -259,9 +264,30 @@ public class ScrimControllerTest extends SysuiTestCase {
@Test
public void transitionToShadeLocked() {
mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
+ mScrimController.setQsPosition(1f, 0);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mNotificationsScrim, OPAQUE,
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
+
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, true,
+ mScrimForBubble, false
+ ));
+ }
+
+ @Test
+ public void transitionToShadeLocked_clippingQs() {
+ mScrimController.setClipsQsScrim(true);
+ mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
+ mScrimController.setQsPosition(1f, 0);
finishAnimationsImmediately();
assertScrimAlpha(Map.of(
+ mNotificationsScrim, OPAQUE,
mScrimInFront, TRANSPARENT,
mScrimBehind, OPAQUE));
@@ -403,9 +429,6 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setAodFrontScrimAlpha(0.3f);
Assert.assertEquals(ScrimState.AOD.getFrontAlpha(), mScrimInFront.getViewAlpha(), 0.001f);
Assert.assertNotEquals(0.3f, mScrimInFront.getViewAlpha(), 0.001f);
-
- // Reset value since enums are static.
- mScrimController.setAodFrontScrimAlpha(0f);
}
@Test
@@ -500,11 +523,34 @@ public class ScrimControllerTest extends SysuiTestCase {
// Back scrim should be visible without tint
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
mScrimBehind, OPAQUE));
assertScrimTinted(Map.of(
mScrimInFront, false,
mScrimBehind, false,
+ mNotificationsScrim, false,
+ mScrimForBubble, false
+ ));
+ }
+
+ @Test
+ public void transitionToKeyguardBouncer_clippingQs() {
+ mScrimController.setClipsQsScrim(true);
+ mScrimController.transitionTo(ScrimState.BOUNCER);
+ finishAnimationsImmediately();
+ // Front scrim should be transparent
+ // Back scrim should be clipping QS
+ // Notif scrim should be visible without tint
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, OPAQUE,
+ mScrimBehind, OPAQUE));
+
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, true,
+ mNotificationsScrim, false,
mScrimForBubble, false
));
}
@@ -530,9 +576,11 @@ public class ScrimControllerTest extends SysuiTestCase {
finishAnimationsImmediately();
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
mScrimBehind, TRANSPARENT));
assertScrimTinted(Map.of(
+ mNotificationsScrim, false,
mScrimInFront, false,
mScrimBehind, true,
mScrimForBubble, false
@@ -542,6 +590,7 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setPanelExpansion(0.5f);
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, SEMI_TRANSPARENT,
mScrimBehind, SEMI_TRANSPARENT));
}
@@ -617,6 +666,32 @@ public class ScrimControllerTest extends SysuiTestCase {
}
@Test
+ public void qsExpansion_clippingQs() {
+ reset(mScrimBehind);
+ mScrimController.setClipsQsScrim(true);
+ mScrimController.setQsPosition(1f, 999 /* value doesn't matter */);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE,
+ mNotificationsScrim, OPAQUE));
+ }
+
+ @Test
+ public void qsExpansion_half_clippingQs() {
+ reset(mScrimBehind);
+ mScrimController.setClipsQsScrim(true);
+ mScrimController.setQsPosition(0.5f, 999 /* value doesn't matter */);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE,
+ mNotificationsScrim, SEMI_TRANSPARENT));
+ }
+
+ @Test
public void panelExpansionAffectsAlpha() {
mScrimController.setPanelExpansion(0f);
mScrimController.setPanelExpansion(0.5f);
@@ -919,13 +994,13 @@ public class ScrimControllerTest extends SysuiTestCase {
@Test
public void testAnimatesTransitionToAod() {
- when(mDozeParamenters.shouldControlScreenOff()).thenReturn(false);
+ when(mDozeParameters.shouldControlScreenOff()).thenReturn(false);
ScrimState.AOD.prepare(ScrimState.KEYGUARD);
Assert.assertFalse("No animation when ColorFade kicks in",
ScrimState.AOD.getAnimateChange());
- reset(mDozeParamenters);
- when(mDozeParamenters.shouldControlScreenOff()).thenReturn(true);
+ reset(mDozeParameters);
+ when(mDozeParameters.shouldControlScreenOff()).thenReturn(true);
ScrimState.AOD.prepare(ScrimState.KEYGUARD);
Assert.assertTrue("Animate scrims when ColorFade won't be triggered",
ScrimState.AOD.getAnimateChange());
@@ -977,6 +1052,7 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setPanelExpansion(0.5f);
// notifications scrim alpha change require calling setQsPosition
mScrimController.setQsPosition(0, 300);
+ finishAnimationsImmediately();
assertScrimAlpha(Map.of(
mScrimBehind, SEMI_TRANSPARENT,
@@ -985,6 +1061,21 @@ public class ScrimControllerTest extends SysuiTestCase {
}
@Test
+ public void testScrimsVisible_whenShadeVisible_clippingQs() {
+ mScrimController.setClipsQsScrim(true);
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+ mScrimController.setPanelExpansion(0.5f);
+ // notifications scrim alpha change require calling setQsPosition
+ mScrimController.setQsPosition(0.5f, 300);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mScrimBehind, OPAQUE,
+ mNotificationsScrim, SEMI_TRANSPARENT,
+ mScrimInFront, TRANSPARENT));
+ }
+
+ @Test
public void testScrimsVisible_whenShadeVisibleOnLockscreen() {
mScrimController.transitionTo(ScrimState.KEYGUARD);
mScrimController.setQsPosition(0.5f, 300);
@@ -1008,8 +1099,6 @@ public class ScrimControllerTest extends SysuiTestCase {
}
private void assertScrimTinted(Map<ScrimView, Boolean> scrimToTint) {
- // notifications scrim should have always transparent tint
- assertScrimTint(mNotificationsScrim, false);
scrimToTint.forEach((scrim, hasTint) -> assertScrimTint(scrim, hasTint));
}
@@ -1047,6 +1136,12 @@ public class ScrimControllerTest extends SysuiTestCase {
}
scrimToAlpha.forEach((scrimView, alpha) -> assertScrimAlpha(scrimView, alpha));
+ // When clipping, QS scrim should not affect combined visibility.
+ if (mScrimController.getClipQsScrim() && scrimToAlpha.get(mScrimBehind) == OPAQUE) {
+ scrimToAlpha = new HashMap<>(scrimToAlpha);
+ scrimToAlpha.remove(mScrimBehind);
+ }
+
// Check combined scrim visibility.
final int visibility;
if (scrimToAlpha.values().contains(OPAQUE)) {