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

Commit 4bdc37d3 authored by Aravind Akella's avatar Aravind Akella
Browse files

Fix registerListener and flush bugs.

1) Fix registerListener to return false when called with a Trigger sensor. Correct java documentation.
2) Remove reservedFlags and FlushCompleteListener parameters from the public API.
3) Create SensorEventListener2 which extends SensorEventListener and has the onFlushCompleted callback.
3) Change flush(Sensor) API to flush(SensorEventListener).

Change-Id: I56ce4e0b6e329483e129a14ad7e8a0cd35665ffe
Bug: 10894703
parent 6ac16894
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -10691,10 +10691,6 @@ package android.hardware {
    method public int getMinFrequency();
  }
  public abstract interface FlushCompleteListener {
    method public abstract void onFlushCompleted(android.hardware.Sensor);
  }
  public class GeomagneticField {
    ctor public GeomagneticField(float, float, float, long);
    method public float getDeclination();
@@ -10752,6 +10748,10 @@ package android.hardware {
    method public abstract void onSensorChanged(android.hardware.SensorEvent);
  }
  public abstract interface SensorEventListener2 implements android.hardware.SensorEventListener {
    method public abstract void onFlushCompleted(android.hardware.Sensor);
  }
  public abstract deprecated interface SensorListener {
    method public abstract void onAccuracyChanged(int, int);
    method public abstract void onSensorChanged(int, float[]);
@@ -10759,7 +10759,7 @@ package android.hardware {
  public abstract class SensorManager {
    method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
    method public boolean flush(android.hardware.Sensor);
    method public boolean flush(android.hardware.SensorEventListener);
    method public static float getAltitude(float, float);
    method public static void getAngleChange(float[], float[], float[]);
    method public android.hardware.Sensor getDefaultSensor(int);
@@ -10773,9 +10773,9 @@ package android.hardware {
    method public deprecated boolean registerListener(android.hardware.SensorListener, int);
    method public deprecated boolean registerListener(android.hardware.SensorListener, int, int);
    method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int);
    method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, int, int, android.hardware.FlushCompleteListener);
    method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, int);
    method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, android.os.Handler);
    method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, int, int, android.os.Handler, android.hardware.FlushCompleteListener);
    method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, int, android.os.Handler);
    method public static boolean remapCoordinateSystem(float[], int, int, float[]);
    method public boolean requestTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
    method public deprecated void unregisterListener(android.hardware.SensorListener);
+2 −2
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ package android.hardware;
/**
 * Used for receiving a notification when a flush() has been successfully completed.
 */
