/*
 * Copyright (C) 2020 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 com.android.server.location.provider;

import static android.location.provider.ProviderRequest.INTERVAL_DISABLED;

import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import static com.android.server.location.LocationManagerService.D;
import static com.android.server.location.LocationManagerService.TAG;
import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG;

import android.annotation.Nullable;
import android.location.Location;
import android.location.LocationResult;
import android.location.provider.ProviderRequest;
import android.os.SystemClock;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import com.android.server.DeviceIdleInternal;
import com.android.server.FgThread;
import com.android.server.location.injector.DeviceIdleHelper;
import com.android.server.location.injector.DeviceStationaryHelper;
import com.android.server.location.injector.Injector;

import java.io.FileDescriptor;
import java.io.PrintWriter;

/**
 * Throttles location providers completely while the device is in doze and stationary, and returns
 * the last known location as a new location at the appropriate interval instead. Hypothetically,
 * this throttling could be applied only when the device is stationary - however we don't trust the
 * accuracy of the on-device SMD (which could allow for 100s of feet of movement without triggering
 * in some use cases) enough to rely just on this. Instead we require the device to be in doze mode
 * and stationary to narrow down the effect of false positives/negatives.
 */
public final class StationaryThrottlingLocationProvider extends DelegateLocationProvider
        implements DeviceIdleHelper.DeviceIdleListener, DeviceIdleInternal.StationaryListener {

    private static final long MAX_STATIONARY_LOCATION_AGE_MS = 30000;

    final Object mLock = new Object();

    private final String mName;
    private final DeviceIdleHelper mDeviceIdleHelper;
    private final DeviceStationaryHelper mDeviceStationaryHelper;

    @GuardedBy("mLock")
    private boolean mDeviceIdle = false;
    @GuardedBy("mLock")
    private boolean mDeviceStationary = false;
    @GuardedBy("mLock")
    private long mDeviceStationaryRealtimeMs = Long.MIN_VALUE;
    @GuardedBy("mLock")
    private ProviderRequest mIncomingRequest = ProviderRequest.EMPTY_REQUEST;
    @GuardedBy("mLock")
    private ProviderRequest mOutgoingRequest = ProviderRequest.EMPTY_REQUEST;
    @GuardedBy("mLock")
    long mThrottlingIntervalMs = INTERVAL_DISABLED;
    @GuardedBy("mLock")
    @Nullable DeliverLastLocationRunnable mDeliverLastLocationCallback = null;
    @GuardedBy("mLock")
    @Nullable Location mLastLocation;

    public StationaryThrottlingLocationProvider(String name, Injector injector,
            AbstractLocationProvider delegate) {
        super(DIRECT_EXECUTOR, delegate);

        mName = name;
        mDeviceIdleHelper = injector.getDeviceIdleHelper();
        mDeviceStationaryHelper = injector.getDeviceStationaryHelper();

        // must be last statement in the constructor because reference is escaping
        initializeDelegate();
    }

    @Override
    public void onReportLocation(LocationResult locationResult) {
        super.onReportLocation(locationResult);

        synchronized (mLock) {
            mLastLocation = locationResult.getLastLocation();
            onThrottlingChangedLocked(false);
        }
    }

    @Override
    protected void onStart() {
        mDelegate.getController().start();

        synchronized (mLock) {
            mDeviceIdleHelper.addListener(this);
            mDeviceIdle = mDeviceIdleHelper.isDeviceIdle();
            mDeviceStationaryHelper.addListener(this);
            mDeviceStationary = false;
            mDeviceStationaryRealtimeMs = Long.MIN_VALUE;

            onThrottlingChangedLocked(false);
        }
    }

    @Override
    protected void onStop() {
        synchronized (mLock) {
            mDeviceStationaryHelper.removeListener(this);
            mDeviceIdleHelper.removeListener(this);

            mIncomingRequest = ProviderRequest.EMPTY_REQUEST;
            mOutgoingRequest = ProviderRequest.EMPTY_REQUEST;
            mThrottlingIntervalMs = INTERVAL_DISABLED;

            if (mDeliverLastLocationCallback != null) {
                FgThread.getHandler().removeCallbacks(mDeliverLastLocationCallback);
                mDeliverLastLocationCallback = null;
            }

            mLastLocation = null;
        }

        mDelegate.getController().stop();
    }

    @Override
    protected void onSetRequest(ProviderRequest request) {
        synchronized (mLock) {
            mIncomingRequest = request;
            onThrottlingChangedLocked(true);
        }
    }

    @Override
    public void onDeviceIdleChanged(boolean deviceIdle) {
        synchronized (mLock) {
            if (deviceIdle == mDeviceIdle) {
                return;
            }

            mDeviceIdle = deviceIdle;
            onThrottlingChangedLocked(false);
        }
    }

    @Override
    public void onDeviceStationaryChanged(boolean deviceStationary) {
        synchronized (mLock) {
            if (mDeviceStationary == deviceStationary) {
                return;
            }

            mDeviceStationary = deviceStationary;
            if (mDeviceStationary) {
                mDeviceStationaryRealtimeMs = SystemClock.elapsedRealtime();
            } else {
                mDeviceStationaryRealtimeMs = Long.MIN_VALUE;
            }
            onThrottlingChangedLocked(false);
        }
    }

    @GuardedBy("mLock")
    private void onThrottlingChangedLocked(boolean deliverImmediate) {
        long throttlingIntervalMs = INTERVAL_DISABLED;
        if (mDeviceStationary && mDeviceIdle && !mIncomingRequest.isLocationSettingsIgnored()
                && mLastLocation != null
                && mLastLocation.getElapsedRealtimeAgeMillis(mDeviceStationaryRealtimeMs)
                <= MAX_STATIONARY_LOCATION_AGE_MS) {
            throttlingIntervalMs = mIncomingRequest.getIntervalMillis();
        }

        ProviderRequest newRequest;
        if (throttlingIntervalMs != INTERVAL_DISABLED) {
            newRequest = ProviderRequest.EMPTY_REQUEST;
        } else {
            newRequest = mIncomingRequest;
        }

        if (!newRequest.equals(mOutgoingRequest)) {
            mOutgoingRequest = newRequest;
            mDelegate.getController().setRequest(mOutgoingRequest);
        }

        if (throttlingIntervalMs == mThrottlingIntervalMs) {
            return;
        }

        long oldThrottlingIntervalMs = mThrottlingIntervalMs;
        mThrottlingIntervalMs = throttlingIntervalMs;

        if (mThrottlingIntervalMs != INTERVAL_DISABLED) {
            if (oldThrottlingIntervalMs == INTERVAL_DISABLED) {
                if (D) {
                    Log.d(TAG, mName + " provider stationary throttled");
                }
                EVENT_LOG.logProviderStationaryThrottled(mName, true, mOutgoingRequest);
            }

            if (mDeliverLastLocationCallback != null) {
                FgThread.getHandler().removeCallbacks(mDeliverLastLocationCallback);
            }
            mDeliverLastLocationCallback = new DeliverLastLocationRunnable();

            Preconditions.checkState(mLastLocation != null);

            if (deliverImmediate) {
                FgThread.getHandler().post(mDeliverLastLocationCallback);
            } else {
                long delayMs = mThrottlingIntervalMs - mLastLocation.getElapsedRealtimeAgeMillis();
                FgThread.getHandler().postDelayed(mDeliverLastLocationCallback, delayMs);
            }
        } else {
            if (oldThrottlingIntervalMs != INTERVAL_DISABLED) {
                EVENT_LOG.logProviderStationaryThrottled(mName, false, mOutgoingRequest);
                if (D) {
                    Log.d(TAG, mName + " provider stationary unthrottled");
                }
            }

            FgThread.getHandler().removeCallbacks(mDeliverLastLocationCallback);
            mDeliverLastLocationCallback = null;
        }
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (mThrottlingIntervalMs != INTERVAL_DISABLED) {
            pw.println("stationary throttled=" + mLastLocation);
        } else {
            pw.print("stationary throttled=false");
            if (!mDeviceIdle) {
                pw.print(" (not idle)");
            }
            if (!mDeviceStationary) {
                pw.print(" (not stationary)");
            }
            pw.println();
        }

        mDelegate.dump(fd, pw, args);
    }

    private class DeliverLastLocationRunnable implements Runnable {

        DeliverLastLocationRunnable() {}

        @Override
        public void run() {
            Location location;
            synchronized (mLock) {
                if (mDeliverLastLocationCallback != this) {
                    return;
                }
                if (mLastLocation == null) {
                    return;
                }

                location = new Location(mLastLocation);
                location.setTime(System.currentTimeMillis());
                location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
                if (location.hasSpeed()) {
                    location.removeSpeed();
                    if (location.hasSpeedAccuracy()) {
                        location.removeSpeedAccuracy();
                    }
                }
                if (location.hasBearing()) {
                    location.removeBearing();
                    if (location.hasBearingAccuracy()) {
                        location.removeBearingAccuracy();
                    }
                }

                mLastLocation = location;
                FgThread.getHandler().postDelayed(this, mThrottlingIntervalMs);
            }

            reportLocation(LocationResult.wrap(location));
        }
    }
}
