diff options
author | Joe LaPenna <jlapenna@google.com> | 2015-08-27 15:12:11 -0700 |
---|---|---|
committer | Joe LaPenna <jlapenna@google.com> | 2015-09-02 11:37:48 -0700 |
commit | 23d681bb90a4c70d47da895c883b1fdc0854d49a (patch) | |
tree | 153026285b38054f7afa8675cb897fd35d7a7a9c | |
parent | 38ae119688f94d68c42d8d29958038e37bb74915 (diff) | |
download | frameworks_base-23d681bb90a4c70d47da895c883b1fdc0854d49a.zip frameworks_base-23d681bb90a4c70d47da895c883b1fdc0854d49a.tar.gz frameworks_base-23d681bb90a4c70d47da895c883b1fdc0854d49a.tar.bz2 |
Device Idle: Android wear support
- Provide config param: autoPowerModeThresholdAngle allowing us to
adjust the tilt threshold on a per-device basis.
- Provide config param: autoPowerModePrefetchLocation allowing us to
skip location prefectching on a per-device basis.
- Provide config param: autoPowerModeAnyMotionSensor allowing us to
use a device-specific sensor on to detect additional types of movement
that would trigger exiting device idle.
- PRovide config param: autoPowerModePreferWristTilt allows us to use
the wrist tilt detector in lieu of the SMD if an anymotion sensor
isn't specified.
- Allow DeviceIdleController to use wrist tilt sensors if the device provides
one.
- Use wrist tilt or SMD when an "any motion" sensor isn't available.
- Fix bugs where DeviceIdleController would crash on devices that did
not have a location and/or gps provider (some android wear devices).
BUG: 22661021
Change-Id: Ib9f7cdf8f16483ba8f466b7b5c97bdf0494ba228
-rwxr-xr-x | core/res/res/values/config.xml | 15 | ||||
-rwxr-xr-x | core/res/res/values/symbols.xml | 4 | ||||
-rw-r--r-- | services/core/java/com/android/server/AnyMotionDetector.java | 14 | ||||
-rw-r--r-- | services/core/java/com/android/server/DeviceIdleController.java | 79 |
4 files changed, 84 insertions, 28 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 694d263..77d79ad 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -166,6 +166,21 @@ so that applications can still use their own mechanisms. --> <bool name="config_enableAutoPowerModes">false</bool> + <!-- The threshold angle for any motion detection in auto-power save modes. + In hundreths of a degree. --> + <integer name="config_autoPowerModeThresholdAngle">200</integer> + + <!-- The sensor id of an "any motion" sensor used in auto-power save modes. + 0 indicates this sensor is not available. --> + <integer name="config_autoPowerModeAnyMotionSensor">0</integer> + + <!-- If an any motion sensor is not available, prefer the wrist tilt detector over the + SMD. --> + <bool name="config_autoPowerModePreferWristTilt">false</bool> + + <!-- If a location should be pre-fetched when going into device idle. --> + <bool name="config_autoPowerModePrefetchLocation">true</bool> + <!-- The duration (in milliseconds) that the radio will scan for a signal when there's no network connection. If the scan doesn't timeout, use zero --> <integer name="config_radioScanningTimeout">0</integer> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 4e94a64..35443fe 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -253,6 +253,10 @@ <java-symbol type="bool" name="config_cellBroadcastAppLinks" /> <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" /> <java-symbol type="bool" name="config_enableAutoPowerModes" /> + <java-symbol type="integer" name="config_autoPowerModeThresholdAngle" /> + <java-symbol type="integer" name="config_autoPowerModeAnyMotionSensor" /> + <java-symbol type="bool" name="config_autoPowerModePreferWristTilt" /> + <java-symbol type="bool" name="config_autoPowerModePrefetchLocation" /> <java-symbol type="bool" name="config_enable_emergency_call_while_sim_locked" /> <java-symbol type="bool" name="config_enable_puk_unlock_screen" /> <java-symbol type="bool" name="config_enableBurnInProtection" /> diff --git a/services/core/java/com/android/server/AnyMotionDetector.java b/services/core/java/com/android/server/AnyMotionDetector.java index 6a67316..a0b5c15 100644 --- a/services/core/java/com/android/server/AnyMotionDetector.java +++ b/services/core/java/com/android/server/AnyMotionDetector.java @@ -58,9 +58,6 @@ public class AnyMotionDetector { /** Current measurement state. */ private int mState; - /** Threshold angle in degrees beyond which the device is considered moving. */ - private final float THRESHOLD_ANGLE = 2f; - /** Threshold energy above which the device is considered moving. */ private final float THRESHOLD_ENERGY = 5f; @@ -88,6 +85,9 @@ public class AnyMotionDetector { private SensorManager mSensorManager; private PowerManager.WakeLock mWakeLock; + /** Threshold angle in degrees beyond which the device is considered moving. */ + private final float mThresholdAngle; + /** The minimum number of samples required to detect AnyMotion. */ private int mNumSufficientSamples; @@ -106,7 +106,7 @@ public class AnyMotionDetector { private DeviceIdleCallback mCallback = null; public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm, - DeviceIdleCallback callback) { + DeviceIdleCallback callback, float thresholdAngle) { if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated."); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.setReferenceCounted(false); @@ -116,6 +116,7 @@ public class AnyMotionDetector { mMeasurementInProgress = false; mState = STATE_INACTIVE; mCallback = callback; + mThresholdAngle = thresholdAngle; mRunningStats = new RunningSignalStats(); mNumSufficientSamples = (int) Math.ceil( ((double)ORIENTATION_MEASUREMENT_DURATION_MILLIS / SAMPLING_INTERVAL_MILLIS)); @@ -224,8 +225,9 @@ public class AnyMotionDetector { Vector3 previousGravityVectorNormalized = mPreviousGravityVector.normalized(); Vector3 currentGravityVectorNormalized = mCurrentGravityVector.normalized(); float angle = previousGravityVectorNormalized.angleBetween(currentGravityVectorNormalized); - if (DEBUG) Slog.d(TAG, "getStationaryStatus: angle = " + angle); - if ((angle < THRESHOLD_ANGLE) && (mRunningStats.getEnergy() < THRESHOLD_ENERGY)) { + if (DEBUG) Slog.d(TAG, "getStationaryStatus: angle = " + angle + + " energy = " + mRunningStats.getEnergy()); + if ((angle < mThresholdAngle) && (mRunningStats.getEnergy() < THRESHOLD_ENERGY)) { return RESULT_STATIONARY; } else if (Float.isNaN(angle)) { /** diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index 80fd441..46fd28a 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -128,7 +128,8 @@ public class DeviceIdleController extends SystemService private boolean mNotMoving; private boolean mLocating; private boolean mLocated; - private boolean mHaveGps; + private boolean mHasGps; + private boolean mHasNetworkLocation; private Location mLastGenericLocation; private Location mLastGpsLocation; @@ -882,17 +883,37 @@ public class DeviceIdleController extends SystemService mDisplayManager = (DisplayManager) getContext().getSystemService( Context.DISPLAY_SERVICE); mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); - 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); + int sigMotionSensorId = getContext().getResources().getInteger( + com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor); + if (sigMotionSensorId > 0) { + mSigMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true); + } + if (mSigMotionSensor == null && getContext().getResources().getBoolean( + com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) { + mSigMotionSensor = mSensorManager.getDefaultSensor( + Sensor.TYPE_WRIST_TILT_GESTURE); + } + if (mSigMotionSensor == null) { + // As a last ditch, fall back to SMD. + mSigMotionSensor = mSensorManager.getDefaultSensor( + Sensor.TYPE_SIGNIFICANT_MOTION); + } + if (getContext().getResources().getBoolean( + com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) { + mLocationManager = (LocationManager) getContext().getSystemService( + Context.LOCATION_SERVICE); + mLocationRequest = new LocationRequest() + .setQuality(LocationRequest.ACCURACY_FINE) + .setInterval(0) + .setFastestInterval(0) + .setNumUpdates(1); + } + + float angleThreshold = getContext().getResources().getInteger( + com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f; mAnyMotionDetector = new AnyMotionDetector( (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), - mHandler, mSensorManager, this); + mHandler, mSensorManager, this, angleThreshold); Intent intent = new Intent(ACTION_STEP_IDLE_STATE) .setPackage("android") @@ -1279,17 +1300,30 @@ public class DeviceIdleController extends SystemService EventLogTags.writeDeviceIdle(mState, "step"); cancelSensingAlarmLocked(); scheduleSensingAlarmLocked(mConstants.LOCATING_TIMEOUT); - mLocating = true; - mLocationManager.requestLocationUpdates(mLocationRequest, mGenericLocationListener, - mHandler.getLooper()); - if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { - mHaveGps = true; + if (mLocationManager != null + && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) { + mLocationManager.requestLocationUpdates(mLocationRequest, + mGenericLocationListener, mHandler.getLooper()); + mLocating = true; + } else { + mHasNetworkLocation = false; + } + if (mLocationManager != null + && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { + mHasGps = true; mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, mGpsLocationListener, mHandler.getLooper()); + mLocating = true; } else { - mHaveGps = false; + mHasGps = false; } - break; + // If we have a location provider, we're all set, the listeners will move state + // forward. + if (mLocating) { + break; + } + + // Otherwise, we have to move from locating into idle maintenance. case STATE_LOCATING: cancelSensingAlarmLocked(); cancelLocatingLocked(); @@ -1346,7 +1380,7 @@ public class DeviceIdleController extends SystemService } if (DEBUG) Slog.d(TAG, "Generic location: " + location); mLastGenericLocation = new Location(location); - if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHaveGps) { + if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) { return; } mLocated = true; @@ -1413,9 +1447,9 @@ public class DeviceIdleController extends SystemService void scheduleAlarmLocked(long delay, boolean idleUntil) { if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")"); if (mSigMotionSensor == null) { - // If there is no significant motion sensor on this device, then we won't schedule + // If there is no motion sensor on this device, then we won't schedule // alarms, because we can't determine if the device is not moving. This effectively - // turns off normal exeuction of device idling, although it is still possible to + // turns off normal execution of device idling, although it is still possible to // manually poke it by pretending like the alarm is going off. return; } @@ -1902,8 +1936,9 @@ public class DeviceIdleController extends SystemService 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); + pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps="); + pw.print(mHasGps); pw.print(" mHasNetwork="); + pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated); if (mLastGenericLocation != null) { pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation); } |