auto import from //branches/cupcake/...@132276
diff --git a/init/devices.c b/init/devices.c
index 0addfc9..b1ef6ab 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -123,12 +123,13 @@
     { "/dev/msm_pcm_ctl",   0660,   AID_SYSTEM,     AID_AUDIO,      1 },
     { "/dev/msm_snd",       0660,   AID_SYSTEM,     AID_AUDIO,      1 },
     { "/dev/msm_mp3",       0660,   AID_SYSTEM,     AID_AUDIO,      1 },
+    { "/dev/msm_audpre",    0660,   AID_SYSTEM,     AID_AUDIO,      0 },
+    { "/dev/htc-acoustic",  0660,   AID_SYSTEM,     AID_AUDIO,      0 },
     { "/dev/smd0",          0640,   AID_RADIO,      AID_RADIO,      0 },
     { "/dev/qmi",           0640,   AID_RADIO,      AID_RADIO,      0 },
     { "/dev/qmi0",          0640,   AID_RADIO,      AID_RADIO,      0 },
     { "/dev/qmi1",          0640,   AID_RADIO,      AID_RADIO,      0 },
     { "/dev/qmi2",          0640,   AID_RADIO,      AID_RADIO,      0 },
-    { "/dev/htc-acoustic",  0640,   AID_RADIO,      AID_RADIO,      0 },
     { NULL, 0, 0, 0, 0 },
 };
 
diff --git a/libpixelflinger/Android.mk b/libpixelflinger/Android.mk
index 510e11e..50eb5f5 100644
--- a/libpixelflinger/Android.mk
+++ b/libpixelflinger/Android.mk
@@ -48,9 +48,7 @@
 PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer
 endif
 
-LOCAL_SHARED_LIBRARIES := \
-	libhardware_legacy	\
-	libcutils
+LOCAL_SHARED_LIBRARIES := libcutils
 
 ifneq ($(TARGET_ARCH),arm)
 # Required to define logging functions on the simulator.
@@ -63,15 +61,19 @@
 # Shared library
 #
 
-ifneq ($(BUILD_TINY_ANDROID),true)
 LOCAL_MODULE:= libpixelflinger
 LOCAL_SRC_FILES := $(PIXELFLINGER_SRC_FILES)
-LOCAL_CFLAGS := $(PIXELFLINGER_CFLAGS) -DWITH_LIB_HARDWARE
+LOCAL_CFLAGS := $(PIXELFLINGER_CFLAGS)
+ifneq ($(BUILD_TINY_ANDROID),true)
+# Really this should go away entirely or at least not depend on
+# libhardware, but this at least gets us built.
+LOCAL_SHARED_LIBRARIES += libhardware_legacy
+LOCAL_CFLAGS += -DWITH_LIB_HARDWARE
+endif
 ifeq ($(TARGET_ARCH),arm)
 LOCAL_WHOLE_STATIC_LIBRARIES := libpixelflinger_armv6
 endif
 include $(BUILD_SHARED_LIBRARY)
-endif
 
 #
 # Static library version
diff --git a/toolbox/top.c b/toolbox/top.c
index 0f40a0c..dcc0843 100644
--- a/toolbox/top.c
+++ b/toolbox/top.c
@@ -41,15 +41,20 @@
 
 struct cpu_info {
     long unsigned utime, ntime, stime, itime;
+    long unsigned iowtime, irqtime, sirqtime;
 };
 
