Merge "Add blurs to WAKE_AND_UNLOCK"

This commit is contained in:
Lucas Dupin
2020-02-11 17:03:34 +00:00
committed by Android (Google) Code Review
13 changed files with 222 additions and 97 deletions

View File

@@ -26,6 +26,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.ServiceManager;
import android.util.DisplayMetrics;
import android.view.Choreographer;
import android.view.IWindowManager;
import android.view.LayoutInflater;
@@ -203,4 +204,11 @@ public class DependencyProvider {
public ViewMediatorCallback providesViewMediatorCallback(KeyguardViewMediator viewMediator) {
return viewMediator.getViewMediatorCallback();
}
/** */
@Singleton
@Provides
public Choreographer providesChoreographer() {
return Choreographer.getInstance();
}
}

View File

@@ -19,14 +19,13 @@ package com.android.systemui.dagger;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.view.Choreographer;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.DumpController;
import com.android.systemui.assist.AssistModule;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.log.dagger.LogModule;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -34,18 +33,22 @@ import com.android.systemui.recents.Recents;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.BlurUtils;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarWindowBlurController;
import com.android.systemui.statusbar.NotificationShadeWindowBlurController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
import com.android.systemui.statusbar.notification.people.PeopleHubModule;
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.ConcurrencyModule;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.time.SystemClock;
@@ -100,11 +103,16 @@ public abstract class SystemUIModule {
@Singleton
@Provides
@Nullable
static StatusBarWindowBlurController providesBlurController(BlurUtils blurUtils,
@Main Resources resources, SysuiStatusBarStateController statusBarStateController,
DumpController dumpController) {
return blurUtils.supportsBlursOnWindows() ? new StatusBarWindowBlurController(resources,
statusBarStateController, blurUtils, dumpController) : null;
static NotificationShadeWindowBlurController providesBlurController(BlurUtils blurUtils,
SysuiStatusBarStateController statusBarStateController,
DumpController dumpController, BiometricUnlockController biometricUnlockController,
KeyguardStateController keyguardStateController,
NotificationShadeWindowController notificationShadeWindowController,
Choreographer choreographer) {
return blurUtils.supportsBlursOnWindows() ? new NotificationShadeWindowBlurController(
statusBarStateController, blurUtils, biometricUnlockController,
keyguardStateController, notificationShadeWindowController, choreographer,
dumpController) : null;
}
/** */

View File

@@ -101,6 +101,7 @@ import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.statusbar.BlurUtils;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.EmergencyDialerConstants;
@@ -1668,7 +1669,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
if (mBackgroundDrawable == null) {
mBackgroundDrawable = new ScrimDrawable();
mScrimAlpha = 0.8f;
mScrimAlpha = ScrimController.BUSY_SCRIM_ALPHA;
}
getWindow().setBackgroundDrawable(mBackgroundDrawable);
}

View File

@@ -149,7 +149,7 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
}
if (mBlurUtils.supportsBlursOnWindows()) {
background.setAlpha((int) (ScrimController.GRADIENT_SCRIM_ALPHA_BUSY * 255));
background.setAlpha((int) (ScrimController.BUSY_SCRIM_ALPHA * 255));
mBlurUtils.applyBlur(d.getWindow().getDecorView().getViewRootImpl(),
mBlurUtils.radiusForRatio(1));
} else {

View File

@@ -0,0 +1,176 @@
/*
* Copyright (C) 2020 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
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.view.Choreographer
import android.view.View
import com.android.internal.util.IndentingPrintWriter
import com.android.systemui.DumpController
import com.android.systemui.Dumpable
import com.android.systemui.Interpolators
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
import com.android.systemui.statusbar.phone.NotificationShadeWindowController
import com.android.systemui.statusbar.phone.PanelExpansionListener
import com.android.systemui.statusbar.policy.KeyguardStateController
import java.io.FileDescriptor
import java.io.PrintWriter
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.max
/**
* Controller responsible for statusbar window blur.
*/
@Singleton
class NotificationShadeWindowBlurController @Inject constructor(
private val statusBarStateController: SysuiStatusBarStateController,
private val blurUtils: BlurUtils,
private val biometricUnlockController: BiometricUnlockController,
private val keyguardStateController: KeyguardStateController,
private val notificationShadeWindowController: NotificationShadeWindowController,
private val choreographer: Choreographer,
dumpController: DumpController
) : PanelExpansionListener, Dumpable {
companion object {
private const val WAKE_UP_ANIMATION_ENABLED = true
private const val SHADE_BLUR_ENABLED = true
}
lateinit var root: View
private var keyguardAnimator: Animator? = null
private var notificationAnimator: Animator? = null
private var updateScheduled: Boolean = false
private var shadeExpansion = 1.0f
private var shadeBlurRadius = 0
set(value) {
if (field == value) return
field = value
scheduleUpdate()
}
private var wakeAndUnlockBlurRadius = 0
set(value) {
if (field == value) return
field = value
scheduleUpdate()
}
private var incomingNotificationBlurRadius = 0
set(value) {
if (field == value) return
field = value
scheduleUpdate()
}
/**
* Callback that updates the window blur value and is called only once per frame.
*/
private val updateBlurCallback = Choreographer.FrameCallback {
updateScheduled = false
var notificationBlur = 0
if (statusBarStateController.state == StatusBarState.KEYGUARD) {
notificationBlur = (incomingNotificationBlurRadius * shadeExpansion).toInt()
}
val blur = max(max(shadeBlurRadius, wakeAndUnlockBlurRadius), notificationBlur)
blurUtils.applyBlur(root.viewRootImpl, blur)
}
/**
* Animate blurs when unlocking.
*/
private val keyguardStateCallback = object : KeyguardStateController.Callback {
override fun onKeyguardFadingAwayChanged() {
if (!keyguardStateController.isKeyguardFadingAway ||
biometricUnlockController.mode != MODE_WAKE_AND_UNLOCK) {
return
}
keyguardAnimator?.cancel()
keyguardAnimator = ValueAnimator.ofFloat(1f, 0f).apply {
duration = keyguardStateController.keyguardFadingAwayDuration
startDelay = keyguardStateController.keyguardFadingAwayDelay
interpolator = Interpolators.DECELERATE_QUINT
addUpdateListener { animation: ValueAnimator ->
wakeAndUnlockBlurRadius =
blurUtils.radiusForRatio(animation.animatedValue as Float)
}
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
keyguardAnimator = null
scheduleUpdate()
}
})
start()
}
}
override fun onKeyguardShowingChanged() {
if (keyguardStateController.isShowing) {
keyguardAnimator?.cancel()
notificationAnimator?.cancel()
}
}
}
init {
dumpController.registerDumpable(this)
if (WAKE_UP_ANIMATION_ENABLED) {
keyguardStateController.addCallback(keyguardStateCallback)
}
}
/**
* Update blurs when pulling down the shade
*/
override fun onPanelExpansionChanged(expansion: Float, tracking: Boolean) {
if (!SHADE_BLUR_ENABLED) {
return
}
var newBlur = 0
if (statusBarStateController.state == StatusBarState.SHADE) {
newBlur = blurUtils.radiusForRatio(expansion)
}
if (shadeBlurRadius == newBlur) {
return
}
shadeBlurRadius = newBlur
scheduleUpdate()
}
private fun scheduleUpdate() {
if (updateScheduled) {
return
}
updateScheduled = true
choreographer.postFrameCallback(updateBlurCallback)
}
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
IndentingPrintWriter(pw, " ").use {
it.println("StatusBarWindowBlurController:")
it.increaseIndent()
it.println("shadeBlurRadius: $shadeBlurRadius")
it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
}
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (C) 2020 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
import android.content.res.Resources
import android.view.View
import com.android.internal.util.IndentingPrintWriter
import com.android.systemui.DumpController
import com.android.systemui.Dumpable
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.statusbar.phone.PanelExpansionListener
import java.io.FileDescriptor
import java.io.PrintWriter
import javax.inject.Inject
import javax.inject.Singleton
/**
* Controller responsible for statusbar window blur.
*/
@Singleton
class StatusBarWindowBlurController @Inject constructor(
@Main private val resources: Resources,
private val statusBarStateController: SysuiStatusBarStateController,
private val blurUtils: BlurUtils,
dumpController: DumpController
) : PanelExpansionListener, Dumpable {
lateinit var root: View
private var blurRadius = 0
init {
dumpController.registerDumpable(this)
}
override fun onPanelExpansionChanged(expansion: Float, tracking: Boolean) {
val newBlur = if (statusBarStateController.state == StatusBarState.SHADE)
blurUtils.radiusForRatio(expansion)
else
0
if (blurRadius == newBlur) {
return
}
blurRadius = newBlur
blurUtils.applyBlur(root.viewRootImpl, blurRadius)
}
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
IndentingPrintWriter(pw, " ").use {
it.println("StatusBarWindowBlurController:")
it.increaseIndent()
it.println("blurRadius: $blurRadius")
}
}
}

