Fixed an issue where the statusbar was made opaque even though it wasnt
Because on Pixel 4 and other devices, the light reveal scrim doesn't have full alpha, the notification panel was marked opaque which removed the wallpaper. This could lead to the wallpaper not being visible in a couple of situations where it should have been, leaving AOD exposed. Because of a separate bug (b/196306312), whenever the wallpaper is hidden, we'd see a color layer, which would lead to the screen becoming flickery and awake on AOD. Fixes: 194760238 Test: atest SystemUITests Change-Id: I5a7e80e2ced8f15f1b215549d0c051f1d61d2953
This commit is contained in:
@@ -178,7 +178,10 @@ class PowerButtonReveal(
|
|||||||
*/
|
*/
|
||||||
class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
|
class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
|
||||||
|
|
||||||
lateinit var revealAmountListener: Consumer<Float>
|
/**
|
||||||
|
* Listener that is called if the scrim's opaqueness changes
|
||||||
|
*/
|
||||||
|
lateinit var isScrimOpaqueChangedListener: Consumer<Boolean>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How much of the underlying views are revealed, in percent. 0 means they will be completely
|
* How much of the underlying views are revealed, in percent. 0 means they will be completely
|
||||||
@@ -190,7 +193,7 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context,
|
|||||||
field = value
|
field = value
|
||||||
|
|
||||||
revealEffect.setRevealAmountOnScrim(value, this)
|
revealEffect.setRevealAmountOnScrim(value, this)
|
||||||
revealAmountListener.accept(value)
|
updateScrimOpaque()
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,6 +232,31 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the scrim currently fully opaque
|
||||||
|
*/
|
||||||
|
var isScrimOpaque = false
|
||||||
|
private set(value) {
|
||||||
|
if (field != value) {
|
||||||
|
field = value
|
||||||
|
isScrimOpaqueChangedListener.accept(field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateScrimOpaque() {
|
||||||
|
isScrimOpaque = revealAmount == 0.0f && alpha == 1.0f && visibility == VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setAlpha(alpha: Float) {
|
||||||
|
super.setAlpha(alpha)
|
||||||
|
updateScrimOpaque()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setVisibility(visibility: Int) {
|
||||||
|
super.setVisibility(visibility)
|
||||||
|
updateScrimOpaque()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Paint used to draw a transparent-to-white radial gradient. This will be scaled and translated
|
* Paint used to draw a transparent-to-white radial gradient. This will be scaled and translated
|
||||||
* via local matrix in [onDraw] so we never need to construct a new shader.
|
* via local matrix in [onDraw] so we never need to construct a new shader.
|
||||||
|
|||||||
@@ -182,10 +182,10 @@ public interface NotificationShadeWindowController extends RemoteInputController
|
|||||||
default void setFaceAuthDisplayBrightness(float brightness) {}
|
default void setFaceAuthDisplayBrightness(float brightness) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How much {@link LightRevealScrim} obscures the UI.
|
* If {@link LightRevealScrim} obscures the UI.
|
||||||
* @param amount 0 when opaque, 1 when not transparent
|
* @param opaque if the scrim is opaque
|
||||||
*/
|
*/
|
||||||
default void setLightRevealScrimAmount(float amount) {}
|
default void setLightRevealScrimOpaque(boolean opaque) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom listener to pipe data back to plugins about whether or not the status bar would be
|
* Custom listener to pipe data back to plugins about whether or not the status bar would be
|
||||||
|
|||||||
@@ -606,12 +606,11 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLightRevealScrimAmount(float amount) {
|
public void setLightRevealScrimOpaque(boolean opaque) {
|
||||||
boolean lightRevealScrimOpaque = amount == 0;
|
if (mCurrentState.mLightRevealScrimOpaque == opaque) {
|
||||||
if (mCurrentState.mLightRevealScrimOpaque == lightRevealScrimOpaque) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mCurrentState.mLightRevealScrimOpaque = lightRevealScrimOpaque;
|
mCurrentState.mLightRevealScrimOpaque = opaque;
|
||||||
apply(mCurrentState);
|
apply(mCurrentState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1338,8 +1338,19 @@ public class StatusBar extends SystemUI implements
|
|||||||
mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);
|
mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);
|
||||||
|
|
||||||
mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
|
mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
|
||||||
mLightRevealScrim.setRevealAmountListener(
|
mLightRevealScrim.setScrimOpaqueChangedListener((opaque) -> {
|
||||||
mNotificationShadeWindowController::setLightRevealScrimAmount);
|
Runnable updateOpaqueness = () -> {
|
||||||
|
mNotificationShadeWindowController.setLightRevealScrimOpaque(
|
||||||
|
mLightRevealScrim.isScrimOpaque());
|
||||||
|
};
|
||||||
|
if (opaque) {
|
||||||
|
// Delay making the view opaque for a frame, because it needs some time to render
|
||||||
|
// otherwise this can lead to a flicker where the scrim doesn't cover the screen
|
||||||
|
mLightRevealScrim.post(updateOpaqueness);
|
||||||
|
} else {
|
||||||
|
updateOpaqueness.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
mUnlockedScreenOffAnimationController.initialize(this, mLightRevealScrim);
|
mUnlockedScreenOffAnimationController.initialize(this, mLightRevealScrim);
|
||||||
updateLightRevealScrimVisibility();
|
updateLightRevealScrimVisibility();
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
|
|||||||
val newScrimView = LightRevealScrim(context, null)
|
val newScrimView = LightRevealScrim(context, null)
|
||||||
.apply {
|
.apply {
|
||||||
revealEffect = LinearLightRevealEffect(isVerticalFold)
|
revealEffect = LinearLightRevealEffect(isVerticalFold)
|
||||||
revealAmountListener = Consumer {}
|
isScrimOpaqueChangedListener = Consumer {}
|
||||||
revealAmount = 0f
|
revealAmount = 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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.testing.AndroidTestingRunner
|
||||||
|
import android.view.View
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
@RunWith(AndroidTestingRunner::class)
|
||||||
|
@SmallTest
|
||||||
|
class LightRevealScrimTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
private lateinit var scrim: LightRevealScrim
|
||||||
|
private var isOpaque = false
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
scrim = LightRevealScrim(context, null)
|
||||||
|
scrim.isScrimOpaqueChangedListener = Consumer { opaque ->
|
||||||
|
isOpaque = opaque
|
||||||
|
}
|
||||||
|
scrim.revealAmount = 0f
|
||||||
|
assertTrue("Scrim is not opaque in initial setup", scrim.isScrimOpaque)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testAlphaSetsOpaque() {
|
||||||
|
scrim.alpha = 0.5f
|
||||||
|
assertFalse("Scrim is opaque even though alpha is set", scrim.isScrimOpaque)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testVisibilitySetsOpaque() {
|
||||||
|
scrim.visibility = View.INVISIBLE
|
||||||
|
assertFalse("Scrim is opaque even though it's invisible", scrim.isScrimOpaque)
|
||||||
|
scrim.visibility = View.GONE
|
||||||
|
assertFalse("Scrim is opaque even though it's gone", scrim.isScrimOpaque)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testRevealSetsOpaque() {
|
||||||
|
scrim.revealAmount = 0.5f
|
||||||
|
assertFalse("Scrim is opaque even though it's revealed", scrim.isScrimOpaque)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -146,7 +146,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
|
|||||||
mNotificationShadeWindowController.attach();
|
mNotificationShadeWindowController.attach();
|
||||||
|
|
||||||
clearInvocations(mWindowManager);
|
clearInvocations(mWindowManager);
|
||||||
mNotificationShadeWindowController.setLightRevealScrimAmount(0f);
|
mNotificationShadeWindowController.setLightRevealScrimOpaque(true);
|
||||||
verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
|
verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
|
||||||
assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) == 0).isTrue();
|
assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) == 0).isTrue();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user