+#define PROC_NAME_LEN 64
+#define THREAD_NAME_LEN 32
+
 struct proc_info {
     struct proc_info *next;
     pid_t pid;
     pid_t tid;
     uid_t uid;
     gid_t gid;
-    char name[256];
+    char name[PROC_NAME_LEN];
+    char tname[THREAD_NAME_LEN];
     char state;
     long unsigned utime;
     long unsigned stime;
@@ -69,7 +74,7 @@
 #define die(...) { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); }
 
 #define INIT_PROCS 50
-#define THREAD_MULT 4
+#define THREAD_MULT 8
 static struct proc_info **old_procs, **new_procs;
 static int num_old_procs, num_new_procs;
 static struct proc_info *free_procs;
@@ -228,7 +233,8 @@
 
     file = fopen("/proc/stat", "r");
     if (!file) die("Could not open /proc/stat.\n");
-    fscanf(file, "cpu  %lu %lu %lu %lu", &new_cpu.utime, &new_cpu.ntime, &new_cpu.stime, &new_cpu.itime);
+    fscanf(file, "cpu  %lu %lu %lu %lu %lu %lu %lu", &new_cpu.utime, &new_cpu.ntime, &new_cpu.stime,
+            &new_cpu.itime, &new_cpu.iowtime, &new_cpu.irqtime, &new_cpu.sirqtime);
     fclose(file);
 
     proc_num = 0;
@@ -237,7 +243,9 @@
             continue;
 
         pid = atoi(pid_dir->d_name);
-
+        
+        struct proc_info cur_proc;
+        
         if (!threads) {
             proc = alloc_proc();
 
@@ -254,6 +262,12 @@
 
             proc->num_threads = 0;
         } else {
+            sprintf(filename, "/proc/%d/cmdline", pid);
+            read_cmdline(filename, &cur_proc);
+
+            sprintf(filename, "/proc/%d/status", pid);
+            read_status(filename, &cur_proc);
+            
             proc = NULL;
         }
 
@@ -275,11 +289,9 @@
                 sprintf(filename, "/proc/%d/task/%d/stat", pid, tid);
                 read_stat(filename, proc);
 
-                sprintf(filename, "/proc/%d/task/%d/cmdline", pid, tid);
-                read_cmdline(filename, proc);
-
-                sprintf(filename, "/proc/%d/task/%d/status", pid, tid);
-                read_status(filename, proc);
+                strcpy(proc->name, cur_proc.name);
+                proc->uid = cur_proc.uid;
+                proc->gid = cur_proc.gid;
 
                 add_proc(proc_num++, proc);
             } else {
@@ -315,8 +327,9 @@
     if (!open_paren || !close_paren) return 1;
 
     *open_paren = *close_paren = '\0';
-    strcpy(proc->name, open_paren + 1);
-
+    strncpy(proc->tname, open_paren + 1, THREAD_NAME_LEN);
+    proc->tname[THREAD_NAME_LEN-1] = 0;
+    
     /* Scan rest of string. */
     sscanf(close_paren + 1, " %c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
                  "%lu %lu %*d %*d %*d %*d %*d %*d %*d %lu %ld",
@@ -347,8 +360,11 @@
     if (!file) return 1;
     fgets(line, MAX_LINE, file);
     fclose(file);
-    if (strlen(line) > 0)
-        strcpy(proc->name, line);
+    if (strlen(line) > 0) {
+        strncpy(proc->name, line, PROC_NAME_LEN);
+        proc->name[PROC_NAME_LEN-1] = 0;
+    } else
+        proc->name[0] = 0;
     return 0;
 }
 
@@ -391,16 +407,34 @@
         }
     }
 
-    total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime)
-                     - (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime);
+    total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime
+                        + new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime)
+                     - (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime
+                        + old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime);
 
     qsort(new_procs, num_new_procs, sizeof(struct proc_info *), proc_cmp);
 
     printf("\n\n\n");