View File

@@ -18,8 +18,8 @@ package com.android.systemui.statusbar.phone;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;

View File

@@ -45,7 +45,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarWindowBlurController;
import com.android.systemui.statusbar.NotificationShadeWindowBlurController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -81,7 +81,7 @@ public class NotificationShadeWindowViewController {
private final CommandQueue mCommandQueue;
private final NotificationShadeWindowView mView;
private final ShadeController mShadeController;
private final StatusBarWindowBlurController mBlurController;
private final NotificationShadeWindowBlurController mBlurController;
private GestureDetector mGestureDetector;
private View mBrightnessMirror;
@@ -123,7 +123,7 @@ public class NotificationShadeWindowViewController {
CommandQueue commandQueue,
ShadeController shadeController,
DockManager dockManager,
@Nullable StatusBarWindowBlurController blurController,
@Nullable NotificationShadeWindowBlurController blurController,
NotificationShadeWindowView statusBarWindowView,
NotificationPanelViewController notificationPanelViewController) {
mInjectionInflationController = injectionInflationController;

View File

@@ -107,7 +107,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
/**
* Default alpha value for most scrims.
*/
public static final float GRADIENT_SCRIM_ALPHA = 0.2f;
public static final float SCRIM_ALPHA = 0.2f;
/**
* Scrim opacity when the phone is about to wake-up.
*/
@@ -116,12 +116,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
* A scrim varies its opacity based on a busyness factor, for example
* how many notifications are currently visible.
*/
public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.7f;
public static final float BUSY_SCRIM_ALPHA = 0.54f;
/**
* The most common scrim, the one under the keyguard.
*/
protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = SCRIM_ALPHA;
static final int TAG_KEY_ANIM = R.id.scrim;
private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
@@ -481,7 +481,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
// Darken scrim as you pull down the shade when unlocked
float behindFraction = getInterpolatedFraction();
behindFraction = (float) Math.pow(behindFraction, 0.8f);
mBehindAlpha = behindFraction * GRADIENT_SCRIM_ALPHA_BUSY;
mBehindAlpha = behindFraction * BUSY_SCRIM_ALPHA;
mInFrontAlpha = 0;
} else if (mState == ScrimState.KEYGUARD || mState == ScrimState.PULSING) {
// Either darken of make the scrim transparent when you
@@ -489,7 +489,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
float interpolatedFract = getInterpolatedFraction();
float alphaBehind = mState.getBehindAlpha();
if (mDarkenWhileDragging) {
mBehindAlpha = MathUtils.lerp(GRADIENT_SCRIM_ALPHA_BUSY, alphaBehind,
mBehindAlpha = MathUtils.lerp(BUSY_SCRIM_ALPHA, alphaBehind,
interpolatedFract);
mInFrontAlpha = mState.getFrontAlpha();
} else {

View File

@@ -92,7 +92,7 @@ public enum ScrimState {
BOUNCER {
@Override
public void prepare(ScrimState previousState) {
mBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
mBehindAlpha = ScrimController.BUSY_SCRIM_ALPHA;
mFrontAlpha = 0f;
mBubbleAlpha = 0f;
}
@@ -106,7 +106,7 @@ public enum ScrimState {
public void prepare(ScrimState previousState) {
mBehindAlpha = 0;
mBubbleAlpha = 0f;
mFrontAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
mFrontAlpha = ScrimController.BUSY_SCRIM_ALPHA;
}
},
@@ -234,8 +234,8 @@ public enum ScrimState {
mBubbleTint = Color.TRANSPARENT;
mFrontAlpha = ScrimController.TRANSPARENT;
mBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
mBubbleAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
mBehindAlpha = ScrimController.BUSY_SCRIM_ALPHA;
mBubbleAlpha = ScrimController.BUSY_SCRIM_ALPHA;
mAnimationDuration = ScrimController.ANIMATION_DURATION;
mBlankScreen = false;

View File

@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.ViewRootImpl.sNewInsetsMode;
import static android.view.WindowInsets.Type.navigationBars;
import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_FADING;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;

View File

@@ -38,7 +38,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarWindowBlurController;
import com.android.systemui.statusbar.NotificationShadeWindowBlurController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -80,7 +80,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
@Mock private DockManager mDockManager;
@Mock private NotificationPanelViewController mNotificationPanelViewController;
@Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
@Mock private StatusBarWindowBlurController mStatusBarWindowBlurController;
@Mock private NotificationShadeWindowBlurController mNotificationShadeWindowBlurController;
@Before
public void setUp() {
@@ -114,7 +114,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
new CommandQueue(mContext),
mShadeController,
mDockManager,
mStatusBarWindowBlurController,
mNotificationShadeWindowBlurController,
mView,
mNotificationPanelViewController);
mController.setupExpandedStatusBar();

View File

@@ -521,10 +521,10 @@ public class ScrimControllerTest extends SysuiTestCase {
Assert.assertEquals(ScrimController.TRANSPARENT,
mScrimInFront.getViewAlpha(), 0.0f);
// Back scrim should be visible
Assert.assertEquals(ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
Assert.assertEquals(ScrimController.BUSY_SCRIM_ALPHA,
mScrimBehind.getViewAlpha(), 0.0f);
// Bubble scrim should be visible
Assert.assertEquals(ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
Assert.assertEquals(ScrimController.BUSY_SCRIM_ALPHA,
mScrimBehind.getViewAlpha(), 0.0f);
}