[go: nahoru, domu]

blob: d2fc9c483fd2075bdf012983fb6d7f8cd0966e21 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// 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.ContextUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.device.mojom.SensorType;
import java.util.HashSet;
import java.util.List;
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 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) {
synchronized (mActiveSensors) {
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) {
synchronized (mActiveSensors) {
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.
*/
protected PlatformSensorProvider(Context context) {
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
}
/**
* Creates PlatformSensorProvider instance.
*
* @return PlatformSensorProvider new PlatformSensorProvider instance.
*/
protected static PlatformSensorProvider createForTest(Context context) {
return new PlatformSensorProvider(context);
}
/**
* Creates PlatformSensorProvider instance.
*
* @return PlatformSensorProvider new PlatformSensorProvider instance.
*/
@CalledByNative
protected static PlatformSensorProvider create() {
return new PlatformSensorProvider(ContextUtils.getApplicationContext());
}
/**
* Sets |mSensorManager| to null for testing purposes.
*/
@CalledByNative
protected void setSensorManagerToNullForTesting() {
mSensorManager = null;
}
/**
* Checks if |type| sensor is available.
*
* @param type type of a sensor.
* @return If |type| sensor is available, returns true; otherwise returns false.
*/
@CalledByNative
protected boolean hasSensorType(int type) {
if (mSensorManager == null) return false;
// Type of the sensor to be constructed. @see android.hardware.Sensor.TYPE_*
int sensorType;
switch (type) {
case SensorType.AMBIENT_LIGHT:
sensorType = Sensor.TYPE_LIGHT;
break;
case SensorType.ACCELEROMETER:
sensorType = Sensor.TYPE_ACCELEROMETER;
break;
case SensorType.LINEAR_ACCELERATION:
sensorType = Sensor.TYPE_LINEAR_ACCELERATION;
break;
case SensorType.GRAVITY:
sensorType = Sensor.TYPE_GRAVITY;
break;
case SensorType.GYROSCOPE:
sensorType = Sensor.TYPE_GYROSCOPE;
break;
case SensorType.MAGNETOMETER:
sensorType = Sensor.TYPE_MAGNETIC_FIELD;
break;
case SensorType.ABSOLUTE_ORIENTATION_QUATERNION:
sensorType = Sensor.TYPE_ROTATION_VECTOR;
break;
case SensorType.RELATIVE_ORIENTATION_QUATERNION:
sensorType = Sensor.TYPE_GAME_ROTATION_VECTOR;
break;
default:
return false;
}
List<Sensor> sensors = mSensorManager.getSensorList(sensorType);
return !sensors.isEmpty();
}
}