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

Commit 7c6ba2e8 authored by George Mount's avatar George Mount
Browse files

Fix Chronometer countdown

Fixes: 359936006

The Chronometer countdown was counting down by 2 seconds rather
than by one second. This CL does two things: it fixes the
delay to work when counting down. It also rounds off the time
so that it doesn't count zero for two seconds. There is
special handling for counting down. The previous behavior started
with rounding down the count down. With the new rounding behavior,
count down has to do something different so that it achieves the same
behavior.

Flag: EXEMPT bugfix

Test: new test, manual testing
Change-Id: I611d21f1abb547d4ba5f2c3b269c1be1d480be0a
parent ae928a0f
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -289,8 +289,7 @@ public class Chronometer extends TextView {

    private synchronized void updateText(long now) {
        mNow = now;
        long seconds = mCountDown ? mBase - now : now - mBase;
        seconds /= 1000;
        long seconds = Math.round((mCountDown ? mBase - now - 499 : now - mBase) / 1000f);
        boolean negative = false;
        if (seconds < 0) {
            seconds = -seconds;
@@ -348,9 +347,19 @@ public class Chronometer extends TextView {
    };

    private void postTickOnNextSecond() {
        long nowMillis = SystemClock.elapsedRealtime();
        int millis = (int) ((nowMillis - mBase) % 1000);
        postDelayed(mTickRunnable, 1000 - millis);
        long nowMillis = mNow;
        long delayMillis;
        if (mCountDown) {
            delayMillis = (mBase - nowMillis) % 1000;
            if (delayMillis <= 0) {
                delayMillis += 1000;
            }
        } else {
            delayMillis = 1000 - (Math.abs(nowMillis - mBase) % 1000);
        }
        // Aim for 1 millisecond into the next second so we don't update exactly on the second
        delayMillis++;
        postDelayed(mTickRunnable, delayMillis);
    }

    void dispatchChronometerTick() {
+28 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.widget;

import android.app.Activity;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;

import androidx.test.filters.LargeTest;
@@ -28,7 +29,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Test {@link DatePicker} focus changes.
 * Test {@link Chronometer} counting up and down.
 */
@SuppressWarnings("deprecation")
@LargeTest
@@ -50,26 +51,48 @@ public class ChronometerTest extends ActivityInstrumentationTestCase2<Chronomete
    }

    public void testChronometerTicksSequentially() throws Throwable {
        final CountDownLatch latch = new CountDownLatch(5);
        final CountDownLatch latch = new CountDownLatch(6);
        ArrayList<String> ticks = new ArrayList<>();
        runOnUiThread(() -> {
            mChronometer.setOnChronometerTickListener((chronometer) -> {
                ticks.add(chronometer.getText().toString());
                latch.countDown();
                try {
                    Thread.sleep(500);
                    Thread.sleep(250);
                } catch (InterruptedException e) {
                }
            });
            mChronometer.start();
        });
        assertTrue(latch.await(6, TimeUnit.SECONDS));
        assertTrue(ticks.size() >= 5);
        assertTrue(latch.await(5500, TimeUnit.MILLISECONDS));
        assertEquals("00:00", ticks.get(0));
        assertEquals("00:01", ticks.get(1));
        assertEquals("00:02", ticks.get(2));
        assertEquals("00:03", ticks.get(3));
        assertEquals("00:04", ticks.get(4));
        assertEquals("00:05", ticks.get(5));
    }

    public void testChronometerCountDown() throws Throwable {
        final CountDownLatch latch = new CountDownLatch(5);
        ArrayList<String> ticks = new ArrayList<>();
        runOnUiThread(() -> {
            mChronometer.setBase(SystemClock.elapsedRealtime() + 3_000);
            mChronometer.setCountDown(true);
            mChronometer.post(() -> {
                mChronometer.setOnChronometerTickListener((chronometer) -> {
                    ticks.add(chronometer.getText().toString());
                    latch.countDown();
                });
                mChronometer.start();
            });
        });
        assertTrue(latch.await(4500, TimeUnit.MILLISECONDS));
        assertEquals("00:02", ticks.get(0));
        assertEquals("00:01", ticks.get(1));
        assertEquals("00:00", ticks.get(2));
        assertEquals("−00:01", ticks.get(3));
        assertEquals("−00:02", ticks.get(4));
    }

    private void runOnUiThread(Runnable runnable) throws InterruptedException {