Index: device/generic_sensor/android/java/src/org/chromium/device/sensors/GenericPlatformSensor.java |
diff --git a/device/generic_sensor/android/java/src/org/chromium/device/sensors/GenericPlatformSensor.java b/device/generic_sensor/android/java/src/org/chromium/device/sensors/GenericPlatformSensor.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b5764decc8b0c4a9c387a1865781e2e998ec6e1d |
--- /dev/null |
+++ b/device/generic_sensor/android/java/src/org/chromium/device/sensors/GenericPlatformSensor.java |
@@ -0,0 +1,122 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.device.sensors; |
+ |
+import android.hardware.Sensor; |
+import android.hardware.SensorEvent; |
+import android.hardware.SensorEventListener; |
+import android.hardware.SensorManager; |
+import android.os.Build; |
+import android.os.Handler; |
+ |
+import org.chromium.mojom.device.mojom.ReportingMode; |
+ |
+import java.nio.BufferOverflowException; |
+import java.nio.ByteBuffer; |
+ |
+import java.util.List; |
+ |
+/** |
+ * Implementation of PlatformSensor that uses Android Sensor Framework. |
+ */ |
+public class GenericPlatformSensor extends PlatformSensor implements SensorEventListener { |
+ private static final double MICROSECONDS_PER_SECOND = 1000000; |
+ private final Sensor mSensor; |
+ private final SensorManager mSensorManager; |
+ private final Handler mHandler; |
+ private final int mMinDelay; |
+ private final int mReadingCount; |
+ |
+ protected GenericPlatformSensor(int sensorType, int readingCount, SensorManager sensorManager, |
+ Handler handler) throws SensorException { |
+ mReadingCount = readingCount; |
+ mSensorManager = sensorManager; |
+ mHandler = handler; |
+ List<Sensor> sensors = mSensorManager.getSensorList(sensorType); |
+ if (sensors.isEmpty()) throw new SensorException(); |
+ mSensor = sensors.get(0); |
+ mMinDelay = mSensor.getMinDelay(); |
+ } |
+ |
+ /** |
+ * Fills shared buffer with sensor reading data, throws exception if number of received values |
+ * is less than the number required for the PlatformSensor. |
+ */ |
+ protected void fillSensorReadingData(SensorEvent event, ByteBuffer buffer) |
+ throws SensorException { |
+ if (event.values.length < mReadingCount) throw new SensorException(); |
+ for (int i = 0; i < mReadingCount; ++i) { |
+ buffer.putDouble(event.values[i]); |
+ } |
+ } |
+ |
+ @Override |
+ protected int getReportingMode() { |
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
+ return mSensor.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS |
+ ? ReportingMode.CONTINUOUS |
+ : ReportingMode.ON_CHANGE; |
+ } |
+ return ReportingMode.CONTINUOUS; |
+ } |
+ |
+ @Override |
+ protected boolean startSensor(SensorConfiguration configuration) { |
+ if (mNativePlatformSensorAndroid == 0 || mBuffer == null || mSensorReadingData == null) { |
+ return false; |
+ } |
+ |
+ stopSensor(); |
+ return mSensorManager.registerListener( |
+ this, mSensor, getSamplingPeriod(configuration), mHandler); |
+ } |
+ |
+ @Override |
+ protected void stopSensor() { |
+ mSensorManager.unregisterListener(this); |
+ } |
+ |
+ @Override |
+ protected boolean checkSensorConfiguration(SensorConfiguration configuration) { |
+ return mMinDelay <= getSamplingPeriod(configuration); |
+ } |
+ |
+ /** |
+ * Converts frequency provided by the SensorConfiguration to sampling period in microseconds. |
+ */ |
+ private int getSamplingPeriod(SensorConfiguration configuration) { |
+ if (configuration.getFrequency() > 0) { |
+ return (int) ((1 / configuration.getFrequency()) * MICROSECONDS_PER_SECOND); |
+ } else { |
+ return 0; |
+ } |
+ } |
+ |
+ @Override |
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {} |
+ |
+ @Override |
+ public void onSensorChanged(SensorEvent event) { |
+ try { |
+ mSensorReadingData.mark(); |
+ // Timestamp in milliseconds |
+ mSensorReadingData.putDouble(event.timestamp * 0.000001d); |
+ fillSensorReadingData(event, mSensorReadingData); |
+ |
+ mSensorReadingData.reset(); |
+ |
+ mBuffer.mark(); |
+ mBuffer.put(mSensorReadingData); |
+ mSensorReadingData.reset(); |
+ mBuffer.reset(); |
+ |
+ if (getReportingMode() == ReportingMode.ON_CHANGE) { |
+ nativeNotifyPlatformSensorReadingChanged(mNativePlatformSensorAndroid); |
+ } |
+ } catch (BufferOverflowException | SensorException e) { |
+ nativeNotifyPlatformSensorError(mNativePlatformSensorAndroid); |
+ } |
+ } |
+} |