diff options
4 files changed, 184 insertions, 14 deletions
diff --git a/packages/SystemUI/shared/res/values-my/bools.xml b/packages/SystemUI/shared/res/values-my/bools.xml new file mode 100644 index 000000000000..bcf4b2d570ea --- /dev/null +++ b/packages/SystemUI/shared/res/values-my/bools.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2023 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. +--> + +<!-- Formatting note: terminate all comments with a period, to avoid breaking + the documentation output. To suppress comment lines from the documentation + output, insert an eat-comment element after the comment lines. +--> + +<resources> + <!-- Whether to add padding at the bottom of the complication clock --> + <bool name="dream_overlay_complication_clock_bottom_padding">true</bool> +</resources>
\ No newline at end of file diff --git a/packages/SystemUI/shared/res/values/bools.xml b/packages/SystemUI/shared/res/values/bools.xml new file mode 100644 index 000000000000..4b74ead94f5f --- /dev/null +++ b/packages/SystemUI/shared/res/values/bools.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2023 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. +--> + +<!-- Formatting note: terminate all comments with a period, to avoid breaking + the documentation output. To suppress comment lines from the documentation + output, insert an eat-comment element after the comment lines. +--> + +<resources> + <!-- Whether to add padding at the bottom of the complication clock --> + <bool name="dream_overlay_complication_clock_bottom_padding">false</bool> +</resources>
\ No newline at end of file diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextClock.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextClock.kt index 5a6f1840bc95..bc4879dcb4e9 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextClock.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextClock.kt @@ -16,34 +16,51 @@ package com.android.systemui.shared.shadow import android.content.Context +import android.content.res.Resources +import android.content.res.TypedArray import android.graphics.Canvas import android.util.AttributeSet import android.widget.TextClock import com.android.systemui.shared.R import com.android.systemui.shared.shadow.DoubleShadowTextHelper.ShadowInfo import com.android.systemui.shared.shadow.DoubleShadowTextHelper.applyShadows +import javax.inject.Inject import kotlin.math.floor /** Extension of [TextClock] which draws two shadows on the text (ambient and key shadows) */ +class ResourcesProvider @Inject constructor(private val context: Context) { + fun getResources(): Resources { + return context.resources + } + + fun getBoolean(resourceId: Int): Boolean { + return getResources().getBoolean(resourceId) + } +} + class DoubleShadowTextClock @JvmOverloads constructor( + private val resourcesProvider: ResourcesProvider, context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, - defStyleRes: Int = 0 + defStyleRes: Int = 0, + attributesInput: TypedArray? = null ) : TextClock(context, attrs, defStyleAttr, defStyleRes) { private val mAmbientShadowInfo: ShadowInfo private val mKeyShadowInfo: ShadowInfo init { - val attributes = - context.obtainStyledAttributes( - attrs, - R.styleable.DoubleShadowTextClock, - defStyleAttr, - defStyleRes - ) + var attributes: TypedArray = + attributesInput + ?: context.obtainStyledAttributes( + attrs, + R.styleable.DoubleShadowTextClock, + defStyleAttr, + defStyleRes + ) + try { val keyShadowBlur = attributes.getDimensionPixelSize(R.styleable.DoubleShadowTextClock_keyShadowBlur, 0) @@ -98,18 +115,29 @@ constructor( 0 ) if (removeTextDescent) { - setPaddingRelative( - 0, - 0, - 0, - textDescentExtraPadding - floor(paint.fontMetrics.descent.toDouble()).toInt() - ) + val addBottomPaddingToClock = + resourcesProvider.getBoolean( + R.bool.dream_overlay_complication_clock_bottom_padding + ) + val metrics = paint.fontMetrics + val padding = + if (addBottomPaddingToClock) { + textDescentExtraPadding + + floor(metrics.descent.toDouble()).toInt() / paddingDividedOffset + } else { + textDescentExtraPadding - floor(metrics.descent.toDouble()).toInt() + } + setPaddingRelative(0, 0, 0, padding) } } finally { attributes.recycle() } } + companion object { + private val paddingDividedOffset = 2 + } + public override fun onDraw(canvas: Canvas) { applyShadows(mKeyShadowInfo, mAmbientShadowInfo, this, canvas) { super.onDraw(canvas) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt new file mode 100644 index 000000000000..3c9db8f00329 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023 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.shadow + +import android.content.Context +import android.content.res.TypedArray +import android.testing.AndroidTestingRunner +import android.util.AttributeSet +import androidx.test.filters.SmallTest +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.shared.shadow.DoubleShadowTextClock +import com.android.systemui.shared.shadow.ResourcesProvider +import com.android.systemui.util.mockito.whenever +import junit.framework.Assert.assertTrue +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class DoubleShadowTextClockTest : SysuiTestCase() { + @get:Rule val mockito: MockitoRule = MockitoJUnit.rule() + + @Mock lateinit var resourcesProvider: ResourcesProvider + + @Mock lateinit var attributes: TypedArray + + private lateinit var context: Context + private var attrs: AttributeSet? = null + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + context = getContext() + whenever(attributes.getBoolean(R.styleable.DoubleShadowTextClock_removeTextDescent, false)) + .thenReturn(true) + } + + @Test + fun testAddingPaddingToBottomOfClockWhenConfigIsTrue() { + whenever( + resourcesProvider.getBoolean(R.bool.dream_overlay_complication_clock_bottom_padding) + ) + .thenReturn(true) + + val doubleShadowTextClock = + DoubleShadowTextClock( + resourcesProvider = resourcesProvider, + context = context, + attrs = attrs, + attributesInput = attributes + ) + assertTrue(doubleShadowTextClock.paddingBottom > 0) + } + + @Test + fun testRemovingPaddingToBottomOfClockWhenConfigIsFalse() { + whenever( + resourcesProvider.getBoolean(R.bool.dream_overlay_complication_clock_bottom_padding) + ) + .thenReturn(false) + + val doubleShadowTextClock = + DoubleShadowTextClock( + resourcesProvider = resourcesProvider, + context = context, + attrs = attrs, + attributesInput = attributes + ) + assertTrue(doubleShadowTextClock.paddingBottom < 0) + } +} |