/*
 * Copyright (C) 2015 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;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.SystemClock;
import android.util.Slog;

import java.lang.Float;

/**
 * Determines if the device has been set upon a stationary object.
 */
public class AnyMotionDetector {
    interface DeviceIdleCallback {
        public void onAnyMotionResult(int result);
    }

    private static final String TAG = "AnyMotionDetector";

    private static final boolean DEBUG = false;

    /** Stationary status is unknown due to insufficient orientation measurements. */
    public static final int RESULT_UNKNOWN = -1;

    /** Device is stationary, e.g. still on a table. */
    public static final int RESULT_STATIONARY = 0;

    /** Device has been moved. */
    public static final int RESULT_MOVED = 1;

    /** Orientation measurements are being performed or are planned. */
    private static final int STATE_INACTIVE = 0;

    /** No orientation measurements are being performed or are planned. */
    private static final int STATE_ACTIVE = 1;

    /** Current measurement state. */
    private int mState;

    /** Threshold energy above which the device is considered moving. */
    private final float THRESHOLD_ENERGY = 5f;

    /** The duration of the accelerometer orientation measurement. */
    private static final long ORIENTATION_MEASUREMENT_DURATION_MILLIS = 2500;

    /** The maximum duration we will collect accelerometer data. */
    private static final long ACCELEROMETER_DATA_TIMEOUT_MILLIS = 3000;

    /** The interval between accelerometer orientation measurements. */
    private static final long ORIENTATION_MEASUREMENT_INTERVAL_MILLIS = 5000;

    /** The maximum duration we will hold a wakelock to determine stationary status. */
    private static final long WAKELOCK_TIMEOUT_MILLIS = 30000;

    /**
     * The duration in milliseconds after which an orientation measurement is considered
     * too stale to be used.
     */
    private static final int STALE_MEASUREMENT_TIMEOUT_MILLIS = 2 * 60 * 1000;

    /** The accelerometer sampling interval. */
    private static final int SAMPLING_INTERVAL_MILLIS = 40;

    private final Handler mHandler;
    private final Object mLock = new Object();
    private Sensor mAccelSensor;
    private SensorManager mSensorManager;
    private PowerManager.WakeLock mWakeLock;

    /** Threshold angle in degrees beyond which the device is considered moving. */
    private final float mThresholdAngle;

    /** The minimum number of samples required to detect AnyMotion. */
    private int mNumSufficientSamples;

    /** True if an orientation measurement is in progress. */
    private boolean mMeasurementInProgress;

    /** The most recent gravity vector. */
    private Vector3 mCurrentGravityVector = null;

    /** The second most recent gravity vector. */
    private Vector3 mPreviousGravityVector = null;

    /** Running sum of squared errors. */
    private RunningSignalStats mRunningStats;

    private DeviceIdleCallback mCallback = null;