+    printf("User %ld%%, System %ld%%, IOW %ld%%, IRQ %ld%%\n",
+            ((new_cpu.utime + new_cpu.ntime) - (old_cpu.utime + old_cpu.ntime)) * 100  / total_delta_time,
+            ((new_cpu.stime ) - (old_cpu.stime)) * 100 / total_delta_time,
+            ((new_cpu.iowtime) - (old_cpu.iowtime)) * 100 / total_delta_time,
+            ((new_cpu.irqtime + new_cpu.sirqtime)
+                    - (old_cpu.irqtime + old_cpu.sirqtime)) * 100 / total_delta_time);
+    printf("User %ld + Nice %ld + Sys %ld + Idle %ld + IOW %ld + IRQ %ld + SIRQ %ld = %ld\n",
+            new_cpu.utime - old_cpu.utime,
+            new_cpu.ntime - old_cpu.ntime,
+            new_cpu.stime - old_cpu.stime,
+            new_cpu.itime - old_cpu.itime,
+            new_cpu.iowtime - old_cpu.iowtime,
+            new_cpu.irqtime - old_cpu.irqtime,
+            new_cpu.sirqtime - old_cpu.sirqtime,
+            total_delta_time);
+    printf("\n");
     if (!threads) 
         printf("%5s %4s %1s %5s %7s %7s %-8s %s\n", "PID", "CPU%", "S", "#THR", "VSS", "RSS", "UID", "Name");
     else
-        printf("%5s %5s %4s %1s %7s %7s %-8s %s\n", "PID", "TID", "CPU%", "S", "VSS", "RSS", "UID", "Name");
+        printf("%5s %5s %4s %1s %7s %7s %-8s %-15s %s\n", "PID", "TID", "CPU%", "S", "VSS", "RSS", "UID", "Thread", "Proc");
 
     for (i = 0; i < num_new_procs; i++) {
         proc = new_procs[i];
@@ -423,10 +457,10 @@
         }
         if (!threads) 
             printf("%5d %3ld%% %c %5d %6ldK %6ldK %-8.8s %s\n", proc->pid, proc->delta_time * 100 / total_delta_time, proc->state, proc->num_threads,
-                proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->name);
+                proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->name[0] != 0 ? proc->name : proc->tname);
         else
-            printf("%5d %5d %3ld%% %c %6ldK %6ldK %-8.8s %s\n", proc->pid, proc->tid, proc->delta_time * 100 / total_delta_time, proc->state,
-                proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->name);
+            printf("%5d %5d %3ld%% %c %6ldK %6ldK %-8.8s %-15s %s\n", proc->pid, proc->tid, proc->delta_time * 100 / total_delta_time, proc->state,
+                proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->tname, proc->name);
     }
 }
 
diff --git a/vold/misc.c b/vold/misc.c
index 951414c..b8e5957 100644
--- a/vold/misc.c
+++ b/vold/misc.c
@@ -49,8 +49,11 @@
 
 	/* slurp it into our buffer */
 	ret = read(fd, buffer, size);
-	if (ret != size)
+	if (ret != size) {
+	        free(buffer);
+	        buffer = NULL;
 		goto bail;
+        }
 
 	/* let the caller know how big it is */
 	*_size = size;
@@ -59,33 +62,90 @@
 	close(fd);
 	return buffer;
 }
-char *truncate_sysfs_path(char *path, int num_elements_to_remove, char *buffer)
+
+char *truncate_sysfs_path(char *path, int count, char *buffer, size_t bufflen)
 {
-    int i;
+    char*  p;
 
-    strcpy(buffer, path);
+    strlcpy(buffer, path, bufflen);
+    p = buffer + strlen(buffer);
 
-    for (i = 0; i < num_elements_to_remove; i++) {
-        char *p = &buffer[strlen(buffer)-1];
+    for ( ; count > 0; count-- ) {
+        while (p > buffer && p[-1] != '/') {
+            p--; 
+        }
+        if (p == buffer)
+            break;
 
-        for (p = &buffer[strlen(buffer) -1]; *p != '/'; p--);
-        *p = '\0';
+        p -= 1;
     }
+    p[0] = '\0';
 
     return buffer;
 }
 
-char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var)
+/* used to read the first line of a /sys file into a heap-allocated buffer
+ * this assumes that reading the file returns a list of zero-terminated strings,
+ * each could also have a terminating \n before the 0
+ *
+ * returns NULL on error, of a new string on success, which must be freed by the
+ * caller.
+ */
+char *read_first_line_of(const char*  filepath)
 {
-    char filename[255];
-    char *p;
+    char *p, *q, *line;
+    size_t  len;
     ssize_t sz;
 
-    sprintf(filename, "/sys%s/%s", devpath, var);
-    p = read_file(filename, &sz);
-    p[(strlen(p) - 1)] = '\0';
-    strncpy(buffer, p, maxlen);
+    p = read_file((char*)filepath, &sz);
+    if (p == NULL)
+        goto FAIL;
+
+    /* search end of first line */
+    q = memchr(p, sz, '\0');
+    if (q == NULL)
+        q = p + sz;  /* let's be flexible */
+
+    len = (size_t)(q - p); /* compute line length */
+    if (len == 0)
+        goto FAIL;
+
+    if (p[len-1] == '\n') { /* strip trailing \n */
+        len -= 1;
+        if (len == 0)
+            goto FAIL;
+    }
+
+    line = malloc(len+1);
+    if (line == NULL)
+        goto FAIL;
+
+    memcpy(line, p, len);
+    line[len] = 0;
     free(p);
+
+    return line;
+
+FAIL:
+    if (p != NULL)
+        free(p);
+
+    return NULL;
+}
+
+char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var)
+{
+    char filename[255], *line;
+
+    snprintf(filename, sizeof filename, "/sys%s/%s", devpath, var);
+
+    line = read_first_line_of(filename);
+    if (line == NULL)
+        return NULL;
+
+    snprintf(buffer, maxlen, "%s", line);
+    free(line);
+
     return buffer;
 }
 
