Darker accent color on custom clock over light wallpaper.
Fixes: 134441011 Test: visual -- checked clock on light lock screen wallpaper Test: Added ClockPaletteTest Change-Id: I98768d0ef2acaf6f33aa5e47bc94e0bb1266b3ec
This commit is contained in:
@@ -74,6 +74,11 @@ public class AnalogClockController implements ClockPlugin {
|
||||
private View mView;
|
||||
private TextClock mLockClock;
|
||||
|
||||
/**
|
||||
* Helper to extract colors from wallpaper palette for clock face.
|
||||
*/
|
||||
private final ClockPalette mPalette = new ClockPalette();
|
||||
|
||||
/**
|
||||
* Create a BubbleClockController instance.
|
||||
*
|
||||
@@ -162,17 +167,21 @@ public class AnalogClockController implements ClockPlugin {
|
||||
public void setStyle(Style style) {}
|
||||
|
||||
@Override
|
||||
public void setTextColor(int color) { }
|
||||
public void setTextColor(int color) {
|
||||
updateColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
|
||||
if (colorPalette == null || colorPalette.length == 0) {
|
||||
return;
|
||||
}
|
||||
final int length = colorPalette.length;
|
||||
mLockClock.setTextColor(colorPalette[Math.max(0, length - 2)]);
|
||||
mAnalogClock.setClockColors(colorPalette[Math.max(0, length - 5)],
|
||||
colorPalette[Math.max(0, length - 2)]);
|
||||
mPalette.setColorPalette(supportsDarkText, colorPalette);
|
||||
updateColor();
|
||||
}
|
||||
|
||||
private void updateColor() {
|
||||
final int primary = mPalette.getPrimaryColor();
|
||||
final int secondary = mPalette.getSecondaryColor();
|
||||
mLockClock.setTextColor(secondary);
|
||||
mAnalogClock.setClockColors(primary, secondary);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -184,6 +193,7 @@ public class AnalogClockController implements ClockPlugin {
|
||||
|
||||
@Override
|
||||
public void setDarkAmount(float darkAmount) {
|
||||
mPalette.setDarkAmount(darkAmount);
|
||||
mClockPosition.setDarkAmount(darkAmount);
|
||||
mBigClockView.setDarkAmount(darkAmount);
|
||||
}
|
||||
|
||||
@@ -74,6 +74,11 @@ public class BubbleClockController implements ClockPlugin {
|
||||
private View mLockClockContainer;
|
||||
private TextClock mLockClock;
|
||||
|
||||
/**
|
||||
* Helper to extract colors from wallpaper palette for clock face.
|
||||
*/
|
||||
private final ClockPalette mPalette = new ClockPalette();
|
||||
|
||||
/**
|
||||
* Create a BubbleClockController instance.
|
||||
*
|
||||
@@ -162,22 +167,26 @@ public class BubbleClockController implements ClockPlugin {
|
||||
public void setStyle(Style style) {}
|
||||
|
||||
@Override
|
||||
public void setTextColor(int color) { }
|
||||
public void setTextColor(int color) {
|
||||
updateColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
|
||||
if (colorPalette == null || colorPalette.length == 0) {
|
||||
return;
|
||||
}
|
||||
final int length = colorPalette.length;
|
||||
final int primaryColor = colorPalette[Math.max(0, length - 2)];
|
||||
final int secondaryColor = colorPalette[Math.max(0, length - 5)];
|
||||
mLockClock.setTextColor(primaryColor);
|
||||
mAnalogClock.setClockColors(secondaryColor, primaryColor);
|
||||
mPalette.setColorPalette(supportsDarkText, colorPalette);
|
||||
updateColor();
|
||||
}
|
||||
|
||||
private void updateColor() {
|
||||
final int primary = mPalette.getPrimaryColor();
|
||||
final int secondary = mPalette.getSecondaryColor();
|
||||
mLockClock.setTextColor(secondary);
|
||||
mAnalogClock.setClockColors(primary, secondary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDarkAmount(float darkAmount) {
|
||||
mPalette.setDarkAmount(darkAmount);
|
||||
mClockPosition.setDarkAmount(darkAmount);
|
||||
mView.setDarkAmount(darkAmount);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.graphics.Color
|
||||
import android.util.MathUtils
|
||||
|
||||
private const val PRIMARY_INDEX = 5
|
||||
private const val SECONDARY_DARK_INDEX = 8
|
||||
private const val SECONDARY_LIGHT_INDEX = 2
|
||||
|
||||
/**
|
||||
* A helper class to extract colors from a clock face.
|
||||
*/
|
||||
class ClockPalette {
|
||||
|
||||
private var darkAmount: Float = 0f
|
||||
private var accentPrimary: Int = Color.WHITE
|
||||
private var accentSecondaryLight: Int = Color.WHITE
|
||||
private var accentSecondaryDark: Int = Color.BLACK
|
||||
private val lightHSV: FloatArray = FloatArray(3)
|
||||
private val darkHSV: FloatArray = FloatArray(3)
|
||||
private val hsv: FloatArray = FloatArray(3)
|
||||
|
||||
/** Returns a color from the palette as an RGB packed int. */
|
||||
fun getPrimaryColor(): Int {
|
||||
return accentPrimary
|
||||
}
|
||||
|
||||
/** Returns either a light or dark color from the palette as an RGB packed int. */
|
||||
fun getSecondaryColor(): Int {
|
||||
Color.colorToHSV(accentSecondaryLight, lightHSV)
|
||||
Color.colorToHSV(accentSecondaryDark, darkHSV)
|
||||
for (i in 0..2) {
|
||||
hsv[i] = MathUtils.lerp(darkHSV[i], lightHSV[i], darkAmount)
|
||||
}
|
||||
return Color.HSVToColor(hsv)
|
||||
}
|
||||
|
||||
/** See {@link ClockPlugin#setColorPalette}. */
|
||||
fun setColorPalette(supportsDarkText: Boolean, colorPalette: IntArray?) {
|
||||
if (colorPalette == null || colorPalette.isEmpty()) {
|
||||
accentPrimary = Color.WHITE
|
||||
accentSecondaryLight = Color.WHITE
|
||||
accentSecondaryDark = if (supportsDarkText) Color.BLACK else Color.WHITE
|
||||
return
|
||||
}
|
||||
val length = colorPalette.size
|
||||
accentPrimary = colorPalette[Math.max(0, length - PRIMARY_INDEX)]
|
||||
accentSecondaryLight = colorPalette[Math.max(0, length - SECONDARY_LIGHT_INDEX)]
|
||||
accentSecondaryDark = colorPalette[Math.max(0,
|
||||
length - if (supportsDarkText) SECONDARY_DARK_INDEX else SECONDARY_LIGHT_INDEX)]
|
||||
}
|
||||
|
||||
/** See {@link ClockPlugin#setDarkAmount}. */
|
||||
fun setDarkAmount(darkAmount: Float) {
|
||||
this.darkAmount = darkAmount
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.android.keyguard.clock;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
@@ -67,9 +68,9 @@ public final class AnalogClockControllerTest extends SysuiTestCase {
|
||||
public void setColorPalette_setDigitalClock() {
|
||||
ViewGroup smallClock = (ViewGroup) mClockController.getView();
|
||||
// WHEN color palette is set
|
||||
mClockController.setColorPalette(true, new int[]{42});
|
||||
mClockController.setColorPalette(true, new int[]{Color.RED});
|
||||
// THEN child of small clock should have text color set.
|
||||
TextView digitalClock = (TextView) smallClock.getChildAt(0);
|
||||
assertThat(digitalClock.getCurrentTextColor()).isEqualTo(42);
|
||||
assertThat(digitalClock.getCurrentTextColor()).isEqualTo(Color.RED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.keyguard.clock;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
@@ -66,9 +67,9 @@ public final class BubbleClockControllerTest extends SysuiTestCase {
|
||||
public void setColorPalette_setDigitalClock() {
|
||||
ViewGroup smallClock = (ViewGroup) mClockController.getView();
|
||||
// WHEN text color is set
|
||||
mClockController.setColorPalette(true, new int[]{42});
|
||||
mClockController.setColorPalette(true, new int[]{Color.RED});
|
||||
// THEN child of small clock should have text color set.
|
||||
TextView digitalClock = (TextView) smallClock.getChildAt(0);
|
||||
assertThat(digitalClock.getCurrentTextColor()).isEqualTo(42);
|
||||
assertThat(digitalClock.getCurrentTextColor()).isEqualTo(Color.RED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.graphics.Color
|
||||
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 ClockPaletteTest : SysuiTestCase() {
|
||||
|
||||
private lateinit var clockPalette: ClockPalette
|
||||
private lateinit var colors: IntArray
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
clockPalette = ClockPalette()
|
||||
// colors used are reds from light to dark.
|
||||
val hsv: FloatArray = FloatArray(3)
|
||||
Color.colorToHSV(Color.RED, hsv)
|
||||
colors = IntArray(10)
|
||||
val step: Float = (0f - hsv[2]) / colors.size
|
||||
for (i in 0 until colors.size) {
|
||||
hsv[2] += step
|
||||
colors[i] = Color.HSVToColor(hsv)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDark() {
|
||||
// GIVEN on AOD
|
||||
clockPalette.setDarkAmount(1f)
|
||||
// AND GIVEN that wallpaper doesn't support dark text
|
||||
clockPalette.setColorPalette(false, colors)
|
||||
// THEN the secondary color should be lighter than the primary color
|
||||
assertThat(value(clockPalette.getPrimaryColor()))
|
||||
.isGreaterThan(value(clockPalette.getSecondaryColor()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDarkText() {
|
||||
// GIVEN on lock screen
|
||||
clockPalette.setDarkAmount(0f)
|
||||
// AND GIVEN that wallpaper supports dark text
|
||||
clockPalette.setColorPalette(true, colors)
|
||||
// THEN the secondary color should be darker the primary color
|
||||
assertThat(value(clockPalette.getPrimaryColor()))
|
||||
.isLessThan(value(clockPalette.getSecondaryColor()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLightText() {
|
||||
// GIVEN on lock screen
|
||||
clockPalette.setDarkAmount(0f)
|
||||
// AND GIVEN that wallpaper doesn't support dark text
|
||||
clockPalette.setColorPalette(false, colors)
|
||||
// THEN the secondary color should be darker than the primary color
|
||||
assertThat(value(clockPalette.getPrimaryColor()))
|
||||
.isGreaterThan(value(clockPalette.getSecondaryColor()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNullColors() {
|
||||
// GIVEN on AOD
|
||||
clockPalette.setDarkAmount(1f)
|
||||
// AND GIVEN that wallpaper colors are null
|
||||
clockPalette.setColorPalette(false, null)
|
||||
// THEN the primary color should be whilte
|
||||
assertThat(clockPalette.getPrimaryColor()).isEqualTo(Color.WHITE)
|
||||
}
|
||||
|
||||
private fun value(color: Int): Float {
|
||||
val hsv: FloatArray = FloatArray(3)
|
||||
Color.colorToHSV(color, hsv)
|
||||
return hsv[2]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user