am 9601b51c: am 42544cf8: Merge "Track wireless charger detector timeout explicitly." into klp-dev

* commit '9601b51cd96b99ff7e016e09f3c25d3b59f56602':
  Track wireless charger detector timeout explicitly.
This commit is contained in:
Jeff Brown
2013-10-02 09:37:10 -07:00
committed by Android Git Automerger
2 changed files with 71 additions and 49 deletions

View File

@@ -453,7 +453,8 @@ public final class PowerManagerService extends IPowerManager.Stub
mDisplayPowerControllerCallbacks, mHandler);
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"));
createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
mHandler);
mSettingsObserver = new SettingsObserver(mHandler);
mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);

View File

@@ -21,8 +21,11 @@ import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Slog;
import android.util.TimeUtils;
import java.io.PrintWriter;
@@ -70,12 +73,12 @@ final class WirelessChargerDetector {
private static final String TAG = "WirelessChargerDetector";
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
// 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.
private static final int MIN_SAMPLES = 3;
@@ -97,6 +100,7 @@ final class WirelessChargerDetector {
private final SensorManager mSensorManager;
private final SuspendBlocker mSuspendBlocker;
private final Handler mHandler;
// The gravity sensor, or null if none.
private Sensor mGravitySensor;
@@ -116,6 +120,9 @@ final class WirelessChargerDetector {
// The suspend blocker is held while this is the case.
private boolean mDetectionInProgress;
// The time when detection was last performed.
private long mDetectionStartTime;
// True if the rest position should be updated if at rest.
// Otherwise, the current rest position is simply checked and cleared if movement
// is detected but no new rest position is stored.
@@ -127,18 +134,17 @@ final class WirelessChargerDetector {
// The number of samples collected that showed evidence of not being at rest.
private int mMovingSamples;
// The time and value of the first sample that was collected.
private long mFirstSampleTime;
// The value of the first sample that was collected.
private float mFirstSampleX, mFirstSampleY, mFirstSampleZ;
// The time and value of the last sample that was collected (for debugging only).
private long mLastSampleTime;
// The value of the last sample that was collected.
private float mLastSampleX, mLastSampleY, mLastSampleZ;
public WirelessChargerDetector(SensorManager sensorManager,
SuspendBlocker suspendBlocker) {
SuspendBlocker suspendBlocker, Handler handler) {
mSensorManager = sensorManager;
mSuspendBlocker = suspendBlocker;
mHandler = handler;
mGravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
}
@@ -152,13 +158,13 @@ final class WirelessChargerDetector {
pw.println(" mAtRest=" + mAtRest);
pw.println(" mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ);
pw.println(" mDetectionInProgress=" + mDetectionInProgress);
pw.println(" mDetectionStartTime=" + (mDetectionStartTime == 0 ? "0 (never)"
: TimeUtils.formatUptime(mDetectionStartTime)));
pw.println(" mMustUpdateRestPosition=" + mMustUpdateRestPosition);
pw.println(" mTotalSamples=" + mTotalSamples);
pw.println(" mMovingSamples=" + mMovingSamples);
pw.println(" mFirstSampleTime=" + mFirstSampleTime);
pw.println(" mFirstSampleX=" + mFirstSampleX
+ ", mFirstSampleY=" + mFirstSampleY + ", mFirstSampleZ=" + mFirstSampleZ);
pw.println(" mLastSampleTime=" + mLastSampleTime);
pw.println(" mLastSampleX=" + mLastSampleX
+ ", mLastSampleY=" + mLastSampleY + ", mLastSampleZ=" + mLastSampleZ);
}
@@ -217,22 +223,56 @@ final class WirelessChargerDetector {
private void startDetectionLocked() {
if (!mDetectionInProgress && mGravitySensor != null) {
if (mSensorManager.registerListener(mListener, mGravitySensor,
SensorManager.SENSOR_DELAY_UI)) {
SAMPLING_INTERVAL_MILLIS * 1000)) {
mSuspendBlocker.acquire();
mDetectionInProgress = true;
mDetectionStartTime = SystemClock.uptimeMillis();
mTotalSamples = 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) {
synchronized (mLock) {
if (!mDetectionInProgress) {
return;
private void finishDetectionLocked() {
if (mDetectionInProgress) {
mSensorManager.unregisterListener(mListener);
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;
}
mLastSampleTime = timeNanos;
if (DEBUG) {
Slog.d(TAG, "New state: mAtRest=" + mAtRest
+ ", mRestX=" + mRestX + ", mRestY=" + mRestY + ", mRestZ=" + mRestZ
+ ", mTotalSamples=" + mTotalSamples
+ ", mMovingSamples=" + mMovingSamples);
}
mDetectionInProgress = false;
mSuspendBlocker.release();
}
}
private void processSampleLocked(float x, float y, float z) {
if (mDetectionInProgress) {
mLastSampleX = x;
mLastSampleY = y;
mLastSampleZ = z;
@@ -240,7 +280,6 @@ final class WirelessChargerDetector {
mTotalSamples += 1;
if (mTotalSamples == 1) {
// Save information about the first sample collected.
mFirstSampleTime = timeNanos;
mFirstSampleX = x;
mFirstSampleY = y;
mFirstSampleZ = z;
@@ -260,32 +299,6 @@ final class WirelessChargerDetector {
}
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);
}
}
}
}
@@ -323,14 +336,22 @@ final class WirelessChargerDetector {
private final SensorEventListener mListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
// We use SystemClock.elapsedRealtimeNanos() instead of event.timestamp because
// on some devices the sensor HAL may produce timestamps that are not monotonic.
processSample(SystemClock.elapsedRealtimeNanos(),
event.values[0], event.values[1], event.values[2]);
synchronized (mLock) {
processSampleLocked(event.values[0], event.values[1], event.values[2]);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
private final Runnable mSensorTimeout = new Runnable() {
@Override
public void run() {
synchronized (mLock) {
finishDetectionLocked();
}
}
};
}