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

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Slog;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;

/**
 * A special helper class used by the WindowManager
 * for receiving notifications from the SensorManager when
 * the orientation of the device has changed.
 *
 * NOTE: If changing anything here, please run the API demo
 * "App/Activity/Screen Orientation" to ensure that all orientation
 * modes still work correctly.
 *
 * You can also visualize the behavior of the WindowOrientationListener.
 * Refer to frameworks/base/tools/orientationplot/README.txt for details.
 */
public abstract class WindowOrientationListener {
    private static final String TAG = "WindowOrientationListener";
    private static final boolean LOG = SystemProperties.getBoolean(
            "debug.orientation.log", false);

    private static final boolean USE_GRAVITY_SENSOR = false;

    private Handler mHandler;
    private SensorManager mSensorManager;
    private boolean mEnabled;
    private int mRate;
    private String mSensorType;
    private Sensor mSensor;
    private OrientationJudge mOrientationJudge;
    private int mCurrentRotation = -1;

    private final Object mLock = new Object();

    /**
     * Creates a new WindowOrientationListener.
     * 
     * @param context for the WindowOrientationListener.
     * @param handler Provides the Looper for receiving sensor updates.
     */
    public WindowOrientationListener(Context context, Handler handler) {
        this(context, handler, SensorManager.SENSOR_DELAY_UI);
    }

    /**
     * Creates a new WindowOrientationListener.
     * 
     * @param context for the WindowOrientationListener.
     * @param handler Provides the Looper for receiving sensor updates.
     * @param rate at which sensor events are processed (see also
     * {@link android.hardware.SensorManager SensorManager}). Use the default
     * value of {@link android.hardware.SensorManager#SENSOR_DELAY_NORMAL 
     * SENSOR_DELAY_NORMAL} for simple screen orientation change detection.
     *
     * This constructor is private since no one uses it.
     */
    private WindowOrientationListener(Context context, Handler handler, int rate) {
        mHandler = handler;
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mRate = rate;
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_DEVICE_ORIENTATION);

        if (mSensor != null) {
            mOrientationJudge = new OrientationSensorJudge();
        }

