+ if (sensor[s].type != SENSOR_TYPE_ACCELEROMETER)
+ return 0;
+
+ if (sensor[s].sampling_rate < 25)
+ return 0;
+
+ return 1;
+}
+
+
+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[s].quirks & QUIRK_TERSE_DRIVER) && sensor[s].selected_trigger == sensor[s].motion_trigger_name)
+ setup_trigger(s, sensor[s].init_trigger_name);
+}
+
+
+static float get_group_max_sampling_rate (int s)
+{
+ /* Review the sampling rates of linked sensors and return the maximum */
+
+ int i, vi;
+
+ float arbitrated_rate = 0;
+
+ if (is_enabled(s))
+ arbitrated_rate = sensor[s].requested_rate;
+
+ /* If any of the currently active sensors built on top of this one need a higher sampling rate, switch to this rate */
+ for (i = 0; i < sensor_count; i++)
+ for (vi = 0; vi < sensor[i].base_count; vi++)
+ if (sensor[i].base[vi] == s && is_enabled(i) && sensor[i].requested_rate > arbitrated_rate) /* If sensor i depends on sensor s */
+ arbitrated_rate = sensor[i].requested_rate;
+
+ /* If any of the currently active sensors we rely on is using a higher sampling rate, switch to this rate */
+ for (vi = 0; vi < sensor[s].base_count; vi++) {
+ i = sensor[s].base[vi];
+ if (is_enabled(i) && sensor[i].requested_rate > arbitrated_rate)
+ arbitrated_rate = sensor[i].requested_rate;
+ }
+
+ return arbitrated_rate;
+}
+
+
+static int sensor_set_rate (int s, float requested_rate)
+{
+ /* Set the rate at which a specific sensor should report events. See Android sensors.h for indication on sensor trigger modes */
+
+ char sysfs_path[PATH_MAX];
+ char avail_sysfs_path[PATH_MAX];
+ int dev_num = sensor[s].dev_num;
+ int i = sensor[s].catalog_index;
+ const char *prefix = sensor_catalog[i].tag;
+ int per_sensor_sampling_rate;
+ int per_device_sampling_rate;
+ char freqs_buf[100];
+ char* cursor;
+ int n;
+ float sr;
+ float group_max_sampling_rate;
+ float cur_sampling_rate; /* Currently used sampling rate */
+ float arb_sampling_rate; /* Granted sampling rate after arbitration */
+
+ ALOGV("Sampling rate %g requested on sensor %d (%s)\n", requested_rate, s, sensor[s].friendly_name);
+
+ sensor[s].requested_rate = requested_rate;
+
+ arb_sampling_rate = requested_rate;
+
+ if (arb_sampling_rate < sensor[s].min_supported_rate) {
+ ALOGV("Sampling rate %g too low for %s, using %g instead\n", arb_sampling_rate, sensor[s].friendly_name, sensor[s].min_supported_rate);
+ arb_sampling_rate = sensor[s].min_supported_rate;
+ }
+
+ /* If one of the linked sensors uses a higher rate, adopt it */
+ group_max_sampling_rate = get_group_max_sampling_rate(s);
+
+ if (arb_sampling_rate < group_max_sampling_rate) {
+ ALOGV("Using %s sampling rate to %g too due to dependency\n", sensor[s].friendly_name, arb_sampling_rate);
+ arb_sampling_rate = group_max_sampling_rate;
+ }
+
+ if (sensor[s].max_supported_rate && arb_sampling_rate > sensor[s].max_supported_rate) {
+ ALOGV("Sampling rate %g too high for %s, using %g instead\n", arb_sampling_rate, sensor[s].friendly_name, sensor[s].max_supported_rate);
+ arb_sampling_rate = sensor[s].max_supported_rate;
+ }
+
+ sensor[s].sampling_rate = arb_sampling_rate;
+
+ /* If the sensor is virtual, we're done */
+ if (sensor[s].is_virtual)
+ return 0;
+
+ /* If we're dealing with a poll-mode sensor */
+ if (sensor[s].mode == MODE_POLL) {
+ if (is_enabled(s))
+ pthread_cond_signal(&thread_release_cond[s]); /* Wake up thread so the new sampling rate gets used */
+ return 0;
+ }
+
+ sprintf(sysfs_path, SENSOR_SAMPLING_PATH, dev_num, prefix);
+
+ if (sysfs_read_float(sysfs_path, &cur_sampling_rate) != -1) {
+ per_sensor_sampling_rate = 1;
+ per_device_sampling_rate = 0;
+ } else {
+ per_sensor_sampling_rate = 0;
+
+ sprintf(sysfs_path, DEVICE_SAMPLING_PATH, dev_num);
+
+ if (sysfs_read_float(sysfs_path, &cur_sampling_rate) != -1)
+ per_device_sampling_rate = 1;
+ else
+ per_device_sampling_rate = 0;
+ }
+
+ if (!per_sensor_sampling_rate && !per_device_sampling_rate) {
+ ALOGE("No way to adjust sampling rate on sensor %d\n", s);
+ return -ENOSYS;
+ }
+
+ /* Check if we have contraints on allowed sampling rates */
+
+ sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num);
+
+ if (sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf)) > 0) {
+ cursor = freqs_buf;
+
+ /* Decode allowed sampling rates string, ex: "10 20 50 100" */
+
+ /* While we're not at the end of the string */
+ while (*cursor && cursor[0]) {