Make DeviceIdle motion sensing flaggable-off

We will still go through the same routine as before, and in particular
a misconfigured phone without any motion sensors will still fail to
progress into full doze state.

With config_autoPowerModeUseMotionSensor overriden to false, this is not
true any more and we make STATE_SENSING a no-op that moves straight into
STATE_LOCATING as if we immediately got a "no motion" callback.

Bug: 110756616
Test: atest com.android.server.DeviceIdleControllerTest
Test: atest BatterySaverPolicyTest
Change-Id: I00d778c44257b3e3682494c0d3b10f4c3d68c382
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index af9d4c8..45c13ec 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -272,6 +272,7 @@
     private PowerManager mPowerManager;
     private INetworkPolicyManager mNetworkPolicyManager;
     private SensorManager mSensorManager;
+    private final boolean mUseMotionSensor;
     private Sensor mMotionSensor;
     private LocationRequest mLocationRequest;
     private Intent mIdleIntent;
@@ -1629,6 +1630,9 @@
         mHandler = mInjector.getHandler(this);
         mAppStateTracker = mInjector.getAppStateTracker(context, FgThread.get().getLooper());
         LocalServices.addService(AppStateTracker.class, mAppStateTracker);
+
+        mUseMotionSensor = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_autoPowerModeUseMotionSensor);
     }
 
     public DeviceIdleController(Context context) {
@@ -1729,20 +1733,23 @@
                         ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
                 mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class);
                 mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
-                int sigMotionSensorId = getContext().getResources().getInteger(
-                        com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
-                if (sigMotionSensorId > 0) {
-                    mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
-                }
-                if (mMotionSensor == null && getContext().getResources().getBoolean(
-                        com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
-                    mMotionSensor = mSensorManager.getDefaultSensor(
-                            Sensor.TYPE_WRIST_TILT_GESTURE, true);
-                }
-                if (mMotionSensor == null) {
-                    // As a last ditch, fall back to SMD.
-                    mMotionSensor = mSensorManager.getDefaultSensor(
-                            Sensor.TYPE_SIGNIFICANT_MOTION, true);
+
+                if (mUseMotionSensor) {
+                    int sigMotionSensorId = getContext().getResources().getInteger(
+                            com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
+                    if (sigMotionSensorId > 0) {
+                        mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
+                    }
+                    if (mMotionSensor == null && getContext().getResources().getBoolean(
+                            com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
+                        mMotionSensor = mSensorManager.getDefaultSensor(
+                                Sensor.TYPE_WRIST_TILT_GESTURE, true);
+                    }
+                    if (mMotionSensor == null) {
+                        // As a last ditch, fall back to SMD.
+                        mMotionSensor = mSensorManager.getDefaultSensor(
+                                Sensor.TYPE_SIGNIFICANT_MOTION, true);
+                    }
                 }
 
                 if (getContext().getResources().getBoolean(
@@ -2588,14 +2595,21 @@
                 mState = STATE_SENSING;
                 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
                 EventLogTags.writeDeviceIdle(mState, reason);
-                scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT);
                 cancelLocatingLocked();
-                mNotMoving = false;
                 mLocated = false;
                 mLastGenericLocation = null;
                 mLastGpsLocation = null;
-                mAnyMotionDetector.checkForAnyMotion();
-                break;
+
+                // If we have an accelerometer, wait to find out whether we are moving.
+                if (mUseMotionSensor && mAnyMotionDetector.hasSensor()) {
+                    scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT);
+                    mNotMoving = false;
+                    mAnyMotionDetector.checkForAnyMotion();
+                    break;
+                }
+
+                mNotMoving = true;
+                // Otherwise, fall through and check this off the list of requirements.
             case STATE_SENSING:
                 cancelSensingTimeoutAlarmLocked();
                 mState = STATE_LOCATING;
@@ -2893,9 +2907,12 @@
 
     void scheduleAlarmLocked(long delay, boolean idleUntil) {
         if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
-        if (mMotionSensor == null && !(mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
-                  || mState == STATE_IDLE_MAINTENANCE)) {
-            // If there is no motion sensor on this device, then we won't schedule
+
+        if (mUseMotionSensor && mMotionSensor == null
+                && mState != STATE_QUICK_DOZE_DELAY
+                && mState != STATE_IDLE
+                && mState != STATE_IDLE_MAINTENANCE) {
+            // If there is no motion sensor on this device, but we need one, then we won't schedule
             // alarms, because we can't determine if the device is not moving.  This effectively
             // turns off normal execution of device idling, although it is still possible to
             // manually poke it by pretending like the alarm is going off.
@@ -3765,13 +3782,20 @@
             pw.print("  mLightEnabled="); pw.print(mLightEnabled);
             pw.print("  mDeepEnabled="); pw.println(mDeepEnabled);
             pw.print("  mForceIdle="); pw.println(mForceIdle);
-            pw.print("  mMotionSensor="); pw.println(mMotionSensor);
+            pw.print("  mUseMotionSensor="); pw.print(mUseMotionSensor);
+            if (mUseMotionSensor) {
+                pw.print(" mMotionSensor="); pw.println(mMotionSensor);
+            } else {
+                pw.println();
+            }
             pw.print("  mScreenOn="); pw.println(mScreenOn);
             pw.print("  mScreenLocked="); pw.println(mScreenLocked);
             pw.print("  mNetworkConnected="); pw.println(mNetworkConnected);
             pw.print("  mCharging="); pw.println(mCharging);
             pw.print("  mMotionActive="); pw.println(mMotionListener.active);
-            pw.print("  mNotMoving="); pw.println(mNotMoving);
+            if (mUseMotionSensor) {
+                pw.print("  mNotMoving="); pw.println(mNotMoving);
+            }
             pw.print("  mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
                     pw.print(mHasGps); pw.print(" mHasNetwork=");
                     pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);