Reconcile with honeycomb-mr1-release

Change-Id: Id7ed4b392060d34981e51f60b5b407b6989737e6
diff --git a/Makefile.common b/Makefile.common
index 9c6d40a..15d6801 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -78,6 +78,7 @@
 	android/utils/filelock.c \
 	android/utils/ini.c \
 	android/utils/intmap.c \
+	android/utils/lineinput.c \
 	android/utils/mapfile.c \
 	android/utils/misc.c \
 	android/utils/panic.c \
diff --git a/android/console.c b/android/console.c
index 505d331..daae2d7 100644
--- a/android/console.c
+++ b/android/console.c
@@ -1854,9 +1854,10 @@
     p = args;
     while (*p) {
         char*  q;
+        char   temp[128];
         int    type, code, value, ret;
 
-        p += strspn( args, " \t" );  /* skip spaces */
+        p += strspn( p, " \t" );  /* skip spaces */
         if (*p == 0)
             break;
 
@@ -1865,7 +1866,8 @@
         if (q == p)
             break;
 
-        ret = android_event_from_str( p, &type, &code, &value );
+        snprintf(temp, sizeof temp, "%.*s", q-p, p);
+        ret = android_event_from_str( temp, &type, &code, &value );
         if (ret < 0) {
             if (ret == -1) {
                 control_write( client,
diff --git a/android/hw-events.c b/android/hw-events.c
index 7c3f9e9..4318f65 100644
--- a/android/hw-events.c
+++ b/android/hw-events.c
@@ -106,7 +106,7 @@
     if (namelen <= 0)
         return -1;
 
-    for ( ; list != NULL; list += 1 ) {
+    for ( ; list->name != NULL; list += 1 ) {
         if ( !memcmp(name, list->name, namelen) &&
              list->name[namelen] == 0 )
         {
@@ -167,7 +167,11 @@
         q = pend;
 
     list   = eventList_findByType( *ptype );
-    *pcode = eventList_findCodeByName( list, p, q-p );
+    if (list == NULL) {
+        *pcode = -1;
+    } else {
+        *pcode = eventList_findCodeByName( list, p, q-p );
+    }
     if (*pcode < 0) {
         *pcode = (int) strtol( p, &end, 0 );
         if (end != q)
diff --git a/android/hw-lcd.c b/android/hw-lcd.c
index 2c06d69..f84f661 100644
--- a/android/hw-lcd.c
+++ b/android/hw-lcd.c
@@ -19,12 +19,14 @@
     char  temp[8];
 
     /* map density to one of our three values for now */
-    if (density < (LCD_DENSITY_MIN + LCD_DENSITY_DEFAULT)/2)
-        density = LCD_DENSITY_MIN;
-    else if (density < (LCD_DENSITY_DEFAULT + LCD_DENSITY_MAX)/2)
-        density = LCD_DENSITY_DEFAULT;
+    if (density < (LCD_DENSITY_LDPI + LCD_DENSITY_MDPI)/2)
+        density = LCD_DENSITY_LDPI;
+    else if (density < (LCD_DENSITY_MDPI + LCD_DENSITY_HDPI)/2)
+        density = LCD_DENSITY_MDPI;
+    else if (density < (LCD_DENSITY_HDPI + LCD_DENSITY_XHDPI)/2)
+        density = LCD_DENSITY_HDPI;
     else
-        density = LCD_DENSITY_MAX;
+        density = LCD_DENSITY_XHDPI;
 
     snprintf(temp, sizeof temp, "%d", density);
     boot_property_add("qemu.sf.lcd_density", temp);
diff --git a/android/hw-lcd.h b/android/hw-lcd.h
index b9fdb72..c902b13 100644
--- a/android/hw-lcd.h
+++ b/android/hw-lcd.h
@@ -12,9 +12,10 @@
 #ifndef _ANDROID_HW_LCD_H
 #define _ANDROID_HW_LCD_H
 
-#define  LCD_DENSITY_MIN      120
-#define  LCD_DENSITY_DEFAULT  160
-#define  LCD_DENSITY_MAX      240
+#define  LCD_DENSITY_LDPI      120
+#define  LCD_DENSITY_MDPI      160
+#define  LCD_DENSITY_HDPI      240
+#define  LCD_DENSITY_XHDPI     320
 
 /* Sets the boot property corresponding to the emulated abstract LCD density */
 extern void  hwLcd_setBootProperty(int density);
diff --git a/android/main.c b/android/main.c
index aa3ee46..37bf34a 100644
--- a/android/main.c
+++ b/android/main.c
@@ -39,6 +39,7 @@
 #include "android/user-config.h"
 #include "android/utils/bufprint.h"
 #include "android/utils/filelock.h"
+#include "android/utils/lineinput.h"
 #include "android/utils/path.h"
 #include "android/utils/tempfile.h"
 
@@ -1089,6 +1090,25 @@
         }
         args[n++] = "-android-hw";
         args[n++] = strdup(coreHwIniPath);
+
+        /* In verbose mode, dump the file's content */
+        if (VERBOSE_CHECK(init)) {
+            FILE* file = fopen(coreHwIniPath, "rt");
+            if (file == NULL) {
+                derror("Could not open hardware configuration file: %s\n",
+                       coreHwIniPath);
+            } else {
+                LineInput* input = lineInput_newFromStdFile(file);
+                const char* line;
+                printf("Content of hardware configuration file:\n");
+                while ((line = lineInput_getLine(input)) !=  NULL) {
+                    printf("  %s\n", line);
+                }
+                printf(".\n");
+                lineInput_free(input);
+                fclose(file);
+            }
+        }
     }
 
     if(VERBOSE_CHECK(init)) {
diff --git a/android/utils/lineinput.c b/android/utils/lineinput.c
new file mode 100644
index 0000000..18e8a1c
--- /dev/null
+++ b/android/utils/lineinput.c
@@ -0,0 +1,244 @@
+/* Copyright (C) 2011 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+#include <errno.h>
+#include "android/utils/system.h"
+#include "android/utils/assert.h"
+#include "android/utils/lineinput.h"
+
+struct LineInput {
+    char*   line;
+    size_t  line_size;
+    int     line_num;
+    int     error;
+    int     eof;
+
+    struct {
+        FILE*  file;
+    } std;
+
+    char    line0[128];
+};
+
+/* Error codes returned by the internal line reading function(s) */
+enum {
+    LINEINPUT_ERROR = -1,
+    LINEINPUT_EOF = -2,
+};
+
+
+static LineInput*
+_lineInput_new( void )
+{
+    LineInput*  input;
+
+    ANEW0(input);
+    input->line      = input->line0;
+    input->line_size = sizeof(input->line0);
+
+    return input;
+}
+
+/* Create a LineInput object that reads from a FILE* object */
+LineInput*
+lineInput_newFromStdFile( FILE* file )
+{
+    LineInput* input = _lineInput_new();
+
+    input->std.file = file;
+    return input;
+}
+
+/* Grow the line buffer a bit */
+static void
+_lineInput_grow( LineInput* input )
+{
+    char*  line;
+
+    input->line_size += input->line_size >> 1;
+    line = input->line;
+    if (line == input->line0)
+        line = NULL;
+
+    AARRAY_RENEW(line, input->line_size);
+    input->line = line;
+}
+
+/* Forward declaration */
+static int _lineInput_getLineFromStdFile( LineInput* input, FILE* file );
+
+const char*
+lineInput_getLine( LineInput* input )
+{
+    return lineInput_getLineAndSize(input, NULL);
+}
+
+const char*
+lineInput_getLineAndSize( LineInput* input, size_t *pSize )
+{
+    int ret;
+
+    /* be safe */
+    if (pSize)
+        *pSize = 0;
+
+    /* check parameters */
+    if (input == NULL) {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    /* check state */
+    if (input->error) {
+        return NULL;
+    }
+    if (input->eof) {
+        return NULL;
+    }
+
+    ret = _lineInput_getLineFromStdFile(input, input->std.file);
+    if (ret >= 0) {
+        input->line_num += 1;
+        if (pSize != NULL) {
+            *pSize = ret;
+            return input->line;
+        }
+        return input->line;
+    }
+    if (ret == LINEINPUT_EOF) {
+        input->line_num += 1;
+        input->eof = 1;
+        return NULL;
+    }
+    if (ret == LINEINPUT_ERROR) {
+        input->error = errno;
+        return NULL;
+    }
+    AASSERT_UNREACHED();
+    return NULL;
+}
+
+/* Returns the number of the last line read by lineInput_getLine */
+int
+lineInput_getLineNumber( LineInput* input )
+{
+    return input->line_num;
+}
+
+/* Returns TRUE iff the end of file was reached */
+int
+lineInput_isEof( LineInput* input )
+{
+    return (input->eof != 0);
+}
+
+/* Return the error condition of a LineInput object.
+ * These are standard errno code for the last operation.
+ * Note: EOF corresponds to 0 here.
+ */
+int
+lineInput_getError( LineInput* input )
+{
+    return input->error;
+}
+
+void
+lineInput_free( LineInput* input )
+{
+    if (input != NULL) {
+        if (input->line != NULL) {
+            if (input->line != input->line0)
+                AFREE(input->line);
+            input->line = NULL;
+            input->line_size = 0;
+        }
+        AFREE(input);
+    }
+}
+
+
+/* Internal function used to read a new line from a FILE* using fgets().
+ * We assume that this is more efficient than calling fgetc() in a loop.
+ *
+ * Return length of line, or either LINEINPUT_EOF / LINEINPUT_ERROR
+ */
+static int
+_lineInput_getLineFromStdFile( LineInput* input, FILE* file )
+{
+    int   offset = 0;
+    char* p;
+
+    input->line[0] = '\0';
+
+    for (;;) {
+        char* buffer = input->line + offset;
+        int   avail  = input->line_size - offset;
+
+        if (!fgets(buffer, avail, file)) {
+            /* We either reached the end of file or an i/o error occured.
+             * If we already read line data, just return it this time.
+             */
+            if (offset > 0) {
+                return offset;
+            }
+            goto INPUT_ERROR;
+        }
+
+        /* Find the terminating zero */
+        p = memchr(buffer, '\0', avail);
+        AASSERT(p != NULL);
+
+        if (p == buffer) {
+            /* This happens when the file has an embedded '\0', treat it
+             * as an eof, or bad things usually happen after that. */
+            input->eof = 1;
+            if (offset > 0)
+                return offset;
+            else
+                return LINEINPUT_EOF;
+        }
+
+        if (p[-1] != '\n' && p[-1] != '\r') {
+            /* This happens when the line is longer than our current buffer,
+            * so grow its size and try again. */
+            offset = p - input->line;
+            _lineInput_grow(input);
+            continue;
+        }
+
+        break;
+    }
+
+    /* Get rid of trailing newline(s). Consider: \n, \r, and \r\n */
+    if (p[-1] == '\n') {
+        p -= 1;
+        if (p > input->line && p[-1] == '\r') {
+            p -= 1;
+        }
+        p[0] = '\0';
+    }
+    else if (p[-1] == '\r') {
+        p -= 1;
+        p[0] = '\0';
+    }
+
+    /* We did it */
+    return (p - input->line);
+
+INPUT_ERROR:
+    if (feof(file)) {
+        input->eof = 1;
+        return LINEINPUT_EOF;
+    }
+    input->error = errno;
+    return LINEINPUT_ERROR;
+}
+
diff --git a/android/utils/lineinput.h b/android/utils/lineinput.h
new file mode 100644
index 0000000..1870285
--- /dev/null
+++ b/android/utils/lineinput.h
@@ -0,0 +1,56 @@
+/* Copyright (C) 2011 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+#ifndef _ANDROID_UTILS_LINEINPUT_H
+#define _ANDROID_UTILS_LINEINPUT_H
+
+#include <stdio.h>
+
+/* A LineInput is used to read input text, one line at a time,
+ * into a temporary buffer owner by the LineInput object.
+ */
+typedef struct LineInput LineInput;
+
+/* Create a LineInput object that reads from a FILE* object */
+LineInput*  lineInput_newFromStdFile( FILE* file );
+
+/* Read next line from input. The result is zero-terminated with
+ * all newlines removed (\n, \r or \r\n) automatically.
+ *
+ * Returns NULL in case of error, or when the end of file is reached.
+ * See lineInput_isEof() and lineInput_getError()
+ *
+ * The returned string is owned by the LineInput object and its
+ * value will not persist any other call to any LineInput functions.
+ */
+const char* lineInput_getLine( LineInput* input );
+
+/* Same as lineInput_getLine(), but also returns the line size into
+ * '*pSize' to save you a strlen() call.
+ */
+const char* lineInput_getLineAndSize( LineInput* input, size_t *pSize );
+
+/* Returns the number of the last line read by lineInput_getLine */
+int lineInput_getLineNumber( LineInput* input );
+
+/* Returns TRUE iff the end of file was reached */
+int lineInput_isEof( LineInput* input );
+
+/* Return the error condition of a LineInput object.
+ * These are standard errno code for the last operation.
+ * Note: EOF corresponds to 0 here.
+ */
+int lineInput_getError( LineInput* input );
+
+/* Free a LineInput object. */
+void lineInput_free( LineInput* input );
+
+#endif /* _ANDROID_UTILS_LINEINPUT_H */
diff --git a/vl-android.c b/vl-android.c
index a1b88be..acde409 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -3549,10 +3549,10 @@
 
 /* Find a likely location for support files using the location of the binary.
    For installed binaries this will be "$bindir/../share/qemu".  When
-   running from the build tree this will be "$bindir/../pc-bios".
+   running from the build tree this will be "$bindir/../usr/share/pc-bios".
    The emulator running from the SDK will find the support files in $bindir/lib/pc-bios. */
 #define SHARE_SUFFIX "/share/qemu"
-#define BUILD_SUFFIX "/pc-bios"
+#define BUILD_SUFFIX "/usr/share/pc-bios"
 #define SDK_SUFFIX "/lib/pc-bios"
 static char *find_datadir(const char *argv0)
 {
@@ -5079,6 +5079,13 @@
             } else {
                 /* Successful locking */
                 hda_opts = drive_add(sdPath, HD_ALIAS, 0);
+                /* Set this property of any operation involving the SD Card
+                 * will be x100 slower, due to the corresponding file being
+                 * mounted as O_DIRECT. Note that this is only 'unsafe' in
+                 * the context of an emulator crash. The data is already
+                 * synced properly when the emulator exits (either normally or through ^C).
+                 */
+                qemu_opt_set(hda_opts, "cache", "unsafe");
             }
         }
     }
@@ -5093,10 +5100,7 @@
                 PANIC("Snapshot storage already in use: %s", spath);
             }
             hdb_opts = drive_add(spath, HD_ALIAS, 1);
-            /* VERY IMPORTANT:
-             *    Set this property or the file will be mounted with O_DIRECT,
-             *    which will slow down snapshot saving x100 !
-             */
+            /* See comment above to understand why this is needed. */
             qemu_opt_set(hdb_opts, "cache", "unsafe");
         }
     }