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

Commit 2d9b658e authored by George Mount's avatar George Mount
Browse files

Chronometer: fix countdown by two seconds

Fixes: 418000654

Flag: EXEMPT Bug Fix

When the chronometer countdown landed on the exact millisecond,
it was rounding to the wrong value. This is because when counting
down, it tended toward the second down rather than rounding, but
if it landed on the exact millisecond, it would round up. To solve
this, the tick is now delayed by 3 milliseconds past the second
rather than 1 millisecond past the second.

Test: local tests, broken test app

Change-Id: I7595f6485515facb08f379eb99ce486e37e8299b
parent b58847b3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -357,8 +357,8 @@ public class Chronometer extends TextView {
        } 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++;
        // Aim for 3 milliseconds into the next second so we don't update exactly on the second
        delayMillis += 3;
        postDelayed(mTickRunnable, delayMillis);
    }

+16 −8
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ public class ChronometerTest extends ActivityInstrumentationTestCase2<Chronomete
        final CountDownLatch latch = new CountDownLatch(6);
        ArrayList<String> ticks = new ArrayList<>();
        runOnUiThread(() -> {
            mChronometer.setBase(SystemClock.elapsedRealtime());
            mChronometer.setOnChronometerTickListener((chronometer) -> {
                ticks.add(chronometer.getText().toString());
                latch.countDown();
@@ -74,25 +75,32 @@ public class ChronometerTest extends ActivityInstrumentationTestCase2<Chronomete
    }

    public void testChronometerCountDown() throws Throwable {
        final CountDownLatch latch = new CountDownLatch(5);
        final CountDownLatch latch = new CountDownLatch(12);
        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();
            });

            // start in the next frame so that it is more than 1 ms below 3 seconds
            mChronometer.post(() -> mChronometer.start());
        });
        assertTrue(latch.await(4500, TimeUnit.MILLISECONDS));
        assertTrue(latch.await(12500, 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));
        assertEquals("−00:03", ticks.get(5));
        assertEquals("−00:04", ticks.get(6));
        assertEquals("−00:05", ticks.get(7));
        assertEquals("−00:06", ticks.get(8));
        assertEquals("−00:07", ticks.get(9));
        assertEquals("−00:08", ticks.get(10));
        assertEquals("−00:09", ticks.get(11));
    }

    private void runOnUiThread(Runnable runnable) throws InterruptedException {