2018-02-28 15:09:36 -08:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2018 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.launcher3.graphics;
|
|
|
|
|
|
2020-03-17 14:24:42 -07:00
|
|
|
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
|
2018-11-05 11:08:31 -08:00
|
|
|
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
|
|
|
|
|
|
2018-05-08 11:10:44 -07:00
|
|
|
import android.animation.ObjectAnimator;
|
2018-02-28 15:09:36 -08:00
|
|
|
import android.graphics.Bitmap;
|
|
|
|
|
import android.graphics.Canvas;
|
|
|
|
|
import android.graphics.Color;
|
|
|
|
|
import android.graphics.LinearGradient;
|
|
|
|
|
import android.graphics.Paint;
|
|
|
|
|
import android.graphics.Rect;
|
|
|
|
|
import android.graphics.RectF;
|
|
|
|
|
import android.graphics.Shader;
|
2018-05-08 11:10:44 -07:00
|
|
|
import android.graphics.drawable.Drawable;
|
2018-02-28 15:09:36 -08:00
|
|
|
import android.util.DisplayMetrics;
|
2020-03-06 15:35:55 -08:00
|
|
|
import android.util.FloatProperty;
|
2018-02-28 15:09:36 -08:00
|
|
|
import android.view.View;
|
2020-03-20 12:50:04 -07:00
|
|
|
import android.view.WindowInsets;
|
2018-02-28 15:09:36 -08:00
|
|
|
|
2021-04-26 09:52:47 -07:00
|
|
|
import com.android.launcher3.BaseDraggingActivity;
|
2018-02-28 15:09:36 -08:00
|
|
|
import com.android.launcher3.R;
|
2020-03-20 12:50:04 -07:00
|
|
|
import com.android.launcher3.Utilities;
|
2021-05-06 15:09:15 +08:00
|
|
|
import com.android.launcher3.config.FeatureFlags;
|
2023-01-10 17:50:32 -08:00
|
|
|
import com.android.launcher3.testing.shared.ResourceUtils;
|
2021-05-06 15:09:15 +08:00
|
|
|
import com.android.launcher3.util.DynamicResource;
|
2023-01-10 17:50:32 -08:00
|
|
|
import com.android.launcher3.util.ScreenOnTracker;
|
|
|
|
|
import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
|
2018-05-08 11:10:44 -07:00
|
|
|
import com.android.launcher3.util.Themes;
|
2021-05-06 15:09:15 +08:00
|
|
|
import com.android.systemui.plugins.ResourceProvider;
|
2018-02-28 15:09:36 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* View scrim which draws behind hotseat and workspace
|
|
|
|
|
*/
|
2021-04-26 09:52:47 -07:00
|
|
|
public class SysUiScrim implements View.OnAttachStateChangeListener {
|
2018-05-08 11:10:44 -07:00
|
|
|
|
2021-02-02 16:45:07 -08:00
|
|
|
public static final FloatProperty<SysUiScrim> SYSUI_PROGRESS =
|
|
|
|
|
new FloatProperty<SysUiScrim>("sysUiProgress") {
|
2018-05-08 11:10:44 -07:00
|
|
|
@Override
|
2021-02-02 16:45:07 -08:00
|
|
|
public Float get(SysUiScrim scrim) {
|
2018-05-08 11:10:44 -07:00
|
|
|
return scrim.mSysUiProgress;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2021-02-02 16:45:07 -08:00
|
|
|
public void setValue(SysUiScrim scrim, float value) {
|
2018-05-08 11:10:44 -07:00
|
|
|
scrim.setSysUiProgress(value);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-02 16:45:07 -08:00
|
|
|
private static final FloatProperty<SysUiScrim> SYSUI_ANIM_MULTIPLIER =
|
|
|
|
|
new FloatProperty<SysUiScrim>("sysUiAnimMultiplier") {
|
2018-05-08 11:10:44 -07:00
|
|
|
@Override
|
2021-02-02 16:45:07 -08:00
|
|
|
public Float get(SysUiScrim scrim) {
|
2018-05-08 11:10:44 -07:00
|
|
|
return scrim.mSysUiAnimMultiplier;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2021-02-02 16:45:07 -08:00
|
|
|
public void setValue(SysUiScrim scrim, float value) {
|
2018-05-08 11:10:44 -07:00
|
|
|
scrim.mSysUiAnimMultiplier = value;
|
|
|
|
|
scrim.reapplySysUiAlpha();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-03-17 14:24:42 -07:00
|
|
|
/**
|
|
|
|
|
* Receiver used to get a signal that the user unlocked their device.
|
|
|
|
|
*/
|
2023-01-10 17:50:32 -08:00
|
|
|
private final ScreenOnListener mScreenOnListener = new ScreenOnListener() {
|
2019-02-28 20:36:37 -08:00
|
|
|
@Override
|
2023-01-10 17:50:32 -08:00
|
|
|
public void onScreenOnChanged(boolean isOn) {
|
|
|
|
|
if (!isOn) {
|
2019-02-28 20:36:37 -08:00
|
|
|
mAnimateScrimOnNextDraw = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-10 17:50:32 -08:00
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onUserPresent() {
|
|
|
|
|
// ACTION_USER_PRESENT is sent after onStart/onResume. This covers the case where
|
|
|
|
|
// the user unlocked and the Launcher is not in the foreground.
|
|
|
|
|
mAnimateScrimOnNextDraw = false;
|
|
|
|
|
}
|
2019-02-28 20:36:37 -08:00
|
|
|
};
|
|
|
|
|
|
2018-02-28 15:09:36 -08:00
|
|
|
private static final int MAX_HOTSEAT_SCRIM_ALPHA = 100;
|
|
|
|
|
private static final int ALPHA_MASK_HEIGHT_DP = 500;
|
|
|
|
|
private static final int ALPHA_MASK_BITMAP_DP = 200;
|
|
|
|
|
private static final int ALPHA_MASK_WIDTH_DP = 2;
|
|
|
|
|
|
2021-05-06 15:09:15 +08:00
|
|
|
private boolean mDrawTopScrim, mDrawBottomScrim, mDrawWallpaperScrim;
|
2018-02-28 15:09:36 -08:00
|
|
|
|
2021-05-06 15:09:15 +08:00
|
|
|
private final RectF mWallpaperScrimRect = new RectF();
|
|
|
|
|
private final Paint mWallpaperScrimPaint = new Paint();
|
2018-02-28 15:09:36 -08:00
|
|
|
private final RectF mFinalMaskRect = new RectF();
|
|
|
|
|
private final Paint mBottomMaskPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
|
|
|
|
|
private final Bitmap mBottomMask;
|
|
|
|
|
private final int mMaskHeight;
|
|
|
|
|
|
2021-04-26 09:52:47 -07:00
|
|
|
private final View mRoot;
|
|
|
|
|
private final BaseDraggingActivity mActivity;
|
2018-05-08 11:10:44 -07:00
|
|
|
private final Drawable mTopScrim;
|
|
|
|
|
|
|
|
|
|
private float mSysUiProgress = 1;
|
2018-05-10 15:08:51 -07:00
|
|
|
private boolean mHideSysUiScrim;
|
2018-02-28 15:09:36 -08:00
|
|
|
|
2018-05-08 11:10:44 -07:00
|
|
|
private boolean mAnimateScrimOnNextDraw = false;
|
|
|
|
|
private float mSysUiAnimMultiplier = 1;
|
2021-05-06 15:09:15 +08:00
|
|
|
private int mWallpaperScrimMaxAlpha;
|
2018-05-08 11:10:44 -07:00
|
|
|
|
2021-02-02 16:45:07 -08:00
|
|
|
public SysUiScrim(View view) {
|
2021-04-26 09:52:47 -07:00
|
|
|
mRoot = view;
|
|
|
|
|
mActivity = BaseDraggingActivity.fromContext(view.getContext());
|
2019-05-08 15:29:37 -07:00
|
|
|
mMaskHeight = ResourceUtils.pxFromDp(ALPHA_MASK_BITMAP_DP,
|
2018-02-28 15:09:36 -08:00
|
|
|
view.getResources().getDisplayMetrics());
|
2018-10-31 13:57:15 -07:00
|
|
|
mTopScrim = Themes.getAttrDrawable(view.getContext(), R.attr.workspaceStatusBarScrim);
|
|
|
|
|
mBottomMask = mTopScrim == null ? null : createDitheredAlphaMask();
|
|
|
|
|
mHideSysUiScrim = mTopScrim == null;
|
2018-02-28 15:09:36 -08:00
|
|
|
|
2021-05-06 15:09:15 +08:00
|
|
|
mDrawWallpaperScrim = FeatureFlags.ENABLE_WALLPAPER_SCRIM.get()
|
|
|
|
|
&& !Themes.getAttrBoolean(view.getContext(), R.attr.isMainColorDark)
|
|
|
|
|
&& !Themes.getAttrBoolean(view.getContext(), R.attr.isWorkspaceDarkText);
|
|
|
|
|
ResourceProvider rp = DynamicResource.provider(view.getContext());
|
|
|
|
|
int wallpaperScrimColor = rp.getColor(R.color.wallpaper_scrim_color);
|
|
|
|
|
mWallpaperScrimMaxAlpha = Color.alpha(wallpaperScrimColor);
|
|
|
|
|
mWallpaperScrimPaint.setColor(wallpaperScrimColor);
|
|
|
|
|
|
2021-04-26 09:52:47 -07:00
|
|
|
view.addOnAttachStateChangeListener(this);
|
2018-02-28 15:09:36 -08:00
|
|
|
}
|
|
|
|
|
|
2021-02-02 16:45:07 -08:00
|
|
|
/**
|
|
|
|
|
* Draw the top and bottom scrims
|
|
|
|
|
*/
|
2018-05-08 11:10:44 -07:00
|
|
|
public void draw(Canvas canvas) {
|
2018-10-31 13:57:15 -07:00
|
|
|
if (!mHideSysUiScrim) {
|
2018-05-08 11:10:44 -07:00
|
|
|
if (mSysUiProgress <= 0) {
|
|
|
|
|
mAnimateScrimOnNextDraw = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mAnimateScrimOnNextDraw) {
|
|
|
|
|
mSysUiAnimMultiplier = 0;
|
|
|
|
|
reapplySysUiAlphaNoInvalidate();
|
|
|
|
|
|
2020-03-17 14:24:42 -07:00
|
|
|
ObjectAnimator oa = createSysuiMultiplierAnim(1);
|
|
|
|
|
oa.setDuration(600);
|
2021-04-26 09:52:47 -07:00
|
|
|
oa.setStartDelay(mActivity.getWindow().getTransitionBackgroundFadeDuration());
|
2020-03-17 14:24:42 -07:00
|
|
|
oa.start();
|
2018-05-08 11:10:44 -07:00
|
|
|
mAnimateScrimOnNextDraw = false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-06 15:09:15 +08:00
|
|
|
if (mDrawWallpaperScrim) {
|
|
|
|
|
canvas.drawRect(mWallpaperScrimRect, mWallpaperScrimPaint);
|
|
|
|
|
}
|
2018-05-08 11:10:44 -07:00
|
|
|
if (mDrawTopScrim) {
|
|
|
|
|
mTopScrim.draw(canvas);
|
|
|
|
|
}
|
|
|
|
|
if (mDrawBottomScrim) {
|
|
|
|
|
canvas.drawBitmap(mBottomMask, null, mFinalMaskRect, mBottomMaskPaint);
|
|
|
|
|
}
|
2018-02-28 15:09:36 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-17 14:24:42 -07:00
|
|
|
/**
|
|
|
|
|
* @return an ObjectAnimator that controls the fade in/out of the sys ui scrim.
|
|
|
|
|
*/
|
|
|
|
|
public ObjectAnimator createSysuiMultiplierAnim(float... values) {
|
|
|
|
|
ObjectAnimator anim = ObjectAnimator.ofFloat(this, SYSUI_ANIM_MULTIPLIER, values);
|
2019-07-24 17:32:08 -07:00
|
|
|
anim.setAutoCancel(true);
|
2020-03-17 14:24:42 -07:00
|
|
|
return anim;
|
2019-07-24 17:32:08 -07:00
|
|
|
}
|
|
|
|
|
|
2020-03-19 13:19:31 -07:00
|
|
|
/**
|
|
|
|
|
* Determines whether to draw the top and/or bottom scrim based on new insets.
|
|
|
|
|
*/
|
2021-04-26 09:52:47 -07:00
|
|
|
public void onInsetsChanged(Rect insets) {
|
|
|
|
|
mDrawTopScrim = mTopScrim != null && insets.top > 0;
|
|
|
|
|
mDrawBottomScrim = mBottomMask != null
|
|
|
|
|
&& !mActivity.getDeviceProfile().isVerticalBarLayout()
|
2020-03-20 12:50:04 -07:00
|
|
|
&& hasBottomNavButtons();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean hasBottomNavButtons() {
|
2021-04-26 09:52:47 -07:00
|
|
|
if (Utilities.ATLEAST_Q && mActivity.getRootView() != null
|
|
|
|
|
&& mActivity.getRootView().getRootWindowInsets() != null) {
|
|
|
|
|
WindowInsets windowInsets = mActivity.getRootView().getRootWindowInsets();
|
2020-03-20 12:50:04 -07:00
|
|
|
return windowInsets.getTappableElementInsets().bottom > 0;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
2018-05-08 11:10:44 -07:00
|
|
|
}
|
|
|
|
|
|
2018-02-28 15:09:36 -08:00
|
|
|
@Override
|
|
|
|
|
public void onViewAttachedToWindow(View view) {
|
2020-03-17 14:24:42 -07:00
|
|
|
if (!KEYGUARD_ANIMATION.get() && mTopScrim != null) {
|
2023-01-10 17:50:32 -08:00
|
|
|
ScreenOnTracker.INSTANCE.get(mActivity).addListener(mScreenOnListener);
|
2019-02-28 20:36:37 -08:00
|
|
|
}
|
2018-02-28 15:09:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onViewDetachedFromWindow(View view) {
|
2020-03-17 14:24:42 -07:00
|
|
|
if (!KEYGUARD_ANIMATION.get() && mTopScrim != null) {
|
2023-01-10 17:50:32 -08:00
|
|
|
ScreenOnTracker.INSTANCE.get(mActivity).removeListener(mScreenOnListener);
|
2019-02-28 20:36:37 -08:00
|
|
|
}
|
2018-02-28 15:09:36 -08:00
|
|
|
}
|
|
|
|
|
|
2021-02-02 16:45:07 -08:00
|
|
|
/**
|
|
|
|
|
* Set the width and height of the view being scrimmed
|
|
|
|
|
* @param w
|
|
|
|
|
* @param h
|
|
|
|
|
*/
|
2018-05-08 11:10:44 -07:00
|
|
|
public void setSize(int w, int h) {
|
2018-10-31 13:57:15 -07:00
|
|
|
if (mTopScrim != null) {
|
2018-05-08 11:10:44 -07:00
|
|
|
mTopScrim.setBounds(0, 0, w, h);
|
|
|
|
|
mFinalMaskRect.set(0, h - mMaskHeight, w, h);
|
|
|
|
|
}
|
2021-05-06 15:09:15 +08:00
|
|
|
mWallpaperScrimRect.set(0, 0, w, h);
|
2018-05-08 11:10:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setSysUiProgress(float progress) {
|
|
|
|
|
if (progress != mSysUiProgress) {
|
|
|
|
|
mSysUiProgress = progress;
|
|
|
|
|
reapplySysUiAlpha();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void reapplySysUiAlpha() {
|
2018-10-31 13:57:15 -07:00
|
|
|
reapplySysUiAlphaNoInvalidate();
|
|
|
|
|
if (!mHideSysUiScrim) {
|
2021-04-26 09:52:47 -07:00
|
|
|
mRoot.invalidate();
|
2018-05-08 11:10:44 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void reapplySysUiAlphaNoInvalidate() {
|
|
|
|
|
float factor = mSysUiProgress * mSysUiAnimMultiplier;
|
|
|
|
|
mBottomMaskPaint.setAlpha(Math.round(MAX_HOTSEAT_SCRIM_ALPHA * factor));
|
2018-10-31 13:57:15 -07:00
|
|
|
if (mTopScrim != null) {
|
|
|
|
|
mTopScrim.setAlpha(Math.round(255 * factor));
|
|
|
|
|
}
|
2021-05-06 15:09:15 +08:00
|
|
|
mWallpaperScrimPaint.setAlpha(Math.round(mWallpaperScrimMaxAlpha * factor));
|
2018-05-08 11:10:44 -07:00
|
|
|
}
|
|
|
|
|
|
2020-01-27 15:04:04 -08:00
|
|
|
private Bitmap createDitheredAlphaMask() {
|
2021-04-26 09:52:47 -07:00
|
|
|
DisplayMetrics dm = mActivity.getResources().getDisplayMetrics();
|
2019-05-08 15:29:37 -07:00
|
|
|
int width = ResourceUtils.pxFromDp(ALPHA_MASK_WIDTH_DP, dm);
|
|
|
|
|
int gradientHeight = ResourceUtils.pxFromDp(ALPHA_MASK_HEIGHT_DP, dm);
|
2018-02-28 15:09:36 -08:00
|
|
|
Bitmap dst = Bitmap.createBitmap(width, mMaskHeight, Bitmap.Config.ALPHA_8);
|
|
|
|
|
Canvas c = new Canvas(dst);
|
|
|
|
|
Paint paint = new Paint(Paint.DITHER_FLAG);
|
|
|
|
|
LinearGradient lg = new LinearGradient(0, 0, 0, gradientHeight,
|
|
|
|
|
new int[]{
|
|
|
|
|
0x00FFFFFF,
|
2018-11-05 11:08:31 -08:00
|
|
|
setColorAlphaBound(Color.WHITE, (int) (0xFF * 0.95)),
|
2018-02-28 15:09:36 -08:00
|
|
|
0xFFFFFFFF},
|
|
|
|
|
new float[]{0f, 0.8f, 1f},
|
|
|
|
|
Shader.TileMode.CLAMP);
|
|
|
|
|
paint.setShader(lg);
|
|
|
|
|
c.drawRect(0, 0, width, gradientHeight, paint);
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
}
|