Loading services/java/com/android/server/power/PowerManagerService.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -453,7 +453,8 @@ public final class PowerManagerService extends IPowerManager.Stub mDisplayPowerControllerCallbacks, mHandler); mDisplayPowerControllerCallbacks, mHandler); mWirelessChargerDetector = new WirelessChargerDetector(sensorManager, mWirelessChargerDetector = new WirelessChargerDetector(sensorManager, createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector")); createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"), mHandler); mSettingsObserver = new SettingsObserver(mHandler); mSettingsObserver = new SettingsObserver(mHandler); mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION); mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION); Loading services/java/com/android/server/power/WirelessChargerDetector.java +69 −48 Original line number Original line Diff line number Diff line Loading @@ -21,8 +21,11 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.SensorManager; import android.os.BatteryManager; import android.os.BatteryManager; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.os.SystemClock; import android.util.Slog; import android.util.Slog; import android.util.TimeUtils; import java.io.PrintWriter; import java.io.PrintWriter; Loading Loading @@ -70,12 +73,12 @@ final class WirelessChargerDetector { private static final String TAG = "WirelessChargerDetector"; private static final String TAG = "WirelessChargerDetector"; private static final boolean DEBUG = false; private static final boolean DEBUG = false; // Number of nanoseconds per millisecond. private static final long NANOS_PER_MS = 1000000; // The minimum amount of time to spend watching the sensor before making // The minimum amount of time to spend watching the sensor before making // a determination of whether movement occurred. // a determination of whether movement occurred. private static final long SETTLE_TIME_NANOS = 500 * NANOS_PER_MS; private static final long SETTLE_TIME_MILLIS = 800; // The sensor sampling interval. private static final int SAMPLING_INTERVAL_MILLIS = 50; // The minimum number of samples that must be collected. // The minimum number of samples that must be collected. private static final int MIN_SAMPLES = 3; private static final int MIN_SAMPLES = 3; Loading @@ -97,6 +100,7 @@ final class WirelessChargerDetector { private final SensorManager mSensorManager; private final SensorManager mSensorManager; private final SuspendBlocker mSuspendBlocker; private final SuspendBlocker mSuspendBlocker; private final Handler mHandler; // The gravity sensor, or null if none. // The gravity sensor, or null if none. private Sensor mGravitySensor; private Sensor mGravitySensor; Loading @@ -116,6 +120,9 @@ final class WirelessChargerDetector { // The suspend blocker is held while this is the case. // The suspend blocker is held while this is the case. private boolean mDetectionInProgress; private boolean mDetectionInProgress; // The time when detection was last performed. private long mDetectionStartTime; // True if the rest position should be updated if at rest. // True if the rest position should be updated if at rest. // Otherwise, the current rest position is simply checked and cleared if movement // Otherwise, the current rest position is simply checked and cleared if movement // is detected but no new rest position is stored. // is detected but no new rest position is stored. Loading @@ -127,18 +134,17 @@ final class WirelessChargerDetector { // The number of samples collected that showed evidence of not being at rest. // The number of samples collected that showed evidence of not being at rest. private int mMovingSamples; private int mMovingSamples; // The time and value of the first sample that was collected. // The value of the first sample that was collected. private long mFirstSampleTime; private float mFirstSampleX, mFirstSampleY, mFirstSampleZ; private float mFirstSampleX, mFirstSampleY, mFirstSampleZ; // The time and value of the last sample that was collected (for debugging only). // The value of the last sample that was collected. private long mLastSampleTime; private float mLastSampleX, mLastSampleY, mLastSampleZ; private float mLastSampleX, mLastSampleY, mLastSampleZ; public WirelessChargerDetector(SensorManager sensorManager, public WirelessChargerDetector(SensorManager sensorManager, SuspendBlocker suspendBlocker) { SuspendBlocker suspendBlocker, Handler handler) { mSensorManager = sensorManager; mSensorManager = sensorManager; mSuspendBlocker = suspendBlocker; mSuspendBlocker = suspendBlocker; mHandler = handler; mGravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); mGravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); } } Loading @@ -152,13 +158,13 @@ final class WirelessChargerDetector { pw.println(" mAtRest=" + mAtRest); pw.println(" mAtRest=" + mAtRest); pw.println(" mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ); pw.println(" mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ); pw.println(" mDetectionInProgress=" + mDetectionInProgress); pw.println(" mDetectionInProgress=" + mDetectionInProgress); pw.println(" mDetectionStartTime=" + (mDetectionStartTime == 0 ? "0 (never)" : TimeUtils.formatUptime(mDetectionStartTime))); pw.println(" mMustUpdateRestPosition=" + mMustUpdateRestPosition); pw.println(" mMustUpdateRestPosition=" + mMustUpdateRestPosition); pw.println(" mTotalSamples=" + mTotalSamples); pw.println(" mTotalSamples=" + mTotalSamples); pw.println(" mMovingSamples=" + mMovingSamples); pw.println(" mMovingSamples=" + mMovingSamples); pw.println(" mFirstSampleTime=" + mFirstSampleTime); pw.println(" mFirstSampleX=" + mFirstSampleX pw.println(" mFirstSampleX=" + mFirstSampleX + ", mFirstSampleY=" + mFirstSampleY + ", mFirstSampleZ=" + mFirstSampleZ); + ", mFirstSampleY=" + mFirstSampleY + ", mFirstSampleZ=" + mFirstSampleZ); pw.println(" mLastSampleTime=" + mLastSampleTime); pw.println(" mLastSampleX=" + mLastSampleX pw.println(" mLastSampleX=" + mLastSampleX + ", mLastSampleY=" + mLastSampleY + ", mLastSampleZ=" + mLastSampleZ); + ", mLastSampleY=" + mLastSampleY + ", mLastSampleZ=" + mLastSampleZ); } } Loading Loading @@ -217,22 +223,56 @@ final class WirelessChargerDetector { private void startDetectionLocked() { private void startDetectionLocked() { if (!mDetectionInProgress && mGravitySensor != null) { if (!mDetectionInProgress && mGravitySensor != null) { if (mSensorManager.registerListener(mListener, mGravitySensor, if (mSensorManager.registerListener(mListener, mGravitySensor, SensorManager.SENSOR_DELAY_UI)) { SAMPLING_INTERVAL_MILLIS * 1000)) { mSuspendBlocker.acquire(); mSuspendBlocker.acquire(); mDetectionInProgress = true; mDetectionInProgress = true; mDetectionStartTime = SystemClock.uptimeMillis(); mTotalSamples = 0; mTotalSamples = 0; mMovingSamples = 0; mMovingSamples = 0; Message msg = Message.obtain(mHandler, mSensorTimeout); msg.setAsynchronous(true); mHandler.sendMessageDelayed(msg, SETTLE_TIME_MILLIS); } } } } } } private void processSample(long timeNanos, float x, float y, float z) { private void finishDetectionLocked() { synchronized (mLock) { if (mDetectionInProgress) { if (!mDetectionInProgress) { mSensorManager.unregisterListener(mListener); return; mHandler.removeCallbacks(mSensorTimeout); if (mMustUpdateRestPosition) { clearAtRestLocked(); if (mTotalSamples < MIN_SAMPLES) { Slog.w(TAG, "Wireless charger detector is broken. Only received " + mTotalSamples + " samples from the gravity sensor but we " + "need at least " + MIN_SAMPLES + " and we expect to see " + "about " + SETTLE_TIME_MILLIS / SAMPLING_INTERVAL_MILLIS + " on average."); } else if (mMovingSamples == 0) { mAtRest = true; mRestX = mLastSampleX; mRestY = mLastSampleY; mRestZ = mLastSampleZ; } mMustUpdateRestPosition = false; } if (DEBUG) { Slog.d(TAG, "New state: mAtRest=" + mAtRest + ", mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ + ", mTotalSamples=" + mTotalSamples + ", mMovingSamples=" + mMovingSamples); } } mLastSampleTime = timeNanos; mDetectionInProgress = false; mSuspendBlocker.release(); } } private void processSampleLocked(float x, float y, float z) { if (mDetectionInProgress) { mLastSampleX = x; mLastSampleX = x; mLastSampleY = y; mLastSampleY = y; mLastSampleZ = z; mLastSampleZ = z; Loading @@ -240,7 +280,6 @@ final class WirelessChargerDetector { mTotalSamples += 1; mTotalSamples += 1; if (mTotalSamples == 1) { if (mTotalSamples == 1) { // Save information about the first sample collected. // Save information about the first sample collected. mFirstSampleTime = timeNanos; mFirstSampleX = x; mFirstSampleX = x; mFirstSampleY = y; mFirstSampleY = y; mFirstSampleZ = z; mFirstSampleZ = z; Loading @@ -260,32 +299,6 @@ final class WirelessChargerDetector { } } clearAtRestLocked(); clearAtRestLocked(); } } // Save the result when done. if (timeNanos - mFirstSampleTime >= SETTLE_TIME_NANOS && mTotalSamples >= MIN_SAMPLES) { mSensorManager.unregisterListener(mListener); if (mMustUpdateRestPosition) { if (mMovingSamples == 0) { mAtRest = true; mRestX = x; mRestY = y; mRestZ = z; } else { clearAtRestLocked(); } mMustUpdateRestPosition = false; } mDetectionInProgress = false; mSuspendBlocker.release(); if (DEBUG) { Slog.d(TAG, "New state: mAtRest=" + mAtRest + ", mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ + ", mTotalSamples=" + mTotalSamples + ", mMovingSamples=" + mMovingSamples); } } } } } } Loading Loading @@ -323,14 +336,22 @@ final class WirelessChargerDetector { private final SensorEventListener mListener = new SensorEventListener() { private final SensorEventListener mListener = new SensorEventListener() { @Override @Override public void onSensorChanged(SensorEvent event) { public void onSensorChanged(SensorEvent event) { // We use SystemClock.elapsedRealtimeNanos() instead of event.timestamp because synchronized (mLock) { // on some devices the sensor HAL may produce timestamps that are not monotonic. processSampleLocked(event.values[0], event.values[1], event.values[2]); processSample(SystemClock.elapsedRealtimeNanos(), } event.values[0], event.values[1], event.values[2]); } } @Override @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { public void onAccuracyChanged(Sensor sensor, int accuracy) { } } }; }; private final Runnable mSensorTimeout = new Runnable() { @Override public void run() { synchronized (mLock) { finishDetectionLocked(); } } }; } } Loading
services/java/com/android/server/power/PowerManagerService.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -453,7 +453,8 @@ public final class PowerManagerService extends IPowerManager.Stub mDisplayPowerControllerCallbacks, mHandler); mDisplayPowerControllerCallbacks, mHandler); mWirelessChargerDetector = new WirelessChargerDetector(sensorManager, mWirelessChargerDetector = new WirelessChargerDetector(sensorManager, createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector")); createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"), mHandler); mSettingsObserver = new SettingsObserver(mHandler); mSettingsObserver = new SettingsObserver(mHandler); mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION); mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION); Loading
services/java/com/android/server/power/WirelessChargerDetector.java +69 −48 Original line number Original line Diff line number Diff line Loading @@ -21,8 +21,11 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.SensorManager; import android.os.BatteryManager; import android.os.BatteryManager; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.os.SystemClock; import android.util.Slog; import android.util.Slog; import android.util.TimeUtils; import java.io.PrintWriter; import java.io.PrintWriter; Loading Loading @@ -70,12 +73,12 @@ final class WirelessChargerDetector { private static final String TAG = "WirelessChargerDetector"; private static final String TAG = "WirelessChargerDetector"; private static final boolean DEBUG = false; private static final boolean DEBUG = false; // Number of nanoseconds per millisecond. private static final long NANOS_PER_MS = 1000000; // The minimum amount of time to spend watching the sensor before making // The minimum amount of time to spend watching the sensor before making // a determination of whether movement occurred. // a determination of whether movement occurred. private static final long SETTLE_TIME_NANOS = 500 * NANOS_PER_MS; private static final long SETTLE_TIME_MILLIS = 800; // The sensor sampling interval. private static final int SAMPLING_INTERVAL_MILLIS = 50; // The minimum number of samples that must be collected. // The minimum number of samples that must be collected. private static final int MIN_SAMPLES = 3; private static final int MIN_SAMPLES = 3; Loading @@ -97,6 +100,7 @@ final class WirelessChargerDetector { private final SensorManager mSensorManager; private final SensorManager mSensorManager; private final SuspendBlocker mSuspendBlocker; private final SuspendBlocker mSuspendBlocker; private final Handler mHandler; // The gravity sensor, or null if none. // The gravity sensor, or null if none. private Sensor mGravitySensor; private Sensor mGravitySensor; Loading @@ -116,6 +120,9 @@ final class WirelessChargerDetector { // The suspend blocker is held while this is the case. // The suspend blocker is held while this is the case. private boolean mDetectionInProgress; private boolean mDetectionInProgress; // The time when detection was last performed. private long mDetectionStartTime; // True if the rest position should be updated if at rest. // True if the rest position should be updated if at rest. // Otherwise, the current rest position is simply checked and cleared if movement // Otherwise, the current rest position is simply checked and cleared if movement // is detected but no new rest position is stored. // is detected but no new rest position is stored. Loading @@ -127,18 +134,17 @@ final class WirelessChargerDetector { // The number of samples collected that showed evidence of not being at rest. // The number of samples collected that showed evidence of not being at rest. private int mMovingSamples; private int mMovingSamples; // The time and value of the first sample that was collected. // The value of the first sample that was collected. private long mFirstSampleTime; private float mFirstSampleX, mFirstSampleY, mFirstSampleZ; private float mFirstSampleX, mFirstSampleY, mFirstSampleZ; // The time and value of the last sample that was collected (for debugging only). // The value of the last sample that was collected. private long mLastSampleTime; private float mLastSampleX, mLastSampleY, mLastSampleZ; private float mLastSampleX, mLastSampleY, mLastSampleZ; public WirelessChargerDetector(SensorManager sensorManager, public WirelessChargerDetector(SensorManager sensorManager, SuspendBlocker suspendBlocker) { SuspendBlocker suspendBlocker, Handler handler) { mSensorManager = sensorManager; mSensorManager = sensorManager; mSuspendBlocker = suspendBlocker; mSuspendBlocker = suspendBlocker; mHandler = handler; mGravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); mGravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); } } Loading @@ -152,13 +158,13 @@ final class WirelessChargerDetector { pw.println(" mAtRest=" + mAtRest); pw.println(" mAtRest=" + mAtRest); pw.println(" mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ); pw.println(" mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ); pw.println(" mDetectionInProgress=" + mDetectionInProgress); pw.println(" mDetectionInProgress=" + mDetectionInProgress); pw.println(" mDetectionStartTime=" + (mDetectionStartTime == 0 ? "0 (never)" : TimeUtils.formatUptime(mDetectionStartTime))); pw.println(" mMustUpdateRestPosition=" + mMustUpdateRestPosition); pw.println(" mMustUpdateRestPosition=" + mMustUpdateRestPosition); pw.println(" mTotalSamples=" + mTotalSamples); pw.println(" mTotalSamples=" + mTotalSamples); pw.println(" mMovingSamples=" + mMovingSamples); pw.println(" mMovingSamples=" + mMovingSamples); pw.println(" mFirstSampleTime=" + mFirstSampleTime); pw.println(" mFirstSampleX=" + mFirstSampleX pw.println(" mFirstSampleX=" + mFirstSampleX + ", mFirstSampleY=" + mFirstSampleY + ", mFirstSampleZ=" + mFirstSampleZ); + ", mFirstSampleY=" + mFirstSampleY + ", mFirstSampleZ=" + mFirstSampleZ); pw.println(" mLastSampleTime=" + mLastSampleTime); pw.println(" mLastSampleX=" + mLastSampleX pw.println(" mLastSampleX=" + mLastSampleX + ", mLastSampleY=" + mLastSampleY + ", mLastSampleZ=" + mLastSampleZ); + ", mLastSampleY=" + mLastSampleY + ", mLastSampleZ=" + mLastSampleZ); } } Loading Loading @@ -217,22 +223,56 @@ final class WirelessChargerDetector { private void startDetectionLocked() { private void startDetectionLocked() { if (!mDetectionInProgress && mGravitySensor != null) { if (!mDetectionInProgress && mGravitySensor != null) { if (mSensorManager.registerListener(mListener, mGravitySensor, if (mSensorManager.registerListener(mListener, mGravitySensor, SensorManager.SENSOR_DELAY_UI)) { SAMPLING_INTERVAL_MILLIS * 1000)) { mSuspendBlocker.acquire(); mSuspendBlocker.acquire(); mDetectionInProgress = true; mDetectionInProgress = true; mDetectionStartTime = SystemClock.uptimeMillis(); mTotalSamples = 0; mTotalSamples = 0; mMovingSamples = 0; mMovingSamples = 0; Message msg = Message.obtain(mHandler, mSensorTimeout); msg.setAsynchronous(true); mHandler.sendMessageDelayed(msg, SETTLE_TIME_MILLIS); } } } } } } private void processSample(long timeNanos, float x, float y, float z) { private void finishDetectionLocked() { synchronized (mLock) { if (mDetectionInProgress) { if (!mDetectionInProgress) { mSensorManager.unregisterListener(mListener); return; mHandler.removeCallbacks(mSensorTimeout); if (mMustUpdateRestPosition) { clearAtRestLocked(); if (mTotalSamples < MIN_SAMPLES) { Slog.w(TAG, "Wireless charger detector is broken. Only received " + mTotalSamples + " samples from the gravity sensor but we " + "need at least " + MIN_SAMPLES + " and we expect to see " + "about " + SETTLE_TIME_MILLIS / SAMPLING_INTERVAL_MILLIS + " on average."); } else if (mMovingSamples == 0) { mAtRest = true; mRestX = mLastSampleX; mRestY = mLastSampleY; mRestZ = mLastSampleZ; } mMustUpdateRestPosition = false; } if (DEBUG) { Slog.d(TAG, "New state: mAtRest=" + mAtRest + ", mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ + ", mTotalSamples=" + mTotalSamples + ", mMovingSamples=" + mMovingSamples); } } mLastSampleTime = timeNanos; mDetectionInProgress = false; mSuspendBlocker.release(); } } private void processSampleLocked(float x, float y, float z) { if (mDetectionInProgress) { mLastSampleX = x; mLastSampleX = x; mLastSampleY = y; mLastSampleY = y; mLastSampleZ = z; mLastSampleZ = z; Loading @@ -240,7 +280,6 @@ final class WirelessChargerDetector { mTotalSamples += 1; mTotalSamples += 1; if (mTotalSamples == 1) { if (mTotalSamples == 1) { // Save information about the first sample collected. // Save information about the first sample collected. mFirstSampleTime = timeNanos; mFirstSampleX = x; mFirstSampleX = x; mFirstSampleY = y; mFirstSampleY = y; mFirstSampleZ = z; mFirstSampleZ = z; Loading @@ -260,32 +299,6 @@ final class WirelessChargerDetector { } } clearAtRestLocked(); clearAtRestLocked(); } } // Save the result when done. if (timeNanos - mFirstSampleTime >= SETTLE_TIME_NANOS && mTotalSamples >= MIN_SAMPLES) { mSensorManager.unregisterListener(mListener); if (mMustUpdateRestPosition) { if (mMovingSamples == 0) { mAtRest = true; mRestX = x; mRestY = y; mRestZ = z; } else { clearAtRestLocked(); } mMustUpdateRestPosition = false; } mDetectionInProgress = false; mSuspendBlocker.release(); if (DEBUG) { Slog.d(TAG, "New state: mAtRest=" + mAtRest + ", mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ + ", mTotalSamples=" + mTotalSamples + ", mMovingSamples=" + mMovingSamples); } } } } } } Loading Loading @@ -323,14 +336,22 @@ final class WirelessChargerDetector { private final SensorEventListener mListener = new SensorEventListener() { private final SensorEventListener mListener = new SensorEventListener() { @Override @Override public void onSensorChanged(SensorEvent event) { public void onSensorChanged(SensorEvent event) { // We use SystemClock.elapsedRealtimeNanos() instead of event.timestamp because synchronized (mLock) { // on some devices the sensor HAL may produce timestamps that are not monotonic. processSampleLocked(event.values[0], event.values[1], event.values[2]); processSample(SystemClock.elapsedRealtimeNanos(), } event.values[0], event.values[1], event.values[2]); } } @Override @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { public void onAccuracyChanged(Sensor sensor, int accuracy) { } } }; }; private final Runnable mSensorTimeout = new Runnable() { @Override public void run() { synchronized (mLock) { finishDetectionLocked(); } } }; } }