Merge "Fix comparison between signed and unsigned error on darwin" into mnc-dev
diff --git a/include/system/camera.h b/include/system/camera.h
index 09c915d..5d0873a 100644
--- a/include/system/camera.h
+++ b/include/system/camera.h
@@ -174,6 +174,22 @@
* count is non-positive or too big to be realized.
*/
CAMERA_CMD_SET_VIDEO_BUFFER_COUNT = 10,
+
+ /**
+ * Configure an explicit format to use for video recording metadata mode.
+ * This can be used to switch the format from the
+ * default IMPLEMENTATION_DEFINED gralloc format to some other
+ * device-supported format, and the default dataspace from the BT_709 color
+ * space to some other device-supported dataspace. arg1 is the HAL pixel
+ * format, and arg2 is the HAL dataSpace. This command returns
+ * INVALID_OPERATION error if it is sent after video recording is started,
+ * or the command is not supported at all.
+ *
+ * If the gralloc format is set to a format other than
+ * IMPLEMENTATION_DEFINED, then HALv3 devices will use gralloc usage flags
+ * of SW_READ_OFTEN.
+ */
+ CAMERA_CMD_SET_VIDEO_FORMAT = 11
};
/** camera fatal errors */
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 736e02e..e598bb8 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>
+#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -33,6 +34,7 @@
#include <log/logd.h>
#include <log/logger.h>
#include <log/logprint.h>
+#include <utils/threads.h>
#define DEFAULT_MAX_ROTATED_LOGS 4
@@ -221,6 +223,10 @@
fprintf(stderr, "failed to set to batch scheduler\n");
}
+ if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
+ fprintf(stderr, "failed set to priority\n");
+ }
+
g_outFD = openLogFile (g_outputFileName);
if (g_outFD < 0) {
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 8df0d0a..7d14648 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -36,6 +36,140 @@
static const char priority_message[] = { KMSG_PRIORITY(LOG_INFO), '\0' };
+// Parsing is hard
+
+// called if we see a '<', s is the next character, returns pointer after '>'
+static char *is_prio(char *s) {
+ if (!isdigit(*s++)) {
+ return NULL;
+ }
+ char c;
+ while ((c = *s++)) {
+ if (!isdigit(c) && (c == '>')) {
+ return s;
+ }
+ }
+ return NULL;
+}
+
+// called if we see a '[', s is the next character, returns pointer after ']'
+static char *is_timestamp(char *s) {
+ while (*s == ' ') {
+ ++s;
+ }
+ if (!isdigit(*s++)) {
+ return NULL;
+ }
+ bool first_period = true;
+ char c;
+ while ((c = *s++)) {
+ if ((c == '.') && first_period) {
+ first_period = false;
+ continue;
+ }
+ if (!isdigit(c) && (c == ']')) {
+ return s;
+ }
+ }
+ return NULL;
+}
+
+// Like strtok_r with "\r\n" except that we look for log signatures (regex)
+// \(\(<[0-9]+>\)\([[] *[0-9]+[]]\)\{0,1\}\|[[] *[0-9]+[]]\)
+// and split if we see a second one without a newline.
+
+#define SIGNATURE_MASK 0xF0
+// <digit> following ('0' to '9' masked with ~SIGNATURE_MASK) added to signature
+#define LESS_THAN_SIG SIGNATURE_MASK
+#define OPEN_BRACKET_SIG ((SIGNATURE_MASK << 1) & SIGNATURE_MASK)
+// space is one more than <digit> of 9
+#define OPEN_BRACKET_SPACE ((char)(OPEN_BRACKET_SIG | 10))
+
+char *log_strtok_r(char *s, char **last) {
+ if (!s) {
+ if (!(s = *last)) {
+ return NULL;
+ }
+ // fixup for log signature split <,
+ // LESS_THAN_SIG + <digit>
+ if ((*s & SIGNATURE_MASK) == LESS_THAN_SIG) {
+ *s = (*s & ~SIGNATURE_MASK) + '0';
+ *--s = '<';
+ }
+ // fixup for log signature split [,
+ // OPEN_BRACKET_SPACE is space, OPEN_BRACKET_SIG + <digit>
+ if ((*s & SIGNATURE_MASK) == OPEN_BRACKET_SIG) {
+ if (*s == OPEN_BRACKET_SPACE) {
+ *s = ' ';
+ } else {
+ *s = (*s & ~SIGNATURE_MASK) + '0';
+ }
+ *--s = '[';
+ }
+ }
+
+ s += strspn(s, "\r\n");
+
+ if (!*s) { // no non-delimiter characters
+ *last = NULL;
+ return NULL;
+ }
+ char *peek, *tok = s;
+
+ for (;;) {
+ char c = *s++;
+ switch (c) {
+ case '\0':
+ *last = NULL;
+ return tok;
+
+ case '\r':
+ case '\n':
+ s[-1] = '\0';
+ *last = s;
+ return tok;
+
+ case '<':
+ peek = is_prio(s);
+ if (!peek) {
+ break;
+ }
+ if (s != (tok + 1)) { // not first?
+ s[-1] = '\0';
+ *s &= ~SIGNATURE_MASK;
+ *s |= LESS_THAN_SIG; // signature for '<'
+ *last = s;
+ return tok;
+ }
+ s = peek;
+ if ((*s == '[') && ((peek = is_timestamp(s + 1)))) {
+ s = peek;
+ }
+ break;
+
+ case '[':
+ peek = is_timestamp(s);
+ if (!peek) {
+ break;
+ }
+ if (s != (tok + 1)) { // not first?
+ s[-1] = '\0';
+ if (*s == ' ') {
+ *s = OPEN_BRACKET_SPACE;
+ } else {
+ *s &= ~SIGNATURE_MASK;
+ *s |= OPEN_BRACKET_SIG; // signature for '['
+ }
+ *last = s;
+ return tok;
+ }
+ s = peek;
+ break;
+ }
+ }
+ /* NOTREACHED */
+}
+
log_time LogKlog::correction = log_time(CLOCK_REALTIME) - log_time(CLOCK_MONOTONIC);
LogKlog::LogKlog(LogBuffer *buf, LogReader *reader, int fdWrite, int fdRead, bool auditd) :
@@ -81,8 +215,8 @@
char *ep = buffer + len;
*ep = '\0';
len = 0;
- for(char *ptr, *tok = buffer;
- ((tok = strtok_r(tok, "\r\n", &ptr)));
+ for(char *ptr = NULL, *tok = buffer;
+ ((tok = log_strtok_r(tok, &ptr)));
tok = NULL) {
if (((tok + strlen(tok)) == ep) && (retval != 0) && full) {
len = strlen(tok);
diff --git a/logd/LogKlog.h b/logd/LogKlog.h
index 8de9c87..a898c63 100644
--- a/logd/LogKlog.h
+++ b/logd/LogKlog.h
@@ -21,6 +21,8 @@
#include <log/log_read.h>
#include "LogReader.h"
+char *log_strtok_r(char *str, char **saveptr);
+
class LogKlog : public SocketListener {
LogBuffer *logbuf;
LogReader *reader;
diff --git a/logd/main.cpp b/logd/main.cpp
index 6db819e..a876c99 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -27,6 +27,7 @@
#include <sys/capability.h>
#include <sys/klog.h>
#include <sys/prctl.h>
+#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <syslog.h>
@@ -37,6 +38,7 @@
#include <cutils/sockets.h>
#include <log/event_tag_map.h>
#include <private/android_filesystem_config.h>
+#include <utils/threads.h>
#include "CommandListener.h"
#include "LogBuffer.h"
@@ -91,6 +93,10 @@
return -1;
}
+ if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
+ return -1;
+ }
+
if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
return -1;
}
@@ -156,6 +162,7 @@
static void *reinit_thread_start(void * /*obj*/) {
prctl(PR_SET_NAME, "logd.daemon");
set_sched_policy(0, SP_BACKGROUND);
+ setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND);
setgid(AID_SYSTEM);
setuid(AID_SYSTEM);
@@ -417,8 +424,8 @@
kl->synchronize(buf);
}
- for (char *ptr, *tok = buf;
- (rc >= 0) && ((tok = strtok_r(tok, "\r\n", &ptr)));
+ for (char *ptr = NULL, *tok = buf;
+ (rc >= 0) && ((tok = log_strtok_r(tok, &ptr)));
tok = NULL) {
if (al) {
rc = al->log(tok);