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

Commit 9911a28a authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Jeff Sharkey
Browse files

Better handling of NTP-based clocks.

Now that we have a nice Clock abstraction, we can use it to represent
a clock backed by an NTP fix.  (This makes testing logic much easier
to write.)

We now rely completely on NetworkTimeUpdateService to keep our NTP
fix up to date, instead of trying to refresh in the middle of
critical paths which could trigger random ANRs.

Add internal FallbackClock to make it easier to handle missing NTP
fixes.  Add internal SimpleClock to let implementers focus on single
millis() method.

Test: bit FrameworksNetTests:com.android.server.net.NetworkStatsServiceTest
Test: bit FrameworksServicesTests:com.android.server.NetworkPolicyManagerServiceTest
Bug: 69714690, 72320957
Change-Id: Ic32cdcbe093d08b73b0e4b23d6910b23ea8e1968
Exempt-From-Owner-Approval: approved in previous PS
parent 0f888de0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -33036,14 +33036,14 @@ package android.os {
  }
  public final class SystemClock {
    method public static java.time.Clock currentNetworkTimeClock();
    method public static long currentNetworkTimeMillis();
    method public static long currentThreadTimeMillis();
    method public static long elapsedRealtime();
    method public static java.time.Clock elapsedRealtimeClock();
    method public static long elapsedRealtimeNanos();
    method public static boolean setCurrentTimeMillis(long);
    method public static void sleep(long);
    method public static long uptimeMillis();
    method public static java.time.Clock uptimeMillisClock();
  }
  public class TestLooperManager {
+6 −0
Original line number Diff line number Diff line
@@ -257,6 +257,12 @@ package android.os {
    ctor public RecoverySystem();
  }

  public final class SystemClock {
    method public static java.time.Clock elapsedRealtimeClock();
    method public static java.time.Clock uptimeClock();
    method public static deprecated java.time.Clock uptimeMillisClock();
  }

  public class TestLooperManager {
    method public deprecated android.os.MessageQueue getQueue();
  }
+1 −0
Original line number Diff line number Diff line
@@ -37,4 +37,5 @@ interface IAlarmManager {
    void remove(in PendingIntent operation, in IAlarmListener listener);
    long getNextWakeFromIdleTime();
    AlarmManager.AlarmClockInfo getNextAlarmClock(int userId);
    long currentNetworkTimeMillis();
}
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.os;

import android.util.Log;

import java.time.Clock;
import java.time.DateTimeException;
import java.time.ZoneId;
import java.util.Arrays;

/**
 * Single {@link Clock} that will return the best available time from a set of
 * prioritized {@link Clock} instances.
 * <p>
 * For example, when {@link SystemClock#currentNetworkTimeClock()} isn't able to
 * provide the time, this class could use {@link Clock#systemUTC()} instead.
 *
 * @hide
 */
public class BestClock extends SimpleClock {
    private static final String TAG = "BestClock";

    private final Clock[] clocks;

    public BestClock(ZoneId zone, Clock... clocks) {
        super(zone);
        this.clocks = clocks;
    }

    @Override
    public long millis() {
        for (Clock clock : clocks) {
            try {
                return clock.millis();
            } catch (DateTimeException e) {
                // Ignore and attempt the next clock
                Log.w(TAG, e.toString());
            }
        }
        throw new DateTimeException(
                "No clocks in " + Arrays.toString(clocks) + " were able to provide time");
    }
}
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.os;

import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;

/** {@hide} */
public abstract class SimpleClock extends Clock {
    private final ZoneId zone;

    public SimpleClock(ZoneId zone) {
        this.zone = zone;
    }

    @Override
    public ZoneId getZone() {
        return zone;
    }

    @Override
    public Clock withZone(ZoneId zone) {
        return new SimpleClock(zone) {
            @Override
            public long millis() {
                return SimpleClock.this.millis();
            }
        };
    }

    @Override
    public abstract long millis();

    @Override
    public Instant instant() {
        return Instant.ofEpochMilli(millis());
    }
}
Loading