public interface FlushCompleteListener {
public interface SensorEventListener2 extends SensorEventListener {
    /**
     * Called after flush() is completed. This flush() could have been initiated by this application
     * or some other application. All the events in the batch at the point when the flush was called
@@ -28,7 +28,7 @@ public interface FlushCompleteListener {
     *
     * @param sensor The {@link android.hardware.Sensor Sensor} on which flush was called.
     *
     * @see android.hardware.SensorManager#flush(Sensor)
     * @see android.hardware.SensorManager#flush(SensorEventListener)
     */
    public void onFlushCompleted(Sensor sensor);
}
+57 −52
Original line number Diff line number Diff line
@@ -533,8 +533,6 @@ public abstract class SensorManager {
     *
     * @see #unregisterListener(SensorEventListener)
     * @see #registerListener(SensorEventListener, Sensor, int)
     *
     * @throws IllegalArgumentException when sensor is a trigger sensor.
     */
    public void unregisterListener(SensorEventListener listener, Sensor sensor) {
        if (listener == null || sensor == null) {
@@ -601,7 +599,6 @@ public abstract class SensorManager {
     * @see #unregisterListener(SensorEventListener)
     * @see #unregisterListener(SensorEventListener, Sensor)
     *
     * @throws IllegalArgumentException when sensor is null or a trigger sensor
     */
    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs) {
        return registerListener(listener, sensor, rateUs, null);
@@ -638,7 +635,9 @@ public abstract class SensorManager {
     * {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. </p>
     *
     * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
     *            that will receive the sensor events.
     *            that will receive the sensor events. If the application is interested in receiving
     *            flush complete notifications, it should register with
     *            {@link android.hardware.SensorEventListener SensorEventListener2} instead.
     * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
     * @param rateUs The desired delay between two consecutive events in microseconds. This is only
     *            a hint to the system. Events may be received faster or slower than the specified
@@ -651,30 +650,23 @@ public abstract class SensorManager {
     *            large. If this is set to zero, batch mode is disabled and events are delivered in
     *            continuous mode as soon as they are available which is equivalent to calling
     *            {@link #registerListener(SensorEventListener, Sensor, int)}.
     * @param reservedFlags Always set to Zero.
     * @param flushCompleteListener A {@link android.hardware.FlushCompleteListener
     *            FlushCompleteListener} object which is called when any application calls flush()
     *            on this sensor and all the events in the batch at the time of calling flush() are
     *            successfully delivered to the listeners.
     * @return true if batch mode is successfully enabled for this sensor, false otherwise.
     * @return <code>true</code> if batch mode is successfully enabled for this sensor,
     *         <code>false</code> otherwise.
     * @see #registerListener(SensorEventListener, Sensor, int)
     * @see #unregisterListener(SensorEventListener)
     * @see #flush(Sensor)
     * @throws IllegalArgumentException when sensor or listener is null or a trigger sensor.
     * @see #flush(SensorEventListener)
     */
    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
            int maxBatchReportLatencyUs, int reservedFlags,
            FlushCompleteListener flushCompleteListener) {
            int maxBatchReportLatencyUs) {
        int delay = getDelay(rateUs);
        return registerListenerImpl(listener, sensor, delay, null, maxBatchReportLatencyUs,
                                        reservedFlags, flushCompleteListener);
        return registerListenerImpl(listener, sensor, delay, null, maxBatchReportLatencyUs, 0);
    }

    /**
     * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
     * sensor. Events are delivered in continuous mode as soon as they are available. To reduce the
     * battery usage, use {@link #registerListener(SensorEventListener, Sensor, int, int, int,
     * FlushCompleteListener)} which enables batch mode for the sensor.
     * battery usage, use {@link #registerListener(SensorEventListener, Sensor, int, int)} which
     * enables batch mode for the sensor.
     *
     * <p class="note"></p>
     * Note: Don't use this method with a one shot trigger sensor such as
@@ -706,67 +698,80 @@ public abstract class SensorManager {
     *        {@link android.hardware.SensorEvent sensor events} will be
     *        delivered to.
     *
     * @return true if the sensor is supported and successfully enabled.
     * @return <code>true</code> if the sensor is supported and successfully enabled.
     *
     * @see #registerListener(SensorEventListener, Sensor, int)
     * @see #unregisterListener(SensorEventListener)
     * @see #unregisterListener(SensorEventListener, Sensor)
     *
     * @throws IllegalArgumentException when sensor is null or a trigger sensor
     */
    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
            Handler handler) {
        if (listener == null || sensor == null) {
            return false;
        }

        int delay = getDelay(rateUs);
        return registerListenerImpl(listener, sensor, delay, handler, 0, 0, null);
        return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
    }

    /**
     * Enables batch mode for a sensor with the given rate and maxBatchReportLatency.
     * @param handler
     *        The {@link android.os.Handler Handler} the
     *        {@link android.hardware.SensorEvent sensor events} will be
     *        delivered to.
     * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
     *            that will receive the sensor events. If the application is interested in receiving
     *            flush complete notifications, it should register with
     *            {@link android.hardware.SensorEventListener SensorEventListener2} instead.
     * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
     * @param rateUs The desired delay between two consecutive events in microseconds. This is only
     *            a hint to the system. Events may be received faster or slower than the specified
     *            rate. Usually events are received faster. Can be one of
     *            {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
     *            {@link #SENSOR_DELAY_GAME}, {@link #SENSOR_DELAY_FASTEST} or the delay in
     *            microseconds.
     * @param maxBatchReportLatencyUs An event in the batch can be delayed by at most
     *            maxBatchReportLatency microseconds. More events can be batched if this value is
     *            large. If this is set to zero, batch mode is disabled and events are delivered in
     *            continuous mode as soon as they are available which is equivalent to calling
     *            {@link #registerListener(SensorEventListener, Sensor, int)}.
     * @param handler The {@link android.os.Handler Handler} the
     *        {@link android.hardware.SensorEvent sensor events} will be delivered to.
     *
     * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
     * @return <code>true</code> if batch mode is successfully enabled for this sensor,
     *         <code>false</code> otherwise.
     * @see #registerListener(SensorEventListener, Sensor, int, int)
     */
    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
            int maxBatchReportLatencyUs, int reservedFlags, Handler handler,
            FlushCompleteListener flushCompleteListener) {
            int maxBatchReportLatencyUs, Handler handler) {
        int delayUs = getDelay(rateUs);
        return registerListenerImpl(listener, sensor, delayUs, handler, maxBatchReportLatencyUs,
                                        reservedFlags, flushCompleteListener);
        return registerListenerImpl(listener, sensor, delayUs, handler, maxBatchReportLatencyUs, 0);
    }

    /** @hide */
    protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
            FlushCompleteListener flushCompleteListener);
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags);


    /**
     * Flushes the batch FIFO of the given sensor. If there are events in the FIFO of this sensor,
     * they are returned as if the batch timeout has expired. Events are returned in the
     * usual way through the SensorEventListener. This call doesn't effect the batch timeout for
     * this sensor. This call is asynchronous and returns immediately. FlushCompleteListener is
     * called after all the events in the batch at the time of calling this method have been
     * delivered successfully.
     * @param sensor
     *        The {@link android.hardware.Sensor Sensor} to flush.
     * @return true if the flush is initiated successfully. false if the sensor isn't active
     *         i.e no application is registered for updates from this sensor.
     * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
     * @throws IllegalArgumentException when sensor is null or a trigger sensor.
     * Flushes the batch FIFO of all the sensors registered for this listener. If there are events
     * in the FIFO of the sensor, they are returned as if the batch timeout in the FIFO of the
     * sensors had expired. Events are returned in the usual way through the SensorEventListener.
     * This call doesn't affect the batch timeout for this sensor. This call is asynchronous and
     * returns immediately.
     * {@link android.hardware.SensorEventListener2#onFlushCompleted onFlushCompleted} is called
     * after all the events in the batch at the time of calling this method have been delivered
     * successfully. If the hardware doesn't support flush, it still returns true and a trivial
     * flush complete event is sent after the current event for all the clients registered for this
     * sensor.
     *
     * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
     *        which was previously used in a registerListener call.
     * @return <code>true</code> if the flush is initiated successfully on all the sensors
     *         registered for this listener, false if no sensor is previously registered for this
     *         listener or flush on one of the sensors fails.
     * @see #registerListener(SensorEventListener, Sensor, int, int)
     * @throws IllegalArgumentException when listener is null.
     */
    public boolean flush(Sensor sensor) {
        return flushImpl(sensor);
    public boolean flush(SensorEventListener listener) {
        return flushImpl(listener);
    }

    /** @hide */
    protected abstract boolean flushImpl(Sensor sensor);
    protected abstract boolean flushImpl(SensorEventListener listener);

    /**
     * <p>
+30 −55
Original line number Diff line number Diff line
@@ -93,17 +93,20 @@ public class SystemSensorManager extends SensorManager {
    /** @hide */
    @Override
    protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
            FlushCompleteListener flushCompleteListener) {
        if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
        if (listener == null) throw new IllegalArgumentException("listener cannot be null");
        if (reservedFlags != 0) throw new IllegalArgumentException("reservedFlags should be zero");
        if (delayUs < 0) throw new IllegalArgumentException("rateUs should be positive");
        if (maxBatchReportLatencyUs < 0)
            throw new IllegalArgumentException("maxBatchReportLatencyUs should be positive");
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
        if (listener == null || sensor == null) {
            Log.e(TAG, "sensor or listener is null");
            return false;
        }
        // Trigger Sensors should use the requestTriggerSensor call.
        if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
            throw new IllegalArgumentException("Trigger Sensors cannot use registerListener");
        if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) {
            Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
            return false;
        }
        if (maxBatchReportLatencyUs < 0 || delayUs < 0) {
            Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");
            return false;
        }

        // Invariants to preserve:
        // - one Looper per SensorEventListener
@@ -113,7 +116,7 @@ public class SystemSensorManager extends SensorManager {
            SensorEventQueue queue = mSensorListeners.get(listener);
            if (queue == null) {
                Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
                queue = new SensorEventQueue(listener, looper, this, flushCompleteListener);
                queue = new SensorEventQueue(listener, looper, this);
                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {
                    queue.dispose();
                    return false;
@@ -200,16 +203,17 @@ public class SystemSensorManager extends SensorManager {
        }
    }

    protected boolean flushImpl(Sensor sensor) {
        if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
        if(Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
            throw new IllegalArgumentException("Trigger Sensors cannot call flush");
    protected boolean flushImpl(SensorEventListener listener) {
        if (listener == null) throw new IllegalArgumentException("listener cannot be null");

        FlushEventQueue queue = new FlushEventQueue(mMainLooper, this);
        if (queue.flushSensor(sensor) != 0) {
        synchronized (mSensorListeners) {
            SensorEventQueue queue = mSensorListeners.get(listener);
            if (queue == null) {
                return false;
            } else {
                return (queue.flush() == 0);
            }
        }
        return true;
    }

    /*
@@ -224,7 +228,7 @@ public class SystemSensorManager extends SensorManager {
                int maxBatchReportLatencyUs, int reservedFlags);
        private static native int nativeDisableSensor(int eventQ, int handle);
        private static native void nativeDestroySensorEventQueue(int eventQ);
        private static native int nativeFlushSensor(int eventQ, int handle);
        private static native int nativeFlushSensor(int eventQ);
        private int nSensorEventQueue;
        private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
        protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
@@ -291,10 +295,9 @@ public class SystemSensorManager extends SensorManager {
            return false;
        }

        public int flushSensor(Sensor sensor) {
        public int flush() {
            if (nSensorEventQueue == 0) throw new NullPointerException();
            if (sensor == null) throw new NullPointerException();
            return nativeFlushSensor(nSensorEventQueue, sensor.getHandle());
            return nativeFlushSensor(nSensorEventQueue);
        }

        public boolean hasSensors() {
@@ -347,14 +350,12 @@ public class SystemSensorManager extends SensorManager {

    static final class SensorEventQueue extends BaseEventQueue {
        private final SensorEventListener mListener;
        private final FlushCompleteListener mFlushCompleteListener;
        private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();

        public SensorEventQueue(SensorEventListener listener, Looper looper,
                SystemSensorManager manager, FlushCompleteListener flushCompleteListener) {
                SystemSensorManager manager) {
            super(looper, manager);
            mListener = listener;
            mFlushCompleteListener = flushCompleteListener;
        }

        public void addSensorEvent(Sensor sensor) {
@@ -408,9 +409,9 @@ public class SystemSensorManager extends SensorManager {

        @SuppressWarnings("unused")
        protected void dispatchFlushCompleteEvent(int handle) {
            if (mListener instanceof SensorEventListener2) {
                final Sensor sensor = sHandleToSensor.get(handle);
            if (mFlushCompleteListener != null) {
                mFlushCompleteListener.onFlushCompleted(sensor);
                ((SensorEventListener2)mListener).onFlushCompleted(sensor);
            }
            return;
        }
@@ -464,30 +465,4 @@ public class SystemSensorManager extends SensorManager {
        protected void dispatchFlushCompleteEvent(int handle) {
        }
    }

    static final class FlushEventQueue extends BaseEventQueue {
        public FlushEventQueue(Looper looper, SystemSensorManager manager) {
            super(looper, manager);
        }

        @SuppressWarnings("unused")
        @Override
        protected void dispatchSensorEvent(int handle, float[] values, int accuracy,
                long timestamp) {
        }

        @Override
        @SuppressWarnings("unused")
        protected void addSensorEvent(Sensor sensor) {
        }

        @Override
        @SuppressWarnings("unused")
        protected void removeSensorEvent(Sensor sensor) {
        }

        @SuppressWarnings("unused")
        protected void dispatchFlushCompleteEvent(int handle) {
        }
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -220,9 +220,9 @@ static void nativeDestroySensorEventQueue(JNIEnv *env, jclass clazz, jint eventQ
    receiver->decStrong((void*)nativeInitSensorEventQueue);
}

static jint nativeFlushSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle) {
static jint nativeFlushSensor(JNIEnv *env, jclass clazz, jint eventQ) {
    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
    return receiver->getSensorEventQueue()->flushSensor(handle);
    return receiver->getSensorEventQueue()->flush();
}

//----------------------------------------------------------------------------
@@ -255,7 +255,7 @@ static JNINativeMethod gBaseEventQueueMethods[] = {
            (void*)nativeDestroySensorEventQueue },

    {"nativeFlushSensor",
            "(II)I",
            "(I)I",
            (void*)nativeFlushSensor },
};