Merge "am b4ef85c..b4ef85c from mirror-m-wireless-internal-release"
diff --git a/cpio/Android.mk b/cpio/Android.mk
index b9d18ba..2aa7297 100644
--- a/cpio/Android.mk
+++ b/cpio/Android.mk
@@ -10,7 +10,7 @@
LOCAL_CFLAGS := -Werror
-LOCAL_STATIC_LIBRARIES := libcutils
+LOCAL_SHARED_LIBRARIES := libcutils
include $(BUILD_HOST_EXECUTABLE)
diff --git a/debuggerd/elf_utils.cpp b/debuggerd/elf_utils.cpp
index 764b9db..5ea03e7 100644
--- a/debuggerd/elf_utils.cpp
+++ b/debuggerd/elf_utils.cpp
@@ -29,6 +29,8 @@
#include "elf_utils.h"
+#define NOTE_ALIGN(size) ((size + 3) & ~3)
+
template <typename HdrType, typename PhdrType, typename NhdrType>
static bool get_build_id(
Backtrace* backtrace, uintptr_t base_addr, uint8_t* e_ident, std::string* build_id) {
@@ -60,7 +62,7 @@
addr += sizeof(nhdr);
if (nhdr.n_type == NT_GNU_BUILD_ID) {
// Skip the name (which is the owner and should be "GNU").
- addr += nhdr.n_namesz;
+ addr += NOTE_ALIGN(nhdr.n_namesz);
uint8_t build_id_data[128];
if (nhdr.n_namesz > sizeof(build_id_data)) {
ALOGE("Possible corrupted note, name size value is too large: %u",
@@ -80,7 +82,7 @@
} else {
// Move past the extra note data.
hdr_size -= sizeof(nhdr);
- size_t skip_bytes = nhdr.n_namesz + nhdr.n_descsz;
+ size_t skip_bytes = NOTE_ALIGN(nhdr.n_namesz) + NOTE_ALIGN(nhdr.n_descsz);
addr += skip_bytes;
if (hdr_size < skip_bytes) {
break;
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 352510b..6800ad2 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -88,7 +88,7 @@
int min_capacity;
bool level_only;
- gr_surface surface;
+ GRSurface* surface;
};
struct animation {
@@ -115,7 +115,7 @@
struct key_state keys[KEY_MAX + 1];
struct animation *batt_anim;
- gr_surface surf_unknown;
+ GRSurface* surf_unknown;
int boot_min_cap;
};
@@ -274,7 +274,7 @@
}
/* returns the last y-offset of where the surface ends */
-static int draw_surface_centered(struct charger* /*charger*/, gr_surface surface)
+static int draw_surface_centered(struct charger* /*charger*/, GRSurface* surface)
{
int w;
int h;
@@ -697,7 +697,7 @@
charger->batt_anim = &battery_animation;
- gr_surface* scale_frames;
+ GRSurface** scale_frames;
int scale_count;
ret = res_create_multi_display_surface("charger/battery_scale", &scale_count, &scale_frames);
if (ret < 0) {
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index fed81f8..02fe2b5 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -215,6 +215,8 @@
void fs_config(const char *path, int dir,
unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities);
+ssize_t fs_config_generate(char *buffer, size_t length, const struct fs_path_config *pc);
+
__END_DECLS
#endif
diff --git a/include/system/window.h b/include/system/window.h
index af0418b..a875427 100644
--- a/include/system/window.h
+++ b/include/system/window.h
@@ -300,7 +300,8 @@
NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* private */
NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17,/* private */
NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18,
- NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19
+ NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19,
+ NATIVE_WINDOW_SET_SURFACE_DAMAGE = 20, /* private */
};
/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */
@@ -493,31 +494,12 @@
* DO NOT CALL THIS HOOK DIRECTLY. Instead, use the helper functions
* defined below.
*
- * (*perform)() returns -ENOENT if the 'what' parameter is not supported
- * by the surface's implementation.
+ * (*perform)() returns -ENOENT if the 'what' parameter is not supported
+ * by the surface's implementation.
*
- * The valid operations are:
- * NATIVE_WINDOW_SET_USAGE
- * NATIVE_WINDOW_CONNECT (deprecated)
- * NATIVE_WINDOW_DISCONNECT (deprecated)
- * NATIVE_WINDOW_SET_CROP (private)
- * NATIVE_WINDOW_SET_BUFFER_COUNT
- * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY (deprecated)
- * NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
- * NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
- * NATIVE_WINDOW_SET_BUFFERS_DATASPACE
- * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS
- * NATIVE_WINDOW_SET_BUFFERS_FORMAT
- * NATIVE_WINDOW_SET_SCALING_MODE (private)
- * NATIVE_WINDOW_LOCK (private)
- * NATIVE_WINDOW_UNLOCK_AND_POST (private)
- * NATIVE_WINDOW_API_CONNECT (private)
- * NATIVE_WINDOW_API_DISCONNECT (private)
- * NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS (private)
- * NATIVE_WINDOW_SET_POST_TRANSFORM_CROP (private)
- *
+ * See above for a list of valid operations, such as
+ * NATIVE_WINDOW_SET_USAGE or NATIVE_WINDOW_CONNECT
*/
-
int (*perform)(struct ANativeWindow* window,
int operation, ... );
@@ -934,6 +916,30 @@
sidebandHandle);
}
+/*
+ * native_window_set_surface_damage(..., android_native_rect_t* rects, int numRects)
+ * Set the surface damage (i.e., the region of the surface that has changed
+ * since the previous frame). The damage set by this call will be reset (to the
+ * default of full-surface damage) after calling queue, so this must be called
+ * prior to every frame with damage that does not cover the whole surface if the
+ * caller desires downstream consumers to use this optimization.
+ *
+ * The damage region is specified as an array of rectangles, with the important
+ * caveat that the origin of the surface is considered to be the bottom-left
+ * corner, as in OpenGL ES.
+ *
+ * If numRects is set to 0, rects may be NULL, and the surface damage will be
+ * set to the full surface (the same as if this function had not been called for
+ * this frame).
+ */
+static inline int native_window_set_surface_damage(
+ struct ANativeWindow* window,
+ const android_native_rect_t* rects, size_t numRects)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_SURFACE_DAMAGE,
+ rects, numRects);
+}
+
__END_DECLS
#endif /* SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H */
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
index b875efd..54cace9 100644
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -57,7 +57,6 @@
libbacktrace_shared_libraries := \
libbase \
libunwind \
- libunwind-ptrace \
libbacktrace_shared_libraries_host := \
liblog \
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 659f614..7fd66cd 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -19,12 +19,52 @@
** by the device side of adb.
*/
-#include <stdint.h>
-#include <string.h>
-#include <sys/stat.h>
+#define LOG_TAG "fs_config"
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <cutils/fs.h>
+#include <log/log.h>
#include <private/android_filesystem_config.h>
+/* The following structure is stored little endian */
+struct fs_path_config_from_file {
+ uint16_t len;
+ uint16_t mode;
+ uint16_t uid;
+ uint16_t gid;
+ uint64_t capabilities;
+ char prefix[];
+} __attribute__((__aligned__(sizeof(uint64_t))));
+
+/* My kingdom for <endian.h> */
+static inline uint16_t get2LE(const uint8_t* src)
+{
+ return src[0] | (src[1] << 8);
+}
+
+static inline uint64_t get8LE(const uint8_t* src)
+{
+ uint32_t low, high;
+
+ low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+ high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
+ return ((uint64_t) high << 32) | (uint64_t) low;
+}
+
+#define ALIGN(x, alignment) ( ((x) + ((alignment) - 1)) & ~((alignment) - 1) )
+
/* Rules for directories.
** These rules are applied based on "first match", so they
** should start with the most specific path and work their
@@ -61,6 +101,9 @@
** way up to the root. Prefixes ending in * denotes wildcard
** and will allow partial matches.
*/
+static const char conf_dir[] = "/system/etc/fs_config_dirs";
+static const char conf_file[] = "/system/etc/fs_config_files";
+
static const struct fs_path_config android_files[] = {
{ 00440, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.rc" },
{ 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.sh" },
@@ -68,6 +111,8 @@
{ 00550, AID_DHCP, AID_SHELL, 0, "system/etc/dhcpcd/dhcpcd-run-hooks" },
{ 00555, AID_ROOT, AID_ROOT, 0, "system/etc/ppp/*" },
{ 00555, AID_ROOT, AID_ROOT, 0, "system/etc/rc.*" },
+ { 00444, AID_ROOT, AID_ROOT, 0, conf_dir + 1 },
+ { 00444, AID_ROOT, AID_ROOT, 0, conf_file + 1 },
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" },
{ 00644, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/*" },
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private/*" },
@@ -101,30 +146,116 @@
{ 00644, AID_ROOT, AID_ROOT, 0, 0 },
};
+static int fs_config_open(int dir)
+{
+ int fd = -1;
+
+ const char *out = getenv("OUT");
+ if (out && *out) {
+ char *name = NULL;
+ asprintf(&name, "%s%s", out, dir ? conf_dir : conf_file);
+ if (name) {
+ fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY));
+ free(name);
+ }
+ }
+ if (fd < 0) {
+ fd = TEMP_FAILURE_RETRY(open(dir ? conf_dir : conf_file, O_RDONLY));
+ }
+ return fd;
+}
+
+static bool fs_config_cmp(bool dir, const char *prefix, size_t len,
+ const char *path, size_t plen)
+{
+ if (dir) {
+ if (plen < len) {
+ return false;
+ }
+ } else {
+ /* If name ends in * then allow partial matches. */
+ if (prefix[len - 1] == '*') {
+ return !strncmp(prefix, path, len - 1);
+ }
+ if (plen != len) {
+ return false;
+ }
+ }
+ return !strncmp(prefix, path, len);
+}
+
void fs_config(const char *path, int dir,
unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities)
{
const struct fs_path_config *pc;
int plen;
+ struct stat st;
+ void *address = NULL;
+
+ int fd = fs_config_open(dir);
+ if ((fd >= 0)
+ && (TEMP_FAILURE_RETRY(fstat(fd, &st)) >= 0)
+ && (size_t)st.st_size) {
+ address = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (address == MAP_FAILED) {
+ address = NULL;
+ }
+ } else if (fd >= 0) {
+ close(fd);
+ }
if (path[0] == '/') {
path++;
}
- pc = dir ? android_dirs : android_files;
plen = strlen(path);
- for(; pc->prefix; pc++){
- int len = strlen(pc->prefix);
- if (dir) {
- if(plen < len) continue;
- if(!strncmp(pc->prefix, path, len)) break;
- continue;
+
+ if (address) {
+ const struct fs_path_config_from_file *p = (const struct fs_path_config_from_file *)
+ address;
+ const char *end = (const char *)address + st.st_size;
+ const struct fs_path_config_from_file *e = (const struct fs_path_config_from_file *)
+ (end - sizeof(*p));
+ uint16_t host_len = sizeof(*p);
+ for (; p < e; p = (const struct fs_path_config_from_file *)(((const char *)p) + host_len)) {
+ host_len = get2LE((const uint8_t *)&(p->len));
+ ssize_t len, remainder = host_len - sizeof(*p);
+ if (remainder <= 0) {
+ ALOGE("%s is truncated", dir ? conf_dir : conf_file);
+ p = e;
+ break;
+ }
+ len = (const char *)e - (const char *)p;
+ if (remainder > len) {
+ remainder = len;
+ }
+ len = strnlen(p->prefix, remainder);
+ if (len >= remainder) { /* missing a terminating null */
+ ALOGE("%s is corrupted", dir ? conf_dir : conf_file);
+ p = e;
+ break;
+ }
+ if (fs_config_cmp(dir, p->prefix, len, path, plen)) {
+ break;
+ }
}
- /* If name ends in * then allow partial matches. */
- if (pc->prefix[len -1] == '*') {
- if(!strncmp(pc->prefix, path, len - 1)) break;
- } else if (plen == len){
- if(!strncmp(pc->prefix, path, len)) break;
+ if (p < e) {
+ *uid = get2LE((const uint8_t *)&(p->uid));
+ *gid = get2LE((const uint8_t *)&(p->gid));
+ *mode = (*mode & (~07777)) | get2LE((const uint8_t *)&(p->mode));
+ *capabilities = get8LE((const uint8_t *)&(p->capabilities));
+ }
+ munmap(address, st.st_size);
+ close(fd);
+ if (p < e) {
+ return;
+ }
+ }
+
+ pc = dir ? android_dirs : android_files;
+ for(; pc->prefix; pc++){
+ if (fs_config_cmp(dir, pc->prefix, strlen(pc->prefix), path, plen)) {
+ break;
}
}
*uid = pc->uid;
@@ -132,3 +263,22 @@
*mode = (*mode & (~07777)) | pc->mode;
*capabilities = pc->capabilities;
}
+
+ssize_t fs_config_generate(char *buffer, size_t length, const struct fs_path_config *pc)
+{
+ struct fs_path_config_from_file *p = (struct fs_path_config_from_file *)buffer;
+ size_t len = ALIGN(sizeof(*p) + strlen(pc->prefix) + 1, sizeof(uint64_t));
+
+ if ((length < len) || (len > UINT16_MAX)) {
+ return -ENOSPC;
+ }
+ memset(p, 0, len);
+ uint16_t host_len = len;
+ p->len = get2LE((const uint8_t *)&host_len);
+ p->mode = get2LE((const uint8_t *)&(pc->mode));
+ p->uid = get2LE((const uint8_t *)&(pc->uid));
+ p->gid = get2LE((const uint8_t *)&(pc->gid));
+ p->capabilities = get8LE((const uint8_t *)&(pc->capabilities));
+ strcpy(p->prefix, pc->prefix);
+ return len;
+}
diff --git a/libsparse/sparse.c b/libsparse/sparse.c
index 65c09e0..311678a 100644
--- a/libsparse/sparse.c
+++ b/libsparse/sparse.c
@@ -238,14 +238,15 @@
struct backed_block *last_bb = NULL;
struct backed_block *bb;
struct backed_block *start;
+ unsigned int last_block = 0;
int64_t file_len = 0;
int ret;
/*
- * overhead is sparse file header, initial skip chunk, split chunk, end
- * skip chunk, and crc chunk.
+ * overhead is sparse file header, the potential end skip
+ * chunk and crc chunk.
*/
- int overhead = sizeof(sparse_header_t) + 4 * sizeof(chunk_header_t) +
+ int overhead = sizeof(sparse_header_t) + 2 * sizeof(chunk_header_t) +
sizeof(uint32_t);
len -= overhead;
@@ -258,6 +259,11 @@
for (bb = start; bb; bb = backed_block_iter_next(bb)) {
count = 0;
+ if (backed_block_block(bb) > last_block)
+ count += sizeof(chunk_header_t);
+ last_block = backed_block_block(bb) +
+ DIV_ROUND_UP(backed_block_len(bb), to->block_size);
+
/* will call out_counter_write to update count */
ret = sparse_file_write_block(out_counter, bb);
if (ret) {
@@ -270,6 +276,7 @@
* requested size, split the chunk. Results in sparse files that
* are at least 7/8ths of the requested size
*/
+ file_len += sizeof(chunk_header_t);
if (!last_bb || (len - file_len > (len / 8))) {
backed_block_split(from->backed_block_list, bb, len - file_len);
last_bb = bb;
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index 561ea3e..bdfed3b 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -69,7 +69,11 @@
{ }
static void setname() {
- prctl(PR_SET_NAME, "logd.control");
+ static bool name_set;
+ if (!name_set) {
+ prctl(PR_SET_NAME, "logd.control");
+ name_set = true;
+ }
}
int CommandListener::ClearCmd::runCommand(SocketClient *cli,
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index bdb2915..90370e9 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -24,6 +24,7 @@
#include <sys/uio.h>
#include <syslog.h>
+#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
#include "libaudit.h"
@@ -110,7 +111,7 @@
pid_t pid = getpid();
pid_t tid = gettid();
- uid_t uid = getuid();
+ uid_t uid = AID_LOGD;
log_time now;
static const char audit_str[] = " audit(";
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index fc9e30f..3b4ef88 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -23,6 +23,7 @@
#include <cutils/sockets.h>
#include <log/logger.h>
+#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
#include "LogListener.h"
@@ -34,7 +35,11 @@
{ }
bool LogListener::onDataAvailable(SocketClient *cli) {
- prctl(PR_SET_NAME, "logd.writer");
+ static bool name_set;
+ if (!name_set) {
+ prctl(PR_SET_NAME, "logd.writer");
+ name_set = true;
+ }
char buffer[sizeof_log_id_t + sizeof(uint16_t) + sizeof(log_time)
+ LOGGER_ENTRY_MAX_PAYLOAD];
@@ -75,7 +80,7 @@
return false;
}
- if (cred->uid == getuid()) {
+ if (cred->uid == AID_LOGD) {
// ignore log messages we send to ourself.
// Such log messages are often generated by libraries we depend on
// which use standard Android logging.
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index f7df275..745e847 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -37,7 +37,11 @@
}
bool LogReader::onDataAvailable(SocketClient *cli) {
- prctl(PR_SET_NAME, "logd.reader");
+ static bool name_set;
+ if (!name_set) {
+ prctl(PR_SET_NAME, "logd.reader");
+ name_set = true;
+ }
char buffer[255];
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 40fbfae..0801fe8 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -430,14 +430,14 @@
if (fp) {
while (fgets(buffer, sizeof(buffer), fp)) {
int uid;
- if (sscanf(buffer, "Groups: %d", &uid) == 1) {
+ if (sscanf(buffer, "Uid: %d", &uid) == 1) {
fclose(fp);
return uid;
}
}
fclose(fp);
}
- return getuid(); // associate this with the logger
+ return AID_LOGD; // associate this with the logger
}
}
diff --git a/logd/main.cpp b/logd/main.cpp
index 1ffb8b0..4aa38b3 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -35,8 +35,8 @@
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
#include <cutils/sockets.h>
+#include <private/android_filesystem_config.h>
-#include "private/android_filesystem_config.h"
#include "CommandListener.h"
#include "LogBuffer.h"
#include "LogListener.h"