    public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm,
            DeviceIdleCallback callback, float thresholdAngle) {
        if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated.");
        synchronized (mLock) {
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
            mWakeLock.setReferenceCounted(false);
            mHandler = handler;
            mSensorManager = sm;
            mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            mMeasurementInProgress = false;
            mState = STATE_INACTIVE;
            mCallback = callback;
            mThresholdAngle = thresholdAngle;
            mRunningStats = new RunningSignalStats();
            mNumSufficientSamples = (int) Math.ceil(
                    ((double)ORIENTATION_MEASUREMENT_DURATION_MILLIS / SAMPLING_INTERVAL_MILLIS));
            if (DEBUG) Slog.d(TAG, "mNumSufficientSamples = " + mNumSufficientSamples);
        }
    }

    /*
     * Acquire accel data until we determine AnyMotion status.
     */
    public void checkForAnyMotion() {
        if (DEBUG) {
            Slog.d(TAG, "checkForAnyMotion(). mState = " + mState);
        }
        if (mState != STATE_ACTIVE) {
            synchronized (mLock) {
                mState = STATE_ACTIVE;
                if (DEBUG) {
                    Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_ACTIVE.");
                }
                mCurrentGravityVector = null;
                mPreviousGravityVector = null;
                mWakeLock.acquire();
                Message wakelockTimeoutMsg = Message.obtain(mHandler, mWakelockTimeout);
                mHandler.sendMessageDelayed(wakelockTimeoutMsg, WAKELOCK_TIMEOUT_MILLIS);
                startOrientationMeasurementLocked();
            }
        }
    }

    public void stop() {
        synchronized (mLock) {
            if (mState == STATE_ACTIVE) {
                mState = STATE_INACTIVE;
                if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE.");
            }
            if (mMeasurementInProgress) {
                mMeasurementInProgress = false;
                mSensorManager.unregisterListener(mListener);
            }
            mHandler.removeCallbacks(mMeasurementTimeout);
            mHandler.removeCallbacks(mSensorRestart);
            mCurrentGravityVector = null;
            mPreviousGravityVector = null;
            if (mWakeLock.isHeld()) {
                mWakeLock.release();
                mHandler.removeCallbacks(mWakelockTimeout);
            }
        }
    }

    private void startOrientationMeasurementLocked() {
        if (DEBUG) Slog.d(TAG, "startOrientationMeasurementLocked: mMeasurementInProgress=" +
            mMeasurementInProgress + ", (mAccelSensor != null)=" + (mAccelSensor != null));
        if (!mMeasurementInProgress && mAccelSensor != null) {
            if (mSensorManager.registerListener(mListener, mAccelSensor,
                    SAMPLING_INTERVAL_MILLIS * 1000)) {
                mMeasurementInProgress = true;
                mRunningStats.reset();
            }
            Message measurementTimeoutMsg = Message.obtain(mHandler, mMeasurementTimeout);
            mHandler.sendMessageDelayed(measurementTimeoutMsg, ACCELEROMETER_DATA_TIMEOUT_MILLIS);
        }
    }

    private int stopOrientationMeasurementLocked() {
        if (DEBUG) Slog.d(TAG, "stopOrientationMeasurement. mMeasurementInProgress=" +
                mMeasurementInProgress);
        int status = RESULT_UNKNOWN;
        if (mMeasurementInProgress) {
            mSensorManager.unregisterListener(mListener);
            mHandler.removeCallbacks(mMeasurementTimeout);
            mMeasurementInProgress = false;
            mPreviousGravityVector = mCurrentGravityVector;
            mCurrentGravityVector = mRunningStats.getRunningAverage();
            if (mRunningStats.getSampleCount() == 0) {
                Slog.w(TAG, "No accelerometer data acquired for orientation measurement.");
            }
            if (DEBUG) {
                Slog.d(TAG, "mRunningStats = " + mRunningStats.toString());
                String currentGravityVectorString = (mCurrentGravityVector == null) ?
                        "null" : mCurrentGravityVector.toString();
                String previousGravityVectorString = (mPreviousGravityVector == null) ?
                        "null" : mPreviousGravityVector.toString();
                Slog.d(TAG, "mCurrentGravityVector = " + currentGravityVectorString);
                Slog.d(TAG, "mPreviousGravityVector = " + previousGravityVectorString);
            }
            mRunningStats.reset();
            status = getStationaryStatus();
            if (DEBUG) Slog.d(TAG, "getStationaryStatus() returned " + status);
            if (status != RESULT_UNKNOWN) {
                if (mWakeLock.isHeld()) {
                    mWakeLock.release();
                    mHandler.removeCallbacks(mWakelockTimeout);
                }
                if (DEBUG) {
                    Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE. status = " + status);
                }
                mState = STATE_INACTIVE;
            } else {
                /*
                 * Unknown due to insufficient measurements. Schedule another orientation
                 * measurement.
                 */
                if (DEBUG) Slog.d(TAG, "stopOrientationMeasurementLocked(): another measurement" +
                        " scheduled in " + ORIENTATION_MEASUREMENT_INTERVAL_MILLIS +
                        " milliseconds.");
                Message msg = Message.obtain(mHandler, mSensorRestart);
                mHandler.sendMessageDelayed(msg, ORIENTATION_MEASUREMENT_INTERVAL_MILLIS);
            }
        }
        return status;
    }

    /*
     * Updates mStatus to the current AnyMotion status.
     */
    public int getStationaryStatus() {
        if ((mPreviousGravityVector == null) || (mCurrentGravityVector == null)) {
            return RESULT_UNKNOWN;
        }
        Vector3 previousGravityVectorNormalized = mPreviousGravityVector.normalized();
        Vector3 currentGravityVectorNormalized = mCurrentGravityVector.normalized();
        float angle = previousGravityVectorNormalized.angleBetween(currentGravityVectorNormalized);
        if (DEBUG) Slog.d(TAG, "getStationaryStatus: angle = " + angle
                + " energy = " + mRunningStats.getEnergy());
        if ((angle < mThresholdAngle) && (mRunningStats.getEnergy() < THRESHOLD_ENERGY)) {
            return RESULT_STATIONARY;
        } else if (Float.isNaN(angle)) {
          /**
           * Floating point rounding errors have caused the angle calcuation's dot product to 
           * exceed 1.0. In such case, we report RESULT_MOVED to prevent devices from rapidly
           * retrying this measurement.
           */
            return RESULT_MOVED;
        }
        long diffTime = mCurrentGravityVector.timeMillisSinceBoot -
                mPreviousGravityVector.timeMillisSinceBoot;
        if (diffTime > STALE_MEASUREMENT_TIMEOUT_MILLIS) {
            if (DEBUG) Slog.d(TAG, "getStationaryStatus: mPreviousGravityVector is too stale at " +
                    diffTime + " ms ago. Returning RESULT_UNKNOWN.");
            return RESULT_UNKNOWN;
        }
        return RESULT_MOVED;
    }

    private final SensorEventListener mListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            int status = RESULT_UNKNOWN;
            synchronized (mLock) {
                Vector3 accelDatum = new Vector3(SystemClock.elapsedRealtime(), event.values[0],
                        event.values[1], event.values[2]);
                mRunningStats.accumulate(accelDatum);

                // If we have enough samples, stop accelerometer data acquisition.
                if (mRunningStats.getSampleCount() >= mNumSufficientSamples) {
                    status = stopOrientationMeasurementLocked();
                }
            }
            if (status != RESULT_UNKNOWN) {
                mHandler.removeCallbacks(mWakelockTimeout);
                mCallback.onAnyMotionResult(status);
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };

    private final Runnable mSensorRestart = new Runnable() {
        @Override
        public void run() {
            synchronized (mLock) {
                startOrientationMeasurementLocked();
            }
        }
    };

    private final Runnable mMeasurementTimeout = new Runnable() {
        @Override
        public void run() {
            int status = RESULT_UNKNOWN;
            synchronized (mLock) {
                if (DEBUG) Slog.i(TAG, "mMeasurementTimeout. Failed to collect sufficient accel " +
                      "data within " + ACCELEROMETER_DATA_TIMEOUT_MILLIS + " ms. Stopping " +
                      "orientation measurement.");
                status = stopOrientationMeasurementLocked();
            }
            if (status != RESULT_UNKNOWN) {
                mHandler.removeCallbacks(mWakelockTimeout);
                mCallback.onAnyMotionResult(status);
            }
        }
    };

    private final Runnable mWakelockTimeout = new Runnable() {
        @Override
        public void run() {
            synchronized (mLock) {
                stop();
            }
        }
    };

    /**
     * A timestamped three dimensional vector and some vector operations.
     */
    public static final class Vector3 {
        public long timeMillisSinceBoot;
        public float x;
        public float y;
        public float z;

        public Vector3(long timeMillisSinceBoot, float x, float y, float z) {
            this.timeMillisSinceBoot = timeMillisSinceBoot;
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public float norm() {
            return (float) Math.sqrt(dotProduct(this));
        }

        public Vector3 normalized() {
            float mag = norm();
            return new Vector3(timeMillisSinceBoot, x / mag, y / mag, z / mag);
        }

        /**
         * Returns the angle between this 3D vector and another given 3D vector.
         * Assumes both have already been normalized.
         *
         * @param other The other Vector3 vector.
         * @return angle between this vector and the other given one.
         */
        public float angleBetween(Vector3 other) {
            Vector3 crossVector = cross(other);
            float degrees = Math.abs((float)Math.toDegrees(
                    Math.atan2(crossVector.norm(), dotProduct(other))));
            Slog.d(TAG, "angleBetween: this = " + this.toString() +
                ", other = " + other.toString() + ", degrees = " + degrees);
            return degrees;
        }

        public Vector3 cross(Vector3 v) {
            return new Vector3(
                v.timeMillisSinceBoot,
                y * v.z - z * v.y,
                z * v.x - x * v.z,
                x * v.y - y * v.x);
        }

        @Override
        public String toString() {
            String msg = "";
            msg += "timeMillisSinceBoot=" + timeMillisSinceBoot;
            msg += " | x=" + x;
            msg += ", y=" + y;
            msg += ", z=" + z;
            return msg;
        }

        public float dotProduct(Vector3 v) {
            return x * v.x + y * v.y + z * v.z;
        }

        public Vector3 times(float val) {
            return new Vector3(timeMillisSinceBoot, x * val, y * val, z * val);
        }

        public Vector3 plus(Vector3 v) {
            return new Vector3(v.timeMillisSinceBoot, x + v.x, y + v.y, z + v.z);
        }

        public Vector3 minus(Vector3 v) {
            return new Vector3(v.timeMillisSinceBoot, x - v.x, y - v.y, z - v.z);
        }
    }

    /**
     * Maintains running statistics on the signal revelant to AnyMotion detection, including:
     * <ul>
     *   <li>running average.
     *   <li>running sum-of-squared-errors as the energy of the signal derivative.
     * <ul>
     */
    private static class RunningSignalStats {
        Vector3 previousVector;
        Vector3 currentVector;
        Vector3 runningSum;
        float energy;
        int sampleCount;

        public RunningSignalStats() {
            reset();
        }

        public void reset() {
            previousVector = null;
            currentVector = null;
            runningSum = new Vector3(0, 0, 0, 0);
            energy = 0;
            sampleCount = 0;
        }

        /**
         * Apply a 3D vector v as the next element in the running SSE.
         */
        public void accumulate(Vector3 v) {
            if (v == null) {
                if (DEBUG) Slog.i(TAG, "Cannot accumulate a null vector.");
                return;
            }
            sampleCount++;
            runningSum = runningSum.plus(v);
            previousVector = currentVector;
            currentVector = v;
            if (previousVector != null) {
                Vector3 dv = currentVector.minus(previousVector);
                float incrementalEnergy = dv.x * dv.x + dv.y * dv.y + dv.z * dv.z;
                energy += incrementalEnergy;
                if (DEBUG) Slog.i(TAG, "Accumulated vector " + currentVector.toString() +
                        ", runningSum = " + runningSum.toString() +
                        ", incrementalEnergy = " + incrementalEnergy +
                        ", energy = " + energy);
            }
        }

        public Vector3 getRunningAverage() {
            if (sampleCount > 0) {
              return runningSum.times((float)(1.0f / sampleCount));
            }
            return null;
        }

        public float getEnergy() {
            return energy;
        }

        public int getSampleCount() {
            return sampleCount;
        }

        @Override
        public String toString() {
            String msg = "";
            String currentVectorString = (currentVector == null) ?
                "null" : currentVector.toString();
            String previousVectorString = (previousVector == null) ?
                "null" : previousVector.toString();
            msg += "previousVector = " + previousVectorString;
            msg += ", currentVector = " + currentVectorString;
            msg += ", sampleCount = " + sampleCount;
            msg += ", energy = " + energy;
            return msg;
        }
    }
}
