Merge "Added a cmd for configuring number of video buffers for camera, if supported" into jb-mr1-dev
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c
index 5d261cd..c059b89 100644
--- a/libusbhost/usbhost.c
+++ b/libusbhost/usbhost.c
@@ -49,7 +49,8 @@
 
 #include "usbhost/usbhost.h"
 
-#define USB_FS_DIR "/dev/bus/usb"
+#define DEV_DIR             "/dev"
+#define USB_FS_DIR          "/dev/bus/usb"
 #define USB_FS_ID_SCANNER   "/dev/bus/usb/%d/%d"
 #define USB_FS_ID_FORMAT    "/dev/bus/usb/%03d/%03d"
 
@@ -77,39 +78,72 @@
     return 0;
 }
 
+static int find_existing_devices_bus(char *busname,
+                                     usb_device_added_cb added_cb,
+                                     void *client_data)
+{
+    char devname[32];
+    DIR *devdir;
+    struct dirent *de;
+    int done = 0;
+
+    devdir = opendir(busname);
+    if(devdir == 0) return 0;
+
+    while ((de = readdir(devdir)) && !done) {
+        if(badname(de->d_name)) continue;
+
+        snprintf(devname, sizeof(devname), "%s/%s", busname, de->d_name);
+        done = added_cb(devname, client_data);
+    } // end of devdir while
+    closedir(devdir);
+
+    return done;
+}
+
 /* returns true if one of the callbacks indicates we are done */
 static int find_existing_devices(usb_device_added_cb added_cb,
-                                  usb_device_removed_cb removed_cb,
                                   void *client_data)
 {
-    char busname[32], devname[32];
-    DIR *busdir , *devdir ;
+    char busname[32];
+    DIR *busdir;
     struct dirent *de;
     int done = 0;
 
     busdir = opendir(USB_FS_DIR);
-    if(busdir == 0) return 1;
+    if(busdir == 0) return 0;
 
     while ((de = readdir(busdir)) != 0 && !done) {
         if(badname(de->d_name)) continue;
 
-        snprintf(busname, sizeof busname, "%s/%s", USB_FS_DIR, de->d_name);
-        devdir = opendir(busname);
-        if(devdir == 0) continue;
-
-        while ((de = readdir(devdir)) && !done) {
-            if(badname(de->d_name)) continue;
-
-            snprintf(devname, sizeof devname, "%s/%s", busname, de->d_name);
-            done = added_cb(devname, client_data);
-        } // end of devdir while
-        closedir(devdir);
-    } //end of busdir while
+        snprintf(busname, sizeof(busname), "%s/%s", USB_FS_DIR, de->d_name);
+        done = find_existing_devices_bus(busname, added_cb,
+                                         client_data);
+    }
     closedir(busdir);
 
     return done;
 }
 
