Merge "Add static methods to BitSet."
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 40bc2ec..aa3b1dd 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -30,6 +30,7 @@
 #include <time.h>
 
 #include <private/android_filesystem_config.h>
+#include <cutils/properties.h>
 #include <logwrap/logwrap.h>
 
 #include "mincrypt/rsa.h"
@@ -335,6 +336,26 @@
     return -1;
 }
 
+static int set_verified_property(char *name) {
+    int ret;
+    char *key;
+    ret = asprintf(&key, "partition.%s.verified", name);
+    if (ret < 0) {
+        ERROR("Error formatting verified property");
+        return ret;
+    }
+    ret = PROP_NAME_MAX - strlen(key);
+    if (ret < 0) {
+        ERROR("Verified property name is too long");
+        return -1;
+    }
+    ret = property_set(key, "1");
+    if (ret < 0)
+        ERROR("Error setting verified property %s: %d", key, ret);
+    free(key);
+    return ret;
+}
+
 int fs_mgr_setup_verity(struct fstab_rec *fstab) {
 
     int retval = -1;
@@ -351,6 +372,13 @@
     io->flags |= 1;
     io->target_count = 1;
 
+    // check to ensure that the verity device is ext4
+    // TODO: support non-ext4 filesystems
+    if (strcmp(fstab->fs_type, "ext4")) {
+        ERROR("Cannot verify non-ext4 device (%s)", fstab->fs_type);
+        return retval;
+    }
+
     // get the device mapper fd
     int fd;
     if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
@@ -403,7 +431,8 @@
         goto out;
     }
 
-    retval = 0;
+    // set the property indicating that the partition is verified
+    retval = set_verified_property(mount_point);
 
 out:
     close(fd);
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index fc3ac67..710f5b6 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -646,7 +646,7 @@
         healthd_register_event(epollfd, charger_event_handler);
     }
 
-    ret = res_create_surface("charger/battery_fail", &charger->surf_unknown);
+    ret = res_create_display_surface("charger/battery_fail", &charger->surf_unknown);
     if (ret < 0) {
         LOGE("Cannot load battery_fail image\n");
         charger->surf_unknown = NULL;
@@ -656,7 +656,7 @@
 
     gr_surface* scale_frames;
     int scale_count;
-    ret = res_create_multi_surface("charger/battery_scale", &scale_count, &scale_frames);
+    ret = res_create_multi_display_surface("charger/battery_scale", &scale_count, &scale_frames);
     if (ret < 0) {
         LOGE("Cannot load battery_scale image\n");
         charger->batt_anim->num_frames = 0;
diff --git a/init/property_service.c b/init/property_service.c
index 3ad5f51..10b1cc7 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -97,6 +97,7 @@
     { "persist.gps.",      AID_GPS,      0 },
     { "persist.service.bdroid.", AID_BLUETOOTH,   0 },
     { "selinux."         , AID_SYSTEM,   0 },
+    { "partition."        , AID_SYSTEM,   0},
     { NULL, 0, 0 }
 };
 
@@ -456,40 +457,73 @@
     *sz = pa_workspace.size;
 }
 
