Loading services/core/java/com/android/server/AnyMotionDetector.java +19 −14 Original line number Original line Diff line number Diff line Loading @@ -16,9 +16,6 @@ package com.android.server; package com.android.server; import android.app.AlarmManager; import android.content.BroadcastReceiver; import android.content.Intent; import android.hardware.Sensor; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorEventListener; Loading Loading @@ -85,17 +82,12 @@ public class AnyMotionDetector { /** The accelerometer sampling interval. */ /** The accelerometer sampling interval. */ private static final int SAMPLING_INTERVAL_MILLIS = 40; private static final int SAMPLING_INTERVAL_MILLIS = 40; private AlarmManager mAlarmManager; private final Handler mHandler; private final Handler mHandler; private Intent mAlarmIntent; private final Object mLock = new Object(); private final Object mLock = new Object(); private Sensor mAccelSensor; private Sensor mAccelSensor; private SensorManager mSensorManager; private SensorManager mSensorManager; private PowerManager.WakeLock mWakeLock; private PowerManager.WakeLock mWakeLock; /** The time when detection was last performed. */ private long mDetectionStartTime; /** The minimum number of samples required to detect AnyMotion. */ /** The minimum number of samples required to detect AnyMotion. */ private int mNumSufficientSamples; private int mNumSufficientSamples; Loading @@ -113,11 +105,11 @@ public class AnyMotionDetector { private DeviceIdleCallback mCallback = null; private DeviceIdleCallback mCallback = null; public AnyMotionDetector(AlarmManager am, PowerManager pm, Handler handler, SensorManager sm, public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm, DeviceIdleCallback callback) { DeviceIdleCallback callback) { if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated."); if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated."); mAlarmManager = am; mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.setReferenceCounted(false); mHandler = handler; mHandler = handler; mSensorManager = sm; mSensorManager = sm; mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); Loading @@ -144,6 +136,22 @@ public class AnyMotionDetector { } } } } 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() { private void startOrientationMeasurement() { if (DEBUG) Slog.d(TAG, "startOrientationMeasurement: mMeasurementInProgress=" + if (DEBUG) Slog.d(TAG, "startOrientationMeasurement: mMeasurementInProgress=" + mMeasurementInProgress + ", (mAccelSensor != null)=" + (mAccelSensor != null)); mMeasurementInProgress + ", (mAccelSensor != null)=" + (mAccelSensor != null)); Loading @@ -153,7 +161,6 @@ public class AnyMotionDetector { SAMPLING_INTERVAL_MILLIS * 1000)) { SAMPLING_INTERVAL_MILLIS * 1000)) { mWakeLock.acquire(); mWakeLock.acquire(); mMeasurementInProgress = true; mMeasurementInProgress = true; mDetectionStartTime = SystemClock.elapsedRealtime(); mRunningStats.reset(); mRunningStats.reset(); } } Loading @@ -170,9 +177,7 @@ public class AnyMotionDetector { if (mMeasurementInProgress) { if (mMeasurementInProgress) { mSensorManager.unregisterListener(mListener); mSensorManager.unregisterListener(mListener); mHandler.removeCallbacks(mMeasurementTimeout); mHandler.removeCallbacks(mMeasurementTimeout); if (mWakeLock.isHeld()) { mWakeLock.release(); mWakeLock.release(); } long detectionEndTime = SystemClock.elapsedRealtime(); long detectionEndTime = SystemClock.elapsedRealtime(); mMeasurementInProgress = false; mMeasurementInProgress = false; mPreviousGravityVector = mCurrentGravityVector; mPreviousGravityVector = mCurrentGravityVector; Loading services/core/java/com/android/server/DeviceIdleController.java +225 −36 Original line number Original line Diff line number Diff line Loading @@ -34,10 +34,15 @@ import android.hardware.SensorManager; import android.hardware.TriggerEvent; import android.hardware.TriggerEvent; import android.hardware.TriggerEventListener; import android.hardware.TriggerEventListener; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager; import android.location.LocationRequest; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.net.INetworkPolicyManager; import android.net.INetworkPolicyManager; import android.net.Uri; import android.net.Uri; import android.os.BatteryStats; import android.os.BatteryStats; import android.os.Binder; import android.os.Binder; import android.os.Bundle; import android.os.Environment; import android.os.Environment; import android.os.FileUtils; import android.os.FileUtils; import android.os.Handler; import android.os.Handler; Loading Loading @@ -107,6 +112,8 @@ public class DeviceIdleController extends SystemService private DisplayManager mDisplayManager; private DisplayManager mDisplayManager; private SensorManager mSensorManager; private SensorManager mSensorManager; private Sensor mSigMotionSensor; private Sensor mSigMotionSensor; private LocationManager mLocationManager; private LocationRequest mLocationRequest; private PendingIntent mSensingAlarmIntent; private PendingIntent mSensingAlarmIntent; private PendingIntent mAlarmIntent; private PendingIntent mAlarmIntent; private Intent mIdleIntent; private Intent mIdleIntent; Loading @@ -117,6 +124,13 @@ public class DeviceIdleController extends SystemService private boolean mScreenOn; private boolean mScreenOn; private boolean mCharging; private boolean mCharging; private boolean mSigMotionActive; private boolean mSigMotionActive; private boolean mSensing; private boolean mNotMoving; private boolean mLocating; private boolean mLocated; private boolean mHaveGps; private Location mLastGenericLocation; private Location mLastGpsLocation; /** Device is currently active. */ /** Device is currently active. */ private static final int STATE_ACTIVE = 0; private static final int STATE_ACTIVE = 0; Loading @@ -126,16 +140,19 @@ public class DeviceIdleController extends SystemService private static final int STATE_IDLE_PENDING = 2; private static final int STATE_IDLE_PENDING = 2; /** Device is currently sensing motion. */ /** Device is currently sensing motion. */ private static final int STATE_SENSING = 3; private static final int STATE_SENSING = 3; /** Device is currently finding location (and may still be sensing). */ private static final int STATE_LOCATING = 4; /** Device is in the idle state, trying to stay asleep as much as possible. */ /** Device is in the idle state, trying to stay asleep as much as possible. */ private static final int STATE_IDLE = 4; private static final int STATE_IDLE = 5; /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ private static final int STATE_IDLE_MAINTENANCE = 5; private static final int STATE_IDLE_MAINTENANCE = 6; private static String stateToString(int state) { private static String stateToString(int state) { switch (state) { switch (state) { case STATE_ACTIVE: return "ACTIVE"; case STATE_ACTIVE: return "ACTIVE"; case STATE_INACTIVE: return "INACTIVE"; case STATE_INACTIVE: return "INACTIVE"; case STATE_IDLE_PENDING: return "IDLE_PENDING"; case STATE_IDLE_PENDING: return "IDLE_PENDING"; case STATE_SENSING: return "SENSING"; case STATE_SENSING: return "SENSING"; case STATE_LOCATING: return "LOCATING"; case STATE_IDLE: return "IDLE"; case STATE_IDLE: return "IDLE"; case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; default: return Integer.toString(state); default: return Integer.toString(state); Loading Loading @@ -258,6 +275,48 @@ public class DeviceIdleController extends SystemService } } }; }; private final LocationListener mGenericLocationListener = new LocationListener() { @Override public void onLocationChanged(Location location) { synchronized (DeviceIdleController.this) { receivedGenericLocationLocked(location); } } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } }; private final LocationListener mGpsLocationListener = new LocationListener() { @Override public void onLocationChanged(Location location) { synchronized (DeviceIdleController.this) { receivedGpsLocationLocked(location); } } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } }; /** /** * All times are in milliseconds. These constants are kept synchronized with the system * All times are in milliseconds. These constants are kept synchronized with the system * global Settings. Any access to this class or its fields should be done while * global Settings. Any access to this class or its fields should be done while Loading @@ -267,6 +326,8 @@ public class DeviceIdleController extends SystemService // Key names stored in the settings value. // Key names stored in the settings value. private static final String KEY_INACTIVE_TIMEOUT = "inactive_to"; private static final String KEY_INACTIVE_TIMEOUT = "inactive_to"; private static final String KEY_SENSING_TIMEOUT = "sensing_to"; private static final String KEY_SENSING_TIMEOUT = "sensing_to"; private static final String KEY_LOCATING_TIMEOUT = "locating_to"; private static final String KEY_LOCATION_ACCURACY = "location_accuracy"; private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to"; private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to"; private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to"; private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to"; private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to"; private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to"; Loading Loading @@ -294,7 +355,8 @@ public class DeviceIdleController extends SystemService public long INACTIVE_TIMEOUT; public long INACTIVE_TIMEOUT; /** /** * If we don't receive a callback from AnyMotion in this amount of time, we will change from * If we don't receive a callback from AnyMotion in this amount of time + * {@link #LOCATING_TIMEOUT}, we will change from * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING * will be ignored. * will be ignored. * @see Settings.Global#DEVICE_IDLE_CONSTANTS * @see Settings.Global#DEVICE_IDLE_CONSTANTS Loading @@ -302,6 +364,23 @@ public class DeviceIdleController extends SystemService */ */ public long SENSING_TIMEOUT; public long SENSING_TIMEOUT; /** * This is how long we will wait to try to get a good location fix before going in to * idle mode. * @see Settings.Global#DEVICE_IDLE_CONSTANTS * @see #KEY_LOCATING_TIMEOUT */ public long LOCATING_TIMEOUT; /** * The desired maximum accuracy (in meters) we consider the location to be good enough to go * on to idle. We will be trying to get an accuracy fix at least this good or until * {@link #LOCATING_TIMEOUT} expires. * @see Settings.Global#DEVICE_IDLE_CONSTANTS * @see #KEY_LOCATION_ACCURACY */ public float LOCATION_ACCURACY; /** /** * This is the time, after seeing motion, that we wait after becoming inactive from * This is the time, after seeing motion, that we wait after becoming inactive from * that until we start looking for motion again. * that until we start looking for motion again. Loading Loading @@ -423,7 +502,10 @@ public class DeviceIdleController extends SystemService INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT, INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT, !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L); !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L); SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT, SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT, !DEBUG ? 5 * 60 * 1000L : 60 * 1000L); !DEBUG ? 4 * 60 * 1000L : 60 * 1000L); LOCATING_TIMEOUT = mParser.getLong(KEY_LOCATING_TIMEOUT, !DEBUG ? 30 * 1000L : 15 * 1000L); LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20); MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT, MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT, !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT, IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT, Loading Loading @@ -462,6 +544,14 @@ public class DeviceIdleController extends SystemService TimeUtils.formatDuration(SENSING_TIMEOUT, pw); TimeUtils.formatDuration(SENSING_TIMEOUT, pw); pw.println(); pw.println(); pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("="); TimeUtils.formatDuration(LOCATING_TIMEOUT, pw); pw.println(); pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("="); pw.print(LOCATION_ACCURACY); pw.print("m"); pw.println(); pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("="); pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("="); TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw); TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw); pw.println(); pw.println(); Loading Loading @@ -515,17 +605,27 @@ public class DeviceIdleController extends SystemService @Override @Override public void onAnyMotionResult(int result) { public void onAnyMotionResult(int result) { if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")"); if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")"); if (mState == STATE_SENSING) { if (result == AnyMotionDetector.RESULT_MOVED) { if (result == AnyMotionDetector.RESULT_STATIONARY) { if (DEBUG) Slog.d(TAG, "RESULT_MOVED received."); synchronized (this) { handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion"); } } else if (result == AnyMotionDetector.RESULT_STATIONARY) { if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received."); if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received."); if (mState == STATE_SENSING) { // If we are currently sensing, it is time to move to locating. synchronized (this) { synchronized (this) { mNotMoving = true; stepIdleStateLocked(); stepIdleStateLocked(); } } } else if (result == AnyMotionDetector.RESULT_MOVED) { } else if (mState == STATE_LOCATING) { if (DEBUG) Slog.d(TAG, "RESULT_MOVED received."); // If we are currently locating, note that we are not moving and step // if we have located the position. synchronized (this) { synchronized (this) { EventLogTags.writeDeviceIdle(mState, "sense_moved"); mNotMoving = true; enterInactiveStateLocked(); if (mLocated) { stepIdleStateLocked(); } } } } } } } Loading Loading @@ -783,8 +883,14 @@ public class DeviceIdleController extends SystemService Context.DISPLAY_SERVICE); Context.DISPLAY_SERVICE); mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); mSigMotionSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION); mSigMotionSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION); mLocationManager = (LocationManager) getContext().getSystemService( Context.LOCATION_SERVICE); mLocationRequest = new LocationRequest() .setQuality(LocationRequest.ACCURACY_FINE) .setInterval(0) .setFastestInterval(0) .setNumUpdates(1); mAnyMotionDetector = new AnyMotionDetector( mAnyMotionDetector = new AnyMotionDetector( mAlarmManager, (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), mHandler, mSensorManager, this); mHandler, mSensorManager, this); Loading Loading @@ -1049,7 +1155,7 @@ public class DeviceIdleController extends SystemService // We consider any situation where the display is showing something to be it on, // We consider any situation where the display is showing something to be it on, // because if there is anything shown we are going to be updating it at some // because if there is anything shown we are going to be updating it at some // frequency so can't be allowed to go into deep sleeps. // frequency so can't be allowed to go into deep sleeps. boolean screenOn = mCurDisplay.getState() != Display.STATE_OFF;; boolean screenOn = mCurDisplay.getState() == Display.STATE_ON; if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn); if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn); if (!screenOn && mScreenOn) { if (!screenOn && mScreenOn) { mScreenOn = false; mScreenOn = false; Loading Loading @@ -1092,10 +1198,7 @@ public class DeviceIdleController extends SystemService scheduleReportActiveLocked(activeReason, activeUid); scheduleReportActiveLocked(activeReason, activeUid); mState = STATE_ACTIVE; mState = STATE_ACTIVE; mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; mNextIdlePendingDelay = 0; resetIdleManagementLocked(); mNextIdleDelay = 0; cancelAlarmLocked(); stopMonitoringSignificantMotion(); } } } } Loading @@ -1106,20 +1209,20 @@ public class DeviceIdleController extends SystemService // waiting to see if we will ultimately go idle. // waiting to see if we will ultimately go idle. mState = STATE_INACTIVE; mState = STATE_INACTIVE; if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE"); if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE"); mNextIdlePendingDelay = 0; resetIdleManagementLocked(); mNextIdleDelay = 0; scheduleAlarmLocked(mInactiveTimeout, false); scheduleAlarmLocked(mInactiveTimeout, false); EventLogTags.writeDeviceIdle(mState, "no activity"); EventLogTags.writeDeviceIdle(mState, "no activity"); } } } } /** void resetIdleManagementLocked() { * This is called when we've failed to receive a callback from AnyMotionDetector mNextIdlePendingDelay = 0; * within the DEFAULT_SENSING_TIMEOUT, to return to STATE_INACTIVE. mNextIdleDelay = 0; */ cancelAlarmLocked(); void enterInactiveStateLocked() { cancelSensingAlarmLocked(); mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; cancelLocatingLocked(); becomeInactiveIfAppropriateLocked(); stopMonitoringSignificantMotion(); mAnyMotionDetector.stop(); } } void exitForceIdleLocked() { void exitForceIdleLocked() { Loading Loading @@ -1160,11 +1263,37 @@ public class DeviceIdleController extends SystemService case STATE_IDLE_PENDING: case STATE_IDLE_PENDING: mState = STATE_SENSING; mState = STATE_SENSING; if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING."); if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING."); EventLogTags.writeDeviceIdle(mState, "step"); scheduleSensingAlarmLocked(mConstants.SENSING_TIMEOUT); scheduleSensingAlarmLocked(mConstants.SENSING_TIMEOUT); cancelSensingAlarmLocked(); cancelLocatingLocked(); mAnyMotionDetector.checkForAnyMotion(); mAnyMotionDetector.checkForAnyMotion(); mNotMoving = false; mLocated = false; mLastGenericLocation = null; mLastGpsLocation = null; break; break; case STATE_SENSING: case STATE_SENSING: mState = STATE_LOCATING; if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING."); EventLogTags.writeDeviceIdle(mState, "step"); cancelSensingAlarmLocked(); cancelSensingAlarmLocked(); scheduleSensingAlarmLocked(mConstants.LOCATING_TIMEOUT); mLocating = true; mLocationManager.requestLocationUpdates(mLocationRequest, mGenericLocationListener, mHandler.getLooper()); if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { mHaveGps = true; mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, mGpsLocationListener, mHandler.getLooper()); } else { mHaveGps = false; } break; case STATE_LOCATING: cancelSensingAlarmLocked(); cancelLocatingLocked(); mAnyMotionDetector.stop(); case STATE_IDLE_MAINTENANCE: case STATE_IDLE_MAINTENANCE: scheduleAlarmLocked(mNextIdleDelay, true); scheduleAlarmLocked(mNextIdleDelay, true); if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay + if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay + Loading @@ -1173,6 +1302,7 @@ public class DeviceIdleController extends SystemService if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay); if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay); mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT); mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT); mState = STATE_IDLE; mState = STATE_IDLE; EventLogTags.writeDeviceIdle(mState, "step"); mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); break; break; case STATE_IDLE: case STATE_IDLE: Loading @@ -1193,18 +1323,54 @@ public class DeviceIdleController extends SystemService if (DEBUG) Slog.d(TAG, "significantMotionLocked()"); if (DEBUG) Slog.d(TAG, "significantMotionLocked()"); // When the sensor goes off, its trigger is automatically removed. // When the sensor goes off, its trigger is automatically removed. mSigMotionActive = false; mSigMotionActive = false; handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion"); } void handleMotionDetectedLocked(long timeout, String type) { // The device is not yet active, so we want to go back to the pending idle // The device is not yet active, so we want to go back to the pending idle // state to wait again for no motion. Note that we only monitor for significant // state to wait again for no motion. Note that we only monitor for significant // motion after moving out of the inactive state, so no need to worry about that. // motion after moving out of the inactive state, so no need to worry about that. if (mState != STATE_ACTIVE) { if (mState != STATE_ACTIVE) { scheduleReportActiveLocked("motion", Process.myUid()); scheduleReportActiveLocked(type, Process.myUid()); mState = STATE_ACTIVE; mState = STATE_ACTIVE; mInactiveTimeout = mConstants.MOTION_INACTIVE_TIMEOUT; mInactiveTimeout = timeout; EventLogTags.writeDeviceIdle(mState, "motion"); EventLogTags.writeDeviceIdle(mState, type); becomeInactiveIfAppropriateLocked(); becomeInactiveIfAppropriateLocked(); } } } } void receivedGenericLocationLocked(Location location) { if (mState != STATE_LOCATING) { cancelLocatingLocked(); return; } if (DEBUG) Slog.d(TAG, "Generic location: " + location); mLastGenericLocation = new Location(location); if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHaveGps) { return; } mLocated = true; if (mNotMoving) { stepIdleStateLocked(); } } void receivedGpsLocationLocked(Location location) { if (mState != STATE_LOCATING) { cancelLocatingLocked(); return; } if (DEBUG) Slog.d(TAG, "GPS location: " + location); mLastGpsLocation = new Location(location); if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) { return; } mLocated = true; if (mNotMoving) { stepIdleStateLocked(); } } void startMonitoringSignificantMotion() { void startMonitoringSignificantMotion() { if (DEBUG) Slog.d(TAG, "startMonitoringSignificantMotion()"); if (DEBUG) Slog.d(TAG, "startMonitoringSignificantMotion()"); if (mSigMotionSensor != null && !mSigMotionActive) { if (mSigMotionSensor != null && !mSigMotionActive) { Loading @@ -1229,8 +1395,19 @@ public class DeviceIdleController extends SystemService } } void cancelSensingAlarmLocked() { void cancelSensingAlarmLocked() { if (mSensing) { if (DEBUG) Slog.d(TAG, "cancelSensingAlarmLocked()"); if (DEBUG) Slog.d(TAG, "cancelSensingAlarmLocked()"); mAlarmManager.cancel(mSensingAlarmIntent); mAlarmManager.cancel(mSensingAlarmIntent); mSensing = false; } } void cancelLocatingLocked() { if (mLocating) { mLocationManager.removeUpdates(mGenericLocationListener); mLocationManager.removeUpdates(mGpsLocationListener); mLocating = false; } } } void scheduleAlarmLocked(long delay, boolean idleUntil) { void scheduleAlarmLocked(long delay, boolean idleUntil) { Loading @@ -1254,9 +1431,11 @@ public class DeviceIdleController extends SystemService void scheduleSensingAlarmLocked(long delay) { void scheduleSensingAlarmLocked(long delay) { if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); cancelSensingAlarmLocked(); mNextAlarmTime = SystemClock.elapsedRealtime() + delay; mNextAlarmTime = SystemClock.elapsedRealtime() + delay; mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextAlarmTime, mSensingAlarmIntent); mNextAlarmTime, mSensingAlarmIntent); mSensing = true; } } private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, Loading Loading @@ -1721,6 +1900,16 @@ public class DeviceIdleController extends SystemService pw.print(" mScreenOn="); pw.println(mScreenOn); pw.print(" mScreenOn="); pw.println(mScreenOn); pw.print(" mCharging="); pw.println(mCharging); pw.print(" mCharging="); pw.println(mCharging); pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); pw.print(" mSensing="); pw.print(mSensing); pw.print(" mNotMoving="); pw.println(mNotMoving); pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHaveGps="); pw.print(mHaveGps); pw.print(" mLocated="); pw.println(mLocated); if (mLastGenericLocation != null) { pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation); } if (mLastGpsLocation != null) { pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation); } pw.print(" mState="); pw.println(stateToString(mState)); pw.print(" mState="); pw.println(stateToString(mState)); pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); pw.println(); pw.println(); Loading Loading
services/core/java/com/android/server/AnyMotionDetector.java +19 −14 Original line number Original line Diff line number Diff line Loading @@ -16,9 +16,6 @@ package com.android.server; package com.android.server; import android.app.AlarmManager; import android.content.BroadcastReceiver; import android.content.Intent; import android.hardware.Sensor; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorEventListener; Loading Loading @@ -85,17 +82,12 @@ public class AnyMotionDetector { /** The accelerometer sampling interval. */ /** The accelerometer sampling interval. */ private static final int SAMPLING_INTERVAL_MILLIS = 40; private static final int SAMPLING_INTERVAL_MILLIS = 40; private AlarmManager mAlarmManager; private final Handler mHandler; private final Handler mHandler; private Intent mAlarmIntent; private final Object mLock = new Object(); private final Object mLock = new Object(); private Sensor mAccelSensor; private Sensor mAccelSensor; private SensorManager mSensorManager; private SensorManager mSensorManager; private PowerManager.WakeLock mWakeLock; private PowerManager.WakeLock mWakeLock; /** The time when detection was last performed. */ private long mDetectionStartTime; /** The minimum number of samples required to detect AnyMotion. */ /** The minimum number of samples required to detect AnyMotion. */ private int mNumSufficientSamples; private int mNumSufficientSamples; Loading @@ -113,11 +105,11 @@ public class AnyMotionDetector { private DeviceIdleCallback mCallback = null; private DeviceIdleCallback mCallback = null; public AnyMotionDetector(AlarmManager am, PowerManager pm, Handler handler, SensorManager sm, public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm, DeviceIdleCallback callback) { DeviceIdleCallback callback) { if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated."); if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated."); mAlarmManager = am; mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.setReferenceCounted(false); mHandler = handler; mHandler = handler; mSensorManager = sm; mSensorManager = sm; mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); Loading @@ -144,6 +136,22 @@ public class AnyMotionDetector { } } } } 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() { private void startOrientationMeasurement() { if (DEBUG) Slog.d(TAG, "startOrientationMeasurement: mMeasurementInProgress=" + if (DEBUG) Slog.d(TAG, "startOrientationMeasurement: mMeasurementInProgress=" + mMeasurementInProgress + ", (mAccelSensor != null)=" + (mAccelSensor != null)); mMeasurementInProgress + ", (mAccelSensor != null)=" + (mAccelSensor != null)); Loading @@ -153,7 +161,6 @@ public class AnyMotionDetector { SAMPLING_INTERVAL_MILLIS * 1000)) { SAMPLING_INTERVAL_MILLIS * 1000)) { mWakeLock.acquire(); mWakeLock.acquire(); mMeasurementInProgress = true; mMeasurementInProgress = true; mDetectionStartTime = SystemClock.elapsedRealtime(); mRunningStats.reset(); mRunningStats.reset(); } } Loading @@ -170,9 +177,7 @@ public class AnyMotionDetector { if (mMeasurementInProgress) { if (mMeasurementInProgress) { mSensorManager.unregisterListener(mListener); mSensorManager.unregisterListener(mListener); mHandler.removeCallbacks(mMeasurementTimeout); mHandler.removeCallbacks(mMeasurementTimeout); if (mWakeLock.isHeld()) { mWakeLock.release(); mWakeLock.release(); } long detectionEndTime = SystemClock.elapsedRealtime(); long detectionEndTime = SystemClock.elapsedRealtime(); mMeasurementInProgress = false; mMeasurementInProgress = false; mPreviousGravityVector = mCurrentGravityVector; mPreviousGravityVector = mCurrentGravityVector; Loading
services/core/java/com/android/server/DeviceIdleController.java +225 −36 Original line number Original line Diff line number Diff line Loading @@ -34,10 +34,15 @@ import android.hardware.SensorManager; import android.hardware.TriggerEvent; import android.hardware.TriggerEvent; import android.hardware.TriggerEventListener; import android.hardware.TriggerEventListener; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager; import android.location.LocationRequest; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.net.INetworkPolicyManager; import android.net.INetworkPolicyManager; import android.net.Uri; import android.net.Uri; import android.os.BatteryStats; import android.os.BatteryStats; import android.os.Binder; import android.os.Binder; import android.os.Bundle; import android.os.Environment; import android.os.Environment; import android.os.FileUtils; import android.os.FileUtils; import android.os.Handler; import android.os.Handler; Loading Loading @@ -107,6 +112,8 @@ public class DeviceIdleController extends SystemService private DisplayManager mDisplayManager; private DisplayManager mDisplayManager; private SensorManager mSensorManager; private SensorManager mSensorManager; private Sensor mSigMotionSensor; private Sensor mSigMotionSensor; private LocationManager mLocationManager; private LocationRequest mLocationRequest; private PendingIntent mSensingAlarmIntent; private PendingIntent mSensingAlarmIntent; private PendingIntent mAlarmIntent; private PendingIntent mAlarmIntent; private Intent mIdleIntent; private Intent mIdleIntent; Loading @@ -117,6 +124,13 @@ public class DeviceIdleController extends SystemService private boolean mScreenOn; private boolean mScreenOn; private boolean mCharging; private boolean mCharging; private boolean mSigMotionActive; private boolean mSigMotionActive; private boolean mSensing; private boolean mNotMoving; private boolean mLocating; private boolean mLocated; private boolean mHaveGps; private Location mLastGenericLocation; private Location mLastGpsLocation; /** Device is currently active. */ /** Device is currently active. */ private static final int STATE_ACTIVE = 0; private static final int STATE_ACTIVE = 0; Loading @@ -126,16 +140,19 @@ public class DeviceIdleController extends SystemService private static final int STATE_IDLE_PENDING = 2; private static final int STATE_IDLE_PENDING = 2; /** Device is currently sensing motion. */ /** Device is currently sensing motion. */ private static final int STATE_SENSING = 3; private static final int STATE_SENSING = 3; /** Device is currently finding location (and may still be sensing). */ private static final int STATE_LOCATING = 4; /** Device is in the idle state, trying to stay asleep as much as possible. */ /** Device is in the idle state, trying to stay asleep as much as possible. */ private static final int STATE_IDLE = 4; private static final int STATE_IDLE = 5; /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ private static final int STATE_IDLE_MAINTENANCE = 5; private static final int STATE_IDLE_MAINTENANCE = 6; private static String stateToString(int state) { private static String stateToString(int state) { switch (state) { switch (state) { case STATE_ACTIVE: return "ACTIVE"; case STATE_ACTIVE: return "ACTIVE"; case STATE_INACTIVE: return "INACTIVE"; case STATE_INACTIVE: return "INACTIVE"; case STATE_IDLE_PENDING: return "IDLE_PENDING"; case STATE_IDLE_PENDING: return "IDLE_PENDING"; case STATE_SENSING: return "SENSING"; case STATE_SENSING: return "SENSING"; case STATE_LOCATING: return "LOCATING"; case STATE_IDLE: return "IDLE"; case STATE_IDLE: return "IDLE"; case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; default: return Integer.toString(state); default: return Integer.toString(state); Loading Loading @@ -258,6 +275,48 @@ public class DeviceIdleController extends SystemService } } }; }; private final LocationListener mGenericLocationListener = new LocationListener() { @Override public void onLocationChanged(Location location) { synchronized (DeviceIdleController.this) { receivedGenericLocationLocked(location); } } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } }; private final LocationListener mGpsLocationListener = new LocationListener() { @Override public void onLocationChanged(Location location) { synchronized (DeviceIdleController.this) { receivedGpsLocationLocked(location); } } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } }; /** /** * All times are in milliseconds. These constants are kept synchronized with the system * All times are in milliseconds. These constants are kept synchronized with the system * global Settings. Any access to this class or its fields should be done while * global Settings. Any access to this class or its fields should be done while Loading @@ -267,6 +326,8 @@ public class DeviceIdleController extends SystemService // Key names stored in the settings value. // Key names stored in the settings value. private static final String KEY_INACTIVE_TIMEOUT = "inactive_to"; private static final String KEY_INACTIVE_TIMEOUT = "inactive_to"; private static final String KEY_SENSING_TIMEOUT = "sensing_to"; private static final String KEY_SENSING_TIMEOUT = "sensing_to"; private static final String KEY_LOCATING_TIMEOUT = "locating_to"; private static final String KEY_LOCATION_ACCURACY = "location_accuracy"; private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to"; private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to"; private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to"; private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to"; private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to"; private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to"; Loading Loading @@ -294,7 +355,8 @@ public class DeviceIdleController extends SystemService public long INACTIVE_TIMEOUT; public long INACTIVE_TIMEOUT; /** /** * If we don't receive a callback from AnyMotion in this amount of time, we will change from * If we don't receive a callback from AnyMotion in this amount of time + * {@link #LOCATING_TIMEOUT}, we will change from * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING * will be ignored. * will be ignored. * @see Settings.Global#DEVICE_IDLE_CONSTANTS * @see Settings.Global#DEVICE_IDLE_CONSTANTS Loading @@ -302,6 +364,23 @@ public class DeviceIdleController extends SystemService */ */ public long SENSING_TIMEOUT; public long SENSING_TIMEOUT; /** * This is how long we will wait to try to get a good location fix before going in to * idle mode. * @see Settings.Global#DEVICE_IDLE_CONSTANTS * @see #KEY_LOCATING_TIMEOUT */ public long LOCATING_TIMEOUT; /** * The desired maximum accuracy (in meters) we consider the location to be good enough to go * on to idle. We will be trying to get an accuracy fix at least this good or until * {@link #LOCATING_TIMEOUT} expires. * @see Settings.Global#DEVICE_IDLE_CONSTANTS * @see #KEY_LOCATION_ACCURACY */ public float LOCATION_ACCURACY; /** /** * This is the time, after seeing motion, that we wait after becoming inactive from * This is the time, after seeing motion, that we wait after becoming inactive from * that until we start looking for motion again. * that until we start looking for motion again. Loading Loading @@ -423,7 +502,10 @@ public class DeviceIdleController extends SystemService INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT, INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT, !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L); !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L); SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT, SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT, !DEBUG ? 5 * 60 * 1000L : 60 * 1000L); !DEBUG ? 4 * 60 * 1000L : 60 * 1000L); LOCATING_TIMEOUT = mParser.getLong(KEY_LOCATING_TIMEOUT, !DEBUG ? 30 * 1000L : 15 * 1000L); LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20); MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT, MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT, !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT, IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT, Loading Loading @@ -462,6 +544,14 @@ public class DeviceIdleController extends SystemService TimeUtils.formatDuration(SENSING_TIMEOUT, pw); TimeUtils.formatDuration(SENSING_TIMEOUT, pw); pw.println(); pw.println(); pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("="); TimeUtils.formatDuration(LOCATING_TIMEOUT, pw); pw.println(); pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("="); pw.print(LOCATION_ACCURACY); pw.print("m"); pw.println(); pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("="); pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("="); TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw); TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw); pw.println(); pw.println(); Loading Loading @@ -515,17 +605,27 @@ public class DeviceIdleController extends SystemService @Override @Override public void onAnyMotionResult(int result) { public void onAnyMotionResult(int result) { if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")"); if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")"); if (mState == STATE_SENSING) { if (result == AnyMotionDetector.RESULT_MOVED) { if (result == AnyMotionDetector.RESULT_STATIONARY) { if (DEBUG) Slog.d(TAG, "RESULT_MOVED received."); synchronized (this) { handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion"); } } else if (result == AnyMotionDetector.RESULT_STATIONARY) { if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received."); if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received."); if (mState == STATE_SENSING) { // If we are currently sensing, it is time to move to locating. synchronized (this) { synchronized (this) { mNotMoving = true; stepIdleStateLocked(); stepIdleStateLocked(); } } } else if (result == AnyMotionDetector.RESULT_MOVED) { } else if (mState == STATE_LOCATING) { if (DEBUG) Slog.d(TAG, "RESULT_MOVED received."); // If we are currently locating, note that we are not moving and step // if we have located the position. synchronized (this) { synchronized (this) { EventLogTags.writeDeviceIdle(mState, "sense_moved"); mNotMoving = true; enterInactiveStateLocked(); if (mLocated) { stepIdleStateLocked(); } } } } } } } Loading Loading @@ -783,8 +883,14 @@ public class DeviceIdleController extends SystemService Context.DISPLAY_SERVICE); Context.DISPLAY_SERVICE); mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); mSigMotionSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION); mSigMotionSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION); mLocationManager = (LocationManager) getContext().getSystemService( Context.LOCATION_SERVICE); mLocationRequest = new LocationRequest() .setQuality(LocationRequest.ACCURACY_FINE) .setInterval(0) .setFastestInterval(0) .setNumUpdates(1); mAnyMotionDetector = new AnyMotionDetector( mAnyMotionDetector = new AnyMotionDetector( mAlarmManager, (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), mHandler, mSensorManager, this); mHandler, mSensorManager, this); Loading Loading @@ -1049,7 +1155,7 @@ public class DeviceIdleController extends SystemService // We consider any situation where the display is showing something to be it on, // We consider any situation where the display is showing something to be it on, // because if there is anything shown we are going to be updating it at some // because if there is anything shown we are going to be updating it at some // frequency so can't be allowed to go into deep sleeps. // frequency so can't be allowed to go into deep sleeps. boolean screenOn = mCurDisplay.getState() != Display.STATE_OFF;; boolean screenOn = mCurDisplay.getState() == Display.STATE_ON; if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn); if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn); if (!screenOn && mScreenOn) { if (!screenOn && mScreenOn) { mScreenOn = false; mScreenOn = false; Loading Loading @@ -1092,10 +1198,7 @@ public class DeviceIdleController extends SystemService scheduleReportActiveLocked(activeReason, activeUid); scheduleReportActiveLocked(activeReason, activeUid); mState = STATE_ACTIVE; mState = STATE_ACTIVE; mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; mNextIdlePendingDelay = 0; resetIdleManagementLocked(); mNextIdleDelay = 0; cancelAlarmLocked(); stopMonitoringSignificantMotion(); } } } } Loading @@ -1106,20 +1209,20 @@ public class DeviceIdleController extends SystemService // waiting to see if we will ultimately go idle. // waiting to see if we will ultimately go idle. mState = STATE_INACTIVE; mState = STATE_INACTIVE; if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE"); if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE"); mNextIdlePendingDelay = 0; resetIdleManagementLocked(); mNextIdleDelay = 0; scheduleAlarmLocked(mInactiveTimeout, false); scheduleAlarmLocked(mInactiveTimeout, false); EventLogTags.writeDeviceIdle(mState, "no activity"); EventLogTags.writeDeviceIdle(mState, "no activity"); } } } } /** void resetIdleManagementLocked() { * This is called when we've failed to receive a callback from AnyMotionDetector mNextIdlePendingDelay = 0; * within the DEFAULT_SENSING_TIMEOUT, to return to STATE_INACTIVE. mNextIdleDelay = 0; */ cancelAlarmLocked(); void enterInactiveStateLocked() { cancelSensingAlarmLocked(); mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; cancelLocatingLocked(); becomeInactiveIfAppropriateLocked(); stopMonitoringSignificantMotion(); mAnyMotionDetector.stop(); } } void exitForceIdleLocked() { void exitForceIdleLocked() { Loading Loading @@ -1160,11 +1263,37 @@ public class DeviceIdleController extends SystemService case STATE_IDLE_PENDING: case STATE_IDLE_PENDING: mState = STATE_SENSING; mState = STATE_SENSING; if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING."); if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING."); EventLogTags.writeDeviceIdle(mState, "step"); scheduleSensingAlarmLocked(mConstants.SENSING_TIMEOUT); scheduleSensingAlarmLocked(mConstants.SENSING_TIMEOUT); cancelSensingAlarmLocked(); cancelLocatingLocked(); mAnyMotionDetector.checkForAnyMotion(); mAnyMotionDetector.checkForAnyMotion(); mNotMoving = false; mLocated = false; mLastGenericLocation = null; mLastGpsLocation = null; break; break; case STATE_SENSING: case STATE_SENSING: mState = STATE_LOCATING; if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING."); EventLogTags.writeDeviceIdle(mState, "step"); cancelSensingAlarmLocked(); cancelSensingAlarmLocked(); scheduleSensingAlarmLocked(mConstants.LOCATING_TIMEOUT); mLocating = true; mLocationManager.requestLocationUpdates(mLocationRequest, mGenericLocationListener, mHandler.getLooper()); if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { mHaveGps = true; mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, mGpsLocationListener, mHandler.getLooper()); } else { mHaveGps = false; } break; case STATE_LOCATING: cancelSensingAlarmLocked(); cancelLocatingLocked(); mAnyMotionDetector.stop(); case STATE_IDLE_MAINTENANCE: case STATE_IDLE_MAINTENANCE: scheduleAlarmLocked(mNextIdleDelay, true); scheduleAlarmLocked(mNextIdleDelay, true); if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay + if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay + Loading @@ -1173,6 +1302,7 @@ public class DeviceIdleController extends SystemService if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay); if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay); mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT); mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT); mState = STATE_IDLE; mState = STATE_IDLE; EventLogTags.writeDeviceIdle(mState, "step"); mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); break; break; case STATE_IDLE: case STATE_IDLE: Loading @@ -1193,18 +1323,54 @@ public class DeviceIdleController extends SystemService if (DEBUG) Slog.d(TAG, "significantMotionLocked()"); if (DEBUG) Slog.d(TAG, "significantMotionLocked()"); // When the sensor goes off, its trigger is automatically removed. // When the sensor goes off, its trigger is automatically removed. mSigMotionActive = false; mSigMotionActive = false; handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion"); } void handleMotionDetectedLocked(long timeout, String type) { // The device is not yet active, so we want to go back to the pending idle // The device is not yet active, so we want to go back to the pending idle // state to wait again for no motion. Note that we only monitor for significant // state to wait again for no motion. Note that we only monitor for significant // motion after moving out of the inactive state, so no need to worry about that. // motion after moving out of the inactive state, so no need to worry about that. if (mState != STATE_ACTIVE) { if (mState != STATE_ACTIVE) { scheduleReportActiveLocked("motion", Process.myUid()); scheduleReportActiveLocked(type, Process.myUid()); mState = STATE_ACTIVE; mState = STATE_ACTIVE; mInactiveTimeout = mConstants.MOTION_INACTIVE_TIMEOUT; mInactiveTimeout = timeout; EventLogTags.writeDeviceIdle(mState, "motion"); EventLogTags.writeDeviceIdle(mState, type); becomeInactiveIfAppropriateLocked(); becomeInactiveIfAppropriateLocked(); } } } } void receivedGenericLocationLocked(Location location) { if (mState != STATE_LOCATING) { cancelLocatingLocked(); return; } if (DEBUG) Slog.d(TAG, "Generic location: " + location); mLastGenericLocation = new Location(location); if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHaveGps) { return; } mLocated = true; if (mNotMoving) { stepIdleStateLocked(); } } void receivedGpsLocationLocked(Location location) { if (mState != STATE_LOCATING) { cancelLocatingLocked(); return; } if (DEBUG) Slog.d(TAG, "GPS location: " + location); mLastGpsLocation = new Location(location); if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) { return; } mLocated = true; if (mNotMoving) { stepIdleStateLocked(); } } void startMonitoringSignificantMotion() { void startMonitoringSignificantMotion() { if (DEBUG) Slog.d(TAG, "startMonitoringSignificantMotion()"); if (DEBUG) Slog.d(TAG, "startMonitoringSignificantMotion()"); if (mSigMotionSensor != null && !mSigMotionActive) { if (mSigMotionSensor != null && !mSigMotionActive) { Loading @@ -1229,8 +1395,19 @@ public class DeviceIdleController extends SystemService } } void cancelSensingAlarmLocked() { void cancelSensingAlarmLocked() { if (mSensing) { if (DEBUG) Slog.d(TAG, "cancelSensingAlarmLocked()"); if (DEBUG) Slog.d(TAG, "cancelSensingAlarmLocked()"); mAlarmManager.cancel(mSensingAlarmIntent); mAlarmManager.cancel(mSensingAlarmIntent); mSensing = false; } } void cancelLocatingLocked() { if (mLocating) { mLocationManager.removeUpdates(mGenericLocationListener); mLocationManager.removeUpdates(mGpsLocationListener); mLocating = false; } } } void scheduleAlarmLocked(long delay, boolean idleUntil) { void scheduleAlarmLocked(long delay, boolean idleUntil) { Loading @@ -1254,9 +1431,11 @@ public class DeviceIdleController extends SystemService void scheduleSensingAlarmLocked(long delay) { void scheduleSensingAlarmLocked(long delay) { if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); cancelSensingAlarmLocked(); mNextAlarmTime = SystemClock.elapsedRealtime() + delay; mNextAlarmTime = SystemClock.elapsedRealtime() + delay; mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextAlarmTime, mSensingAlarmIntent); mNextAlarmTime, mSensingAlarmIntent); mSensing = true; } } private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, Loading Loading @@ -1721,6 +1900,16 @@ public class DeviceIdleController extends SystemService pw.print(" mScreenOn="); pw.println(mScreenOn); pw.print(" mScreenOn="); pw.println(mScreenOn); pw.print(" mCharging="); pw.println(mCharging); pw.print(" mCharging="); pw.println(mCharging); pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); pw.print(" mSensing="); pw.print(mSensing); pw.print(" mNotMoving="); pw.println(mNotMoving); pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHaveGps="); pw.print(mHaveGps); pw.print(" mLocated="); pw.println(mLocated); if (mLastGenericLocation != null) { pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation); } if (mLastGpsLocation != null) { pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation); } pw.print(" mState="); pw.println(stateToString(mState)); pw.print(" mState="); pw.println(stateToString(mState)); pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); pw.println(); pw.println(); Loading