Set hw.keyboard.lid default value to false for API level >= 12

This patch modifies the emulator to extract the target API level for
the AVD or the current platform release, and use it to set the
default value of hw.keyboard.lid.

This will *not* affect any existing AVD/platform that sets the value
explicitely in its config.ini (for AVDs) or hardware.ini (for platform
builds).

The change is beneficial for platform builds targetting API level >= 12,
because the input framework changed its the window orientation behaviour
depending on the availability of a hardware lid.

In short, this allows platform builds to be correctly oriented, even
if they don't provide a custom hardware.ini.

Fix for bug 4128604

Change-Id: I195135aae6f3c4cc11d2f01e1293f3cd6cad2f58
diff --git a/android/avd/hw-config.c b/android/avd/hw-config.c
index b449bb3..65796d9 100644
--- a/android/avd/hw-config.c
+++ b/android/avd/hw-config.c
@@ -11,6 +11,7 @@
 */
 #include "android/avd/hw-config.h"
 #include "android/utils/ini.h"
+#include "android/utils/system.h"
 #include <string.h>
 #include <stdlib.h>
 
@@ -18,6 +19,61 @@
 /* the global variable containing the hardware config for this device */
 AndroidHwConfig   android_hw[1];
 
+static int
+stringToBoolean( const char* value )
+{
+    if (!strcmp(value,"1")    ||
+        !strcmp(value,"yes")  ||
+        !strcmp(value,"YES")  ||
+        !strcmp(value,"true") ||
+        !strcmp(value,"TRUE"))
+    {
+        return 1;
+    }
+    else
+        return 0;
+}
+
+static int64_t
+diskSizeToInt64( const char* diskSize )
+{
+    char*   end;
+    int64_t value;
+
+    value = strtoll(diskSize, &end, 10);
+    if (*end == 'k' || *end == 'K')
+        value *= 1024ULL;
+    else if (*end == 'm' || *end == 'M')
+        value *= 1024*1024ULL;
+    else if (*end == 'g' || *end == 'G')
+        value *= 1024*1024*1024ULL;
+
+    return value;
+}
+
+
+void
+androidHwConfig_init( AndroidHwConfig*  config,
+                      int               apiLevel )
+{
+#define   HWCFG_BOOL(n,s,d,a,t)       config->n = stringToBoolean(d);
+#define   HWCFG_INT(n,s,d,a,t)        config->n = d;
+#define   HWCFG_STRING(n,s,d,a,t)     config->n = ASTRDUP(d);
+#define   HWCFG_DOUBLE(n,s,d,a,t)     config->n = d;
+#define   HWCFG_DISKSIZE(n,s,d,a,t)   config->n = diskSizeToInt64(d);
+
+#include "android/avd/hw-config-defs.h"
+
+    /* Special case for hw.keyboard.lid, we need to set the
+     * default to FALSE for apiLevel >= 12. This allows platform builds
+     * to get correct orientation emulation even if they don't bring
+     * a custom hardware.ini
+     */
+    if (apiLevel >= 12) {
+        config->hw_keyboard_lid = 0;
+    }
+}
+
 int
 androidHwConfig_read( AndroidHwConfig*  config,
                       IniFile*          ini )
@@ -27,11 +83,11 @@
 
     /* use the magic of macros to implement the hardware configuration loaded */
 
-#define   HWCFG_BOOL(n,s,d,a,t)       config->n = iniFile_getBoolean(ini, s, d);
-#define   HWCFG_INT(n,s,d,a,t)        config->n = iniFile_getInteger(ini, s, d);
-#define   HWCFG_STRING(n,s,d,a,t)     config->n = iniFile_getString(ini, s, d);
-#define   HWCFG_DOUBLE(n,s,d,a,t)     config->n = iniFile_getDouble(ini, s, d);
-#define   HWCFG_DISKSIZE(n,s,d,a,t)   config->n = iniFile_getDiskSize(ini, s, d);
+#define   HWCFG_BOOL(n,s,d,a,t)       if (iniFile_getValue(ini, s)) { config->n = iniFile_getBoolean(ini, s, d); }
+#define   HWCFG_INT(n,s,d,a,t)        if (iniFile_getValue(ini, s)) { config->n = iniFile_getInteger(ini, s, d); }
+#define   HWCFG_STRING(n,s,d,a,t)     if (iniFile_getValue(ini, s)) { AFREE(config->n); config->n = iniFile_getString(ini, s, d); }
+#define   HWCFG_DOUBLE(n,s,d,a,t)     if (iniFile_getValue(ini, s)) { config->n = iniFile_getDouble(ini, s, d); }
+#define   HWCFG_DISKSIZE(n,s,d,a,t)   if (iniFile_getValue(ini, s)) { config->n = iniFile_getDiskSize(ini, s, d); }
 
 #include "android/avd/hw-config-defs.h"
 
@@ -57,3 +113,15 @@
 
     return 0;
 }
+
+void
+androidHwConfig_done( AndroidHwConfig* config )
+{
+#define   HWCFG_BOOL(n,s,d,a,t)       config->n = 0;
+#define   HWCFG_INT(n,s,d,a,t)        config->n = 0;
+#define   HWCFG_STRING(n,s,d,a,t)     AFREE(config->n);
+#define   HWCFG_DOUBLE(n,s,d,a,t)     config->n = 0.0;
+#define   HWCFG_DISKSIZE(n,s,d,a,t)   config->n = 0;
+
+#include "android/avd/hw-config-defs.h"
+}