static int active_poll_sensors; /* Number of enabled poll-mode sensors */
+int64_t ts_delta; /* delta between SystemClock.getNanos and our timestamp */
+
/* We use pthread condition variables to get worker threads out of sleep */
static pthread_condattr_t thread_cond_attr [MAX_SENSORS];
static pthread_cond_t thread_release_cond [MAX_SENSORS];
*/
int dev_num = sensor_info[s].dev_num;
- int catalog_index = sensor_info[s].catalog_index;
- int sensor_type = sensor_catalog[catalog_index].type;
/* Refcount per sensor, in terms of enable count */
if (enabled) {
if (sensor_info[s].enable_count > 1)
return 0; /* The sensor was, and remains, in use */
- switch (sensor_type) {
+ switch (sensor_info[s].type) {
case SENSOR_TYPE_MAGNETIC_FIELD:
compass_read_data(&sensor_info[s]);
break;
/* Sensor disabled, lower report available flag */
sensor_info[s].report_pending = 0;
- if (sensor_type == SENSOR_TYPE_MAGNETIC_FIELD)
+ if (sensor_info[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
compass_store_data(&sensor_info[s]);
+
+ if(sensor_info[s].type == SENSOR_TYPE_GYROSCOPE ||
+ sensor_info[s].type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED)
+ gyro_store_data(&sensor_info[s]);
}
/* If uncalibrated type and pair is already active don't adjust counters */
- if (sensor_type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED &&
+ if (sensor_info[s].type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED &&
sensor_info[sensor_info[s].pair_idx].enable_count != 0)
return 0;
static int get_field_count (int s)
{
- int catalog_index = sensor_info[s].catalog_index;
- int sensor_type = sensor_catalog[catalog_index].type;
-
- switch (sensor_type) {
+ switch (sensor_info[s].type) {
case SENSOR_TYPE_ACCELEROMETER: /* m/s^2 */
case SENSOR_TYPE_MAGNETIC_FIELD: /* micro-tesla */
case SENSOR_TYPE_ORIENTATION: /* degrees */
}
-
static void* acquisition_routine (void* param)
{
/*
pthread_mutex_lock(&thread_release_mutex[s]);
/* Pinpoint the moment we start sampling */
- timestamp = get_timestamp();
+ timestamp = get_timestamp_monotonic();
/* Check and honor termination requests */
while (sensor_info[s].thread_data_fd[1] != -1) {
/* Create condition variable and mutex for quick thread release */
ret = pthread_condattr_init(&thread_cond_attr[s]);
- ret = pthread_condattr_setclock(&thread_cond_attr[s], POLLING_CLOCK);
+ ret = pthread_condattr_setclock(&thread_cond_attr[s], CLOCK_MONOTONIC);
ret = pthread_cond_init(&thread_release_cond[s], &thread_cond_attr[s]);
ret = pthread_mutex_init(&thread_release_mutex[s], NULL);
/* Prepare the report timestamp field for the first event, see set_report_ts method */
sensor_info[s].report_ts = 0;
+ ts_delta = load_timestamp_sys_clock() - get_timestamp_monotonic();
+
/* If we want to activate gyro calibrated and gyro uncalibrated is activated
* Deactivate gyro uncalibrated - Uncalibrated releases handler
* Deactivate gyro calibrated - Calibrated releases handler
* Reactivate gyro uncalibrated - Uncalibrated has handler */
- if (sensor_catalog[sensor_info[s].catalog_index].type == SENSOR_TYPE_GYROSCOPE &&
+ if (sensor_info[s].type == SENSOR_TYPE_GYROSCOPE &&
sensor_info[s].pair_idx && sensor_info[sensor_info[s].pair_idx].enable_count != 0) {
sensor_activate(sensor_info[s].pair_idx, 0);
* to request fairly high event rates. Favor continuous triggers if the
* sensor is an accelerometer and uses a sampling rate of at least 25.
*/
- int catalog_index = sensor_info[s].catalog_index;
- if (sensor_catalog[catalog_index].type != SENSOR_TYPE_ACCELEROMETER)
+ if (sensor_info[s].type != SENSOR_TYPE_ACCELEROMETER)
return 0;
if (sensor_info[s].sampling_rate < 25)
sensor_info[s].num_channels &&
(!sensor_info[s].motion_trigger_name[0] ||
!sensor_info[s].report_initialized ||
- is_fast_accelerometer(s))
+ is_fast_accelerometer(s) ||
+ (sensor_info[s].quirks & QUIRK_FORCE_CONTINUOUS))
)
return; /* Nope */
if (sensor_info[s].dev_num == dev_num &&
sensor_info[s].enable_count &&
sensor_info[s].num_channels &&
- !(sensor_info[s].quirks & QUIRK_CONTINUOUS_DRIVER) &&
sensor_info[s].selected_trigger !=
sensor_info[s].motion_trigger_name)
candidate[candidate_count++] = s;
}
}
-static int integrate_device_report(int dev_num)
+static int integrate_device_report (int dev_num)
{
int len;
int s,c;
return -1;
}
+
+
len = read(device_fd[dev_num], buf, MAX_SENSOR_REPORT_SIZE);
if (len == -1) {
sr_offset);
set_report_ts(s, get_timestamp());
- sensor_info[s].report_pending = 1;
+ sensor_info[s].report_pending = DATA_TRIGGER;
sensor_info[s].report_initialized = 1;
}
}
-static int propagate_sensor_report(int s, struct sensors_event_t *data)
+static int propagate_sensor_report (int s, struct sensors_event_t *data)
{
/* There's a sensor report pending for this sensor ; transmit it */
- int catalog_index = sensor_info[s].catalog_index;
- int sensor_type = sensor_catalog[catalog_index].type;
int num_fields = get_field_count(s);
int c;
unsigned char* current_sample;
/* Only return uncalibrated event if also gyro active */
- if (sensor_type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED &&
+ if (sensor_info[s].type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED &&
sensor_info[sensor_info[s].pair_idx].enable_count != 0)
return 0;
data->version = sizeof(sensors_event_t);
data->sensor = s;
- data->type = sensor_type;
+ data->type = sensor_info[s].type;
data->timestamp = sensor_info[s].report_ts;
- ALOGV("Sample on sensor %d (type %d):\n", s, sensor_type);
+ ALOGV("Sample on sensor %d (type %d):\n", s, sensor_info[s].type);
current_sample = sensor_info[s].report_buffer;
continue;
/* If the sensor is continuously firing, leave it alone */
- if ( sensor_info[s].selected_trigger !=
- sensor_info[s].motion_trigger_name)
+ if (sensor_info[s].selected_trigger !=
+ sensor_info[s].motion_trigger_name)
continue;
/* If we haven't seen a sample, there's nothing to duplicate */
if (target_ts <= current_ts) {
/* Mark the sensor for event generation */
set_report_ts(s, current_ts);
- sensor_info[s].report_pending = 1;
+ sensor_info[s].report_pending = DATA_DUPLICATE;
}
}
}
if (len == expected_len) {
set_report_ts(s, get_timestamp());
- sensor_info[s].report_pending = 1;
+ sensor_info[s].report_pending = DATA_SYSFS;
}
}
int64_t period;
/*
- * Check if have have to deal with "terse" drivers that only send events
- * when there is motion, despite the fact that the associated Android
- * sensor type is continuous rather than on-change. In that case we have
- * to duplicate events. Check deadline for the nearest upcoming event.
+ * Check if we're dealing with a driver that only send events when
+ * there is motion, despite the fact that the associated Android sensor
+ * type is continuous rather than on-change. In that case we have to
+ * duplicate events. Check deadline for the nearest upcoming event.
*/
for (s=0; s<sensor_count; s++)
if (sensor_info[s].enable_count &&
for (s=0; s<sensor_count && returned_events < count; s++) {
if (sensor_info[s].report_pending) {
event_count = 0;
- /* Lower flag */
- sensor_info[s].report_pending = 0;
/* Report this event if it looks OK */
event_count = propagate_sensor_report(s, &data[returned_events]);
+ /* Lower flag */
+ sensor_info[s].report_pending = 0;
+
/* Duplicate only if both cal & uncal are active */
- if (sensor_catalog[sensor_info[s].catalog_index].type == SENSOR_TYPE_GYROSCOPE &&
+ if (sensor_info[s].type == SENSOR_TYPE_GYROSCOPE &&
sensor_info[s].pair_idx && sensor_info[sensor_info[s].pair_idx].enable_count != 0) {
struct gyro_cal* gyro_data = (struct gyro_cal*) sensor_info[s].cal_data;
}
+static void tentative_switch_trigger (int s)
+{
+ /*
+ * Under certain situations it may be beneficial to use an alternate
+ * trigger:
+ *
+ * - for applications using the accelerometer with high sampling rates,
+ * prefer the continuous trigger over the any-motion one, to avoid
+ * jumps related to motion thresholds
+ */
+
+ if (is_fast_accelerometer(s) &&
+ !(sensor_info[s].quirks & QUIRK_TERSE_DRIVER) &&
+ sensor_info[s].selected_trigger ==
+ sensor_info[s].motion_trigger_name)
+ setup_trigger(s, sensor_info[s].init_trigger_name);
+}
+
+
int sensor_set_delay(int s, int64_t ns)
{
/* Set the rate at which a specific sensor should report events */
}
}
-
if (max_supported_rate &&
new_sampling_rate > max_supported_rate) {
new_sampling_rate = max_supported_rate;
}
-
/* If the desired rate is already active we're all set */
if (new_sampling_rate == cur_sampling_rate)
return 0;
sysfs_write_float(sysfs_path, new_sampling_rate);
- /* Switch back to continuous sampling for accelerometer based games */
- if (is_fast_accelerometer(s) && sensor_info[s].selected_trigger !=
- sensor_info[s].init_trigger_name)
- setup_trigger(s, sensor_info[s].init_trigger_name);
+ /* Check if it makes sense to use an alternate trigger */
+ tentative_switch_trigger(s);
if (trig_sensors_per_dev[dev_num])
enable_buffer(dev_num, 1);