/*
 * Copyright (C) 2006 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.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.app.IAlarmManager;
import android.content.Context;
import android.location.ILocationManager;
import android.location.LocationTime;
import android.util.Slog;

import dalvik.annotation.optimization.CriticalNative;

import java.time.Clock;
import java.time.DateTimeException;
import java.time.ZoneOffset;

/**
 * Core timekeeping facilities.
 *
 * <p> Three different clocks are available, and they should not be confused:
 *
 * <ul>
 *     <li> <p> {@link System#currentTimeMillis System.currentTimeMillis()}
 *     is the standard "wall" clock (time and date) expressing milliseconds
 *     since the epoch.  The wall clock can be set by the user or the phone
 *     network (see {@link #setCurrentTimeMillis}), so the time may jump
 *     backwards or forwards unpredictably.  This clock should only be used
 *     when correspondence with real-world dates and times is important, such
 *     as in a calendar or alarm clock application.  Interval or elapsed
 *     time measurements should use a different clock.  If you are using
 *     System.currentTimeMillis(), consider listening to the
 *     {@link android.content.Intent#ACTION_TIME_TICK ACTION_TIME_TICK},
 *     {@link android.content.Intent#ACTION_TIME_CHANGED ACTION_TIME_CHANGED}
 *     and {@link android.content.Intent#ACTION_TIMEZONE_CHANGED
 *     ACTION_TIMEZONE_CHANGED} {@link android.content.Intent Intent}
 *     broadcasts to find out when the time changes.
 *
 *     <li> <p> {@link #uptimeMillis} is counted in milliseconds since the
 *     system was booted.  This clock stops when the system enters deep
 *     sleep (CPU off, display dark, device waiting for external input),
 *     but is not affected by clock scaling, idle, or other power saving
 *     mechanisms.  This is the basis for most interval timing
 *     such as {@link Thread#sleep(long) Thread.sleep(millls)},
 *     {@link Object#wait(long) Object.wait(millis)}, and
 *     {@link System#nanoTime System.nanoTime()}.  This clock is guaranteed
 *     to be monotonic, and is suitable for interval timing when the
 *     interval does not span device sleep.  Most methods that accept a
 *     timestamp value currently expect the {@link #uptimeMillis} clock.
 *
 *     <li> <p> {@link #elapsedRealtime} and {@link #elapsedRealtimeNanos}
 *     return the time since the system was booted, and include deep sleep.
 *     This clock is guaranteed to be monotonic, and continues to tick even
 *     when the CPU is in power saving modes, so is the recommend basis
 *     for general purpose interval timing.
 *
 * </ul>
 *
 * There are several mechanisms for controlling the timing of events:
 *
 * <ul>
 *     <li> <p> Standard functions like {@link Thread#sleep(long)
 *     Thread.sleep(millis)} and {@link Object#wait(long) Object.wait(millis)}
 *     are always available.  These functions use the {@link #uptimeMillis}
 *     clock; if the device enters sleep, the remainder of the time will be
 *     postponed until the device wakes up.  These synchronous functions may
 *     be interrupted with {@link Thread#interrupt Thread.interrupt()}, and
 *     you must handle {@link InterruptedException}.
 *
 *     <li> <p> {@link #sleep SystemClock.sleep(millis)} is a utility function
 *     very similar to {@link Thread#sleep(long) Thread.sleep(millis)}, but it
 *     ignores {@link InterruptedException}.  Use this function for delays if
 *     you do not use {@link Thread#interrupt Thread.interrupt()}, as it will
 *     preserve the interrupted state of the thread.
 *
 *     <li> <p> The {@link android.os.Handler} class can schedule asynchronous
 *     callbacks at an absolute or relative time.  Handler objects also use the
 *     {@link #uptimeMillis} clock, and require an {@link android.os.Looper
 *     event loop} (normally present in any GUI application).
 *
 *     <li> <p> The {@link android.app.AlarmManager} can trigger one-time or
 *     recurring events which occur even when the device is in deep sleep
 *     or your application is not running.  Events may be scheduled with your
 *     choice of {@link java.lang.System#currentTimeMillis} (RTC) or
 *     {@link #elapsedRealtime} (ELAPSED_REALTIME), and cause an
 *     {@link android.content.Intent} broadcast when they occur.
 * </ul>
 */
public final class SystemClock {
    private static final String TAG = "SystemClock";

    /**
     * This class is uninstantiable.
     */
    @UnsupportedAppUsage
    private SystemClock() {
        // This space intentionally left blank.
    }

    /**
     * Waits a given number of milliseconds (of uptimeMillis) before returning.
     * Similar to {@link java.lang.Thread#sleep(long)}, but does not throw
     * {@link InterruptedException}; {@link Thread#interrupt()} events are
     * deferred until the next interruptible operation.  Does not return until
     * at least the specified number of milliseconds has elapsed.
     *
     * @param ms to sleep before returning, in milliseconds of uptime.
     */
    public static void sleep(long ms)
    {
        long start = uptimeMillis();
        long duration = ms;
        boolean interrupted = false;
        do {
            try {
                Thread.sleep(duration);
            }
            catch (InterruptedException e) {
                interrupted = true;
            }
            duration = start + ms - uptimeMillis();
        } while (duration > 0);

        if (interrupted) {
            // Important: we don't want to quietly eat an interrupt() event,
            // so we make sure to re-interrupt the thread so that the next
            // call to Thread.sleep() or Object.wait() will be interrupted.
            Thread.currentThread().interrupt();
        }
    }

