/*
 * Copyright (C) 2013 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.power;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.service.power.WirelessChargerDetectorProto;
import android.util.Slog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;

import java.io.PrintWriter;

/**
 * Implements heuristics to detect docking or undocking from a wireless charger.
 * <p>
 * Some devices have wireless charging circuits that are unable to detect when the
 * device is resting on a wireless charger except when the device is actually
 * receiving power from the charger.  The device may stop receiving power
 * if the battery is already nearly full or if it is too hot.  As a result, we cannot
 * always rely on the battery service wireless plug signal to accurately indicate
 * whether the device has been docked or undocked from a wireless charger.
 * </p><p>
 * This is a problem because the power manager typically wakes up the screen and
 * plays a tone when the device is docked in a wireless charger.  It is important
 * for the system to suppress spurious docking and undocking signals because they
 * can be intrusive for the user (especially if they cause a tone to be played
 * late at night for no apparent reason).
 * </p><p>
 * To avoid spurious signals, we apply some special policies to wireless chargers.
 * </p><p>
 * 1. Don't wake the device when undocked from the wireless charger because
 * it might be that the device is still resting on the wireless charger
 * but is not receiving power anymore because the battery is full.
 * Ideally we would wake the device if we could be certain that the user had
 * picked it up from the wireless charger but due to hardware limitations we
 * must be more conservative.
 * </p><p>
 * 2. Don't wake the device when docked on a wireless charger if the
 * battery already appears to be mostly full.  This situation may indicate
 * that the device was resting on the charger the whole time and simply
 * wasn't receiving power because the battery was already full.  We can't tell
 * whether the device was just placed on the charger or whether it has
 * been there for half of the night slowly discharging until it reached
 * the point where it needed to start charging again.  So we suppress docking
 * signals that occur when the battery level is above a given threshold.
 * </p><p>
 * 3. Don't wake the device when docked on a wireless charger if it does
 * not appear to have moved since it was last undocked because it may
 * be that the prior undocking signal was spurious.  We use the gravity
 * sensor to detect this case.
 * </p>
 */
final class WirelessChargerDetector {
    private static final String TAG = "WirelessChargerDetector";
    private static final boolean DEBUG = false;

    // The minimum amount of time to spend watching the sensor before making
    // a determination of whether movement occurred.
    private static final long SETTLE_TIME_MILLIS = 800;

    // The sensor sampling interval.
    private static final int SAMPLING_INTERVAL_MILLIS = 50;

    // The minimum number of samples that must be collected.
    private static final int MIN_SAMPLES = 3;

    // Upper bound on the battery charge percentage in order to consider turning
    // the screen on when the device starts charging wirelessly.
    private static final int WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT = 95;

    // To detect movement, we compute the angle between the gravity vector
    // at rest and the current gravity vector.  This field specifies the
    // cosine of the maximum angle variance that we tolerate while at rest.
    private static final double MOVEMENT_ANGLE_COS_THRESHOLD = Math.cos(5 * Math.PI / 180);

    // Sanity thresholds for the gravity vector.
    private static final double MIN_GRAVITY = SensorManager.GRAVITY_EARTH - 1.0f;
    private static final double MAX_GRAVITY = SensorManager.GRAVITY_EARTH + 1.0f;

    private final Object mLock = new Object();

    private final SensorManager mSensorManager;
    private final SuspendBlocker mSuspendBlocker;
    private final Handler mHandler;

    // The gravity sensor, or null if none.
    private Sensor mGravitySensor;

    // Previously observed wireless power state.
    private boolean mPoweredWirelessly;

    // True if the device is thought to be at rest on a wireless charger.
    private boolean mAtRest;

    // The gravity vector most recently observed while at rest.
    private float mRestX, mRestY, mRestZ;

    /* These properties are only meaningful while detection is in progress. */

    // True if detection is in progress.
    // The suspend blocker is held while this is the case.
    private boolean mDetectionInProgress;

    // The time when detection was last performed.
    private long mDetectionStartTime;

    // True if the rest position should be updated if at rest.
    // Otherwise, the current rest position is simply checked and cleared if movement
    // is detected but no new rest position is stored.
    private boolean mMustUpdateRestPosition;

    // The total number of samples collected.
    private int mTotalSamples;

    // The number of samples collected that showed evidence of not being at rest.
    private int mMovingSamples;

    // The value of the first sample that was collected.
    private float mFirstSampleX, mFirstSampleY, mFirstSampleZ;

    // The value of the last sample that was collected.
    private float mLastSampleX, mLastSampleY, mLastSampleZ;

    public WirelessChargerDetector(SensorManager sensorManager,
            SuspendBlocker suspendBlocker, Handler handler) {
        mSensorManager = sensorManager;
        mSuspendBlocker = suspendBlocker;
        mHandler = handler;

        mGravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
    }

