From 4cbd15965ccb38266eb879ec2f2a44d32cefdee7 Mon Sep 17 00:00:00 2001 From: Robert Snoeberger Date: Wed, 24 Apr 2019 14:20:38 -0400 Subject: [PATCH] Position "At a Glance" on custom clock below status bar. Change summary: - Position below status bar on AOD, and account for burn in prevention movement. - Position below lock icon on lock screen. Fixes: 130797849 Test: visual - checked position on AOD and lock screen Test: visual - checked position with music playing Change-Id: Iad088e8b1d301e19ec9a095462a420e1723aba00 --- .../keyguard/clock/AnalogClockController.java | 12 ++- .../keyguard/clock/BubbleClockController.java | 12 ++- .../keyguard/clock/SmallClockPosition.java | 75 +++++++++++++++++++ .../phone/KeyguardClockPositionAlgorithm.java | 17 +++-- .../keyguard/clock/SmallClockPositionTest.kt | 67 +++++++++++++++++ .../KeyguardClockPositionAlgorithmTest.java | 3 + 6 files changed, 175 insertions(+), 11 deletions(-) create mode 100644 packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java create mode 100644 packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt diff --git a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java index 7d1587cf8dd03..123e1380db0ac 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java @@ -53,6 +53,11 @@ public class AnalogClockController implements ClockPlugin { */ private final SysuiColorExtractor mColorExtractor; + /** + * Computes preferred position of clock. + */ + private final SmallClockPosition mClockPosition; + /** * Renders preview from clock view. */ @@ -82,6 +87,7 @@ public class AnalogClockController implements ClockPlugin { mResources = res; mLayoutInflater = inflater; mColorExtractor = colorExtractor; + mClockPosition = new SmallClockPosition(res); } private void createViews() { @@ -153,7 +159,7 @@ public class AnalogClockController implements ClockPlugin { @Override public int getPreferredY(int totalHeight) { - return totalHeight / 4; + return mClockPosition.getPreferredY(); } @Override @@ -181,7 +187,9 @@ public class AnalogClockController implements ClockPlugin { } @Override - public void setDarkAmount(float darkAmount) { } + public void setDarkAmount(float darkAmount) { + mClockPosition.setDarkAmount(darkAmount); + } @Override public void onTimeZoneChanged(TimeZone timeZone) { diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java index fbbf64cf700b6..8db61b827f3c9 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java @@ -53,6 +53,11 @@ public class BubbleClockController implements ClockPlugin { */ private final SysuiColorExtractor mColorExtractor; + /** + * Computes preferred position of clock. + */ + private final SmallClockPosition mClockPosition; + /** * Renders preview from clock view. */ @@ -82,6 +87,7 @@ public class BubbleClockController implements ClockPlugin { mResources = res; mLayoutInflater = inflater; mColorExtractor = colorExtractor; + mClockPosition = new SmallClockPosition(res); } private void createViews() { @@ -152,7 +158,7 @@ public class BubbleClockController implements ClockPlugin { @Override public int getPreferredY(int totalHeight) { - return totalHeight / 4; + return mClockPosition.getPreferredY(); } @Override @@ -173,7 +179,9 @@ public class BubbleClockController implements ClockPlugin { } @Override - public void setDarkAmount(float darkAmount) { } + public void setDarkAmount(float darkAmount) { + mClockPosition.setDarkAmount(darkAmount); + } @Override public void onTimeTick() { diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java new file mode 100644 index 0000000000000..9b15dc6d5063e --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java @@ -0,0 +1,75 @@ +/* + * 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.keyguard.clock; + +import android.content.res.Resources; +import android.util.MathUtils; + +import com.android.internal.annotations.VisibleForTesting; + +/** + * Computes preferred position of clock by considering height of status bar and lock icon. + */ +class SmallClockPosition { + + /** + * Dimensions used to determine preferred clock position. + */ + private final int mStatusBarHeight; + private final int mKeyguardLockPadding; + private final int mKeyguardLockHeight; + private final int mBurnInOffsetY; + + /** + * Amount of transition between AOD and lock screen. + */ + private float mDarkAmount; + + SmallClockPosition(Resources res) { + this(res.getDimensionPixelSize(com.android.keyguard.R.dimen.status_bar_height), + res.getDimensionPixelSize(com.android.keyguard.R.dimen.keyguard_lock_padding), + res.getDimensionPixelSize(com.android.keyguard.R.dimen.keyguard_lock_height), + res.getDimensionPixelSize(com.android.keyguard.R.dimen.burn_in_prevention_offset_y) + ); + } + + @VisibleForTesting + SmallClockPosition(int statusBarHeight, int lockPadding, int lockHeight, int burnInY) { + mStatusBarHeight = statusBarHeight; + mKeyguardLockPadding = lockPadding; + mKeyguardLockHeight = lockHeight; + mBurnInOffsetY = burnInY; + } + + /** + * See {@link ClockPlugin#setDarkAmount}. + */ + void setDarkAmount(float darkAmount) { + mDarkAmount = darkAmount; + } + + /** + * Gets the preferred Y position accounting for status bar and lock icon heights. + */ + int getPreferredY() { + // On AOD, clock needs to appear below the status bar with enough room for pixel shifting + int aodY = mStatusBarHeight + mKeyguardLockPadding + mBurnInOffsetY; + // On lock screen, clock needs to appear below the lock icon + int lockY = mStatusBarHeight + mKeyguardLockHeight + 2 * mKeyguardLockPadding; + return (int) MathUtils.lerp(lockY, aodY, mDarkAmount); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java index 26e0a705aa5c9..1b866935250ae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java @@ -158,7 +158,12 @@ public class KeyguardClockPositionAlgorithm { } private int getPreferredClockY() { - return mClockPreferredY - mKeyguardStatusHeight - mClockNotificationsMargin; + return mClockPreferredY; + } + + private int getExpandedPreferredClockY() { + return (mHasCustomClock && !mHasVisibleNotifs) ? getPreferredClockY() + : getExpandedClockPosition(); } /** @@ -187,13 +192,11 @@ public class KeyguardClockPositionAlgorithm { private int getClockY() { // Dark: Align the bottom edge of the clock at about half of the screen: - float clockYDark = getPreferredClockY() + burnInPreventionOffsetY(); + float clockYDark = (mHasCustomClock ? getPreferredClockY() : getMaxClockY()) + + burnInPreventionOffsetY(); clockYDark = MathUtils.max(0, clockYDark); - float clockYRegular = getExpandedClockPosition(); - if (mHasCustomClock && !mHasVisibleNotifs) { - clockYRegular = clockYDark; - } + float clockYRegular = getExpandedPreferredClockY(); float clockYBouncer = -mKeyguardStatusHeight; // Move clock up while collapsing the shade @@ -213,7 +216,7 @@ public class KeyguardClockPositionAlgorithm { * @return Alpha from 0 to 1. */ private float getClockAlpha(int y) { - float alphaKeyguard = Math.max(0, y / Math.max(1f, getExpandedClockPosition())); + float alphaKeyguard = Math.max(0, y / Math.max(1f, getExpandedPreferredClockY())); alphaKeyguard = Interpolators.ACCELERATE.getInterpolation(alphaKeyguard); return MathUtils.lerp(alphaKeyguard, 1f, mDarkAmount); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt new file mode 100644 index 0000000000000..f4d59ccb372e2 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt @@ -0,0 +1,67 @@ +/* + * 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.keyguard.clock + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class SmallClockPositionTest : SysuiTestCase() { + + private val statusBarHeight = 100 + private val lockPadding = 15 + private val lockHeight = 35 + private val burnInY = 20 + + private lateinit var position: SmallClockPosition + + @Before + fun setUp() { + position = SmallClockPosition(statusBarHeight, lockPadding, lockHeight, burnInY) + } + + @Test + fun loadResources() { + // Cover constructor taking Resources object. + position = SmallClockPosition(context.resources) + position.setDarkAmount(1f) + assertThat(position.preferredY).isGreaterThan(0) + } + + @Test + fun darkPosition() { + // GIVEN on AOD + position.setDarkAmount(1f) + // THEN Y position is statusBarHeight + lockPadding + burnInY (100 + 15 + 20 = 135) + assertThat(position.preferredY).isEqualTo(135) + } + + @Test + fun lockPosition() { + // GIVEN on lock screen + position.setDarkAmount(0f) + // THEN Y position is statusBarHeight + lockPadding + lockHeight + lockPadding + // (100 + 15 + 35 + 15 = 165) + assertThat(position.preferredY).isEqualTo(165) + } +} \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java index f191cabbb3d9e..f8394f01a0814 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java @@ -316,6 +316,7 @@ public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase { positionClock(); // THEN the clock Y position is the preferred Y position. assertThat(mClockPosition.clockY).isEqualTo(100); + assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE); } @Test @@ -333,6 +334,7 @@ public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase { // THEN the clock Y position is the middle of the screen (SCREEN_HEIGHT / 2) and not // preferred. assertThat(mClockPosition.clockY).isEqualTo(1000); + assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE); } @Test @@ -349,6 +351,7 @@ public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase { positionClock(); // THEN the clock Y position is the middle of the screen (SCREEN_HEIGHT / 2). assertThat(mClockPosition.clockY).isEqualTo(1000); + assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE); } @Test