Merge "Prevent alpha transitions from clipping out-of-bounds clocks" into udc-dev am: 5623c50b66

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23149088

Change-Id: If0a47059c767839b8731268450998d39ff68010f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Hawkwood Glazier
2023-05-13 15:02:12 +00:00
committed by Automerger Merge Worker
10 changed files with 107 additions and 80 deletions

View File

@@ -25,7 +25,7 @@
android:layout_height="wrap_content"
android:clipChildren="false"
android:layout_gravity="center_horizontal|top">
<FrameLayout
<com.android.keyguard.KeyguardClockFrame
android:id="@+id/lockscreen_clock_view"
android:layout_width="wrap_content"
android:layout_height="@dimen/small_clock_height"
@@ -34,7 +34,7 @@
android:clipChildren="false"
android:paddingStart="@dimen/clock_padding_start"
android:visibility="invisible" />
<FrameLayout
<com.android.keyguard.KeyguardClockFrame
android:id="@+id/lockscreen_clock_view_large"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@@ -30,7 +30,7 @@
android:clipChildren="false"
android:layout_width="0dp"
android:layout_height="wrap_content">
<LinearLayout
<com.android.keyguard.KeyguardStatusContainer
android:id="@+id/status_view_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -48,5 +48,5 @@
android:layout_height="wrap_content"
android:padding="@dimen/qs_media_padding"
/>
</LinearLayout>
</com.android.keyguard.KeyguardStatusContainer>
</com.android.keyguard.KeyguardStatusView>

View File

@@ -0,0 +1,39 @@
package com.android.keyguard
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
class KeyguardClockFrame(
context: Context,
attrs: AttributeSet,
) : FrameLayout(context, attrs) {
private var drawAlpha: Int = 255
protected override fun onSetAlpha(alpha: Int): Boolean {
drawAlpha = alpha
return true
}
protected override fun dispatchDraw(canvas: Canvas) {
val restoreTo = saveCanvasAlpha(this, canvas, drawAlpha)
super.dispatchDraw(canvas)
canvas.restoreToCount(restoreTo)
}
companion object {
@JvmStatic
fun saveCanvasAlpha(view: View, canvas: Canvas, alpha: Int): Int {
var (x, y) =
run {
val locationOnScreen = IntArray(2)
view.getLocationOnScreen(locationOnScreen)
Pair(locationOnScreen[0].toFloat(), locationOnScreen[1].toFloat())
}
return canvas.saveLayerAlpha(-1f * x, -1f * y, x + view.width, y + view.height, alpha)
}
}
}

View File

@@ -5,11 +5,11 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import androidx.annotation.IntDef;
@@ -69,12 +69,13 @@ public class KeyguardClockSwitch extends RelativeLayout {
/**
* Frame for small/large clocks
*/
private FrameLayout mSmallClockFrame;
private FrameLayout mLargeClockFrame;
private KeyguardClockFrame mSmallClockFrame;
private KeyguardClockFrame mLargeClockFrame;
private ClockController mClock;
private View mStatusArea;
private int mSmartspaceTopOffset;
private int mDrawAlpha = 255;
/**
* Maintain state so that a newly connected plugin can be initialized.
@@ -121,6 +122,19 @@ public class KeyguardClockSwitch extends RelativeLayout {
onDensityOrFontScaleChanged();
}
@Override
protected boolean onSetAlpha(int alpha) {
mDrawAlpha = alpha;
return true;
}
@Override
protected void dispatchDraw(Canvas canvas) {
int restoreTo = KeyguardClockFrame.saveCanvasAlpha(this, canvas, mDrawAlpha);
super.dispatchDraw(canvas);
canvas.restoreToCount(restoreTo);
}
public void setLogBuffer(LogBuffer logBuffer) {
mLogBuffer = logBuffer;
}

View File

@@ -178,20 +178,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
}
}
/**
* Set alpha directly to mView will clip clock, so we set alpha to clock face instead
*/
public void setAlpha(float alpha) {
ClockController clock = getClock();
if (clock != null) {
clock.getLargeClock().getView().setAlpha(alpha);
clock.getSmallClock().getView().setAlpha(alpha);
}
if (mStatusArea != null) {
mStatusArea.setAlpha(alpha);
}
}
/**
* Attach the controller to the view it relates to.
*/

View File

@@ -0,0 +1,24 @@
package com.android.keyguard
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.widget.LinearLayout
class KeyguardStatusContainer(
context: Context,
attrs: AttributeSet,
) : LinearLayout(context, attrs) {
private var drawAlpha: Int = 255
protected override fun onSetAlpha(alpha: Int): Boolean {
drawAlpha = alpha
return true
}
protected override fun dispatchDraw(canvas: Canvas) {
val restoreTo = KeyguardClockFrame.saveCanvasAlpha(this, canvas, drawAlpha)
super.dispatchDraw(canvas)
canvas.restoreToCount(restoreTo)
}
}

View File

@@ -19,6 +19,7 @@ package com.android.keyguard;
import static java.util.Collections.emptySet;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Build;
import android.os.Trace;
import android.util.AttributeSet;
@@ -47,6 +48,7 @@ public class KeyguardStatusView extends GridLayout {
private KeyguardSliceView mKeyguardSlice;
private View mMediaHostContainer;
private int mDrawAlpha = 255;
private float mDarkAmount = 0;
public KeyguardStatusView(Context context) {
@@ -136,30 +138,16 @@ public class KeyguardStatusView extends GridLayout {
Trace.endSection();
}
/**
* Clock content will be clipped when goes beyond bounds,
* so we setAlpha for all views except clock
*/
public void setAlpha(float alpha, boolean excludeClock) {
if (!excludeClock) {
setAlpha(alpha);
return;
}
if (alpha == 1 || alpha == 0) {
setAlpha(alpha);
}
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child == mStatusViewContainer) {
for (int j = 0; j < mStatusViewContainer.getChildCount(); j++) {
View innerChild = mStatusViewContainer.getChildAt(j);
if (innerChild != mClockView) {
innerChild.setAlpha(alpha);
}
}
} else {
child.setAlpha(alpha);
}
}
@Override
protected boolean onSetAlpha(int alpha) {
mDrawAlpha = alpha;
return true;
}
@Override
protected void dispatchDraw(Canvas canvas) {
int restoreTo = KeyguardClockFrame.saveCanvasAlpha(this, canvas, mDrawAlpha);
super.dispatchDraw(canvas);
canvas.restoreToCount(restoreTo);
}
}

View File

@@ -180,8 +180,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
*/
public void setAlpha(float alpha) {
if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
mView.setAlpha(alpha, true);
mKeyguardClockSwitchController.setAlpha(alpha);
mView.setAlpha(alpha);
}
}

