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

Commit 403edaa3 authored by Neil Fuller's avatar Neil Fuller Committed by Android (Google) Code Review
Browse files

Merge "Introduce system clock time confidence"

parents aaf15355 c4ba2d9c
Loading
Loading
Loading
Loading
+61 −52
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROU
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
import static android.os.UserHandle.USER_SYSTEM;

import static com.android.server.SystemClockTime.TIME_CONFIDENCE_HIGH;
import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH;
import static com.android.server.SystemTimeZone.getTimeZoneId;
import static com.android.server.alarm.Alarm.APP_STANDBY_POLICY_INDEX;
@@ -58,6 +59,8 @@ import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_R
import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_UNDEFINED;

import android.Manifest;
import android.annotation.CurrentTimeMillisLong;
import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.Activity;
@@ -87,7 +90,6 @@ import android.os.BatteryManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -101,7 +103,6 @@ import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.ThreadLocalWorkSource;
import android.os.Trace;
import android.os.UserHandle;
@@ -145,6 +146,8 @@ import com.android.server.DeviceIdleInternal;
import com.android.server.EventLogTags;
import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices;
import com.android.server.SystemClockTime;
import com.android.server.SystemClockTime.TimeConfidence;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
import com.android.server.SystemTimeZone;
@@ -1417,7 +1420,7 @@ public class AlarmManagerService extends SystemService {

    private long convertToElapsed(long when, int type) {
        if (isRtc(type)) {
            when -= mInjector.getCurrentTimeMillis() - mInjector.getElapsedRealtime();
            when -= mInjector.getCurrentTimeMillis() - mInjector.getElapsedRealtimeMillis();
        }
        return when;
    }
@@ -1577,7 +1580,7 @@ public class AlarmManagerService extends SystemService {
            alarmsToDeliver = alarmsForUid;
            mPendingBackgroundAlarms.remove(uid);
        }
        deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, mInjector.getElapsedRealtime());
        deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, mInjector.getElapsedRealtimeMillis());
    }

    /**
@@ -1594,7 +1597,8 @@ public class AlarmManagerService extends SystemService {
                mPendingBackgroundAlarms, alarmsToDeliver, this::isBackgroundRestricted);

        if (alarmsToDeliver.size() > 0) {
            deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, mInjector.getElapsedRealtime());
            deliverPendingBackgroundAlarmsLocked(
                    alarmsToDeliver, mInjector.getElapsedRealtimeMillis());
        }
    }

@@ -1908,17 +1912,8 @@ public class AlarmManagerService extends SystemService {
                mInjector.syncKernelTimeZoneOffset();
            }

            // Ensure that we're booting with a halfway sensible current time.  Use the
            // most recent of Build.TIME, the root file system's timestamp, and the
            // value of the ro.build.date.utc system property (which is in seconds).
            final long systemBuildTime = Long.max(
                    1000L * SystemProperties.getLong("ro.build.date.utc", -1L),
                    Long.max(Environment.getRootDirectory().lastModified(), Build.TIME));
            if (mInjector.getCurrentTimeMillis() < systemBuildTime) {
                Slog.i(TAG, "Current time only " + mInjector.getCurrentTimeMillis()
                        + ", advancing to build time " + systemBuildTime);
                mInjector.setKernelTime(systemBuildTime);
            }
            // Ensure that we're booting with a halfway sensible current time.
            mInjector.initializeTimeIfRequired();

            mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
            // Determine SysUI's uid
@@ -2133,21 +2128,18 @@ public class AlarmManagerService extends SystemService {
        }
    }

    boolean setTimeImpl(long millis) {
        if (!mInjector.isAlarmDriverPresent()) {
            Slog.w(TAG, "Not setting time since no alarm driver is available.");
            return false;
        }

    boolean setTimeImpl(
            @CurrentTimeMillisLong long newSystemClockTimeMillis, @TimeConfidence int confidence,
            @NonNull String logMsg) {
        synchronized (mLock) {
            final long currentTimeMillis = mInjector.getCurrentTimeMillis();
            mInjector.setKernelTime(millis);
            final long oldSystemClockTimeMillis = mInjector.getCurrentTimeMillis();
            mInjector.setCurrentTimeMillis(newSystemClockTimeMillis, confidence, logMsg);

            if (KERNEL_TIME_ZONE_SYNC_ENABLED) {
                // Changing the time may cross a DST transition; sync the kernel offset if needed.
                final TimeZone timeZone = TimeZone.getTimeZone(SystemTimeZone.getTimeZoneId());
                final int currentTzOffset = timeZone.getOffset(currentTimeMillis);
                final int newTzOffset = timeZone.getOffset(millis);
                final int currentTzOffset = timeZone.getOffset(oldSystemClockTimeMillis);
                final int newTzOffset = timeZone.getOffset(newSystemClockTimeMillis);
                if (currentTzOffset != newTzOffset) {
                    Slog.i(TAG, "Timezone offset has changed, updating kernel timezone");
                    mInjector.setKernelTimeZoneOffset(newTzOffset);
@@ -2260,7 +2252,7 @@ public class AlarmManagerService extends SystemService {
            triggerAtTime = 0;
        }

        final long nowElapsed = mInjector.getElapsedRealtime();
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
        final long nominalTrigger = convertToElapsed(triggerAtTime, type);
        // Try to prevent spamming by making sure apps aren't firing alarms in the immediate future
        final long minTrigger = nowElapsed
@@ -2383,7 +2375,7 @@ public class AlarmManagerService extends SystemService {
            // No need to fuzz as this is already earlier than the coming wake-from-idle.
            return changedBeforeFuzz;
        }
        final long nowElapsed = mInjector.getElapsedRealtime();
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
        final long futurity = upcomingWakeFromIdle - nowElapsed;

        if (futurity <= mConstants.MIN_DEVICE_IDLE_FUZZ) {
@@ -2405,7 +2397,7 @@ public class AlarmManagerService extends SystemService {
     * @return {@code true} if the alarm delivery time was updated.
     */
    private boolean adjustDeliveryTimeBasedOnBatterySaver(Alarm alarm) {
        final long nowElapsed = mInjector.getElapsedRealtime();
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
        if (isExemptFromBatterySaver(alarm)) {
            return false;
        }
@@ -2472,7 +2464,7 @@ public class AlarmManagerService extends SystemService {
     * @return {@code true} if the alarm delivery time was updated.
     */
    private boolean adjustDeliveryTimeBasedOnDeviceIdle(Alarm alarm) {
        final long nowElapsed = mInjector.getElapsedRealtime();
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
        if (mPendingIdleUntil == null || mPendingIdleUntil == alarm) {
            return alarm.setPolicyElapsed(DEVICE_IDLE_POLICY_INDEX, nowElapsed);
        }
@@ -2527,7 +2519,7 @@ public class AlarmManagerService extends SystemService {
     *         adjustments made in this call.
     */
    private boolean adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm) {
        final long nowElapsed = mInjector.getElapsedRealtime();
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
        if (mConstants.USE_TARE_POLICY || isExemptFromAppStandby(alarm) || mAppStandbyParole) {
            return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
        }
@@ -2587,7 +2579,7 @@ public class AlarmManagerService extends SystemService {
     * adjustments made in this call.
     */
    private boolean adjustDeliveryTimeBasedOnTareLocked(Alarm alarm) {
        final long nowElapsed = mInjector.getElapsedRealtime();
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
        if (!mConstants.USE_TARE_POLICY
                || isExemptFromTare(alarm) || hasEnoughWealthLocked(alarm)) {
            return alarm.setPolicyElapsed(TARE_POLICY_INDEX, nowElapsed);
@@ -2643,7 +2635,7 @@ public class AlarmManagerService extends SystemService {
                ent.pkg = a.sourcePackage;
                ent.tag = a.statsTag;
                ent.op = "START IDLE";
                ent.elapsedRealtime = mInjector.getElapsedRealtime();
                ent.elapsedRealtime = mInjector.getElapsedRealtimeMillis();
                ent.argRealtime = a.getWhenElapsed();
                mAllowWhileIdleDispatches.add(ent);
            }
@@ -2718,6 +2710,13 @@ public class AlarmManagerService extends SystemService {
            setTimeZoneImpl(tzId, confidence);
        }

        @Override
        public void setTime(
                @CurrentTimeMillisLong long unixEpochTimeMillis, int confidence,
                String logMsg) {
            setTimeImpl(unixEpochTimeMillis, confidence, logMsg);
        }

        @Override
        public void registerInFlightListener(InFlightListener callback) {
            synchronized (mLock) {
@@ -2987,12 +2986,16 @@ public class AlarmManagerService extends SystemService {
        }

        @Override
        public boolean setTime(long millis) {
        public boolean setTime(@CurrentTimeMillisLong long millis) {
            getContext().enforceCallingOrSelfPermission(
                    "android.permission.SET_TIME",
                    "setTime");

            return setTimeImpl(millis);
            // The public API (and the shell command that also uses this method) have no concept
            // of confidence, but since the time should come either from apps working on behalf of
            // the user or a developer, confidence is assumed "high".
            final int timeConfidence = TIME_CONFIDENCE_HIGH;
            return setTimeImpl(millis, timeConfidence, "AlarmManager.setTime() called");
        }

        @Override
@@ -3142,7 +3145,7 @@ public class AlarmManagerService extends SystemService {
                pw.println();
            }

            final long nowELAPSED = mInjector.getElapsedRealtime();
            final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
            final long nowUPTIME = SystemClock.uptimeMillis();
            final long nowRTC = mInjector.getCurrentTimeMillis();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
@@ -3618,7 +3621,7 @@ public class AlarmManagerService extends SystemService {

        synchronized (mLock) {
            final long nowRTC = mInjector.getCurrentTimeMillis();
            final long nowElapsed = mInjector.getElapsedRealtime();
            final long nowElapsed = mInjector.getElapsedRealtimeMillis();
            proto.write(AlarmManagerServiceDumpProto.CURRENT_TIME, nowRTC);
            proto.write(AlarmManagerServiceDumpProto.ELAPSED_REALTIME, nowElapsed);
            proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_CLOCK_TIME,
@@ -3956,7 +3959,7 @@ public class AlarmManagerService extends SystemService {
    void rescheduleKernelAlarmsLocked() {
        // Schedule the next upcoming wakeup alarm.  If there is a deliverable batch
        // prior to that which contains no wakeups, we schedule that as well.
        final long nowElapsed = mInjector.getElapsedRealtime();
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
        long nextNonWakeup = 0;
        if (mAlarmStore.size() > 0) {
            final long firstWakeup = mAlarmStore.getNextWakeupDeliveryTime();
@@ -4069,7 +4072,7 @@ public class AlarmManagerService extends SystemService {
    @GuardedBy("mLock")
    private void removeAlarmsInternalLocked(Predicate<Alarm> whichAlarms, int reason) {
        final long nowRtc = mInjector.getCurrentTimeMillis();
        final long nowElapsed = mInjector.getElapsedRealtime();
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();

        final ArrayList<Alarm> removedAlarms = mAlarmStore.remove(whichAlarms);
        final boolean removedFromStore = !removedAlarms.isEmpty();
@@ -4208,7 +4211,7 @@ public class AlarmManagerService extends SystemService {
    void interactiveStateChangedLocked(boolean interactive) {
        if (mInteractive != interactive) {
            mInteractive = interactive;
            final long nowELAPSED = mInjector.getElapsedRealtime();
            final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
            if (interactive) {
                if (mPendingNonWakeupAlarms.size() > 0) {
                    final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
@@ -4310,7 +4313,6 @@ public class AlarmManagerService extends SystemService {
    private static native void close(long nativeData);
    private static native int set(long nativeData, int type, long seconds, long nanoseconds);
    private static native int waitForAlarm(long nativeData);
    private static native int setKernelTime(long nativeData, long millis);

    /*
     * b/246256335: The @Keep ensures that the native definition is kept even when the optimizer can
@@ -4357,7 +4359,7 @@ public class AlarmManagerService extends SystemService {
                    ent.pkg = alarm.sourcePackage;
                    ent.tag = alarm.statsTag;
                    ent.op = "END IDLE";
                    ent.elapsedRealtime = mInjector.getElapsedRealtime();
                    ent.elapsedRealtime = mInjector.getElapsedRealtimeMillis();
                    ent.argRealtime = alarm.getWhenElapsed();
                    mAllowWhileIdleDispatches.add(ent);
                }
@@ -4602,20 +4604,27 @@ public class AlarmManagerService extends SystemService {
            setKernelTimeZoneOffset(utcOffsetMillis);
        }

        void setKernelTime(long millis) {
            if (mNativeData != 0) {
                AlarmManagerService.setKernelTime(mNativeData, millis);
        void initializeTimeIfRequired() {
            SystemClockTime.initializeIfRequired();
        }

        void setCurrentTimeMillis(
                @CurrentTimeMillisLong long unixEpochMillis,
                @TimeConfidence int confidence,
                @NonNull String logMsg) {
            SystemClockTime.setTimeAndConfidence(unixEpochMillis, confidence, logMsg);
        }

        void close() {
            AlarmManagerService.close(mNativeData);
        }

        long getElapsedRealtime() {
        @ElapsedRealtimeLong
        long getElapsedRealtimeMillis() {
            return SystemClock.elapsedRealtime();
        }

        @CurrentTimeMillisLong
        long getCurrentTimeMillis() {
            return System.currentTimeMillis();
        }
@@ -4665,7 +4674,7 @@ public class AlarmManagerService extends SystemService {
            while (true) {
                int result = mInjector.waitForAlarm();
                final long nowRTC = mInjector.getCurrentTimeMillis();
                final long nowELAPSED = mInjector.getElapsedRealtime();
                final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
                synchronized (mLock) {
                    mLastWakeup = nowELAPSED;
                }
@@ -4913,7 +4922,7 @@ public class AlarmManagerService extends SystemService {
                    // this way, so WAKE_UP alarms will be delivered only when the device is awake.
                    ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
                    synchronized (mLock) {
                        final long nowELAPSED = mInjector.getElapsedRealtime();
                        final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
                        triggerAlarmsLocked(triggerList, nowELAPSED);
                        updateNextAlarmClockLocked();
                    }
@@ -5090,7 +5099,7 @@ public class AlarmManagerService extends SystemService {
            flags |= mConstants.TIME_TICK_ALLOWED_WHILE_IDLE ? FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED
                    : 0;

            setImpl(ELAPSED_REALTIME, mInjector.getElapsedRealtime() + tickEventDelay, 0,
            setImpl(ELAPSED_REALTIME, mInjector.getElapsedRealtimeMillis() + tickEventDelay, 0,
                    0, null, mTimeTickTrigger, TIME_TICK_TAG, flags, workSource, null,
                    Process.myUid(), "android", null, EXACT_ALLOW_REASON_ALLOW_LIST);

@@ -5277,7 +5286,7 @@ public class AlarmManagerService extends SystemService {
            }
            synchronized (mLock) {
                mTemporaryQuotaReserve.replenishQuota(packageName, userId, quotaBump,
                        mInjector.getElapsedRealtime());
                        mInjector.getElapsedRealtimeMillis());
            }
            mHandler.obtainMessage(AlarmHandler.TEMPORARY_QUOTA_CHANGED, userId, -1,
                    packageName).sendToTarget();
@@ -5439,7 +5448,7 @@ public class AlarmManagerService extends SystemService {
        }

        private void updateStatsLocked(InFlight inflight) {
            final long nowELAPSED = mInjector.getElapsedRealtime();
            final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
            BroadcastStats bs = inflight.mBroadcastStats;
            bs.nesting--;
            if (bs.nesting <= 0) {
+3 −77
Original line number Diff line number Diff line
@@ -76,19 +76,17 @@ typedef std::array<int, N_ANDROID_TIMERFDS> TimerFds;
class AlarmImpl
{
public:
    AlarmImpl(const TimerFds &fds, int epollfd, const std::string &rtc_dev)
          : fds{fds}, epollfd{epollfd}, rtc_dev{rtc_dev} {}
    AlarmImpl(const TimerFds &fds, int epollfd)
          : fds{fds}, epollfd{epollfd} {}
    ~AlarmImpl();

    int set(int type, struct timespec *ts);
    int setTime(struct timeval *tv);
    int waitForAlarm();
    int getTime(int type, struct itimerspec *spec);

private:
    const TimerFds fds;
    const int epollfd;
    std::string rtc_dev;
};

AlarmImpl::~AlarmImpl()
@@ -131,43 +129,6 @@ int AlarmImpl::getTime(int type, struct itimerspec *spec)
    return timerfd_gettime(fds[type], spec);
}

int AlarmImpl::setTime(struct timeval *tv)
{
    if (settimeofday(tv, NULL) == -1) {
        ALOGV("settimeofday() failed: %s", strerror(errno));
        return -1;
    }

    android::base::unique_fd fd{open(rtc_dev.c_str(), O_RDWR)};
    if (!fd.ok()) {
        ALOGE("Unable to open %s: %s", rtc_dev.c_str(), strerror(errno));
        return -1;
    }

    struct tm tm;
    if (!gmtime_r(&tv->tv_sec, &tm)) {
        ALOGV("gmtime_r() failed: %s", strerror(errno));
        return -1;
    }

    struct rtc_time rtc = {};
    rtc.tm_sec = tm.tm_sec;
    rtc.tm_min = tm.tm_min;
    rtc.tm_hour = tm.tm_hour;
    rtc.tm_mday = tm.tm_mday;
    rtc.tm_mon = tm.tm_mon;
    rtc.tm_year = tm.tm_year;
    rtc.tm_wday = tm.tm_wday;
    rtc.tm_yday = tm.tm_yday;
    rtc.tm_isdst = tm.tm_isdst;
    if (ioctl(fd, RTC_SET_TIME, &rtc) == -1) {
        ALOGV("RTC_SET_TIME ioctl failed: %s", strerror(errno));
        return -1;
    }

    return 0;
}

int AlarmImpl::waitForAlarm()
{
    epoll_event events[N_ANDROID_TIMERFDS];
@@ -198,28 +159,6 @@ int AlarmImpl::waitForAlarm()
    return result;
}

static jint android_server_alarm_AlarmManagerService_setKernelTime(JNIEnv*, jobject, jlong nativeData, jlong millis)
{
    AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);

    if (millis <= 0 || millis / 1000LL >= std::numeric_limits<time_t>::max()) {
        return -1;
    }

    struct timeval tv;
    tv.tv_sec = (millis / 1000LL);
    tv.tv_usec = ((millis % 1000LL) * 1000LL);

    ALOGD("Setting time of day to sec=%ld", tv.tv_sec);

    int ret = impl->setTime(&tv);
    if (ret < 0) {
        ALOGW("Unable to set rtc to %ld: %s", tv.tv_sec, strerror(errno));
        ret = -1;
    }
    return ret;
}

static jint android_server_alarm_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jlong, jint minswest)
{
    struct timezone tz;
@@ -287,19 +226,7 @@ static jlong android_server_alarm_AlarmManagerService_init(JNIEnv*, jobject)
        }
    }

    // Find the wall clock RTC. We expect this always to be /dev/rtc0, but
    // check the /dev/rtc symlink first so that legacy devices that don't use
    // rtc0 can add a symlink rather than need to carry a local patch to this
    // code.
    //
    // TODO: if you're reading this in a world where all devices are using the
    // GKI, you can remove the readlink and just assume /dev/rtc0.
    std::string dev_rtc;
    if (!android::base::Readlink("/dev/rtc", &dev_rtc)) {
        dev_rtc = "/dev/rtc0";
    }

    std::unique_ptr<AlarmImpl> alarm{new AlarmImpl(fds, epollfd, dev_rtc)};
    std::unique_ptr<AlarmImpl> alarm{new AlarmImpl(fds, epollfd)};

    for (size_t i = 0; i < fds.size(); i++) {
        epoll_event event;
@@ -392,7 +319,6 @@ static const JNINativeMethod sMethods[] = {
    {"close", "(J)V", (void*)android_server_alarm_AlarmManagerService_close},
    {"set", "(JIJJ)I", (void*)android_server_alarm_AlarmManagerService_set},
    {"waitForAlarm", "(J)I", (void*)android_server_alarm_AlarmManagerService_waitForAlarm},
    {"setKernelTime", "(JJ)I", (void*)android_server_alarm_AlarmManagerService_setKernelTime},
    {"setKernelTimezone", "(JI)I", (void*)android_server_alarm_AlarmManagerService_setKernelTimezone},
    {"getNextAlarm", "(JI)J", (void*)android_server_alarm_AlarmManagerService_getNextAlarm},
};
+13 −0
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.server;

import android.annotation.CurrentTimeMillisLong;
import android.app.PendingIntent;

import com.android.server.SystemClockTime.TimeConfidence;
import com.android.server.SystemTimeZone.TimeZoneConfidence;

public interface AlarmManagerInternal {
@@ -59,4 +61,15 @@ public interface AlarmManagerInternal {
     *     for details
     */
    void setTimeZone(String tzId, @TimeZoneConfidence int confidence);

    /**
     * Sets the device's current time and time confidence.
     *
     * @param unixEpochTimeMillis the time
     * @param confidence the confidence that {@code unixEpochTimeMillis} is correct, see {@link
     *     TimeConfidence} for details
     * @param logMsg the reason the time is being changed, for bug report logging
     */
    void setTime(@CurrentTimeMillisLong long unixEpochTimeMillis, @TimeConfidence int confidence,
            String logMsg);
}
Loading