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

Commit bfe51b55 authored by Stevie Kideckel's avatar Stevie Kideckel Committed by Automerger Merge Worker
Browse files

Merge "Schedule time ticks for the next minute when no seconds hand is...

Merge "Schedule time ticks for the next minute when no seconds hand is present" into sc-dev am: 80aaf881

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14881612

Change-Id: I2a70b6ff64a83f71ee8a1581f362daf7741bd4a3
parents 968d29f8 80aaf881
Loading
Loading
Loading
Loading
+47 −23
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ import java.time.Duration;
import java.time.Instant;
import java.time.Instant;
import java.time.LocalTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Formatter;
import java.util.Formatter;
import java.util.Locale;
import java.util.Locale;


@@ -451,7 +452,9 @@ public class AnalogClock extends View {
        if (mSecondHandTintInfo.mHasTintList || mSecondHandTintInfo.mHasTintBlendMode) {
        if (mSecondHandTintInfo.mHasTintList || mSecondHandTintInfo.mHasTintBlendMode) {
            mSecondHand = mSecondHandTintInfo.apply(mSecondHand);
            mSecondHand = mSecondHandTintInfo.apply(mSecondHand);
        }
        }
        mSecondsTick.run();
        // Re-run the tick runnable immediately as the presence or absence of a seconds hand affects
        // the next time we need to tick the clock.
        mTick.run();


        mChanged = true;
        mChanged = true;
        invalidate();
        invalidate();
@@ -583,10 +586,10 @@ public class AnalogClock extends View {
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);


            // OK, this is gross but needed. This class is supported by the
            // OK, this is gross but needed. This class is supported by the
            // remote views machanism and as a part of that the remote views
            // remote views mechanism and as a part of that the remote views
            // can be inflated by a context for another user without the app
            // can be inflated by a context for another user without the app
            // having interact users permission - just for loading resources.
            // having interact users permission - just for loading resources.
            // For exmaple, when adding widgets from a user profile to the
            // For example, when adding widgets from a user profile to the
            // home screen. Therefore, we register the receiver as the current
            // home screen. Therefore, we register the receiver as the current
            // user not the one the context is for.
            // user not the one the context is for.
            getContext().registerReceiverAsUser(mIntentReceiver,
            getContext().registerReceiverAsUser(mIntentReceiver,
@@ -616,14 +619,14 @@ public class AnalogClock extends View {
    private void onVisible() {
    private void onVisible() {
        if (!mVisible) {
        if (!mVisible) {
            mVisible = true;
            mVisible = true;
            mSecondsTick.run();
            mTick.run();
        }
        }


    }
    }


    private void onInvisible() {
    private void onInvisible() {
        if (mVisible) {
        if (mVisible) {
            removeCallbacks(mSecondsTick);
            removeCallbacks(mTick);
            mVisible = false;
            mVisible = false;
        }
        }
    }
    }
@@ -760,6 +763,7 @@ public class AnalogClock extends View {
        }
        }
    }
    }


    /** Intent receiver for the time or time zone changing. */
    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        @Override
        public void onReceive(Context context, Intent intent) {
        public void onReceive(Context context, Intent intent) {
@@ -767,23 +771,40 @@ public class AnalogClock extends View {
                createClock();
                createClock();
            }
            }


            onTimeChanged();
            mTick.run();

            invalidate();
        }
        }
    };
    };
    private boolean mReceiverAttached;
    private boolean mReceiverAttached;


    private final Runnable mSecondsTick = new Runnable() {
    private final Runnable mTick = new Runnable() {
        @Override
        @Override
        public void run() {
        public void run() {
            removeCallbacks(this);
            removeCallbacks(this);
            if (!mVisible || mSecondHand == null) {
            if (!mVisible) {
                return;
                return;
            }
            }


            Instant now = mClock.instant();
            Instant now = mClock.instant();
            LocalTime localTime = now.atZone(mClock.getZone()).toLocalTime();
            ZonedDateTime zonedDateTime = now.atZone(mClock.getZone());
            LocalTime localTime = zonedDateTime.toLocalTime();

            long millisUntilNextTick;
            if (mSecondHand == null) {
                // If there's no second hand, then tick at the start of the next minute.
                //
                // This must be done with ZonedDateTime as opposed to LocalDateTime to ensure proper
                // handling of DST. Also note that because of leap seconds, it should not be assumed
                // that one minute == 60 seconds.
                Instant startOfNextMinute = zonedDateTime.plusMinutes(1).withSecond(0).toInstant();
                millisUntilNextTick = Duration.between(now, startOfNextMinute).toMillis();
                if (millisUntilNextTick <= 0) {
                    // This should never occur, but if it does, then just check the tick again in
                    // one minute to ensure we're always moving forward.
                    millisUntilNextTick = Duration.ofMinutes(1).toMillis();
                }
            } else {
                // If there is a seconds hand, then determine the next tick point based on the fps.
                //
                // How many milliseconds through the second we currently are.
                // How many milliseconds through the second we currently are.
                long millisOfSecond = Duration.ofNanos(localTime.getNano()).toMillis();
                long millisOfSecond = Duration.ofNanos(localTime.getNano()).toMillis();
                // How many milliseconds there are between tick positions for the seconds hand.
                // How many milliseconds there are between tick positions for the seconds hand.
@@ -791,12 +812,15 @@ public class AnalogClock extends View {
                // How many milliseconds we are past the last tick position.
                // How many milliseconds we are past the last tick position.
                long millisPastLastTick = Math.round(millisOfSecond % millisPerTick);
                long millisPastLastTick = Math.round(millisOfSecond % millisPerTick);
                // How many milliseconds there are until the next tick position.
                // How many milliseconds there are until the next tick position.
            long millisUntilNextTick = Math.round(millisPerTick - millisPastLastTick);
                millisUntilNextTick = Math.round(millisPerTick - millisPastLastTick);
            // If we are exactly at the tick position, this could be 0 milliseconds due to rounding.
                // If we are exactly at the tick position, this could be 0 milliseconds due to
            // In this case, advance by the full amount of millis to the next position.
                // rounding. In this case, advance by the full amount of millis to the next
                // position.
                if (millisUntilNextTick <= 0) {
                if (millisUntilNextTick <= 0) {
                    millisUntilNextTick = Math.round(millisPerTick);
                    millisUntilNextTick = Math.round(millisPerTick);
                }
                }
            }

            // Schedule a callback for when the next tick should occur.
            // Schedule a callback for when the next tick should occur.
            postDelayed(this, millisUntilNextTick);
            postDelayed(this, millisUntilNextTick);