        if (mOrientationJudge == null) {
            mSensor = mSensorManager.getDefaultSensor(USE_GRAVITY_SENSOR
                    ? Sensor.TYPE_GRAVITY : Sensor.TYPE_ACCELEROMETER);
            if (mSensor != null) {
                // Create listener only if sensors do exist
                mOrientationJudge = new AccelSensorJudge(context);
            }
        }
    }

    /**
     * Enables the WindowOrientationListener so it will monitor the sensor and call
     * {@link #onProposedRotationChanged(int)} when the device orientation changes.
     */
    public void enable() {
        synchronized (mLock) {
            if (mSensor == null) {
                Slog.w(TAG, "Cannot detect sensors. Not enabled");
                return;
            }
            if (mEnabled == false) {
                if (LOG) {
                    Slog.d(TAG, "WindowOrientationListener enabled");
                }
                mOrientationJudge.resetLocked();
                mSensorManager.registerListener(mOrientationJudge, mSensor, mRate, mHandler);
                mEnabled = true;
            }
        }
    }

    /**
     * Disables the WindowOrientationListener.
     */
    public void disable() {
        synchronized (mLock) {
            if (mSensor == null) {
                Slog.w(TAG, "Cannot detect sensors. Invalid disable");
                return;
            }
            if (mEnabled == true) {
                if (LOG) {
                    Slog.d(TAG, "WindowOrientationListener disabled");
                }
                mSensorManager.unregisterListener(mOrientationJudge);
                mEnabled = false;
            }
        }
    }

    public void onTouchStart() {
        synchronized (mLock) {
            if (mOrientationJudge != null) {
                mOrientationJudge.onTouchStartLocked();
            }
        }
    }

    public void onTouchEnd() {
        long whenElapsedNanos = SystemClock.elapsedRealtimeNanos();

        synchronized (mLock) {
            if (mOrientationJudge != null) {
                mOrientationJudge.onTouchEndLocked(whenElapsedNanos);
            }
        }
    }

    /**
     * Sets the current rotation.
     *
     * @param rotation The current rotation.
     */
    public void setCurrentRotation(int rotation) {
        synchronized (mLock) {
            mCurrentRotation = rotation;
        }
    }

    /**
     * Gets the proposed rotation.
     *
     * This method only returns a rotation if the orientation listener is certain
     * of its proposal.  If the rotation is indeterminate, returns -1.
     *
     * @return The proposed rotation, or -1 if unknown.
     */
    public int getProposedRotation() {
        synchronized (mLock) {
            if (mEnabled) {
                return mOrientationJudge.getProposedRotationLocked();
            }
            return -1;
        }
    }

    /**
     * Returns true if sensor is enabled and false otherwise
     */
    public boolean canDetectOrientation() {
        synchronized (mLock) {
            return mSensor != null;
        }
    }

    /**
     * Called when the rotation view of the device has changed.
     *
     * This method is called whenever the orientation becomes certain of an orientation.
     * It is called each time the orientation determination transitions from being
     * uncertain to being certain again, even if it is the same orientation as before.
     *
     * This should only be called on the Handler thread.
     *
     * @param rotation The new orientation of the device, one of the Surface.ROTATION_* constants.
     * @see android.view.Surface
     */
    public abstract void onProposedRotationChanged(int rotation);

    public void dump(PrintWriter pw, String prefix) {
        synchronized (mLock) {
            pw.println(prefix + TAG);
            prefix += "  ";
            pw.println(prefix + "mEnabled=" + mEnabled);
            pw.println(prefix + "mCurrentRotation=" + mCurrentRotation);
            pw.println(prefix + "mSensorType=" + mSensorType);
            pw.println(prefix + "mSensor=" + mSensor);
            pw.println(prefix + "mRate=" + mRate);

            if (mOrientationJudge != null) {
                mOrientationJudge.dumpLocked(pw, prefix);
            }
        }
    }

    abstract class OrientationJudge implements SensorEventListener {
        // Number of nanoseconds per millisecond.
        protected static final long NANOS_PER_MS = 1000000;

        // Number of milliseconds per nano second.
        protected static final float MILLIS_PER_NANO = 0.000001f;

        // The minimum amount of time that must have elapsed since the screen was last touched
        // before the proposed rotation can change.
        protected static final long PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS =
                500 * NANOS_PER_MS;

        /**
         * Gets the proposed rotation.
         *
         * This method only returns a rotation if the orientation listener is certain
         * of its proposal.  If the rotation is indeterminate, returns -1.
         *
         * Should only be called when holding WindowOrientationListener lock.
         *
         * @return The proposed rotation, or -1 if unknown.
         */
        public abstract int getProposedRotationLocked();

        /**
         * Notifies the orientation judge that the screen is being touched.
         *
         * Should only be called when holding WindowOrientationListener lock.
         */
        public abstract void onTouchStartLocked();

        /**
         * Notifies the orientation judge that the screen is no longer being touched.
         *
         * Should only be called when holding WindowOrientationListener lock.
         *
         * @param whenElapsedNanos Given in the elapsed realtime nanos time base.
         */
        public abstract void onTouchEndLocked(long whenElapsedNanos);

        /**
         * Resets the state of the judge.
         *
         * Should only be called when holding WindowOrientationListener lock.
         */
        public abstract void resetLocked();

        /**
         * Dumps internal state of the orientation judge.
         *
         * Should only be called when holding WindowOrientationListener lock.
         */
        public abstract void dumpLocked(PrintWriter pw, String prefix);

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

        @Override
        public abstract void onSensorChanged(SensorEvent event);
    }

    /**
     * This class filters the raw accelerometer data and tries to detect actual changes in
     * orientation. This is a very ill-defined problem so there are a lot of tweakable parameters,
     * but here's the outline:
     *
     *  - Low-pass filter the accelerometer vector in cartesian coordinates.  We do it in
     *    cartesian space because the orientation calculations are sensitive to the
     *    absolute magnitude of the acceleration.  In particular, there are singularities
     *    in the calculation as the magnitude approaches 0.  By performing the low-pass
     *    filtering early, we can eliminate most spurious high-frequency impulses due to noise.
     *
     *  - Convert the acceleromter vector from cartesian to spherical coordinates.
     *    Since we're dealing with rotation of the device, this is the sensible coordinate
     *    system to work in.  The zenith direction is the Z-axis, the direction the screen
     *    is facing.  The radial distance is referred to as the magnitude below.
     *    The elevation angle is referred to as the "tilt" below.
     *    The azimuth angle is referred to as the "orientation" below (and the azimuth axis is
     *    the Y-axis).
     *    See http://en.wikipedia.org/wiki/Spherical_coordinate_system for reference.
     *
     *  - If the tilt angle is too close to horizontal (near 90 or -90 degrees), do nothing.
     *    The orientation angle is not meaningful when the device is nearly horizontal.
     *    The tilt angle thresholds are set differently for each orientation and different
     *    limits are applied when the device is facing down as opposed to when it is facing
     *    forward or facing up.
     *
     *  - When the orientation angle reaches a certain threshold, consider transitioning
     *    to the corresponding orientation.  These thresholds have some hysteresis built-in
     *    to avoid oscillations between adjacent orientations.
     *
     *  - Wait for the device to settle for a little bit.  Once that happens, issue the
     *    new orientation proposal.
     *
     * Details are explained inline.
     *
     * See http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization for
     * signal processing background.
     */
    final class AccelSensorJudge extends OrientationJudge {
        // We work with all angles in degrees in this class.
        private static final float RADIANS_TO_DEGREES = (float) (180 / Math.PI);

        // Indices into SensorEvent.values for the accelerometer sensor.
        private static final int ACCELEROMETER_DATA_X = 0;
        private static final int ACCELEROMETER_DATA_Y = 1;
        private static final int ACCELEROMETER_DATA_Z = 2;

        // The minimum amount of time that a predicted rotation must be stable before it
        // is accepted as a valid rotation proposal.  This value can be quite small because
        // the low-pass filter already suppresses most of the noise so we're really just
        // looking for quick confirmation that the last few samples are in agreement as to
        // the desired orientation.
        private static final long PROPOSAL_SETTLE_TIME_NANOS = 40 * NANOS_PER_MS;

        // The minimum amount of time that must have elapsed since the device last exited
        // the flat state (time since it was picked up) before the proposed rotation
        // can change.
        private static final long PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS = 500 * NANOS_PER_MS;

        // The minimum amount of time that must have elapsed since the device stopped
        // swinging (time since device appeared to be in the process of being put down
        // or put away into a pocket) before the proposed rotation can change.
        private static final long PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS = 300 * NANOS_PER_MS;

        // The minimum amount of time that must have elapsed since the device stopped
        // undergoing external acceleration before the proposed rotation can change.
        private static final long PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS =
                500 * NANOS_PER_MS;

        // If the tilt angle remains greater than the specified angle for a minimum of
        // the specified time, then the device is deemed to be lying flat
        // (just chillin' on a table).
        private static final float FLAT_ANGLE = 80;
        private static final long FLAT_TIME_NANOS = 1000 * NANOS_PER_MS;

        // If the tilt angle has increased by at least delta degrees within the specified amount
        // of time, then the device is deemed to be swinging away from the user
        // down towards flat (tilt = 90).
        private static final float SWING_AWAY_ANGLE_DELTA = 20;
        private static final long SWING_TIME_NANOS = 300 * NANOS_PER_MS;

        // The maximum sample inter-arrival time in milliseconds.
        // If the acceleration samples are further apart than this amount in time, we reset the
        // state of the low-pass filter and orientation properties.  This helps to handle
        // boundary conditions when the device is turned on, wakes from suspend or there is
        // a significant gap in samples.
        private static final long MAX_FILTER_DELTA_TIME_NANOS = 1000 * NANOS_PER_MS;

        // The acceleration filter time constant.
        //
        // This time constant is used to tune the acceleration filter such that
        // impulses and vibrational noise (think car dock) is suppressed before we
        // try to calculate the tilt and orientation angles.
        //
        // The filter time constant is related to the filter cutoff frequency, which is the
        // frequency at which signals are attenuated by 3dB (half the passband power).
        // Each successive octave beyond this frequency is attenuated by an additional 6dB.
        //
        // Given a time constant t in seconds, the filter cutoff frequency Fc in Hertz
        // is given by Fc = 1 / (2pi * t).
        //
        // The higher the time constant, the lower the cutoff frequency, so more noise
        // will be suppressed.
        //
        // Filtering adds latency proportional the time constant (inversely proportional
        // to the cutoff frequency) so we don't want to make the time constant too
        // large or we can lose responsiveness.  Likewise we don't want to make it too
        // small or we do a poor job suppressing acceleration spikes.
        // Empirically, 100ms seems to be too small and 500ms is too large.
        private static final float FILTER_TIME_CONSTANT_MS = 200.0f;

        /* State for orientation detection. */

        // Thresholds for minimum and maximum allowable deviation from gravity.
        //
        // If the device is undergoing external acceleration (being bumped, in a car
        // that is turning around a corner or a plane taking off) then the magnitude
        // may be substantially more or less than gravity.  This can skew our orientation
        // detection by making us think that up is pointed in a different direction.
        //
        // Conversely, if the device is in freefall, then there will be no gravity to
        // measure at all.  This is problematic because we cannot detect the orientation
        // without gravity to tell us which way is up.  A magnitude near 0 produces
        // singularities in the tilt and orientation calculations.
        //
        // In both cases, we postpone choosing an orientation.
        //
        // However, we need to tolerate some acceleration because the angular momentum
        // of turning the device can skew the observed acceleration for a short period of time.
        private static final float NEAR_ZERO_MAGNITUDE = 1; // m/s^2
        private static final float ACCELERATION_TOLERANCE = 4; // m/s^2
        private static final float MIN_ACCELERATION_MAGNITUDE =
                SensorManager.STANDARD_GRAVITY - ACCELERATION_TOLERANCE;
        private static final float MAX_ACCELERATION_MAGNITUDE =
            SensorManager.STANDARD_GRAVITY + ACCELERATION_TOLERANCE;

        // Maximum absolute tilt angle at which to consider orientation data.  Beyond this (i.e.
        // when screen is facing the sky or ground), we completely ignore orientation data
        // because it's too unstable.
        private static final int MAX_TILT = 80;

        // The tilt angle below which we conclude that the user is holding the device
        // overhead reading in bed and lock into that state.
        private static final int TILT_OVERHEAD_ENTER = -40;

        // The tilt angle above which we conclude that the user would like a rotation
        // change to occur and unlock from the overhead state.
        private static final int TILT_OVERHEAD_EXIT = -15;

        // The gap angle in degrees between adjacent orientation angles for hysteresis.
        // This creates a "dead zone" between the current orientation and a proposed
        // adjacent orientation.  No orientation proposal is made when the orientation
        // angle is within the gap between the current orientation and the adjacent
        // orientation.
        private static final int ADJACENT_ORIENTATION_ANGLE_GAP = 45;

        // The tilt angle range in degrees for each orientation.
        // Beyond these tilt angles, we don't even consider transitioning into the
        // specified orientation.  We place more stringent requirements on unnatural
        // orientations than natural ones to make it less likely to accidentally transition
        // into those states.
        // The first value of each pair is negative so it applies a limit when the device is
        // facing down (overhead reading in bed).
        // The second value of each pair is positive so it applies a limit when the device is
        // facing up (resting on a table).
        // The ideal tilt angle is 0 (when the device is vertical) so the limits establish
        // how close to vertical the device must be in order to change orientation.
        private final int[][] mTiltToleranceConfig = new int[][] {
            /* ROTATION_0   */ { -25, 70 }, // note: these are overridden by config.xml
            /* ROTATION_90  */ { -25, 65 },
            /* ROTATION_180 */ { -25, 60 },
            /* ROTATION_270 */ { -25, 65 }
        };

        // Timestamp and value of the last accelerometer sample.
        private long mLastFilteredTimestampNanos;
        private float mLastFilteredX, mLastFilteredY, mLastFilteredZ;

        // The last proposed rotation, -1 if unknown.
        private int mProposedRotation;

        // Value of the current predicted rotation, -1 if unknown.
        private int mPredictedRotation;

        // Timestamp of when the predicted rotation most recently changed.
        private long mPredictedRotationTimestampNanos;

        // Timestamp when the device last appeared to be flat for sure (the flat delay elapsed).
        private long mFlatTimestampNanos;
        private boolean mFlat;

        // Timestamp when the device last appeared to be swinging.
        private long mSwingTimestampNanos;
        private boolean mSwinging;

        // Timestamp when the device last appeared to be undergoing external acceleration.
        private long mAccelerationTimestampNanos;
        private boolean mAccelerating;

        // Timestamp when the last touch to the touch screen ended
        private long mTouchEndedTimestampNanos = Long.MIN_VALUE;
        private boolean mTouched;

        // Whether we are locked into an overhead usage mode.
        private boolean mOverhead;

        // History of observed tilt angles.
        private static final int TILT_HISTORY_SIZE = 200;
        private float[] mTiltHistory = new float[TILT_HISTORY_SIZE];
        private long[] mTiltHistoryTimestampNanos = new long[TILT_HISTORY_SIZE];
        private int mTiltHistoryIndex;

        public AccelSensorJudge(Context context) {
            // Load tilt tolerance configuration.
            int[] tiltTolerance = context.getResources().getIntArray(
                    com.android.internal.R.array.config_autoRotationTiltTolerance);
            if (tiltTolerance.length == 8) {
                for (int i = 0; i < 4; i++) {
                    int min = tiltTolerance[i * 2];
                    int max = tiltTolerance[i * 2 + 1];
                    if (min >= -90 && min <= max && max <= 90) {
                        mTiltToleranceConfig[i][0] = min;
                        mTiltToleranceConfig[i][1] = max;
                    } else {
                        Slog.wtf(TAG, "config_autoRotationTiltTolerance contains invalid range: "
                                + "min=" + min + ", max=" + max);
                    }
                }
            } else {
                Slog.wtf(TAG, "config_autoRotationTiltTolerance should have exactly 8 elements");
            }
        }

        @Override
        public int getProposedRotationLocked() {
            return mProposedRotation;
        }

        @Override
        public void dumpLocked(PrintWriter pw, String prefix) {
            pw.println(prefix + "AccelSensorJudge");
            prefix += "  ";
            pw.println(prefix + "mProposedRotation=" + mProposedRotation);
            pw.println(prefix + "mPredictedRotation=" + mPredictedRotation);
            pw.println(prefix + "mLastFilteredX=" + mLastFilteredX);
            pw.println(prefix + "mLastFilteredY=" + mLastFilteredY);
            pw.println(prefix + "mLastFilteredZ=" + mLastFilteredZ);
            final long delta = SystemClock.elapsedRealtimeNanos() - mLastFilteredTimestampNanos;
            pw.println(prefix + "mLastFilteredTimestampNanos=" + mLastFilteredTimestampNanos
                    + " (" + (delta * 0.000001f) + "ms ago)");
            pw.println(prefix + "mTiltHistory={last: " + getLastTiltLocked() + "}");
            pw.println(prefix + "mFlat=" + mFlat);
            pw.println(prefix + "mSwinging=" + mSwinging);
            pw.println(prefix + "mAccelerating=" + mAccelerating);
            pw.println(prefix + "mOverhead=" + mOverhead);
            pw.println(prefix + "mTouched=" + mTouched);
            pw.print(prefix + "mTiltToleranceConfig=[");
            for (int i = 0; i < 4; i++) {
                if (i != 0) {
                    pw.print(", ");
                }
                pw.print("[");
                pw.print(mTiltToleranceConfig[i][0]);
                pw.print(", ");
                pw.print(mTiltToleranceConfig[i][1]);
                pw.print("]");
            }
            pw.println("]");
        }

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

        @Override
        public void onSensorChanged(SensorEvent event) {
            int proposedRotation;
            int oldProposedRotation;

            synchronized (mLock) {
                // The vector given in the SensorEvent points straight up (towards the sky) under
                // ideal conditions (the phone is not accelerating).  I'll call this up vector
                // elsewhere.
                float x = event.values[ACCELEROMETER_DATA_X];
                float y = event.values[ACCELEROMETER_DATA_Y];
                float z = event.values[ACCELEROMETER_DATA_Z];

                if (LOG) {
                    Slog.v(TAG, "Raw acceleration vector: "
                            + "x=" + x + ", y=" + y + ", z=" + z
                            + ", magnitude=" + Math.sqrt(x * x + y * y + z * z));
                }

                // Apply a low-pass filter to the acceleration up vector in cartesian space.
                // Reset the orientation listener state if the samples are too far apart in time
                // or when we see values of (0, 0, 0) which indicates that we polled the
                // accelerometer too soon after turning it on and we don't have any data yet.
                final long now = event.timestamp;
                final long then = mLastFilteredTimestampNanos;
                final float timeDeltaMS = (now - then) * 0.000001f;
                final boolean skipSample;
                if (now < then
                        || now > then + MAX_FILTER_DELTA_TIME_NANOS
                        || (x == 0 && y == 0 && z == 0)) {
                    if (LOG) {
                        Slog.v(TAG, "Resetting orientation listener.");
                    }
                    resetLocked();
                    skipSample = true;
                } else {
                    final float alpha = timeDeltaMS / (FILTER_TIME_CONSTANT_MS + timeDeltaMS);
                    x = alpha * (x - mLastFilteredX) + mLastFilteredX;
                    y = alpha * (y - mLastFilteredY) + mLastFilteredY;
                    z = alpha * (z - mLastFilteredZ) + mLastFilteredZ;
                    if (LOG) {
                        Slog.v(TAG, "Filtered acceleration vector: "
                                + "x=" + x + ", y=" + y + ", z=" + z
                                + ", magnitude=" + Math.sqrt(x * x + y * y + z * z));
                    }
                    skipSample = false;
                }
                mLastFilteredTimestampNanos = now;
                mLastFilteredX = x;
                mLastFilteredY = y;
                mLastFilteredZ = z;

                boolean isAccelerating = false;
                boolean isFlat = false;
                boolean isSwinging = false;
                if (!skipSample) {
                    // Calculate the magnitude of the acceleration vector.
                    final float magnitude = (float) Math.sqrt(x * x + y * y + z * z);
                    if (magnitude < NEAR_ZERO_MAGNITUDE) {
                        if (LOG) {
                            Slog.v(TAG, "Ignoring sensor data, magnitude too close to zero.");
                        }
                        clearPredictedRotationLocked();
                    } else {
                        // Determine whether the device appears to be undergoing external
                        // acceleration.
                        if (isAcceleratingLocked(magnitude)) {
                            isAccelerating = true;
                            mAccelerationTimestampNanos = now;
                        }

                        // Calculate the tilt angle.
                        // This is the angle between the up vector and the x-y plane (the plane of
                        // the screen) in a range of [-90, 90] degrees.
                        //   -90 degrees: screen horizontal and facing the ground (overhead)
                        //     0 degrees: screen vertical
                        //    90 degrees: screen horizontal and facing the sky (on table)
                        final int tiltAngle = (int) Math.round(
                                Math.asin(z / magnitude) * RADIANS_TO_DEGREES);
                        addTiltHistoryEntryLocked(now, tiltAngle);

                        // Determine whether the device appears to be flat or swinging.
                        if (isFlatLocked(now)) {
                            isFlat = true;
                            mFlatTimestampNanos = now;
                        }
                        if (isSwingingLocked(now, tiltAngle)) {
                            isSwinging = true;
                            mSwingTimestampNanos = now;
                        }

                        // If the tilt angle is too close to horizontal then we cannot determine
                        // the orientation angle of the screen.
                        if (tiltAngle <= TILT_OVERHEAD_ENTER) {
                            mOverhead = true;
                        } else if (tiltAngle >= TILT_OVERHEAD_EXIT) {
                            mOverhead = false;
                        }
                        if (mOverhead) {
                            if (LOG) {
                                Slog.v(TAG, "Ignoring sensor data, device is overhead: "
                                        + "tiltAngle=" + tiltAngle);
                            }
                            clearPredictedRotationLocked();
                        } else if (Math.abs(tiltAngle) > MAX_TILT) {
                            if (LOG) {
                                Slog.v(TAG, "Ignoring sensor data, tilt angle too high: "
                                        + "tiltAngle=" + tiltAngle);
                            }
                            clearPredictedRotationLocked();
                        } else {
                            // Calculate the orientation angle.
                            // This is the angle between the x-y projection of the up vector onto
                            // the +y-axis, increasing clockwise in a range of [0, 360] degrees.
                            int orientationAngle = (int) Math.round(
                                    -Math.atan2(-x, y) * RADIANS_TO_DEGREES);
                            if (orientationAngle < 0) {
                                // atan2 returns [-180, 180]; normalize to [0, 360]
                                orientationAngle += 360;
                            }

                            // Find the nearest rotation.
                            int nearestRotation = (orientationAngle + 45) / 90;
                            if (nearestRotation == 4) {
                                nearestRotation = 0;
                            }

                            // Determine the predicted orientation.
                            if (isTiltAngleAcceptableLocked(nearestRotation, tiltAngle)
                                    && isOrientationAngleAcceptableLocked(nearestRotation,
                                            orientationAngle)) {
                                updatePredictedRotationLocked(now, nearestRotation);
                                if (LOG) {
                                    Slog.v(TAG, "Predicted: "
                                            + "tiltAngle=" + tiltAngle
                                            + ", orientationAngle=" + orientationAngle
                                            + ", predictedRotation=" + mPredictedRotation
                                            + ", predictedRotationAgeMS="
                                                    + ((now - mPredictedRotationTimestampNanos)
                                                            * 0.000001f));
                                }
                            } else {
                                if (LOG) {
                                    Slog.v(TAG, "Ignoring sensor data, no predicted rotation: "
                                            + "tiltAngle=" + tiltAngle
                                            + ", orientationAngle=" + orientationAngle);
                                }
                                clearPredictedRotationLocked();
                            }
                        }
                    }
                }
                mFlat = isFlat;
                mSwinging = isSwinging;
                mAccelerating = isAccelerating;

                // Determine new proposed rotation.
                oldProposedRotation = mProposedRotation;
                if (mPredictedRotation < 0 || isPredictedRotationAcceptableLocked(now)) {
                    mProposedRotation = mPredictedRotation;
                }
                proposedRotation = mProposedRotation;

                // Write final statistics about where we are in the orientation detection process.
                if (LOG) {
                    Slog.v(TAG, "Result: currentRotation=" + mCurrentRotation
                            + ", proposedRotation=" + proposedRotation
                            + ", predictedRotation=" + mPredictedRotation
                            + ", timeDeltaMS=" + timeDeltaMS
                            + ", isAccelerating=" + isAccelerating
                            + ", isFlat=" + isFlat
                            + ", isSwinging=" + isSwinging
                            + ", isOverhead=" + mOverhead
                            + ", isTouched=" + mTouched
                            + ", timeUntilSettledMS=" + remainingMS(now,
                                    mPredictedRotationTimestampNanos + PROPOSAL_SETTLE_TIME_NANOS)
                            + ", timeUntilAccelerationDelayExpiredMS=" + remainingMS(now,
                                    mAccelerationTimestampNanos + PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS)
                            + ", timeUntilFlatDelayExpiredMS=" + remainingMS(now,
                                    mFlatTimestampNanos + PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS)
                            + ", timeUntilSwingDelayExpiredMS=" + remainingMS(now,
                                    mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS)
                            + ", timeUntilTouchDelayExpiredMS=" + remainingMS(now,
                                    mTouchEndedTimestampNanos + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS));
                }
            }

            // Tell the listener.
            if (proposedRotation != oldProposedRotation && proposedRotation >= 0) {
                if (LOG) {
                    Slog.v(TAG, "Proposed rotation changed!  proposedRotation=" + proposedRotation
                            + ", oldProposedRotation=" + oldProposedRotation);
                }
                onProposedRotationChanged(proposedRotation);
            }
        }

        @Override
        public void onTouchStartLocked() {
            mTouched = true;
        }

        @Override
        public void onTouchEndLocked(long whenElapsedNanos) {
            mTouched = false;
            mTouchEndedTimestampNanos = whenElapsedNanos;
        }

        @Override
        public void resetLocked() {
            mLastFilteredTimestampNanos = Long.MIN_VALUE;
            mProposedRotation = -1;
            mFlatTimestampNanos = Long.MIN_VALUE;
            mFlat = false;
            mSwingTimestampNanos = Long.MIN_VALUE;
            mSwinging = false;
            mAccelerationTimestampNanos = Long.MIN_VALUE;
            mAccelerating = false;
            mOverhead = false;
            clearPredictedRotationLocked();
            clearTiltHistoryLocked();
        }


        /**
         * Returns true if the tilt angle is acceptable for a given predicted rotation.
         */
        private boolean isTiltAngleAcceptableLocked(int rotation, int tiltAngle) {
            return tiltAngle >= mTiltToleranceConfig[rotation][0]
                    && tiltAngle <= mTiltToleranceConfig[rotation][1];
        }

        /**
         * Returns true if the orientation angle is acceptable for a given predicted rotation.
         *
         * This function takes into account the gap between adjacent orientations
         * for hysteresis.
         */
        private boolean isOrientationAngleAcceptableLocked(int rotation, int orientationAngle) {
            // If there is no current rotation, then there is no gap.
            // The gap is used only to introduce hysteresis among advertised orientation
            // changes to avoid flapping.
            final int currentRotation = mCurrentRotation;
            if (currentRotation >= 0) {
                // If the specified rotation is the same or is counter-clockwise adjacent
                // to the current rotation, then we set a lower bound on the orientation angle.
                // For example, if currentRotation is ROTATION_0 and proposed is ROTATION_90,
                // then we want to check orientationAngle > 45 + GAP / 2.
                if (rotation == currentRotation
                        || rotation == (currentRotation + 1) % 4) {
                    int lowerBound = rotation * 90 - 45
                            + ADJACENT_ORIENTATION_ANGLE_GAP / 2;
                    if (rotation == 0) {
                        if (orientationAngle >= 315 && orientationAngle < lowerBound + 360) {
                            return false;
                        }
                    } else {
                        if (orientationAngle < lowerBound) {
                            return false;
                        }
                    }
                }

                // If the specified rotation is the same or is clockwise adjacent,
                // then we set an upper bound on the orientation angle.
                // For example, if currentRotation is ROTATION_0 and rotation is ROTATION_270,
                // then we want to check orientationAngle < 315 - GAP / 2.
                if (rotation == currentRotation
                        || rotation == (currentRotation + 3) % 4) {
                    int upperBound = rotation * 90 + 45
                            - ADJACENT_ORIENTATION_ANGLE_GAP / 2;
                    if (rotation == 0) {
                        if (orientationAngle <= 45 && orientationAngle > upperBound) {
                            return false;
                        }
                    } else {
                        if (orientationAngle > upperBound) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        /**
         * Returns true if the predicted rotation is ready to be advertised as a
         * proposed rotation.
         */
        private boolean isPredictedRotationAcceptableLocked(long now) {
            // The predicted rotation must have settled long enough.
            if (now < mPredictedRotationTimestampNanos + PROPOSAL_SETTLE_TIME_NANOS) {
                return false;
            }

            // The last flat state (time since picked up) must have been sufficiently long ago.
            if (now < mFlatTimestampNanos + PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS) {
                return false;
            }

            // The last swing state (time since last movement to put down) must have been
            // sufficiently long ago.
            if (now < mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS) {
                return false;
            }

            // The last acceleration state must have been sufficiently long ago.
            if (now < mAccelerationTimestampNanos
                    + PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS) {
                return false;
            }

            // The last touch must have ended sufficiently long ago.
            if (mTouched || now < mTouchEndedTimestampNanos
                    + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS) {
                return false;
            }

            // Looks good!
            return true;
        }

        private void clearPredictedRotationLocked() {
            mPredictedRotation = -1;
            mPredictedRotationTimestampNanos = Long.MIN_VALUE;
        }

        private void updatePredictedRotationLocked(long now, int rotation) {
            if (mPredictedRotation != rotation) {
                mPredictedRotation = rotation;
                mPredictedRotationTimestampNanos = now;
            }
        }

        private boolean isAcceleratingLocked(float magnitude) {
            return magnitude < MIN_ACCELERATION_MAGNITUDE
                    || magnitude > MAX_ACCELERATION_MAGNITUDE;
        }

        private void clearTiltHistoryLocked() {
            mTiltHistoryTimestampNanos[0] = Long.MIN_VALUE;
            mTiltHistoryIndex = 1;
        }

        private void addTiltHistoryEntryLocked(long now, float tilt) {
            mTiltHistory[mTiltHistoryIndex] = tilt;
            mTiltHistoryTimestampNanos[mTiltHistoryIndex] = now;
            mTiltHistoryIndex = (mTiltHistoryIndex + 1) % TILT_HISTORY_SIZE;
            mTiltHistoryTimestampNanos[mTiltHistoryIndex] = Long.MIN_VALUE;
        }

        private boolean isFlatLocked(long now) {
            for (int i = mTiltHistoryIndex; (i = nextTiltHistoryIndexLocked(i)) >= 0; ) {
                if (mTiltHistory[i] < FLAT_ANGLE) {
                    break;
                }
                if (mTiltHistoryTimestampNanos[i] + FLAT_TIME_NANOS <= now) {
                    // Tilt has remained greater than FLAT_TILT_ANGLE for FLAT_TIME_NANOS.
                    return true;
                }
            }
            return false;
        }

        private boolean isSwingingLocked(long now, float tilt) {
            for (int i = mTiltHistoryIndex; (i = nextTiltHistoryIndexLocked(i)) >= 0; ) {
                if (mTiltHistoryTimestampNanos[i] + SWING_TIME_NANOS < now) {
                    break;
                }
                if (mTiltHistory[i] + SWING_AWAY_ANGLE_DELTA <= tilt) {
                    // Tilted away by SWING_AWAY_ANGLE_DELTA within SWING_TIME_NANOS.
                    return true;
                }
            }
            return false;
        }

        private int nextTiltHistoryIndexLocked(int index) {
            index = (index == 0 ? TILT_HISTORY_SIZE : index) - 1;
            return mTiltHistoryTimestampNanos[index] != Long.MIN_VALUE ? index : -1;
        }

        private float getLastTiltLocked() {
            int index = nextTiltHistoryIndexLocked(mTiltHistoryIndex);
            return index >= 0 ? mTiltHistory[index] : Float.NaN;
        }

        private float remainingMS(long now, long until) {
            return now >= until ? 0 : (until - now) * 0.000001f;
        }
    }

    final class OrientationSensorJudge extends OrientationJudge {
        private boolean mTouching;
        private long mTouchEndedTimestampNanos = Long.MIN_VALUE;
        private int mProposedRotation = -1;
        private int mDesiredRotation = -1;
        private boolean mRotationEvaluationScheduled;

        @Override
        public int getProposedRotationLocked() {
            return mProposedRotation;
        }

        @Override
        public void onTouchStartLocked() {
            mTouching = true;
        }

        @Override
        public void onTouchEndLocked(long whenElapsedNanos) {
            mTouching = false;
            mTouchEndedTimestampNanos = whenElapsedNanos;
            if (mDesiredRotation != mProposedRotation) {
                final long now = SystemClock.elapsedRealtimeNanos();
                scheduleRotationEvaluationIfNecessaryLocked(now);
            }
        }


        @Override
        public void onSensorChanged(SensorEvent event) {
            int newRotation;
            synchronized (mLock) {
                mDesiredRotation = (int) event.values[0];
                newRotation = evaluateRotationChangeLocked();
            }
            if (newRotation >=0) {
                onProposedRotationChanged(newRotation);
            }
        }

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

        @Override
        public void dumpLocked(PrintWriter pw, String prefix) {
            pw.println(prefix + "OrientationSensorJudge");
            prefix += "  ";
            pw.println(prefix + "mDesiredRotation=" + mDesiredRotation);
            pw.println(prefix + "mProposedRotation=" + mProposedRotation);
            pw.println(prefix + "mTouching=" + mTouching);
            pw.println(prefix + "mTouchEndedTimestampNanos=" + mTouchEndedTimestampNanos);
        }

        @Override
        public void resetLocked() {
            mProposedRotation = -1;
            mDesiredRotation = -1;
            mTouching = false;
            mTouchEndedTimestampNanos = Long.MIN_VALUE;
            unscheduleRotationEvaluationLocked();
        }

        public int evaluateRotationChangeLocked() {
            unscheduleRotationEvaluationLocked();
            if (mDesiredRotation == mProposedRotation) {
                return -1;
            }
            final long now = SystemClock.elapsedRealtimeNanos();
            if (isDesiredRotationAcceptableLocked(now)) {
                mProposedRotation = mDesiredRotation;
                return mProposedRotation;
            } else {
                scheduleRotationEvaluationIfNecessaryLocked(now);
            }
            return -1;
        }

        private boolean isDesiredRotationAcceptableLocked(long now) {
            if (mTouching) {
                return false;
            }
            if (now < mTouchEndedTimestampNanos + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS) {
                return false;
            }
            return true;
        }

        private void scheduleRotationEvaluationIfNecessaryLocked(long now) {
            if (mRotationEvaluationScheduled || mDesiredRotation == mProposedRotation) {
                if (LOG) {
                    Slog.d(TAG, "scheduleRotationEvaluationLocked: " +
                            "ignoring, an evaluation is already scheduled or is unnecessary.");
                }
                return;
            }
            if (mTouching) {
                if (LOG) {
                    Slog.d(TAG, "scheduleRotationEvaluationLocked: " +
                            "ignoring, user is still touching the screen.");
                }
                return;
            }
            long timeOfNextPossibleRotationNanos =
                mTouchEndedTimestampNanos + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS;
            if (now >= timeOfNextPossibleRotationNanos) {
                if (LOG) {
                    Slog.d(TAG, "scheduleRotationEvaluationLocked: " +
                            "ignoring, already past the next possible time of rotation.");
                }
                return;
            }
            // Use a delay instead of an absolute time since handlers are in uptime millis and we
            // use elapsed realtime.
            final long delayMs =
                    (long) Math.ceil((timeOfNextPossibleRotationNanos - now) * MILLIS_PER_NANO);
            mHandler.postDelayed(mRotationEvaluator, delayMs);
            mRotationEvaluationScheduled = true;
        }

        private void unscheduleRotationEvaluationLocked() {
            if (!mRotationEvaluationScheduled) {
                return;
            }
            mHandler.removeCallbacks(mRotationEvaluator);
            mRotationEvaluationScheduled = false;
        }

        private Runnable mRotationEvaluator = new Runnable() {
            @Override
            public void run() {
                int newRotation;
                synchronized (mLock) {
                    mRotationEvaluationScheduled = false;
                    newRotation = evaluateRotationChangeLocked();
                }
                if (newRotation >= 0) {
                    onProposedRotationChanged(newRotation);
                }
            }
        };
    }
}