diff --git a/vold/uevent.c b/vold/uevent.c
index 3b7e53b..b1a6944 100644
--- a/vold/uevent.c
+++ b/vold/uevent.c
@@ -72,7 +72,7 @@
 };
 
 static boolean low_batt = false;
-static boolean door_open = false;
+static boolean door_open = true;
 
 int process_uevent_message(int socket)
 {
diff --git a/vold/volmgr.c b/vold/volmgr.c
index 0cec825..c3ce8d1 100644
--- a/vold/volmgr.c
+++ b/vold/volmgr.c
@@ -356,6 +356,7 @@
     LOG_VOL("Volmgr notified of %d:%d eject", dev->major, dev->minor);
 
     volume_t *v;
+    int rc;
 
     // XXX: Partitioning support is going to need us to stop *all*
     // devices in this volume
@@ -371,9 +372,38 @@
 
     if (v->state == volstate_mounted ||
         v->state == volstate_ums ||
-        v->state == volstate_checking)
+        v->state == volstate_checking) {
+
         volume_setstate(v, volstate_badremoval);
-    else if (v->state == volstate_formatting) {
+
+        /*
+         * Stop any devmapper volumes which
+         * are using us as a source
+         * XXX: We may need to enforce stricter
+         * order here
+         */
+        volume_t *dmvol = vol_root;
+        while (dmvol) {
+            if ((dmvol->media_type == media_devmapper) &&
+                (dmvol->dm->src_type == dmsrc_loopback) &&
+                (!strncmp(dmvol->dm->type_data.loop.loop_src, 
+                          v->mount_point, strlen(v->mount_point)))) {
+
+                pthread_mutex_lock(&dmvol->lock);
+                if (dmvol->state != volstate_nomedia) {
+                    rc = volmgr_shutdown_volume(dmvol, _cb_volstopped_for_devmapper_teardown, false);
+                    if (rc != -EINPROGRESS) {
+                        if (rc)
+                            LOGE("unable to shutdown volume '%s'", v->mount_point);
+                        pthread_mutex_unlock(&dmvol->lock);
+                    }
+                } else 
+                    pthread_mutex_unlock(&dmvol->lock);
+            }
+            dmvol = dmvol->next;
+        }
+
+    } else if (v->state == volstate_formatting) {
         /*
          * The device is being ejected due to
          * kernel disk revalidation.
@@ -409,7 +439,8 @@
     LOG_VOL("Volume %s has been stopped for eject", v->mount_point);
 #endif
 
-    eject_cb(v->dev);
+    if (eject_cb)
+        eject_cb(v->dev);
     v->dev = NULL; // Clear dev because its being ejected
 }