    public void dump(PrintWriter pw) {
        synchronized (mLock) {
            pw.println();
            pw.println("Wireless Charger Detector State:");
            pw.println("  mGravitySensor=" + mGravitySensor);
            pw.println("  mPoweredWirelessly=" + mPoweredWirelessly);
            pw.println("  mAtRest=" + mAtRest);
            pw.println("  mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ);
            pw.println("  mDetectionInProgress=" + mDetectionInProgress);
            pw.println("  mDetectionStartTime=" + (mDetectionStartTime == 0 ? "0 (never)"
                    : TimeUtils.formatUptime(mDetectionStartTime)));
            pw.println("  mMustUpdateRestPosition=" + mMustUpdateRestPosition);
            pw.println("  mTotalSamples=" + mTotalSamples);
            pw.println("  mMovingSamples=" + mMovingSamples);
            pw.println("  mFirstSampleX=" + mFirstSampleX
                    + ", mFirstSampleY=" + mFirstSampleY + ", mFirstSampleZ=" + mFirstSampleZ);
            pw.println("  mLastSampleX=" + mLastSampleX
                    + ", mLastSampleY=" + mLastSampleY + ", mLastSampleZ=" + mLastSampleZ);
        }
    }

    public void writeToProto(ProtoOutputStream proto, long fieldId) {
        final long wcdToken = proto.start(fieldId);
        synchronized (mLock) {
            proto.write(WirelessChargerDetectorProto.IS_POWERED_WIRELESSLY, mPoweredWirelessly);
            proto.write(WirelessChargerDetectorProto.IS_AT_REST, mAtRest);

            final long restVectorToken = proto.start(WirelessChargerDetectorProto.REST);
            proto.write(WirelessChargerDetectorProto.VectorProto.X, mRestX);
            proto.write(WirelessChargerDetectorProto.VectorProto.Y, mRestY);
            proto.write(WirelessChargerDetectorProto.VectorProto.Z, mRestZ);
            proto.end(restVectorToken);

            proto.write(
                    WirelessChargerDetectorProto.IS_DETECTION_IN_PROGRESS, mDetectionInProgress);
            proto.write(WirelessChargerDetectorProto.DETECTION_START_TIME_MS, mDetectionStartTime);
            proto.write(
                    WirelessChargerDetectorProto.IS_MUST_UPDATE_REST_POSITION,
                    mMustUpdateRestPosition);
            proto.write(WirelessChargerDetectorProto.TOTAL_SAMPLES, mTotalSamples);
            proto.write(WirelessChargerDetectorProto.MOVING_SAMPLES, mMovingSamples);

            final long firstSampleVectorToken =
                    proto.start(WirelessChargerDetectorProto.FIRST_SAMPLE);
            proto.write(WirelessChargerDetectorProto.VectorProto.X, mFirstSampleX);
            proto.write(WirelessChargerDetectorProto.VectorProto.Y, mFirstSampleY);
            proto.write(WirelessChargerDetectorProto.VectorProto.Z, mFirstSampleZ);
            proto.end(firstSampleVectorToken);

            final long lastSampleVectorToken =
                    proto.start(WirelessChargerDetectorProto.LAST_SAMPLE);
            proto.write(WirelessChargerDetectorProto.VectorProto.X, mLastSampleX);
            proto.write(WirelessChargerDetectorProto.VectorProto.Y, mLastSampleY);
            proto.write(WirelessChargerDetectorProto.VectorProto.Z, mLastSampleZ);
            proto.end(lastSampleVectorToken);
        }
        proto.end(wcdToken);
    }

    /**
     * Updates the charging state and returns true if docking was detected.
     *
     * @param isPowered True if the device is powered.
     * @param plugType The current plug type.
     * @param batteryLevel The current battery level.
     * @return True if the device is determined to have just been docked on a wireless
     * charger, after suppressing spurious docking or undocking signals.
     */
    public boolean update(boolean isPowered, int plugType, int batteryLevel) {
        synchronized (mLock) {
            final boolean wasPoweredWirelessly = mPoweredWirelessly;

            if (isPowered && plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
                // The device is receiving power from the wireless charger.
                // Update the rest position asynchronously.
                mPoweredWirelessly = true;
                mMustUpdateRestPosition = true;
                startDetectionLocked();
            } else {
                // The device may or may not be on the wireless charger depending on whether
                // the unplug signal that we received was spurious.
                mPoweredWirelessly = false;
                if (mAtRest) {
                    if (plugType != 0 && plugType != BatteryManager.BATTERY_PLUGGED_WIRELESS) {
                        // The device was plugged into a new non-wireless power source.
                        // It's safe to assume that it is no longer on the wireless charger.
                        mMustUpdateRestPosition = false;
                        clearAtRestLocked();
                    } else {
                        // The device may still be on the wireless charger but we don't know.
                        // Check whether the device has remained at rest on the charger
                        // so that we will know to ignore the next wireless plug event
                        // if needed.
                        startDetectionLocked();
                    }
                }
            }

            // Report that the device has been docked only if the device just started
            // receiving power wirelessly, has a high enough battery level that we
            // can be assured that charging was not delayed due to the battery previously
            // having been full, and the device is not known to already be at rest
            // on the wireless charger from earlier.
            return mPoweredWirelessly && !wasPoweredWirelessly
                    && batteryLevel < WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT
                    && !mAtRest;
        }
    }

    private void startDetectionLocked() {
        if (!mDetectionInProgress && mGravitySensor != null) {
            if (mSensorManager.registerListener(mListener, mGravitySensor,
                    SAMPLING_INTERVAL_MILLIS * 1000)) {
                mSuspendBlocker.acquire();
                mDetectionInProgress = true;
                mDetectionStartTime = SystemClock.uptimeMillis();
                mTotalSamples = 0;
                mMovingSamples = 0;

                Message msg = Message.obtain(mHandler, mSensorTimeout);
                msg.setAsynchronous(true);
                mHandler.sendMessageDelayed(msg, SETTLE_TIME_MILLIS);
            }
        }
    }

    private void finishDetectionLocked() {
        if (mDetectionInProgress) {
            mSensorManager.unregisterListener(mListener);
            mHandler.removeCallbacks(mSensorTimeout);

            if (mMustUpdateRestPosition) {
                clearAtRestLocked();
                if (mTotalSamples < MIN_SAMPLES) {
                    Slog.w(TAG, "Wireless charger detector is broken.  Only received "
                            + mTotalSamples + " samples from the gravity sensor but we "
                            + "need at least " + MIN_SAMPLES + " and we expect to see "
                            + "about " + SETTLE_TIME_MILLIS / SAMPLING_INTERVAL_MILLIS
                            + " on average.");
                } else if (mMovingSamples == 0) {
                    mAtRest = true;
                    mRestX = mLastSampleX;
                    mRestY = mLastSampleY;
                    mRestZ = mLastSampleZ;
                }
                mMustUpdateRestPosition = false;
            }

            if (DEBUG) {
                Slog.d(TAG, "New state: mAtRest=" + mAtRest
                        + ", mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ
                        + ", mTotalSamples=" + mTotalSamples
                        + ", mMovingSamples=" + mMovingSamples);
            }

            mDetectionInProgress = false;
            mSuspendBlocker.release();
        }
    }

    private void processSampleLocked(float x, float y, float z) {
        if (mDetectionInProgress) {
            mLastSampleX = x;
            mLastSampleY = y;
            mLastSampleZ = z;

            mTotalSamples += 1;
            if (mTotalSamples == 1) {
                // Save information about the first sample collected.
                mFirstSampleX = x;
                mFirstSampleY = y;
                mFirstSampleZ = z;
            } else {
                // Determine whether movement has occurred relative to the first sample.
                if (hasMoved(mFirstSampleX, mFirstSampleY, mFirstSampleZ, x, y, z)) {
                    mMovingSamples += 1;
                }
            }

            // Clear the at rest flag if movement has occurred relative to the rest sample.
            if (mAtRest && hasMoved(mRestX, mRestY, mRestZ, x, y, z)) {
                if (DEBUG) {
                    Slog.d(TAG, "No longer at rest: "
                            + "mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ
                            + ", x=" + x + ", y=" + y + ", z=" + z);
                }
                clearAtRestLocked();
            }
        }
    }

    private void clearAtRestLocked() {
        mAtRest = false;
        mRestX = 0;
        mRestY = 0;
        mRestZ = 0;
    }

    private static boolean hasMoved(float x1, float y1, float z1,
            float x2, float y2, float z2) {
        final double dotProduct = (x1 * x2) + (y1 * y2) + (z1 * z2);
        final double mag1 = Math.sqrt((x1 * x1) + (y1 * y1) + (z1 * z1));
        final double mag2 = Math.sqrt((x2 * x2) + (y2 * y2) + (z2 * z2));
        if (mag1 < MIN_GRAVITY || mag1 > MAX_GRAVITY
                || mag2 < MIN_GRAVITY || mag2 > MAX_GRAVITY) {
            if (DEBUG) {
                Slog.d(TAG, "Weird gravity vector: mag1=" + mag1 + ", mag2=" + mag2);
            }
            return true;
        }
        final boolean moved = (dotProduct < mag1 * mag2 * MOVEMENT_ANGLE_COS_THRESHOLD);
        if (DEBUG) {
            Slog.d(TAG, "Check: moved=" + moved
                    + ", x1=" + x1 + ", y1=" + y1 + ", z1=" + z1
                    + ", x2=" + x2 + ", y2=" + y2 + ", z2=" + z2
                    + ", angle=" + (Math.acos(dotProduct / mag1 / mag2) * 180 / Math.PI)
                    + ", dotProduct=" + dotProduct
                    + ", mag1=" + mag1 + ", mag2=" + mag2);
        }
        return moved;
    }

    private final SensorEventListener mListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            synchronized (mLock) {
                processSampleLocked(event.values[0], event.values[1], event.values[2]);
            }
        }

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

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