-static void load_properties(char *data, char *prefix)
-{
-    char *key, *value, *eol, *sol, *tmp;
-    size_t plen;
+static void load_properties_from_file(const char *, const char *);
 
-    if (prefix)
-        plen = strlen(prefix);
+/*
+ * Filter is used to decide which properties to load: NULL loads all keys,
+ * "ro.foo.*" is a prefix match, and "ro.foo.bar" is an exact match.
+ */
+static void load_properties(char *data, const char *filter)
+{
+    char *key, *value, *eol, *sol, *tmp, *fn;
+    size_t flen = 0;
+
+    if (filter) {
+        flen = strlen(filter);
+    }
+
     sol = data;
-    while((eol = strchr(sol, '\n'))) {
+    while ((eol = strchr(sol, '\n'))) {
         key = sol;
         *eol++ = 0;
         sol = eol;
 
-        value = strchr(key, '=');
-        if(value == 0) continue;
-        *value++ = 0;
+        while (isspace(*key)) key++;
+        if (*key == '#') continue;
 
-        while(isspace(*key)) key++;
-        if(*key == '#') continue;
-        tmp = value - 2;
-        while((tmp > key) && isspace(*tmp)) *tmp-- = 0;
-
-        if (prefix && strncmp(key, prefix, plen))
-            continue;
-
-        while(isspace(*value)) value++;
         tmp = eol - 2;
-        while((tmp > value) && isspace(*tmp)) *tmp-- = 0;
+        while ((tmp > key) && isspace(*tmp)) *tmp-- = 0;
 
-        property_set(key, value);
+        if (!strncmp(key, "import ", 7) && flen == 0) {
+            fn = key + 7;
+            while (isspace(*fn)) fn++;
+
+            key = strchr(fn, ' ');
+            if (key) {
+                *key++ = 0;
+                while (isspace(*key)) key++;
+            }
+
+            load_properties_from_file(fn, key);
+
+        } else {
+            value = strchr(key, '=');
+            if (!value) continue;
+            *value++ = 0;
+
+            tmp = value - 2;
+            while ((tmp > key) && isspace(*tmp)) *tmp-- = 0;
+
+            while (isspace(*value)) value++;
+
+            if (flen > 0) {
+                if (filter[flen - 1] == '*') {
+                    if (strncmp(key, filter, flen - 1)) continue;
+                } else {
+                    if (strcmp(key, filter)) continue;
+                }
+            }
+
+            property_set(key, value);
+        }
     }
 }
 
-static void load_properties_from_file(const char *fn, char *prefix)
+/*
+ * Filter is used to decide which properties to load: NULL loads all keys,
+ * "ro.foo.*" is a prefix match, and "ro.foo.bar" is an exact match.
+ */
+static void load_properties_from_file(const char *fn, const char *filter)
 {
     char *data;
     unsigned sz;
@@ -497,7 +531,7 @@
     data = read_file(fn, &sz);
 
     if(data != 0) {
-        load_properties(data, prefix);
+        load_properties(data, filter);
         free(data);
     }
 }
@@ -610,8 +644,10 @@
 
     load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
     load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT, NULL);
-    load_properties_from_file(PROP_PATH_FACTORY, "ro.");
+    load_properties_from_file(PROP_PATH_FACTORY, "ro.*");
+
     load_override_properties();
+
     /* Read persistent properties after all default values have been loaded. */
     load_persistent_properties();
 
diff --git a/init/ueventd.c b/init/ueventd.c
index 5517448..662196d 100644
--- a/init/ueventd.c
+++ b/init/ueventd.c
@@ -71,8 +71,8 @@
     klog_init();
 #if LOG_UEVENTS
     /* Ensure we're at a logging level that will show the events */
-    if (klog_get_level() < KLOG_LEVEL_INFO) {
-        klog_set_level(KLOG_LEVEL_INFO);
+    if (klog_get_level() < KLOG_INFO_LEVEL) {
+        klog_set_level(KLOG_INFO_LEVEL);
     }
 #endif
 
diff --git a/liblog/log_read.c b/liblog/log_read.c
index d96f129..2dd07e6 100644
--- a/liblog/log_read.c
+++ b/liblog/log_read.c
@@ -272,11 +272,11 @@
                             const char *msg, char *buf, size_t buf_size)
 {
     ssize_t ret;
+    int errno_save = 0;
     int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
                                    SOCK_STREAM);
     if (sock < 0) {
-        ret = sock;
-        goto done;
+        return sock;
     }
 
     if (msg) {
@@ -292,9 +292,12 @@
 
 done:
     if ((ret == -1) && errno) {
-        ret = -errno;
+        errno_save = errno;
     }
     close(sock);
+    if (errno_save) {
+        errno = errno_save;
+    }
     return ret;
 }
 
@@ -305,6 +308,7 @@
     }
 
     if (strncmp(buf, "success", 7)) {
+        errno = EINVAL;
         return -1;
     }
 
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 7bf91a9..5960609 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -699,7 +699,7 @@
             int ret;
             ret = android_logger_clear(dev->logger);
             if (ret) {
-                perror("clearLog");
+                perror("failed to clear the log");
                 exit(EXIT_FAILURE);
             }
         }
@@ -707,7 +707,7 @@
 #ifdef USERDEBUG_BUILD
 
         if (setLogSize && android_logger_set_log_size(dev->logger, setLogSize)) {
-            perror("setLogSize");
+            perror("failed to set the log size");
             exit(EXIT_FAILURE);
         }
 
@@ -718,13 +718,13 @@
 
             size = android_logger_get_log_size(dev->logger);
             if (size < 0) {
-                perror("getLogSize");
+                perror("failed to get the log size");
                 exit(EXIT_FAILURE);
             }
 
             readable = android_logger_get_log_readable_size(dev->logger);
             if (readable < 0) {
-                perror("getLogReadableSize");
+                perror("failed to get the readable log size");
                 exit(EXIT_FAILURE);
             }
 
@@ -748,7 +748,7 @@
         free(buf);
 
         if (ret) {
-            perror("setPruneList");
+            perror("failed to set the prune list");
             exit(EXIT_FAILURE);
         }
     }
@@ -792,7 +792,7 @@
         }
 
         if (!buf) {
-            perror("response read");
+            perror("failed to read data");
             exit(EXIT_FAILURE);
         }
 
@@ -859,7 +859,7 @@
                 fprintf(stderr, "read: unexpected length.\n");
                 exit(EXIT_FAILURE);
             }
-            perror("logcat read");
+            perror("logcat read failure");
             exit(EXIT_FAILURE);
         }
 
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index c6b248b..2aa2ebb 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -31,7 +31,8 @@
 {  }
 
 bool LogListener::onDataAvailable(SocketClient *cli) {
-    char buffer[1024];
+    char buffer[sizeof_log_id_t + sizeof(log_time) + sizeof(char)
+        + LOGGER_ENTRY_MAX_PAYLOAD];
     struct iovec iov = { buffer, sizeof(buffer) };
     memset(buffer, 0, sizeof(buffer));