Fix issue #23214751: Get a GPS fix before going in to doze

This introduces a new phase of device idle mode, immediately
before going idle (once we are sure the device is not moving),
try to collect a location for the device so that any later
requests for it will have a good chance of having an accurate
value.

We do this with two location requests: one a single-shot as
accurate as possible location, and a second longer-running
attempt to get an accurate location from the GPS.  There is
a limit on how long we will try to collect the location (default
is 30 seconds), and we stop collection once we reach a desired
accuracy (default is 20 meters).

Also cleanup various transition paths out of the normal state
flow to clean up any active state we may have running.

Change-Id: Ibd3d2e9a720fbfd9640755baf5547180dd409f6a
diff --git a/services/core/java/com/android/server/AnyMotionDetector.java b/services/core/java/com/android/server/AnyMotionDetector.java
index 6390bcd..6a67316 100644
--- a/services/core/java/com/android/server/AnyMotionDetector.java
+++ b/services/core/java/com/android/server/AnyMotionDetector.java
@@ -16,9 +16,6 @@
 
 package com.android.server;
 
-import android.app.AlarmManager;
-import android.content.BroadcastReceiver;
-import android.content.Intent;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
@@ -85,17 +82,12 @@
     /** The accelerometer sampling interval. */
     private static final int SAMPLING_INTERVAL_MILLIS = 40;
 
-    private AlarmManager mAlarmManager;
     private final Handler mHandler;
-    private Intent mAlarmIntent;
     private final Object mLock = new Object();
     private Sensor mAccelSensor;
     private SensorManager mSensorManager;
     private PowerManager.WakeLock mWakeLock;
 
-    /** The time when detection was last performed. */
-    private long mDetectionStartTime;
-
     /** The minimum number of samples required to detect AnyMotion. */
     private int mNumSufficientSamples;
 
@@ -113,11 +105,11 @@
 
     private DeviceIdleCallback mCallback = null;
 
-    public AnyMotionDetector(AlarmManager am, PowerManager pm, Handler handler, SensorManager sm,
+    public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm,
             DeviceIdleCallback callback) {
         if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated.");
-        mAlarmManager = am;
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        mWakeLock.setReferenceCounted(false);
         mHandler = handler;
         mSensorManager = sm;
         mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
@@ -144,6 +136,22 @@
         }
     }
 
+    public void stop() {
+        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);
+            mWakeLock.release();
+            mCurrentGravityVector = null;
+            mPreviousGravityVector = null;
+        }
+    }
+
     private void startOrientationMeasurement() {
         if (DEBUG) Slog.d(TAG, "startOrientationMeasurement: mMeasurementInProgress=" +
             mMeasurementInProgress + ", (mAccelSensor != null)=" + (mAccelSensor != null));
@@ -153,7 +161,6 @@
                     SAMPLING_INTERVAL_MILLIS * 1000)) {
                 mWakeLock.acquire();
                 mMeasurementInProgress = true;
-                mDetectionStartTime = SystemClock.elapsedRealtime();
                 mRunningStats.reset();
             }
 
@@ -170,9 +177,7 @@
         if (mMeasurementInProgress) {
             mSensorManager.unregisterListener(mListener);
             mHandler.removeCallbacks(mMeasurementTimeout);
-            if (mWakeLock.isHeld()) {
-                mWakeLock.release();
-            }
+            mWakeLock.release();
             long detectionEndTime = SystemClock.elapsedRealtime();
             mMeasurementInProgress = false;
             mPreviousGravityVector = mCurrentGravityVector;