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"