From 955e08b520602fe1617f4be36698c99858523d33 Mon Sep 17 00:00:00 2001 From: Xavier Ducrohet Date: Mon, 29 Jun 2009 08:01:02 -0700 Subject: [PATCH] Skins can now provide their own hardware support (via AVDs) --- emulator/skins/HVGA-L/hardware.ini | 2 + emulator/skins/HVGA-P/hardware.ini | 2 + emulator/skins/HVGA/hardware.ini | 2 + emulator/skins/QVGA-L/hardware.ini | 2 + emulator/skins/QVGA-P/hardware.ini | 2 + .../app/src/com/android/sdkmanager/Main.java | 60 ++++++++---- .../src/com/android/sdklib/SdkManager.java | 2 +- .../sdklib/internal/avd/AvdManager.java | 92 ++++++++++++++++--- 8 files changed, 129 insertions(+), 35 deletions(-) create mode 100644 emulator/skins/HVGA-L/hardware.ini create mode 100644 emulator/skins/HVGA-P/hardware.ini create mode 100644 emulator/skins/HVGA/hardware.ini create mode 100644 emulator/skins/QVGA-L/hardware.ini create mode 100644 emulator/skins/QVGA-P/hardware.ini diff --git a/emulator/skins/HVGA-L/hardware.ini b/emulator/skins/HVGA-L/hardware.ini new file mode 100644 index 000000000..f6a30b0d2 --- /dev/null +++ b/emulator/skins/HVGA-L/hardware.ini @@ -0,0 +1,2 @@ +# skin-specific hardware values +hw.lcd.density=160 \ No newline at end of file diff --git a/emulator/skins/HVGA-P/hardware.ini b/emulator/skins/HVGA-P/hardware.ini new file mode 100644 index 000000000..f6a30b0d2 --- /dev/null +++ b/emulator/skins/HVGA-P/hardware.ini @@ -0,0 +1,2 @@ +# skin-specific hardware values +hw.lcd.density=160 \ No newline at end of file diff --git a/emulator/skins/HVGA/hardware.ini b/emulator/skins/HVGA/hardware.ini new file mode 100644 index 000000000..f6a30b0d2 --- /dev/null +++ b/emulator/skins/HVGA/hardware.ini @@ -0,0 +1,2 @@ +# skin-specific hardware values +hw.lcd.density=160 \ No newline at end of file diff --git a/emulator/skins/QVGA-L/hardware.ini b/emulator/skins/QVGA-L/hardware.ini new file mode 100644 index 000000000..2efe617a1 --- /dev/null +++ b/emulator/skins/QVGA-L/hardware.ini @@ -0,0 +1,2 @@ +# skin-specific hardware values +hw.lcd.density=120 \ No newline at end of file diff --git a/emulator/skins/QVGA-P/hardware.ini b/emulator/skins/QVGA-P/hardware.ini new file mode 100644 index 000000000..2efe617a1 --- /dev/null +++ b/emulator/skins/QVGA-P/hardware.ini @@ -0,0 +1,2 @@ +# skin-specific hardware values +hw.lcd.density=120 \ No newline at end of file diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java index b5988ffc3..1038d919c 100644 --- a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java +++ b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java @@ -597,21 +597,8 @@ class Main { avdName + AvdManager.AVD_FOLDER_EXTENSION); } - Map hardwareConfig = null; - if (target.isPlatform()) { - try { - hardwareConfig = promptForHardware(target); - } catch (IOException e) { - errorAndExit(e.getMessage()); - } - } - - AvdInfo oldAvdInfo = null; - if (removePrevious) { - oldAvdInfo = avdManager.getAvd(avdName, false /*validAvdOnly*/); - } - // Validate skin is either default (empty) or NNNxMMM or a valid skin name. + Map skinHardwareConfig = null; String skin = mSdkCommandLine.getParamSkin(); if (skin != null && skin.length() == 0) { skin = null; @@ -623,6 +610,17 @@ class Main { if (skin.equalsIgnoreCase(s)) { skin = s; // Make skin names case-insensitive. valid = true; + + // get the hardware properties for this skin + File skinFile = avdManager.getSkinPath(skin, target); + if (skinFile.isDirectory()) { // this should not fail since we got the skin + // name from the target + File skinHardwareFle = new File(skinFile, AvdManager.HARDWARE_INI); + if (skinHardwareFle.isFile()) { + skinHardwareConfig = SdkManager.parsePropertyFile( + skinHardwareFle, mSdkLog); + } + } break; } } @@ -639,6 +637,20 @@ class Main { } } + Map hardwareConfig = null; + if (target.isPlatform()) { + try { + hardwareConfig = promptForHardware(target, skinHardwareConfig); + } catch (IOException e) { + errorAndExit(e.getMessage()); + } + } + + AvdInfo oldAvdInfo = null; + if (removePrevious) { + oldAvdInfo = avdManager.getAvd(avdName, false /*validAvdOnly*/); + } + AvdInfo newAvdInfo = avdManager.createAvd(avdFolder, avdName, target, @@ -805,7 +817,8 @@ class Main { * Prompts the user to setup a hardware config for a Platform-based AVD. * @throws IOException */ - private Map promptForHardware(IAndroidTarget createTarget) throws IOException { + private Map promptForHardware(IAndroidTarget createTarget, + Map skinHardwareConfig) throws IOException { byte[] readLineBuffer = new byte[256]; String result; String defaultAnswer = "no"; @@ -821,8 +834,8 @@ class Main { } if (getBooleanReply(result) == false) { - // no custom config. - return null; + // no custom config, return the skin hardware config in case there is one. + return skinHardwareConfig; } mSdkLog.printf("\n"); // empty line @@ -846,8 +859,12 @@ class Main { } String defaultValue = property.getDefault(); + String defaultFromSkin = skinHardwareConfig != null ? skinHardwareConfig.get( + property.getName()) : null; - if (defaultValue != null) { + if (defaultFromSkin != null) { + mSdkLog.printf("%s [%s (from skin)]:", property.getName(), defaultFromSkin); + } else if (defaultValue != null) { mSdkLog.printf("%s [%s]:", property.getName(), defaultValue); } else { mSdkLog.printf("%s (%s):", property.getName(), property.getType()); @@ -855,7 +872,12 @@ class Main { result = readLine(readLineBuffer); if (result.length() == 0) { - if (defaultValue != null) { + if (defaultFromSkin != null || defaultValue != null) { + if (defaultFromSkin != null) { + // we need to write this one in the AVD file + map.put(property.getName(), defaultFromSkin); + } + mSdkLog.printf("\n"); // empty line i++; // go to the next property if we have a valid default value. // if there's no default, we'll redo this property diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java index 85160a3e2..8c87d4473 100644 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java @@ -535,7 +535,7 @@ public final class SdkManager { String defaultSkin = propertyMap.get(ADDON_DEFAULT_SKIN); if (defaultSkin == null) { if (skins.length == 1) { - defaultSkin = skins[1]; + defaultSkin = skins[0]; } else { defaultSkin = baseTarget.getDefaultSkin(); } diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java index 5179a0d94..a92ac0d76 100644 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java @@ -134,6 +134,8 @@ public final class AvdManager { /** List of valid characters for an AVD name. Used for display purposes. */ public final static String CHARS_AVD_NAME = "a-z A-Z 0-9 . _ -"; + public final static String HARDWARE_INI = "hardware.ini"; + /** An immutable structure describing an Android Virtual Device. */ public static final class AvdInfo { @@ -587,7 +589,46 @@ public final class AvdManager { } } + // add the hardware config to the config file. + // priority order is: + // - values provided by the user + // - values provided by the skin + // - values provided by the target (add-on only). + // In order to follow this priority, we'll add the lowest priority values first and then + // override by higher priority values. + // In the case of a platform with override values from the user, the skin value might + // already be there, but it's ok. + + HashMap finalHardwareValues = new HashMap(); + + File targetHardwareFile = new File(target.getLocation(), AvdManager.HARDWARE_INI); + if (targetHardwareFile.isFile()) { + Map targetHardwareConfig = SdkManager.parsePropertyFile( + targetHardwareFile, mSdkLog); + if (targetHardwareConfig != null) { + finalHardwareValues.putAll(targetHardwareConfig); + values.putAll(targetHardwareConfig); + } + } + + // get the hardware properties for this skin + File skinFile = getSkinPath(skinName, target); + if (skinFile.isDirectory()) { // this should not fail since we got the skin + // name from the target + File skinHardwareFile = new File(skinFile, AvdManager.HARDWARE_INI); + if (skinHardwareFile.isFile()) { + Map skinHardwareConfig = SdkManager.parsePropertyFile( + skinHardwareFile, mSdkLog); + if (skinHardwareConfig != null) { + finalHardwareValues.putAll(skinHardwareConfig); + values.putAll(skinHardwareConfig); + } + } + } + + // finally put the hardware provided by the user. if (hardwareConfig != null) { + finalHardwareValues.putAll(hardwareConfig); values.putAll(hardwareConfig); } @@ -596,10 +637,20 @@ public final class AvdManager { if (mSdkLog != null) { if (target.isPlatform()) { - mSdkLog.printf("Created AVD '%1$s' based on %2$s\n", name, target.getName()); + mSdkLog.printf("Created AVD '%1$s' based on %2$s", name, target.getName()); } else { - mSdkLog.printf("Created AVD '%1$s' based on %2$s (%3$s)\n", name, target.getName(), - target.getVendor()); + mSdkLog.printf("Created AVD '%1$s' based on %2$s (%3$s)", name, + target.getName(), target.getVendor()); + } + + // display the chosen hardware config + if (finalHardwareValues.size() > 0) { + mSdkLog.printf(", with the following hardware config:\n"); + for (Entry entry : finalHardwareValues.entrySet()) { + mSdkLog.printf("%s=%s\n",entry.getKey(), entry.getValue()); + } + } else { + mSdkLog.printf("\n"); } } @@ -694,18 +745,9 @@ public final class AvdManager { /** * Returns the path to the skin, as a relative path to the SDK. */ - private String getSkinRelativePath(String skinName, IAndroidTarget target) { + public String getSkinRelativePath(String skinName, IAndroidTarget target) { // first look to see if the skin is in the target - - String path = target.getPath(IAndroidTarget.SKINS); - File skin = new File(path, skinName); - - if (skin.exists() == false && target.isPlatform() == false) { - target = target.getParent(); - - path = target.getPath(IAndroidTarget.SKINS); - skin = new File(path, skinName); - } + File skin = getSkinPath(skinName, target); // skin really does not exist! if (skin.exists() == false) { @@ -714,7 +756,7 @@ public final class AvdManager { } // get the skin path - path = skin.getAbsolutePath(); + String path = skin.getAbsolutePath(); // make this path relative to the SDK location String sdkLocation = mSdk.getLocation(); @@ -732,6 +774,24 @@ public final class AvdManager { return path; } + /** + * Returns the full absolute OS path to a skin specified by name for a given target. + * @return a {@link File} that may or may not actually exist. + */ + public File getSkinPath(String skinName, IAndroidTarget target) { + String path = target.getPath(IAndroidTarget.SKINS); + File skin = new File(path, skinName); + + if (skin.exists() == false && target.isPlatform() == false) { + target = target.getParent(); + + path = target.getPath(IAndroidTarget.SKINS); + skin = new File(path, skinName); + } + + return skin; + } + /** * Creates the ini file for an AVD. * @@ -1168,10 +1228,12 @@ public final class AvdManager { try { t1.join(); } catch (InterruptedException e) { + // nothing to do here } try { t2.join(); } catch (InterruptedException e) { + // nothing to do here } }