blob: 184994dc8409724e0176289191af34019b5e6ef7 [file] [log] [blame]
// 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.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.mojom.device.mojom.SensorType;
import java.util.HashSet;
import java.util.Set;
/**
* Lifetime is controlled by device::PlatformSensorProviderAndroid.
*/
@JNINamespace("device")
class PlatformSensorProvider {
/**
* SensorManager that is shared among PlatformSensor objects. It is used for Sensor object
* creation and @see android.hardware.SensorEventListener registration.
* @see android.hardware.SensorManager
*/
private final SensorManager mSensorManager;
/**
* Thread that is handling all sensor events.
*/
private HandlerThread mSensorsThread;
/**
* Processes messages on #mSensorsThread message queue. Provided to #mSensorManager when
* sensor should start polling for data.
*/
private Handler mHandler;
/**
* Set of currently active PlatformSensor objects.
*/
private final Set<PlatformSensor> mActiveSensors = new HashSet<PlatformSensor>();
/**
* Returns shared thread Handler.
*
* @return Handler thread handler.
*/
public Handler getHandler() {
return mHandler;
}
/**
* Returns shared SensorManager.
*
* @return SensorManager sensor manager.
*/
public SensorManager getSensorManager() {
return mSensorManager;
}
/**
* Notifies PlatformSensorProvider that sensor started polling for data. Adds sensor to
* a set of active sensors, creates and starts new thread if needed.
*/
public void sensorStarted(PlatformSensor sensor) {
if (mActiveSensors.isEmpty()) startSensorThread();
mActiveSensors.add(sensor);
}
/**
* Notifies PlatformSensorProvider that sensor is no longer polling for data. When
* #mActiveSensors becomes empty thread is stopped.
*/
public void sensorStopped(PlatformSensor sensor) {
mActiveSensors.remove(sensor);
if (mActiveSensors.isEmpty()) stopSensorThread();
}
/**
* Starts sensor handler thread.
*/
protected void startSensorThread() {
if (mSensorsThread == null) {
mSensorsThread = new HandlerThread("SensorsHandlerThread");
mSensorsThread.start();
mHandler = new Handler(mSensorsThread.getLooper());
}
}
/**
* Stops sensor handler thread.
*/
protected void stopSensorThread() {
if (mSensorsThread != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mSensorsThread.quitSafely();
} else {
mSensorsThread.quit();
}
mSensorsThread = null;
mHandler = null;
}
}
/**
* Constructor.
*
* @param context application context.
*/
protected PlatformSensorProvider(Context context) {
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
}
/**
* Creates PlatformSensorProvider instance.
*
* @param context application context.
* @return PlatformSensorProvider new PlatformSensorProvider instance.
*/
@CalledByNative
protected static PlatformSensorProvider create(Context context) {
return new PlatformSensorProvider(context);
}
/**
* Creates PlatformSensor instance.
*
* @param type type of a sensor.
* @return PlatformSensor new PlatformSensor instance or null if sensor cannot be created.
*/
@CalledByNative
protected PlatformSensor createSensor(int type) {
if (mSensorManager == null) return null;
switch (type) {
case SensorType.AMBIENT_LIGHT:
return PlatformSensor.create(Sensor.TYPE_LIGHT, 1, this);
case SensorType.ACCELEROMETER:
return PlatformSensor.create(Sensor.TYPE_ACCELEROMETER, 3, this);
case SensorType.LINEAR_ACCELERATION:
return PlatformSensor.create(Sensor.TYPE_LINEAR_ACCELERATION, 3, this);
case SensorType.GYROSCOPE:
return PlatformSensor.create(Sensor.TYPE_GYROSCOPE, 3, this);
case SensorType.MAGNETOMETER:
return PlatformSensor.create(Sensor.TYPE_MAGNETIC_FIELD, 3, this);
default:
return null;
}
}
}