环境:MSM8909+Android6.0.1+STK3310
1.打开QSensorTest app,用手靠近和远离P-sensor,sensor均能正常上报数据。
2.打电话时查看kernel日志,发现enable函数没有被调用。
P-sensor采用的轮训的方式上报数据,说明上层没有调用sensor的enable函数,在frameworks/base/core/java/android/hardware/SensorManager.java文件中:
1.打开QSensorTest app,用手靠近和远离P-sensor,sensor均能正常上报数据。
2.打电话时查看kernel日志,发现enable函数没有被调用。
P-sensor采用的轮训的方式上报数据,说明上层没有调用sensor的enable函数,在frameworks/base/core/java/android/hardware/SensorManager.java文件中:
/**
* Use this method to get the default sensor for a given type. Note that the
* returned sensor could be a composite sensor, and its data could be
* averaged or filtered. If you need to access the raw sensors use
* {@link SensorManager#getSensorList(int) getSensorList}.
*
* @param type
* of sensors requested
*
* @return the default sensor matching the requested type if one exists and the application
* has the necessary permissions, or null otherwise.
*
* @see #getSensorList(int)
* @see Sensor
*/
public Sensor getDefaultSensor(int type) {
// TODO: need to be smarter, for now, just return the 1st sensor
List<Sensor> l = getSensorList(type);
boolean wakeUpSensor = false;
// For the following sensor types, return a wake-up sensor. These types are by default
// defined as wake-up sensors. For the rest of the SDK defined sensor types return a
// non_wake-up version.
if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION ||
type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE ||
type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE ||
type == Sensor.TYPE_WRIST_TILT_GESTURE) {
wakeUpSensor = true;
}
for (Sensor sensor : l) {
if (sensor.isWakeUpSensor() == wakeUpSensor) return sensor;
}
return null;
}
如果是wakeUpSensor,则正常返回。调用到这的时候,返回的是NULL。在hardware/libhardware/include/hardware/sensors.h中有对wake_up_sensor的详细说明:
/*
* Availability: SENSORS_DEVICE_API_VERSION_1_3
* Sensor flags used in sensor_t.flags.
*/
enum {
/*
* Whether this sensor wakes up the AP from suspend mode when data is available. Whenever
* sensor events are delivered from a wake_up sensor, the driver needs to hold a wake_lock till
* the events are read by the SensorService i.e till sensors_poll_device_t.poll() is called the
* next time. Once poll is called again it means events have been read by the SensorService, the
* driver can safely release the wake_lock. SensorService will continue to hold a wake_lock till
* the app actually reads the events.
*/
SENSOR_FLAG_WAKE_UP = 1U << 0,
/*
* Reporting modes for various sensors. Each sensor will have exactly one of these modes set.
* The least significant 2nd, 3rd and 4th bits are used to represent four possible reporting
* modes.
*/
SENSOR_FLAG_CONTINUOUS_MODE = 0, // 0000
SENSOR_FLAG_ON_CHANGE_MODE = 0x2, // 0010
SENSOR_FLAG_ONE_SHOT_MODE = 0x4, // 0100
SENSOR_FLAG_SPECIAL_REPORTING_MODE = 0x6, // 0110
/*
* Set this flag if the sensor supports data_injection mode and allows data to be injected
* from the SensorService. When in data_injection ONLY sensors with this flag set are injected
* sensor data and only sensors with this flag set are activated. Eg: Accelerometer and Step
* Counter sensors can be set with this flag and SensorService will inject accelerometer data
* and read the corresponding step counts.
*/
SENSOR_FLAG_SUPPORTS_DATA_INJECTION = 0x10 // 1 0000
};
如果是wake_up_sensor的话,需要设置SENSOR_FLAG_WAKE_UP标志,在hardware/qcom/sensors/NativeSensorManager.cpp的int NativeSensorManager::getDataInfo函数中:
case SENSOR_TYPE_PROXIMITY:
has_proximity = 1;
#if defined(SENSORS_DEVICE_API_VERSION_1_3)
/* reporting mode fix up */
list->sensor->flags |= SENSOR_FLAG_ON_CHANGE_MODE;
#endif
list->driver = new ProximitySensor(list);
sensor_proximity = *(list->sensor);
break;
SENSOR_FLAG_ON_CHANGE_MODE等于2,或上SENSOR_FLAG_WAKE_UP之后就是3,因此,driver中的flags配置成3即可。
static struct sensors_classdev sensors_proximity_cdev = {
.name = "stk3x1x-proximity",
.vendor = "Sensortek",
.version = 1,
.handle = SENSORS_PROXIMITY_HANDLE,
.type = SENSOR_TYPE_PROXIMITY,
.max_range = "5.0",
.resolution = "5.0",
.sensor_power = "0.1",
.min_delay = 0,
.fifo_reserved_event_count = 0,
.fifo_max_event_count = 0,
.flags = 3,
.enabled = 0,
.delay_msec = 200,
.sensors_enable = NULL,
.sensors_poll_delay = NULL,
};