View File

@@ -134,7 +134,6 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
private KeyguardClockSwitchController mController;
private View mSliceView;
private LinearLayout mStatusArea;
private FakeExecutor mExecutor;
@Before
@@ -196,8 +195,8 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
mSliceView = new View(getContext());
when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
mStatusArea = new LinearLayout(getContext());
when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(
new LinearLayout(getContext()));
}
@Test
@@ -402,15 +401,6 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
assertNull(mController.getClock());
}
@Test
public void testSetAlpha_setClockAlphaForCLockFace() {
mController.onViewAttached();
mController.setAlpha(0.5f);
verify(mLargeClockView).setAlpha(0.5f);
verify(mSmallClockView).setAlpha(0.5f);
assertEquals(0.5f, mStatusArea.getAlpha(), 0.0f);
}
private void verifyAttachment(VerificationMode times) {
verify(mClockRegistry, times).registerClockChangeListener(
any(ClockRegistry.ClockChangeListener.class));

View File

@@ -24,46 +24,33 @@ class KeyguardStatusViewTest : SysuiTestCase() {
get() = keyguardStatusView.findViewById(R.id.status_view_media_container)
private val statusViewContainer: ViewGroup
get() = keyguardStatusView.findViewById(R.id.status_view_container)
private val clockView: ViewGroup
get() = keyguardStatusView.findViewById(R.id.keyguard_clock_container)
private val childrenExcludingMedia
get() = statusViewContainer.children.filter { it != mediaView }
@Before
fun setUp() {
keyguardStatusView = LayoutInflater.from(context)
.inflate(R.layout.keyguard_status_view, /* root= */ null) as KeyguardStatusView
keyguardStatusView =
LayoutInflater.from(context).inflate(R.layout.keyguard_status_view, /* root= */ null)
as KeyguardStatusView
}
@Test
fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() {
val translationY = 1234f
keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */true)
keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */ true)
assertThat(mediaView.translationY).isEqualTo(0)
childrenExcludingMedia.forEach {
assertThat(it.translationY).isEqualTo(translationY)
}
childrenExcludingMedia.forEach { assertThat(it.translationY).isEqualTo(translationY) }
}
@Test
fun setChildrenTranslationYIncludeMediaView() {
val translationY = 1234f
keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */false)
keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */ false)
statusViewContainer.children.forEach {
assertThat(it.translationY).isEqualTo(translationY)
}
}
@Test
fun setAlphaExcludeClock() {
keyguardStatusView.setAlpha(0.5f, /* excludeClock= */true)
assertThat(statusViewContainer.alpha).isNotEqualTo(0.5f)
assertThat(mediaView.alpha).isEqualTo(0.5f)
assertThat(clockView.alpha).isNotEqualTo(0.5f)
statusViewContainer.children.forEach { assertThat(it.translationY).isEqualTo(translationY) }
}
}