+static void watch_existing_subdirs(struct usb_host_context *context,
+                                   int *wds, int wd_count)
+{
+    char path[100];
+    int i, ret;
+
+    wds[0] = inotify_add_watch(context->fd, USB_FS_DIR, IN_CREATE | IN_DELETE);
+    if (wds[0] < 0)
+        return;
+
+    /* watch existing subdirectories of USB_FS_DIR */
+    for (i = 1; i < wd_count; i++) {
+        snprintf(path, sizeof(path), "%s/%03d", USB_FS_DIR, i);
+        ret = inotify_add_watch(context->fd, path, IN_CREATE | IN_DELETE);
+        if (ret >= 0)
+            wds[i] = ret;
+    }
+}
+
 struct usb_host_context *usb_host_init()
 {
     struct usb_host_context *context = calloc(1, sizeof(struct usb_host_context));
@@ -142,32 +176,28 @@
     char event_buf[512];
     char path[100];
     int i, ret, done = 0;
-    int wd, wds[10];
+    int wd, wdd, wds[10];
     int wd_count = sizeof(wds) / sizeof(wds[0]);
 
     D("Created device discovery thread\n");
 
     /* watch for files added and deleted within USB_FS_DIR */
-    memset(wds, 0, sizeof(wds));
+    for (i = 0; i < wd_count; i++)
+        wds[i] = -1;
+
     /* watch the root for new subdirectories */
-    wds[0] = inotify_add_watch(context->fd, USB_FS_DIR, IN_CREATE | IN_DELETE);
-    if (wds[0] < 0) {
+    wdd = inotify_add_watch(context->fd, DEV_DIR, IN_CREATE | IN_DELETE);
+    if (wdd < 0) {
         fprintf(stderr, "inotify_add_watch failed\n");
         if (discovery_done_cb)
             discovery_done_cb(client_data);
         return;
     }
 
-    /* watch existing subdirectories of USB_FS_DIR */
-    for (i = 1; i < wd_count; i++) {
-        snprintf(path, sizeof(path), "%s/%03d", USB_FS_DIR, i);
-        ret = inotify_add_watch(context->fd, path, IN_CREATE | IN_DELETE);
-        if (ret > 0)
-            wds[i] = ret;
-    }
+    watch_existing_subdirs(context, wds, wd_count);
 
     /* check for existing devices first, after we have inotify set up */
-    done = find_existing_devices(added_cb, removed_cb, client_data);
+    done = find_existing_devices(added_cb, client_data);
     if (discovery_done_cb)
         done |= discovery_done_cb(client_data);
 
@@ -176,14 +206,35 @@
         if (ret >= (int)sizeof(struct inotify_event)) {
             event = (struct inotify_event *)event_buf;
             wd = event->wd;
-            if (wd == wds[0]) {
+            if (wd == wdd) {
+                if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) {
+                    watch_existing_subdirs(context, wds, wd_count);
+                    done = find_existing_devices(added_cb, client_data);
+                } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "bus")) {
+                    for (i = 0; i < wd_count; i++) {
+                        if (wds[i] >= 0) {
+                            inotify_rm_watch(context->fd, wds[i]);
+                            wds[i] = -1;
+                        }
+                    }
+                }
+            } else if (wd == wds[0]) {
                 i = atoi(event->name);
                 snprintf(path, sizeof(path), "%s/%s", USB_FS_DIR, event->name);
-                D("new subdirectory %s: index: %d\n", path, i);
+                D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ?
+                                                     "new" : "gone", path, i);
                 if (i > 0 && i < wd_count) {
-                ret = inotify_add_watch(context->fd, path, IN_CREATE | IN_DELETE);
-                if (ret > 0)
-                    wds[i] = ret;
+                    if (event->mask & IN_CREATE) {
+                        ret = inotify_add_watch(context->fd, path,
+                                                IN_CREATE | IN_DELETE);
+                        if (ret >= 0)
+                            wds[i] = ret;
+                        done = find_existing_devices_bus(path, added_cb,
+                                                         client_data);
+                    } else if (event->mask & IN_DELETE) {
+                        inotify_rm_watch(context->fd, wds[i]);
+                        wds[i] = -1;
+                    }
                 }
             } else {
                 for (i = 1; i < wd_count && !done; i++) {
diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c
index d72e317..2c32ce3 100644
--- a/mkbootimg/mkbootimg.c
+++ b/mkbootimg/mkbootimg.c
@@ -109,18 +109,17 @@
     int fd;
     SHA_CTX ctx;
     uint8_t* sha;
+    unsigned base           = 0x10000000;
+    unsigned kernel_offset  = 0x00008000;
+    unsigned ramdisk_offset = 0x01000000;
+    unsigned second_offset  = 0x00f00000;
+    unsigned tags_offset    = 0x00000100;
 
     argc--;
     argv++;
 
     memset(&hdr, 0, sizeof(hdr));
 
-        /* default load addresses */
-    hdr.kernel_addr =  0x10008000;
-    hdr.ramdisk_addr = 0x11000000;
-    hdr.second_addr =  0x10F00000;
-    hdr.tags_addr =    0x10000100;
-
     while(argc > 0){
         char *arg = argv[0];
         char *val = argv[1];
@@ -140,11 +139,15 @@
         } else if(!strcmp(arg, "--cmdline")) {
             cmdline = val;
         } else if(!strcmp(arg, "--base")) {
-            unsigned base = strtoul(val, 0, 16);
-            hdr.kernel_addr =  base + 0x00008000;
-            hdr.ramdisk_addr = base + 0x01300000;
-            hdr.second_addr =  base + 0x00F00000;
-            hdr.tags_addr =    base + 0x00000100;
+            base = strtoul(val, 0, 16);
+        } else if(!strcmp(arg, "--kernel_offset")) {
+            kernel_offset = strtoul(val, 0, 16);
+        } else if(!strcmp(arg, "--ramdisk_offset")) {
+            ramdisk_offset = strtoul(val, 0, 16);
+        } else if(!strcmp(arg, "--second_offset")) {
+            second_offset = strtoul(val, 0, 16);
+        } else if(!strcmp(arg, "--tags_offset")) {
+            tags_offset = strtoul(val, 0, 16);
         } else if(!strcmp(arg, "--board")) {
             board = val;
         } else if(!strcmp(arg,"--pagesize")) {
@@ -159,6 +162,10 @@
     }
     hdr.page_size = pagesize;
 
+    hdr.kernel_addr =  base + kernel_offset;
+    hdr.ramdisk_addr = base + ramdisk_offset;
+    hdr.second_addr =  base + second_offset;
+    hdr.tags_addr =    base + tags_offset;
 
     if(bootimg == 0) {
         fprintf(stderr,"error: no output filename specified\n");
diff --git a/rootdir/etc/init.goldfish.rc b/rootdir/etc/init.goldfish.rc
index 83b7f8a..cde9dee 100644
--- a/rootdir/etc/init.goldfish.rc
+++ b/rootdir/etc/init.goldfish.rc
@@ -5,6 +5,10 @@
     symlink /mnt/sdcard /sdcard
 
 on boot
+    setsebool in_qemu=1
+    restorecon /sys/qemu_trace/process_name
+    restorecon /sys/qemu_trace/state
+    restorecon /sys/qemu_trace/symbol
     setprop ARGH ARGH
     setprop net.eth0.gw 10.0.2.2
     setprop net.eth0.dns1 10.0.2.3
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 8497591..22e5e0a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -12,6 +12,10 @@
     # Set init and its forked children's oom_adj.
     write /proc/1/oom_adj -16
 
+    # Set the security context for the init process.
+    # This should occur before anything else (e.g. ueventd) is started.
+    setcon u:r:init:s0
+
     start ueventd
 
 # create mountpoints
@@ -128,10 +132,14 @@
     # We chown/chmod /cache again so because mount is run as root + defaults
     chown system cache /cache
     chmod 0770 /cache
+    # We restorecon /cache in case the cache partition has been reset.
+    restorecon /cache
 
     # This may have been created by the recovery system with odd permissions
     chown system cache /cache/recovery
     chmod 0770 /cache/recovery
+    # This may have been created by the recovery system with the wrong context.
+    restorecon /cache/recovery
 
     #change permissions on vmallocinfo so we can grab it from bugreports
     chown root log /proc/vmallocinfo
@@ -150,6 +158,8 @@
     # We chown/chmod /data again so because mount is run as root + defaults
     chown system system /data
     chmod 0771 /data
+    # We restorecon /data in case the userdata partition has been reset.
+    restorecon /data
 
     # Create dump dir and collect dumps.
     # Do this before we mount cache so eventually we can use cache for
@@ -345,6 +355,7 @@
 service ueventd /sbin/ueventd
     class core
     critical
+    seclabel u:r:ueventd:s0
 
 service console /system/bin/sh
     class core
@@ -361,6 +372,7 @@
     class core
     socket adbd stream 660 system system
     disabled
+    seclabel u:r:adbd:s0
 
 # adbd on at boot in emulator
 on property:ro.kernel.qemu=1