Merge "Give adb a proper progress bar."
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 6800ad2..46bad4e 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -699,7 +699,10 @@
GRSurface** scale_frames;
int scale_count;
- ret = res_create_multi_display_surface("charger/battery_scale", &scale_count, &scale_frames);
+ int scale_fps; // Not in use (charger/battery_scale doesn't have FPS text
+ // chunk). We are using hard-coded frame.disp_time instead.
+ ret = res_create_multi_display_surface("charger/battery_scale", &scale_count, &scale_fps,
+ &scale_frames);
if (ret < 0) {
LOGE("Cannot load battery_scale image\n");
charger->batt_anim->num_frames = 0;
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index e2133e9..d236938 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -81,6 +81,8 @@
#define AID_SHARED_RELRO 1037 /* creator of shared GNU RELRO files */
#define AID_DBUS 1038 /* dbus-daemon IPC broker process */
#define AID_TLSDATE 1039 /* tlsdate unprivileged user */
+#define AID_MEDIA_EX 1040 /* mediaextractor process */
+#define AID_AUDIOSERVER 1041 /* audioserver process */
#define AID_SHELL 2000 /* adb and debug shell user */
#define AID_CACHE 2001 /* cache access */
@@ -179,6 +181,8 @@
{ "shared_relro", AID_SHARED_RELRO, },
{ "dbus", AID_DBUS, },
{ "tlsdate", AID_TLSDATE, },
+ { "mediaex", AID_MEDIA_EX, },
+ { "audioserver", AID_AUDIOSERVER, },
{ "shell", AID_SHELL, },
{ "cache", AID_CACHE, },
diff --git a/liblog/log_read.c b/liblog/log_read.c
index 8aa887b..1aff272 100644
--- a/liblog/log_read.c
+++ b/liblog/log_read.c
@@ -501,6 +501,14 @@
remaining -= n;
cp += n;
}
+
+ if (logger_list->pid) {
+ n = snprintf(cp, remaining, " pid=%u", logger_list->pid);
+ n = min(n, remaining);
+ remaining -= n;
+ cp += n;
+ }
+
return send_log_msg(NULL, NULL, buf, len);
}
@@ -880,18 +888,10 @@
sigaction(SIGALRM, &old_sigaction, NULL);
}
- if (ret <= 0) {
- if ((ret == -1) && e) {
- return -e;
- }
- return ret;
+ if ((ret == -1) && e) {
+ return -e;
}
-
- logger_for_each(logger, logger_list) {
- if (log_msg->entry.lid == logger->id) {
- return ret;
- }
- }
+ return ret;
}
/* NOTREACH */
return ret;
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index b594634..9f29a09 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -14,11 +14,17 @@
* limitations under the License.
*/
+#include <fcntl.h>
+#include <sys/endian.h>
#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
#include <cutils/sockets.h>
#include <log/log.h>
#include <log/logger.h>
#include <log/log_read.h>
+#include <private/android_logger.h>
#include "benchmark.h"
@@ -85,6 +91,380 @@
BENCHMARK(BM_clock_overhead);
/*
+ * Measure the time it takes to submit the android logging data to pstore
+ */
+static void BM_pmsg_short(int iters) {
+
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ if (pstore_fd < 0) {
+ return;
+ }
+
+ /*
+ * struct {
+ * // what we provide to pstore
+ * android_pmsg_log_header_t pmsg_header;
+ * // what we provide to socket
+ * android_log_header_t header;
+ * // caller provides
+ * union {
+ * struct {
+ * char prio;
+ * char payload[];
+ * } string;
+ * struct {
+ * uint32_t tag
+ * char payload[];
+ * } binary;
+ * };
+ * };
+ */
+
+ struct timespec ts;
+ clock_gettime(android_log_clockid(), &ts);
+
+ android_pmsg_log_header_t pmsg_header;
+ pmsg_header.magic = LOGGER_MAGIC;
+ pmsg_header.len = sizeof(android_pmsg_log_header_t)
+ + sizeof(android_log_header_t);
+ pmsg_header.uid = getuid();
+ pmsg_header.pid = getpid();
+
+ android_log_header_t header;
+ header.tid = gettid();
+ header.realtime.tv_sec = ts.tv_sec;
+ header.realtime.tv_nsec = ts.tv_nsec;
+
+ static const unsigned nr = 1;
+ static const unsigned header_length = 2;
+ struct iovec newVec[nr + header_length];
+
+ newVec[0].iov_base = (unsigned char *) &pmsg_header;
+ newVec[0].iov_len = sizeof(pmsg_header);
+ newVec[1].iov_base = (unsigned char *) &header;
+ newVec[1].iov_len = sizeof(header);
+
+ android_log_event_int_t buffer;
+
+ header.id = LOG_ID_EVENTS;
+ buffer.header.tag = 0;
+ buffer.payload.type = EVENT_TYPE_INT;
+ uint32_t snapshot = 0;
+ buffer.payload.data = htole32(snapshot);
+
+ newVec[2].iov_base = &buffer;
+ newVec[2].iov_len = sizeof(buffer);
+
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; ++i) {
+ ++snapshot;
+ buffer.payload.data = htole32(snapshot);
+ writev(pstore_fd, newVec, nr);
+ }
+ StopBenchmarkTiming();
+ close(pstore_fd);
+}
+BENCHMARK(BM_pmsg_short);
+
+/*
+ * Measure the time it takes to submit the android logging data to pstore
+ * best case aligned single block.
+ */
+static void BM_pmsg_short_aligned(int iters) {
+
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ if (pstore_fd < 0) {
+ return;
+ }
+
+ /*
+ * struct {
+ * // what we provide to pstore
+ * android_pmsg_log_header_t pmsg_header;
+ * // what we provide to socket
+ * android_log_header_t header;
+ * // caller provides
+ * union {
+ * struct {
+ * char prio;
+ * char payload[];
+ * } string;
+ * struct {
+ * uint32_t tag
+ * char payload[];
+ * } binary;
+ * };
+ * };
+ */
+
+ struct timespec ts;
+ clock_gettime(android_log_clockid(), &ts);
+
+ struct packet {
+ android_pmsg_log_header_t pmsg_header;
+ android_log_header_t header;
+ android_log_event_int_t payload;
+ };
+ char buf[sizeof(struct packet) + 8] __aligned(8);
+ memset(buf, 0, sizeof(buf));
+ struct packet *buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7);
+ if (((uintptr_t)&buffer->pmsg_header) & 7) {
+ fprintf (stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters);
+ }
+
+ buffer->pmsg_header.magic = LOGGER_MAGIC;
+ buffer->pmsg_header.len = sizeof(android_pmsg_log_header_t)
+ + sizeof(android_log_header_t);
+ buffer->pmsg_header.uid = getuid();
+ buffer->pmsg_header.pid = getpid();
+
+ buffer->header.tid = gettid();
+ buffer->header.realtime.tv_sec = ts.tv_sec;
+ buffer->header.realtime.tv_nsec = ts.tv_nsec;
+
+ buffer->header.id = LOG_ID_EVENTS;
+ buffer->payload.header.tag = 0;
+ buffer->payload.payload.type = EVENT_TYPE_INT;
+ uint32_t snapshot = 0;
+ buffer->payload.payload.data = htole32(snapshot);
+
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; ++i) {
+ ++snapshot;
+ buffer->payload.payload.data = htole32(snapshot);
+ write(pstore_fd, &buffer->pmsg_header,
+ sizeof(android_pmsg_log_header_t) +
+ sizeof(android_log_header_t) +
+ sizeof(android_log_event_int_t));
+ }
+ StopBenchmarkTiming();
+ close(pstore_fd);
+}
+BENCHMARK(BM_pmsg_short_aligned);
+
+/*
+ * Measure the time it takes to submit the android logging data to pstore
+ * best case aligned single block.
+ */
+static void BM_pmsg_short_unaligned1(int iters) {
+
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ if (pstore_fd < 0) {
+ return;
+ }
+
+ /*
+ * struct {
+ * // what we provide to pstore
+ * android_pmsg_log_header_t pmsg_header;
+ * // what we provide to socket
+ * android_log_header_t header;
+ * // caller provides
+ * union {
+ * struct {
+ * char prio;
+ * char payload[];
+ * } string;
+ * struct {
+ * uint32_t tag
+ * char payload[];
+ * } binary;
+ * };
+ * };
+ */
+
+ struct timespec ts;
+ clock_gettime(android_log_clockid(), &ts);
+
+ struct packet {
+ android_pmsg_log_header_t pmsg_header;
+ android_log_header_t header;
+ android_log_event_int_t payload;
+ };
+ char buf[sizeof(struct packet) + 8] __aligned(8);
+ memset(buf, 0, sizeof(buf));
+ struct packet *buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1);
+ if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) {
+ fprintf (stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters);
+ }
+
+ buffer->pmsg_header.magic = LOGGER_MAGIC;
+ buffer->pmsg_header.len = sizeof(android_pmsg_log_header_t)
+ + sizeof(android_log_header_t);
+ buffer->pmsg_header.uid = getuid();
+ buffer->pmsg_header.pid = getpid();
+
+ buffer->header.tid = gettid();
+ buffer->header.realtime.tv_sec = ts.tv_sec;
+ buffer->header.realtime.tv_nsec = ts.tv_nsec;
+
+ buffer->header.id = LOG_ID_EVENTS;
+ buffer->payload.header.tag = 0;
+ buffer->payload.payload.type = EVENT_TYPE_INT;
+ uint32_t snapshot = 0;
+ buffer->payload.payload.data = htole32(snapshot);
+
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; ++i) {
+ ++snapshot;
+ buffer->payload.payload.data = htole32(snapshot);
+ write(pstore_fd, &buffer->pmsg_header,
+ sizeof(android_pmsg_log_header_t) +
+ sizeof(android_log_header_t) +
+ sizeof(android_log_event_int_t));
+ }
+ StopBenchmarkTiming();
+ close(pstore_fd);
+}
+BENCHMARK(BM_pmsg_short_unaligned1);
+
+/*
+ * Measure the time it takes to submit the android logging data to pstore
+ * best case aligned single block.
+ */
+static void BM_pmsg_long_aligned(int iters) {
+
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ if (pstore_fd < 0) {
+ return;
+ }
+
+ /*
+ * struct {
+ * // what we provide to pstore
+ * android_pmsg_log_header_t pmsg_header;
+ * // what we provide to socket
+ * android_log_header_t header;
+ * // caller provides
+ * union {
+ * struct {
+ * char prio;
+ * char payload[];
+ * } string;
+ * struct {
+ * uint32_t tag
+ * char payload[];
+ * } binary;
+ * };
+ * };
+ */
+
+ struct timespec ts;
+ clock_gettime(android_log_clockid(), &ts);
+
+ struct packet {
+ android_pmsg_log_header_t pmsg_header;
+ android_log_header_t header;
+ android_log_event_int_t payload;
+ };
+ char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD] __aligned(8);
+ memset(buf, 0, sizeof(buf));
+ struct packet *buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7);
+ if (((uintptr_t)&buffer->pmsg_header) & 7) {
+ fprintf (stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters);
+ }
+
+ buffer->pmsg_header.magic = LOGGER_MAGIC;
+ buffer->pmsg_header.len = sizeof(android_pmsg_log_header_t)
+ + sizeof(android_log_header_t);
+ buffer->pmsg_header.uid = getuid();
+ buffer->pmsg_header.pid = getpid();
+
+ buffer->header.tid = gettid();
+ buffer->header.realtime.tv_sec = ts.tv_sec;
+ buffer->header.realtime.tv_nsec = ts.tv_nsec;
+
+ buffer->header.id = LOG_ID_EVENTS;
+ buffer->payload.header.tag = 0;
+ buffer->payload.payload.type = EVENT_TYPE_INT;
+ uint32_t snapshot = 0;
+ buffer->payload.payload.data = htole32(snapshot);
+
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; ++i) {
+ ++snapshot;
+ buffer->payload.payload.data = htole32(snapshot);
+ write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD);
+ }
+ StopBenchmarkTiming();
+ close(pstore_fd);
+}
+BENCHMARK(BM_pmsg_long_aligned);
+
+/*
+ * Measure the time it takes to submit the android logging data to pstore
+ * best case aligned single block.
+ */
+static void BM_pmsg_long_unaligned1(int iters) {
+
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ if (pstore_fd < 0) {
+ return;
+ }
+
+ /*
+ * struct {
+ * // what we provide to pstore
+ * android_pmsg_log_header_t pmsg_header;
+ * // what we provide to socket
+ * android_log_header_t header;
+ * // caller provides
+ * union {
+ * struct {
+ * char prio;
+ * char payload[];
+ * } string;
+ * struct {
+ * uint32_t tag
+ * char payload[];
+ * } binary;
+ * };
+ * };
+ */
+
+ struct timespec ts;
+ clock_gettime(android_log_clockid(), &ts);
+
+ struct packet {
+ android_pmsg_log_header_t pmsg_header;
+ android_log_header_t header;
+ android_log_event_int_t payload;
+ };
+ char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD] __aligned(8);
+ memset(buf, 0, sizeof(buf));
+ struct packet *buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1);
+ if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) {
+ fprintf (stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters);
+ }
+
+ buffer->pmsg_header.magic = LOGGER_MAGIC;
+ buffer->pmsg_header.len = sizeof(android_pmsg_log_header_t)
+ + sizeof(android_log_header_t);
+ buffer->pmsg_header.uid = getuid();
+ buffer->pmsg_header.pid = getpid();
+
+ buffer->header.tid = gettid();
+ buffer->header.realtime.tv_sec = ts.tv_sec;
+ buffer->header.realtime.tv_nsec = ts.tv_nsec;
+
+ buffer->header.id = LOG_ID_EVENTS;
+ buffer->payload.header.tag = 0;
+ buffer->payload.payload.type = EVENT_TYPE_INT;
+ uint32_t snapshot = 0;
+ buffer->payload.payload.data = htole32(snapshot);
+
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; ++i) {
+ ++snapshot;
+ buffer->payload.payload.data = htole32(snapshot);
+ write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD);
+ }
+ StopBenchmarkTiming();
+ close(pstore_fd);
+}
+BENCHMARK(BM_pmsg_long_unaligned1);
+
+/*
* Measure the time it takes to submit the android logging call using
* discrete acquisition under light load. Expect this to be a dozen or so
* syscall periods (40us).
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 621101c..50afc5f 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -866,13 +866,27 @@
continue;
}
fprintf(stderr, "i=%zu j=%zu\r", i, j);
+ bool android_log_is_loggable = __android_log_is_loggable(
+ levels[i].level, tag, levels[j].level);
if ((levels[i].level < levels[j].level)
|| (levels[j].level == -1)) {
- EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
- levels[j].level));
+ if (android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_FALSE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_FALSE(__android_log_is_loggable(
+ levels[i].level, tag, levels[j].level));
+ }
} else {
- EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
- levels[j].level));
+ if (!android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_TRUE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_TRUE(__android_log_is_loggable(
+ levels[i].level, tag, levels[j].level));
+ }
}
}
}
@@ -891,30 +905,58 @@
fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
i, j, key, buf);
property_set(key, buf);
+ bool android_log_is_loggable = __android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG);
if ((levels[i].level < levels[j].level)
|| (levels[j].level == -1)
|| ((levels[i].level < ANDROID_LOG_DEBUG)
&& (levels[j].level == -2))) {
- EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_FALSE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_FALSE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
} else {
- EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (!android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_TRUE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_TRUE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
}
property_set(key, "");
fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
i, j, key + base_offset, buf);
property_set(key + base_offset, buf);
+ android_log_is_loggable = __android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG);
if ((levels[i].level < levels[j].level)
|| (levels[j].level == -1)
|| ((levels[i].level < ANDROID_LOG_DEBUG)
&& (levels[j].level == -2))) {
- EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_FALSE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_FALSE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
} else {
- EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (!android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_TRUE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_TRUE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
}
property_set(key + base_offset, "");
@@ -923,30 +965,58 @@
fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
i, j, key, buf);
property_set(key, buf);
+ android_log_is_loggable = __android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG);
if ((levels[i].level < levels[j].level)
|| (levels[j].level == -1)
|| ((levels[i].level < ANDROID_LOG_DEBUG)
&& (levels[j].level == -2))) {
- EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_FALSE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_FALSE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
} else {
- EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (!android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_TRUE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_TRUE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
}
property_set(key, "");
fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
i, j, key + base_offset, buf);
property_set(key + base_offset, buf);
+ android_log_is_loggable = __android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG);
if ((levels[i].level < levels[j].level)
|| (levels[j].level == -1)
|| ((levels[i].level < ANDROID_LOG_DEBUG)
&& (levels[j].level == -2))) {
- EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_FALSE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_FALSE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
} else {
- EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (!android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_TRUE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_TRUE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
}
property_set(key + base_offset, "");
}
@@ -969,30 +1039,58 @@
fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
i, j, key, buf);
property_set(key, buf);
+ bool android_log_is_loggable = __android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG);
if ((levels[i].level < levels[j].level)
|| (levels[j].level == -1)
|| ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
&& (levels[j].level == -2))) {
- EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_FALSE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_FALSE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
} else {
- EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (!android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_TRUE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_TRUE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
}
property_set(key, "");
fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
i, j, key + base_offset, buf);
property_set(key + base_offset, buf);
+ android_log_is_loggable = __android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG);
if ((levels[i].level < levels[j].level)
|| (levels[j].level == -1)
|| ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
&& (levels[j].level == -2))) {
- EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_FALSE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_FALSE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
} else {
- EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
- ANDROID_LOG_DEBUG));
+ if (!android_log_is_loggable) {
+ fprintf(stderr, "\n");
+ }
+ EXPECT_TRUE(android_log_is_loggable);
+ for(size_t k = 1000; k; --k) {
+ EXPECT_TRUE(__android_log_is_loggable(
+ levels[i].level, tag, ANDROID_LOG_DEBUG));
+ }
}
property_set(key + base_offset, "");
}
diff --git a/libsparse/append2simg.c b/libsparse/append2simg.c
index 1cf827c..eef8764 100644
--- a/libsparse/append2simg.c
+++ b/libsparse/append2simg.c
@@ -82,7 +82,7 @@
exit(-1);
}
- sparse_output = sparse_file_import_auto(output, true, true);
+ sparse_output = sparse_file_import_auto(output, false, true);
if (!sparse_output) {
fprintf(stderr, "Couldn't import output file\n");
exit(-1);
diff --git a/libutils/Looper.cpp b/libutils/Looper.cpp
index b14884b..952c992 100644
--- a/libutils/Looper.cpp
+++ b/libutils/Looper.cpp
@@ -74,7 +74,7 @@
mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
- mWakeEventFd = eventfd(0, EFD_NONBLOCK);
+ mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd: %s",
strerror(errno));
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 50bf6a4..aa3db8a 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -230,7 +230,7 @@
}
static void writefilestring(char *path, char *s) {
- int fd = open(path, O_WRONLY);
+ int fd = open(path, O_WRONLY | O_CLOEXEC);
int len = strlen(s);
int ret;
@@ -487,7 +487,7 @@
memset(mip, 0, sizeof(struct sysmeminfo));
- fd = open(ZONEINFO_PATH, O_RDONLY);
+ fd = open(ZONEINFO_PATH, O_RDONLY | O_CLOEXEC);
if (fd == -1) {
ALOGE("%s open: errno=%d", ZONEINFO_PATH, errno);
return -1;
@@ -518,7 +518,7 @@
ssize_t ret;
snprintf(path, PATH_MAX, "/proc/%d/statm", pid);
- fd = open(path, O_RDONLY);
+ fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd == -1)
return -1;
@@ -541,7 +541,7 @@
ssize_t ret;
snprintf(path, PATH_MAX, "/proc/%d/cmdline", pid);
- fd = open(path, O_RDONLY);
+ fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd == -1)
return NULL;
ret = read_all(fd, line, sizeof(line) - 1);
@@ -686,19 +686,19 @@
struct epoll_event epev;
int ret;
- mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY);
+ mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC);
if (mpfd < 0) {
ALOGI("No kernel memory.pressure_level support (errno=%d)", errno);
goto err_open_mpfd;
}
- evctlfd = open(MEMCG_SYSFS_PATH "cgroup.event_control", O_WRONLY);
+ evctlfd = open(MEMCG_SYSFS_PATH "cgroup.event_control", O_WRONLY | O_CLOEXEC);
if (evctlfd < 0) {
ALOGI("No kernel memory cgroup event control (errno=%d)", errno);
goto err_open_evctlfd;
}
- evfd = eventfd(0, EFD_NONBLOCK);
+ evfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
if (evfd < 0) {
ALOGE("eventfd failed for level %s; errno=%d", levelstr, errno);
goto err_eventfd;
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index 61b020c..4f517bb 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -605,7 +605,7 @@
char c;
if ((2 == sscanf(buffer, "%d log.tx%c", &num, &c)) &&
- (num <= 24)) {
+ (num <= 40)) {
++count;
} else if (strncmp(buffer, total, sizeof(total) - 1)) {
fprintf(stderr, "WARNING: Parse error: %s", buffer);
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index e103359..7394f11 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -210,9 +210,20 @@
}
unsigned int logMask = -1;
+ pid_t pid = 0;
if (argc > 1) {
logMask = 0;
for (int i = 1; i < argc; ++i) {
+ static const char _pid[] = "pid=";
+ if (!strncmp(argv[i], _pid, sizeof(_pid) - 1)) {
+ pid = atol(argv[i] + sizeof(_pid) - 1);
+ if (pid == 0) {
+ cli->sendMsg("PID Error");
+ return 0;
+ }
+ continue;
+ }
+
int id = atoi(argv[i]);
if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
cli->sendMsg("Range Error");
@@ -222,7 +233,8 @@
}
}
- cli->sendMsg(package_string(mBuf.formatStatistics(uid, logMask)).c_str());
+ cli->sendMsg(package_string(mBuf.formatStatistics(uid, pid,
+ logMask)).c_str());
return 0;
}
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 1e4f3b0..12aa84e 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -100,6 +100,11 @@
unsigned long default_size = property_get_size(global_tuneable);
if (!default_size) {
default_size = property_get_size(global_default);
+ if (!default_size) {
+ default_size = property_get_bool("ro.config.low_ram", false) ?
+ LOG_BUFFER_MIN_SIZE : // 64K
+ LOG_BUFFER_SIZE; // 256K
+ }
}
log_id_for_each(i) {
@@ -494,7 +499,8 @@
size_t second_worst_sizes = 0;
if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) {
- std::unique_ptr<const UidEntry *[]> sorted = stats.sort(2, id);
+ std::unique_ptr<const UidEntry *[]> sorted = stats.sort(
+ AID_ROOT, (pid_t)0, 2, id);
if (sorted.get()) {
if (sorted[0] && sorted[1]) {
@@ -861,10 +867,11 @@
return max;
}
-std::string LogBuffer::formatStatistics(uid_t uid, unsigned int logMask) {
+std::string LogBuffer::formatStatistics(uid_t uid, pid_t pid,
+ unsigned int logMask) {
pthread_mutex_lock(&mLogElementsLock);
- std::string ret = stats.format(uid, logMask);
+ std::string ret = stats.format(uid, pid, logMask);
pthread_mutex_unlock(&mLogElementsLock);
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index c1fec73..c1614e8 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -86,7 +86,7 @@
int setSize(log_id_t id, unsigned long size);
unsigned long getSizeUsed(log_id_t id);
// *strp uses malloc, use free to release.
- std::string formatStatistics(uid_t uid, unsigned int logMask);
+ std::string formatStatistics(uid_t uid, pid_t pid, unsigned int logMask);
void enableStatistics() {
stats.enableStatistics();
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index bf0e30b..afaefc2 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -205,7 +205,7 @@
}
std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const {
- uid_t uid = getKey();
+ uid_t uid = getUid();
std::string name = android::base::StringPrintf("%u", uid);
const char *nameTmp = stat.uidToName(uid);
if (nameTmp) {
@@ -287,8 +287,8 @@
std::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const {
uid_t uid = getUid();
- std::string name = android::base::StringPrintf("%5u/%u",
- getKey(), uid);
+ pid_t pid = getPid();
+ std::string name = android::base::StringPrintf("%5u/%u", pid, uid);
const char *nameTmp = getName();
if (nameTmp) {
name += android::base::StringPrintf(
@@ -325,7 +325,7 @@
std::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const {
uid_t uid = getUid();
std::string name = android::base::StringPrintf("%5u/%u",
- getKey(), uid);
+ getTid(), uid);
const char *nameTmp = getName();
if (nameTmp) {
name += android::base::StringPrintf(
@@ -388,7 +388,8 @@
return formatLine(name, size, pruned);
}
-std::string LogStatistics::format(uid_t uid, unsigned int logMask) const {
+std::string LogStatistics::format(uid_t uid, pid_t pid,
+ unsigned int logMask) const {
static const unsigned short spaces_total = 19;
// Report on total logging, current and for all time
@@ -461,24 +462,38 @@
name = (uid == AID_ROOT)
? "Chattiest UIDs in %s log buffer:"
: "Logging for your UID in %s log buffer:";
- output += uidTable[id].format(*this, uid, name, id);
+ output += uidTable[id].format(*this, uid, pid, name, id);
}
if (enable) {
- name = (uid == AID_ROOT) ? "Chattiest PIDs:" : "Logging for this PID:";
- output += pidTable.format(*this, uid, name);
- name = "Chattiest TIDs:";
- output += tidTable.format(*this, uid, name);
+ name = ((uid == AID_ROOT) && !pid)
+ ? "Chattiest PIDs:"
+ : "Logging for this PID:";
+ output += pidTable.format(*this, uid, pid, name);
+ name = "Chattiest TIDs";
+ if (pid) {
+ name += android::base::StringPrintf(" for PID %d", pid);
+ }
+ name += ":";
+ output += tidTable.format(*this, uid, pid, name);
}
if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
- name = "Chattiest events log buffer TAGs:";
- output += tagTable.format(*this, uid, name, LOG_ID_EVENTS);
+ name = "Chattiest events log buffer TAGs";
+ if (pid) {
+ name += android::base::StringPrintf(" for PID %d", pid);
+ }
+ name += ":";
+ output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS);
}
if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
- name = "Chattiest security log buffer TAGs:";
- output += securityTagTable.format(*this, uid, name, LOG_ID_SECURITY);
+ name = "Chattiest security log buffer TAGs";
+ if (pid) {
+ name += android::base::StringPrintf(" for PID %d", pid);
+ }
+ name += ":";
+ output += securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY);
}
return output;
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index 8558b06..6d999d2 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -47,7 +47,8 @@
typedef typename std::unordered_map<TKey, TEntry>::iterator iterator;
typedef typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator;
- std::unique_ptr<const TEntry *[]> sort(size_t len) const {
+ std::unique_ptr<const TEntry *[]> sort(uid_t uid, pid_t pid,
+ size_t len) const {
if (!len) {
std::unique_ptr<const TEntry *[]> sorted(NULL);
return sorted;
@@ -58,6 +59,14 @@
for(const_iterator it = map.begin(); it != map.end(); ++it) {
const TEntry &entry = it->second;
+
+ if ((uid != AID_ROOT) && (uid != entry.getUid())) {
+ continue;
+ }
+ if (pid && entry.getPid() && (pid != entry.getPid())) {
+ continue;
+ }
+
size_t sizes = entry.getSizes();
ssize_t index = len - 1;
while ((!retval[index] || (sizes > retval[index]->getSizes()))
@@ -118,12 +127,13 @@
std::string format(
const LogStatistics &stat,
uid_t uid,
+ pid_t pid,
const std::string &name = std::string(""),
log_id_t id = LOG_ID_MAX) const {
static const size_t maximum_sorted_entries = 32;
std::string output;
- std::unique_ptr<const TEntry *[]> sorted = sort(maximum_sorted_entries);
-
+ std::unique_ptr<const TEntry *[]> sorted = sort(uid, pid,
+ maximum_sorted_entries);
if (!sorted.get()) {
return output;
}
@@ -136,9 +146,6 @@
if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) {
break;
}
- if ((uid != AID_ROOT) && (uid != entry->getUid())) {
- continue;
- }
if (!headerPrinted) {
output += "\n\n";
output += entry->formatHeader(name, id);
@@ -217,14 +224,24 @@
struct UidEntry : public EntryBaseDropped {
const uid_t uid;
+ pid_t pid;
UidEntry(LogBufferElement *element):
EntryBaseDropped(element),
- uid(element->getUid()) {
+ uid(element->getUid()),
+ pid(element->getPid()) {
}
inline const uid_t&getKey() const { return uid; }
- inline const uid_t&getUid() const { return uid; }
+ inline const uid_t&getUid() const { return getKey(); }
+ inline const pid_t&getPid() const { return pid; }
+
+ inline void add(LogBufferElement *element) {
+ if (pid != element->getPid()) {
+ pid = -1;
+ }
+ EntryBase::add(element);
+ }
std::string formatHeader(const std::string &name, log_id_t id) const;
std::string format(const LogStatistics &stat, log_id_t id) const;
@@ -260,6 +277,7 @@
~PidEntry() { free(name); }
const pid_t&getKey() const { return pid; }
+ const pid_t&getPid() const { return getKey(); }
const uid_t&getUid() const { return uid; }
const char*getName() const { return name; }
@@ -291,30 +309,36 @@
struct TidEntry : public EntryBaseDropped {
const pid_t tid;
+ pid_t pid;
uid_t uid;
char *name;
- TidEntry(pid_t tid):
+ TidEntry(pid_t tid, pid_t pid):
EntryBaseDropped(),
tid(tid),
+ pid(pid),
uid(android::pidToUid(tid)),
name(android::tidToName(tid)) {
}
TidEntry(LogBufferElement *element):
EntryBaseDropped(element),
tid(element->getTid()),
+ pid(element->getPid()),
uid(element->getUid()),
name(android::tidToName(tid)) {
}
TidEntry(const TidEntry &element):
EntryBaseDropped(element),
tid(element.tid),
+ pid(element.pid),
uid(element.uid),
name(element.name ? strdup(element.name) : NULL) {
}
~TidEntry() { free(name); }
const pid_t&getKey() const { return tid; }
+ const pid_t&getTid() const { return getKey(); }
+ const pid_t&getPid() const { return pid; }
const uid_t&getUid() const { return uid; }
const char*getName() const { return name; }
@@ -330,8 +354,10 @@
inline void add(LogBufferElement *element) {
uid_t incomingUid = element->getUid();
- if (getUid() != incomingUid) {
+ pid_t incomingPid = element->getPid();
+ if ((getUid() != incomingUid) || (getPid() != incomingPid)) {
uid = incomingUid;
+ pid = incomingPid;
free(name);
name = android::tidToName(element->getTid());
} else {
@@ -346,23 +372,28 @@
struct TagEntry : public EntryBase {
const uint32_t tag;
+ pid_t pid;
uid_t uid;
TagEntry(LogBufferElement *element):
EntryBase(element),
tag(element->getTag()),
+ pid(element->getPid()),
uid(element->getUid()) {
}
const uint32_t&getKey() const { return tag; }
+ const pid_t&getPid() const { return pid; }
const uid_t&getUid() const { return uid; }
const char*getName() const { return android::tagToName(tag); }
inline void add(LogBufferElement *element) {
- uid_t incomingUid = element->getUid();
- if (uid != incomingUid) {
+ if (uid != element->getUid()) {
uid = -1;
}
+ if (pid != element->getPid()) {
+ pid = -1;
+ }
EntryBase::add(element);
}
@@ -416,8 +447,9 @@
--mDroppedElements[log_id];
}
- std::unique_ptr<const UidEntry *[]> sort(size_t len, log_id id) {
- return uidTable[id].sort(len);
+ std::unique_ptr<const UidEntry *[]> sort(uid_t uid, pid_t pid,
+ size_t len, log_id id) {
+ return uidTable[id].sort(uid, pid, len);
}
// fast track current value by id only
@@ -429,7 +461,7 @@
size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; }
size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; }
- std::string format(uid_t uid, unsigned int logMask) const;
+ std::string format(uid_t uid, pid_t pid, unsigned int logMask) const;
// helper (must be locked directly or implicitly by mLogElementsLock)
const char *pidToName(pid_t pid) const;
diff --git a/logd/LogUtils.h b/logd/LogUtils.h
index b591f28..fccba61 100644
--- a/logd/LogUtils.h
+++ b/logd/LogUtils.h
@@ -43,6 +43,9 @@
bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid);
bool clientHasLogCredentials(SocketClient *cli);
+// Furnished in main.cpp
+bool property_get_bool(const char *key, bool def);
+
static inline bool worstUidEnabledForLogid(log_id_t id) {
return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) || (id == LOG_ID_RADIO);
}
diff --git a/logd/main.cpp b/logd/main.cpp
index 0f55d60..2fcabdc 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -143,7 +143,7 @@
}
// Property helper
-static bool property_get_bool(const char *key, bool def) {
+bool property_get_bool(const char *key, bool def) {
char property[PROPERTY_VALUE_MAX];
property_get(key, property, "");
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 4472c1d..7d0dd44 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -26,8 +26,6 @@
#include "log/log.h"
#include "log/logger.h"
-#define __unused __attribute__((__unused__))
-
/*
* returns statistics
*/
@@ -196,7 +194,7 @@
delete [] buf;
}
-static void caught_signal(int signum __unused) { }
+static void caught_signal(int /* signum */) { }
static void dump_log_msg(const char *prefix,
log_msg *msg, unsigned int version, int lid) {