    /**
     * Sets the current wall time, in milliseconds.  Requires the calling
     * process to have appropriate permissions.
     *
     * @return if the clock was successfully set to the specified time.
     */
    public static boolean setCurrentTimeMillis(long millis) {
        final IAlarmManager mgr = IAlarmManager.Stub
                .asInterface(ServiceManager.getService(Context.ALARM_SERVICE));
        if (mgr == null) {
            return false;
        }

        try {
            return mgr.setTime(millis);
        } catch (RemoteException e) {
            Slog.e(TAG, "Unable to set RTC", e);
        } catch (SecurityException e) {
            Slog.e(TAG, "Unable to set RTC", e);
        }

        return false;
    }

    /**
     * Returns milliseconds since boot, not counting time spent in deep sleep.
     *
     * @return milliseconds of non-sleep uptime since boot.
     */
    @CriticalNative
    native public static long uptimeMillis();

    /**
     * @removed
     */
    @Deprecated
    public static @NonNull Clock uptimeMillisClock() {
        return uptimeClock();
    }

    /**
     * Return {@link Clock} that starts at system boot, not counting time spent
     * in deep sleep.
     *
     * @removed
     */
    public static @NonNull Clock uptimeClock() {
        return new SimpleClock(ZoneOffset.UTC) {
            @Override
            public long millis() {
                return SystemClock.uptimeMillis();
            }
        };
    }

    /**
     * Returns milliseconds since boot, including time spent in sleep.
     *
     * @return elapsed milliseconds since boot.
     */
    @CriticalNative
    native public static long elapsedRealtime();

    /**
     * Return {@link Clock} that starts at system boot, including time spent in
     * sleep.
     *
     * @removed
     */
    public static @NonNull Clock elapsedRealtimeClock() {
        return new SimpleClock(ZoneOffset.UTC) {
            @Override
            public long millis() {
                return SystemClock.elapsedRealtime();
            }
        };
    }

    /**
     * Returns nanoseconds since boot, including time spent in sleep.
     *
     * @return elapsed nanoseconds since boot.
     */
    @CriticalNative
    public static native long elapsedRealtimeNanos();

    /**
     * Returns milliseconds running in the current thread.
     *
     * @return elapsed milliseconds in the thread
     */
    @CriticalNative
    public static native long currentThreadTimeMillis();

    /**
     * Returns microseconds running in the current thread.
     *
     * @return elapsed microseconds in the thread
     *
     * @hide
     */
    @UnsupportedAppUsage
    @CriticalNative
    public static native long currentThreadTimeMicro();

    /**
     * Returns current wall time in  microseconds.
     *
     * @return elapsed microseconds in wall time
     *
     * @hide
     */
    @UnsupportedAppUsage
    @CriticalNative
    public static native long currentTimeMicro();

    /**
     * Returns milliseconds since January 1, 1970 00:00:00.0 UTC, synchronized
     * using a remote network source outside the device.
     * <p>
     * While the time returned by {@link System#currentTimeMillis()} can be
     * adjusted by the user, the time returned by this method cannot be adjusted
     * by the user. Note that synchronization may occur using an insecure
     * network protocol, so the returned time should not be used for security
     * purposes.
     * <p>
     * This performs no blocking network operations and returns values based on
     * a recent successful synchronization event; it will either return a valid
     * time or throw.
     *
     * @throws DateTimeException when no accurate network time can be provided.
     * @hide
     */
    public static long currentNetworkTimeMillis() {
        final IAlarmManager mgr = IAlarmManager.Stub
                .asInterface(ServiceManager.getService(Context.ALARM_SERVICE));
        if (mgr != null) {
            try {
                return mgr.currentNetworkTimeMillis();
            } catch (ParcelableException e) {
                e.maybeRethrow(DateTimeException.class);
                throw new RuntimeException(e);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } else {
            throw new RuntimeException(new DeadSystemException());
        }
    }

    /**
     * Returns a {@link Clock} that starts at January 1, 1970 00:00:00.0 UTC,
     * synchronized using a remote network source outside the device.
     * <p>
     * While the time returned by {@link System#currentTimeMillis()} can be
     * adjusted by the user, the time returned by this method cannot be adjusted
     * by the user. Note that synchronization may occur using an insecure
     * network protocol, so the returned time should not be used for security
     * purposes.
     * <p>
     * This performs no blocking network operations and returns values based on
     * a recent successful synchronization event; it will either return a valid
     * time or throw.
     *
     * @throws DateTimeException when no accurate network time can be provided.
     * @hide
     */
    public static @NonNull Clock currentNetworkTimeClock() {
        return new SimpleClock(ZoneOffset.UTC) {
            @Override
            public long millis() {
                return SystemClock.currentNetworkTimeMillis();
            }
        };
    }

    /**
     * Returns a {@link Clock} that starts at January 1, 1970 00:00:00.0 UTC,
     * synchronized using the device's location provider.
     *
     * @throws DateTimeException when the location provider has not had a location fix since boot.
     */
    public static @NonNull Clock currentGnssTimeClock() {
        return new SimpleClock(ZoneOffset.UTC) {
            private final ILocationManager mMgr = ILocationManager.Stub
                    .asInterface(ServiceManager.getService(Context.LOCATION_SERVICE));
            @Override
            public long millis() {
                LocationTime time;
                try {
                    time = mMgr.getGnssTimeMillis();
                } catch (RemoteException e) {
                    e.rethrowFromSystemServer();
                    return 0;
                }
                if (time == null) {
                    throw new DateTimeException("Gnss based time is not available.");
                }
                long currentNanos = elapsedRealtimeNanos();
                long deltaMs = (currentNanos - time.getElapsedRealtimeNanos()) / 1000000L;
                return time.getTime() + deltaMs;
            }
        };
    }
}
