Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d13a0ab authored by Evan Laird's avatar Evan Laird Committed by Automerger Merge Worker
Browse files

Merge "Change the status bar clock's measuring scheme" into tm-dev am: e1e006e1

parents c2c18cca e1e006e1
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -103,6 +103,10 @@ public class Clock extends TextView implements
    private boolean mShowSeconds;
    private Handler mSecondsHandler;

    // Fields to cache the width so the clock remains at an approximately constant width
    private int mCharsAtCurrentWidth = -1;
    private int mCachedWidth = -1;

    /**
     * Color to be set on this {@link TextView}, when wallpaperTextColor is <b>not</b> utilized.
     */
@@ -302,6 +306,32 @@ public class Clock extends TextView implements
        setContentDescription(mContentDescriptionFormat.format(mCalendar.getTime()));
    }

    /**
     * In order to avoid the clock growing and shrinking due to proportional fonts, we want to
     * cache the drawn width at a given number of characters (removing the cache when it changes),
     * and only use the biggest value. This means that the clock width with grow to the maximum
     * size over time, but reset whenever the number of characters changes (or the configuration
     * changes)
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int chars = getText().length();
        if (chars != mCharsAtCurrentWidth) {
            mCharsAtCurrentWidth = chars;
            mCachedWidth = getMeasuredWidth();
            return;
        }

        int measuredWidth = getMeasuredWidth();
        if (mCachedWidth > measuredWidth) {
            setMeasuredDimension(mCachedWidth, getMeasuredHeight());
        } else {
            mCachedWidth = measuredWidth;
        }
    }

    @Override
    public void onTuningChanged(String key, String newValue) {
        if (CLOCK_SECONDS.equals(key)) {
+130 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.policy

import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View.MeasureSpec.UNSPECIFIED
import android.view.View.MeasureSpec.makeMeasureSpec
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Before
import org.junit.runner.RunWith

import com.google.common.truth.Truth.assertThat
import org.junit.Test

@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class ClockTest : SysuiTestCase() {
    private lateinit var clockView: Clock

    @Before
    fun setUp() {
        allowTestableLooperAsMainThread()
        TestableLooper.get(this).runWithLooper {
            val container = LinearLayout(context)
            val lp = LinearLayout.LayoutParams(1000, WRAP_CONTENT)
            container.layoutParams = lp
            clockView = Clock(context, null)
            container.addView(clockView)
            measureClock()
        }
    }

    @Test
    fun testWidthDoesNotDecrease_sameCharLength() {
        // GIVEN time is narrow
        clockView.text = ONE_3
        measureClock()
        val width1 = clockView.measuredWidth

        // WHEN the text changes to be wider characters
        clockView.text = ZERO_3
        measureClock()
        val width2 = clockView.measuredWidth

        // THEN the width should be wider (or equals when using monospace font)
        assertThat(width2).isAtLeast(width1)
    }

    @Test
    fun testWidthDoesNotDecrease_narrowerFont_sameNumberOfChars() {
        // GIVEN time is wide
        clockView.text = ZERO_3
        measureClock()
        val width1 = clockView.measuredWidth

        // WHEN the text changes to a narrower font
        clockView.text = ONE_3
        measureClock()
        val width2 = clockView.measuredWidth

        // THEN the width should not have decreased, and they should in fact be the same
        assertThat(width2).isEqualTo(width1)
    }

    @Test
    fun testWidthIncreases_whenCharsChanges() {
        // GIVEN wide 3-char text
        clockView.text = ZERO_3
        measureClock()
        val width1 = clockView.measuredWidth

        // WHEN text changes to 4-char wide text
        clockView.text = ZERO_4
        measureClock()
        val width2 = clockView.measuredWidth

        // THEN the text field is wider
        assertThat(width2).isGreaterThan(width1)
    }

    @Test
    fun testWidthDecreases_whenCharsChange_longToShort() {
        // GIVEN wide 4-char text
        clockView.text = ZERO_4
        measureClock()
        val width1 = clockView.measuredWidth

        // WHEN number of characters changes to a narrow 3-char text
        clockView.text = ONE_3
        measureClock()
        val width2 = clockView.measuredWidth

        // THEN the width can shrink, because number of chars changed
        assertThat(width2).isLessThan(width1)
    }

    private fun measureClock() {
        clockView.measure(
                makeMeasureSpec(0, UNSPECIFIED),
                makeMeasureSpec(0, UNSPECIFIED)
        )
    }
}

/**
 * In a non-monospace font, it is expected that "0:00" is wider than "1:11"
 */
private const val ZERO_3 = "0:00"
private const val ZERO_4 = "00:00"
private const val ONE_3 = "1:11"
private const val ONE_4 = "11:11"