merge in lmp-release history after reset to 2ab32d6915eee0e0c175f0c5ae9d78ab0a90791d
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index ffc8714..f142095 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -119,7 +119,6 @@
dump_file("BUDDYINFO", "/proc/buddyinfo");
dump_file("FRAGMENTATION INFO", "/d/extfrag/unusable_index");
-
dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
dump_file("KERNEL WAKE SOURCES", "/d/wakeup_sources");
dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
@@ -134,6 +133,8 @@
do_dmesg();
run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
+ for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
+ for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
if (screenshot_path[0]) {
ALOGI("taking screenshot\n");
@@ -141,9 +142,6 @@
ALOGI("wrote screenshot: %s\n", screenshot_path);
}
- for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
- for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
-
// dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
@@ -382,14 +380,17 @@
_exit(EXIT_FAILURE);
}
+static void vibrate(FILE* vibrator, int ms) {
+ fprintf(vibrator, "%d\n", ms);
+ fflush(vibrator);
+}
+
int main(int argc, char *argv[]) {
struct sigaction sigact;
int do_add_date = 0;
int do_compress = 0;
int do_vibrate = 1;
char* use_outfile = 0;
- char* begin_sound = 0;
- char* end_sound = 0;
int use_socket = 0;
int do_fb = 0;
int do_broadcast = 0;
@@ -402,14 +403,14 @@
// correct program.
return execl("/system/bin/bugreport", "/system/bin/bugreport", NULL);
}
+
ALOGI("begin\n");
-
+ /* clear SIGPIPE handler */
memset(&sigact, 0, sizeof(sigact));
sigact.sa_handler = sigpipe_handler;
sigaction(SIGPIPE, &sigact, NULL);
-
/* set as high priority, and protect from OOM killer */
setpriority(PRIO_PROCESS, 0, -20);
FILE *oom_adj = fopen("/proc/self/oom_adj", "w");
@@ -418,15 +419,11 @@
fclose(oom_adj);
}
- /* very first thing, collect stack traces from Dalvik and native processes (needs root) */
- dump_traces_path = dump_traces();
-
+ /* parse arguments */
int c;
- while ((c = getopt(argc, argv, "b:de:ho:svqzpB")) != -1) {
+ while ((c = getopt(argc, argv, "dho:svqzpB")) != -1) {
switch (c) {
- case 'b': begin_sound = optarg; break;
case 'd': do_add_date = 1; break;
- case 'e': end_sound = optarg; break;
case 'o': use_outfile = optarg; break;
case 's': use_socket = 1; break;
case 'v': break; // compatibility no-op
@@ -441,11 +438,14 @@
}
}
+ /* open the vibrator before dropping root */
FILE *vibrator = 0;
if (do_vibrate) {
- /* open the vibrator before dropping root */
vibrator = fopen("/sys/class/timed_output/vibrator/enable", "w");
- if (vibrator) fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
+ if (vibrator) {
+ fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
+ vibrate(vibrator, 150);
+ }
}
/* read /proc/cmdline before dropping root */
@@ -455,14 +455,18 @@
fclose(cmdline);
}
+ /* collect stack traces from Dalvik and native processes (needs root) */
+ dump_traces_path = dump_traces();
+
+ /* Get the tombstone fds here while we are running as root. */
+ get_tombstone_fds(tombstone_data);
+
+ /* ensure we will keep capabilities when we drop root */
if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
return -1;
}
- /* Get the tombstone fds here while we are running as root. */
- get_tombstone_fds(tombstone_data);
-
/* switch to non-root user and group */
gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW,
AID_MOUNT, AID_INET, AID_NET_BW_STATS };
@@ -496,6 +500,7 @@
return -1;
}
+ /* redirect output if needed */
char path[PATH_MAX], tmp_path[PATH_MAX];
pid_t gzip_pid = -1;
@@ -520,22 +525,12 @@
gzip_pid = redirect_to_file(stdout, tmp_path, do_compress);
}
- if (begin_sound) {
- play_sound(begin_sound);
- } else if (vibrator) {
- fputs("150", vibrator);
- fflush(vibrator);
- }
-
dumpstate();
- if (end_sound) {
- play_sound(end_sound);
- } else if (vibrator) {
- int i;
- for (i = 0; i < 3; i++) {
- fputs("75\n", vibrator);
- fflush(vibrator);
+ /* done */
+ if (vibrator) {
+ for (int i = 0; i < 3; i++) {
+ vibrate(vibrator, 75);
usleep((75 + 50) * 1000);
}
fclose(vibrator);
@@ -552,6 +547,7 @@
fprintf(stderr, "rename(%s, %s): %s\n", tmp_path, path, strerror(errno));
}
+ /* tell activity manager we're done */
if (do_broadcast && use_outfile && do_fb) {
run_command(NULL, 5, "/system/bin/am", "broadcast", "--user", "0",
"-a", "android.intent.action.BUGREPORT_FINISHED",
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index c8ee75e..e3042eb 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -42,6 +42,8 @@
#include "dumpstate.h"
+static const int64_t NANOS_PER_SEC = 1000000000;
+
/* list of native processes to include in the native dumps */
static const char* native_processes_to_dump[] = {
"/system/bin/drmserver",
@@ -293,10 +295,16 @@
return 0;
}
+static int64_t nanotime() {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (int64_t)ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
+}
+
/* forks a command and waits for it to finish */
int run_command(const char *title, int timeout_seconds, const char *command, ...) {
fflush(stdout);
- time_t start = time(NULL);
+ int64_t start = nanotime();
pid_t pid = fork();
/* handle error case */
@@ -340,18 +348,18 @@
for (;;) {
int status;
pid_t p = waitpid(pid, &status, WNOHANG);
- time_t elapsed = time(NULL) - start;
+ int64_t elapsed = nanotime() - start;
if (p == pid) {
if (WIFSIGNALED(status)) {
printf("*** %s: Killed by signal %d\n", command, WTERMSIG(status));
} else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
printf("*** %s: Exit code %d\n", command, WEXITSTATUS(status));
}
- if (title) printf("[%s: %ds elapsed]\n\n", command, (int) elapsed);
+ if (title) printf("[%s: %.3fs elapsed]\n\n", command, (float)elapsed / NANOS_PER_SEC);
return status;
}
- if (timeout_seconds && elapsed > timeout_seconds) {
+ if (timeout_seconds && elapsed / NANOS_PER_SEC > timeout_seconds) {
printf("*** %s: Timed out after %ds (killing pid %d)\n", command, (int) elapsed, pid);
kill(pid, SIGTERM);
return -1;
@@ -578,9 +586,9 @@
if (!strncmp(data, "/system/bin/app_process", strlen("/system/bin/app_process"))) {
/* skip zygote -- it won't dump its stack anyway */
snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
- int fd = open(path, O_RDONLY);
- len = read(fd, data, sizeof(data) - 1);
- close(fd);
+ int cfd = open(path, O_RDONLY);
+ len = read(cfd, data, sizeof(data) - 1);
+ close(cfd);
if (len <= 0) {
continue;
}
@@ -590,6 +598,7 @@
}
++dalvik_found;
+ int64_t start = nanotime();
if (kill(pid, SIGQUIT)) {
fprintf(stderr, "kill(%d, SIGQUIT): %s\n", pid, strerror(errno));
continue;
@@ -606,12 +615,24 @@
struct inotify_event ie;
read(ifd, &ie, sizeof(ie));
}
+
+ if (lseek(fd, 0, SEEK_END) < 0) {
+ fprintf(stderr, "lseek: %s\n", strerror(errno));
+ } else {
+ snprintf(data, sizeof(data), "[dump dalvik stack %d: %.3fs elapsed]\n",
+ pid, (float)(nanotime() - start) / NANOS_PER_SEC);
+ write(fd, data, strlen(data));
+ }
} else if (should_dump_native_traces(data)) {
/* dump native process if appropriate */
if (lseek(fd, 0, SEEK_END) < 0) {
fprintf(stderr, "lseek: %s\n", strerror(errno));
} else {
+ int64_t start = nanotime();
dump_backtrace_to_file(pid, fd);
+ snprintf(data, sizeof(data), "[dump native stack %d: %.3fs elapsed]\n",
+ pid, (float)(nanotime() - start) / NANOS_PER_SEC);
+ write(fd, data, strlen(data));
}
}
}
@@ -639,10 +660,6 @@
return result;
}
-void play_sound(const char* path) {
- run_command(NULL, 5, "/system/bin/stagefright", "-o", "-a", path, NULL);
-}
-
void dump_route_tables() {
const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables";
dump_file("RT_TABLES", RT_TABLES_PATH);
diff --git a/data/etc/android.software.managed_profiles.xml b/data/etc/android.software.managed_users.xml
similarity index 89%
rename from data/etc/android.software.managed_profiles.xml
rename to data/etc/android.software.managed_users.xml
index 532a543..56affe9 100644
--- a/data/etc/android.software.managed_profiles.xml
+++ b/data/etc/android.software.managed_users.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<!-- This is the standard feature indicating that the device supports managed profiles. -->
+<!-- This is the standard feature indicating that the device supports managed users. -->
<permissions>
- <feature name="android.software.managed_profiles" />
+ <feature name="android.software.managed_users" />
</permissions>
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index 7d70a5d..d923eec 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -46,8 +46,8 @@
<!-- Feature to specify if the device supports adding device admins. -->
<feature name="android.software.device_admin" />
- <!-- Feature to specify if the device support managed profiles. -->
- <feature name="android.software.managed_profiles" />
+ <!-- Feature to specify if the device support managed users. -->
+ <feature name="android.software.managed_users" />
<!-- devices with GPS must include android.hardware.location.gps.xml -->
<!-- devices with an autofocus camera and/or flash must include either
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
index 321b2af..8128165 100644
--- a/data/etc/tablet_core_hardware.xml
+++ b/data/etc/tablet_core_hardware.xml
@@ -47,8 +47,8 @@
<!-- Feature to specify if the device supports adding device admins. -->
<feature name="android.software.device_admin" />
- <!-- Feature to specify if the device support managed profiles. -->
- <feature name="android.software.managed_profiles" />
+ <!-- Feature to specify if the device support managed users. -->
+ <feature name="android.software.managed_users" />
<!-- devices with GPS must include android.hardware.location.gps.xml -->
<!-- devices with a rear-facing camera must include one of these as appropriate:
diff --git a/include/gui/SensorEventQueue.h b/include/gui/SensorEventQueue.h
index 5402f37..019308d 100644
--- a/include/gui/SensorEventQueue.h
+++ b/include/gui/SensorEventQueue.h
@@ -27,7 +27,7 @@
#include <gui/BitTube.h>
// ----------------------------------------------------------------------------
-#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 30)
+#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 31)
struct ALooper;
struct ASensorEvent;
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index bae05a8..b4291bb 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -56,7 +56,7 @@
// Set fifo event count zero for older devices which do not support batching. Fused
// sensors also have their fifo counts set to zero.
- if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
+ if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) {
mFifoReservedEventCount = hwSensor->fifoReservedEventCount;
mFifoMaxEventCount = hwSensor->fifoMaxEventCount;
} else {
@@ -206,10 +206,10 @@
break;
default:
// Only pipe the stringType, requiredPermission and flags for custom sensors.
- if (halVersion >= SENSORS_DEVICE_API_VERSION_1_2 && hwSensor->stringType) {
+ if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->stringType) {
mStringType = hwSensor->stringType;
}
- if (halVersion >= SENSORS_DEVICE_API_VERSION_1_2 && hwSensor->requiredPermission) {
+ if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->requiredPermission) {
mRequiredPermission = hwSensor->requiredPermission;
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index ef87e5c..b0695ba 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -186,6 +186,11 @@
mWakeLockAcquired = false;
run("SensorService", PRIORITY_URGENT_DISPLAY);
mLooper = new Looper(false);
+
+ const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
+ mSensorEventBuffer = new sensors_event_t[minBufferSize];
+ mSensorEventScratch = new sensors_event_t[minBufferSize];
+ mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
mInitCheck = NO_ERROR;
}
}
@@ -350,6 +355,9 @@
sensors_event_t const* buffer, const int count) {
for (int i=0 ; i<count ; i++) {
int handle = buffer[i].sensor;
+ if (buffer[i].type == SENSOR_TYPE_META_DATA) {
+ handle = buffer[i].meta_data.sensor;
+ }
if (connection->hasSensor(handle)) {
SensorInterface* sensor = mSensorMap.valueFor(handle);
// If this buffer has an event from a one_shot sensor and this connection is registered
@@ -373,25 +381,22 @@
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
- sensors_event_t buffer[minBufferSize];
- sensors_event_t scratch[minBufferSize];
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();
SensorEventAckReceiver sender(this);
sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
- ssize_t count;
const int halVersion = device.getHalDeviceVersion();
do {
- count = device.poll(buffer, numEventMax);
- if (count<0) {
+ ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
+ if (count < 0) {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
}
// Reset sensors_event_t.flags to zero for all events in the buffer.
for (int i = 0; i < count; i++) {
- buffer[i].flags = 0;
+ mSensorEventBuffer[i].flags = 0;
}
Mutex::Autolock _l(mLock);
// Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
@@ -401,7 +406,7 @@
// releasing the wakelock.
bool bufferHasWakeUpEvent = false;
for (int i = 0; i < count; i++) {
- if (isWakeUpSensorEvent(buffer[i])) {
+ if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
bufferHasWakeUpEvent = true;
break;
}
@@ -412,11 +417,11 @@
mWakeLockAcquired = true;
ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock %s", WAKE_LOCK_NAME);
}
- recordLastValueLocked(buffer, count);
+ recordLastValueLocked(mSensorEventBuffer, count);
// handle virtual sensors
if (count && vcount) {
- sensors_event_t const * const event = buffer;
+ sensors_event_t const * const event = mSensorEventBuffer;
const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();
if (activeVirtualSensorCount) {
size_t k = 0;
@@ -437,17 +442,17 @@
sensors_event_t out;
SensorInterface* si = mActiveVirtualSensors.valueAt(j);
if (si->process(&out, event[i])) {
- buffer[count + k] = out;
+ mSensorEventBuffer[count + k] = out;
k++;
}
}
}
if (k) {
// record the last synthesized values
- recordLastValueLocked(&buffer[count], k);
+ recordLastValueLocked(&mSensorEventBuffer[count], k);
count += k;
// sort the buffer by time-stamps
- sortEventBuffer(buffer, count);
+ sortEventBuffer(mSensorEventBuffer, count);
}
}
}
@@ -455,10 +460,26 @@
// handle backward compatibility for RotationVector sensor
if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
for (int i = 0; i < count; i++) {
- if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
+ if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
// All the 4 components of the quaternion should be available
// No heading accuracy. Set it to -1
- buffer[i].data[4] = -1;
+ mSensorEventBuffer[i].data[4] = -1;
+ }
+ }
+ }
+
+ // Map flush_complete_events in the buffer to SensorEventConnections which called
+ // flush on the hardware sensor. mapFlushEventsToConnections[i] will be the
+ // SensorEventConnection mapped to the corresponding flush_complete_event in
+ // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).
+ for (int i = 0; i < count; ++i) {
+ mMapFlushEventsToConnections[i] = NULL;
+ if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
+ const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
+ SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);
+ if (rec != NULL) {
+ mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();
+ rec->removeFirstPendingFlushConnection();
}
}
}
@@ -466,13 +487,22 @@
// Send our events to clients. Check the state of wake lock for each client and release the
// lock if none of the clients need it.
bool needsWakeLock = false;
- for (size_t i=0 ; i < mActiveConnections.size(); i++) {
- sp<SensorEventConnection> connection(mActiveConnections[i].promote());
+ // Make a copy of the connection vector as some connections may be removed during the
+ // course of this loop (especially when one-shot sensor events are present in the
+ // sensor_event buffer).
+ const SortedVector< wp<SensorEventConnection> > activeConnections(mActiveConnections);
+ size_t numConnections = activeConnections.size();
+ for (size_t i=0 ; i < numConnections; ++i) {
+ sp<SensorEventConnection> connection(activeConnections[i].promote());
if (connection != 0) {
- connection->sendEvents(buffer, count, scratch);
+ connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
+ mMapFlushEventsToConnections);
needsWakeLock |= connection->needsWakeLock();
- // Some sensors need to be auto disabled after the trigger
- cleanupAutoDisabledSensorLocked(connection, buffer, count);
+ // If the connection has one-shot sensors, it may be cleaned up after first trigger.
+ // Early check for one-shot sensors.
+ if (connection->hasOneShotSensors()) {
+ cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count);
+ }
}
}
@@ -481,7 +511,7 @@
mWakeLockAcquired = false;
ALOGD_IF(DEBUG_CONNECTIONS, "released wakelock %s", WAKE_LOCK_NAME);
}
- } while (count >= 0 || Thread::exitPending());
+ } while (!Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
abort();
@@ -823,7 +853,7 @@
continue;
}
SensorEventConnection::FlushInfo& flushInfo = connection->mSensorInfo.editValueFor(handle);
- if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || isVirtualSensor(handle)) {
+ if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
// For older devices just increment pending flush count which will send a trivial
// flush complete event.
flushInfo.mPendingFlushEventsToSend++;
@@ -1030,6 +1060,17 @@
return mSensorInfo.size() ? true : false;
}
+bool SensorService::SensorEventConnection::hasOneShotSensors() const {
+ Mutex::Autolock _l(mConnectionLock);
+ for (size_t i = 0; i < mSensorInfo.size(); ++i) {
+ const int handle = mSensorInfo.keyAt(i);
+ if (mService->getSensorFromHandle(handle).getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
+ return true;
+ }
+ }
+ return false;
+}
+
void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
bool value) {
Mutex::Autolock _l(mConnectionLock);
@@ -1042,19 +1083,14 @@
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t* buffer, size_t numEvents,
- sensors_event_t* scratch) {
+ sensors_event_t* scratch,
+ SensorEventConnection const * const * mapFlushEventsToConnections) {
// filter out events not for this connection
size_t count = 0;
Mutex::Autolock _l(mConnectionLock);
if (scratch) {
size_t i=0;
while (i<numEvents) {
- // Flush complete events can be invalidated. If this event has been invalidated
- // before, ignore and proceed to the next event.
- if (buffer[i].flags & SENSOR_EVENT_INVALID_FLAG) {
- ++i;
- continue;
- }
int32_t sensor_handle = buffer[i].sensor;
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
@@ -1073,19 +1109,13 @@
FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
// Check if there is a pending flush_complete event for this sensor on this connection.
- if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true) {
- SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle);
- if (rec && rec->getFirstPendingFlushConnection() == this) {
- rec->removeFirstPendingFlushConnection();
- flushInfo.mFirstFlushPending = false;
- // Invalidate this flush_complete_event so that it cannot be used by other
- // connections.
- buffer[i].flags |= SENSOR_EVENT_INVALID_FLAG;
- ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
- buffer[i].meta_data.sensor);
- ++i;
- continue;
- }
+ if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
+ this == mapFlushEventsToConnections[i]) {
+ flushInfo.mFirstFlushPending = false;
+ ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
+ buffer[i].meta_data.sensor);
+ ++i;
+ continue;
}
// If there is a pending flush complete event for this sensor on this connection,
@@ -1096,27 +1126,21 @@
}
do {
- if (buffer[i].flags & SENSOR_EVENT_INVALID_FLAG) {
- ++i;
- continue;
- }
+ // Keep copying events into the scratch buffer as long as they are regular
+ // sensor_events are from the same sensor_handle OR they are flush_complete_events
+ // from the same sensor_handle AND the current connection is mapped to the
+ // corresponding flush_complete_event.
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
- // Check if this connection has called flush() on this sensor. Only if
- // a flush() has been explicitly called, send a flush_complete_event.
- SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle);
- if (rec && rec->getFirstPendingFlushConnection() == this) {
- rec->removeFirstPendingFlushConnection();
+ if (this == mapFlushEventsToConnections[i]) {
scratch[count++] = buffer[i];
- // Invalidate this flush_complete_event so that it cannot be used by
- // other connections.
- buffer[i].flags |= SENSOR_EVENT_INVALID_FLAG;
}
++i;
} else {
// Regular sensor event, just copy it to the scratch buffer.
scratch[count++] = buffer[i++];
}
- } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle) ||
+ } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
+ buffer[i].type != SENSOR_TYPE_META_DATA) ||
(buffer[i].type == SENSOR_TYPE_META_DATA &&
buffer[i].meta_data.sensor == sensor_handle)));
}
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 0887f28..9654f65 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -45,14 +45,6 @@
// For older HALs which don't support batching, use a smaller socket buffer size.
#define SOCKET_BUFFER_SIZE_NON_BATCHED 4 * 1024
-// Flags for sensors_event_t.flag. Using only the most significant two bits for flags.
-// MSB is to invalidate a sensor_event (typically a flush_complete_event) so that
-// it won't be used by other connections.
-// MSB 2nd bit is used to indicate whether the event needs to be acknowledged or not.
-// This is typically used for WAKE_UP sensors. WAKE_UP_SENSOR_EVENT_NEEDS_ACK is defined
-// in SensorEveneQueue.h
-#define SENSOR_EVENT_INVALID_FLAG (1U << 31)
-
struct sensors_poll_device_t;
struct sensors_module_t;
@@ -157,9 +149,11 @@
SensorEventConnection(const sp<SensorService>& service, uid_t uid);
status_t sendEvents(sensors_event_t* buffer, size_t count,
- sensors_event_t* scratch);
+ sensors_event_t* scratch,
+ SensorEventConnection const * const * mapFlushEventsToConnections = NULL);
bool hasSensor(int32_t handle) const;
bool hasAnySensor() const;
+ bool hasOneShotSensors() const;
bool addSensor(int32_t handle);
bool removeSensor(int32_t handle);
void setFirstFlushPending(int32_t handle, bool value);
@@ -237,6 +231,9 @@
DefaultKeyedVector<int, SensorInterface*> mActiveVirtualSensors;
SortedVector< wp<SensorEventConnection> > mActiveConnections;
bool mWakeLockAcquired;
+ sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
+ SensorEventConnection const **mMapFlushEventsToConnections;
+
// The size of this vector is constant, only the items are mutable
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;