Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f7f648f authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

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

* commit '9601b51c':
  Track wireless charger detector timeout explicitly.
parents 6d7de848 9601b51c
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -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);


+69 −48
Original line number Original line Diff line number Diff line
@@ -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;


@@ -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;
@@ -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;
@@ -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.
@@ -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);
    }
    }
@@ -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);
        }
        }
@@ -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;
@@ -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;
@@ -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);
                }
            }
        }
        }
    }
    }


@@ -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();
            }
        }
    };
}
}