All actions in AdvManager now receives their own ISdkLog.

Also added 'update' action to AvdSelector.
This commit is contained in:
Xavier Ducrohet
2009-07-01 03:07:01 -07:00
parent 1ceaaeae68
commit 59fc8c9d06
6 changed files with 204 additions and 115 deletions

View File

@@ -658,7 +658,8 @@ class Main {
skin, skin,
mSdkCommandLine.getParamSdCard(), mSdkCommandLine.getParamSdCard(),
hardwareConfig, hardwareConfig,
removePrevious); removePrevious,
mSdkLog);
} catch (AndroidLocationException e) { } catch (AndroidLocationException e) {
errorAndExit(e.getMessage()); errorAndExit(e.getMessage());
@@ -788,7 +789,7 @@ class Main {
try { try {
String avdName = mSdkCommandLine.getParamName(); String avdName = mSdkCommandLine.getParamName();
AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog); AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
avdManager.updateAvd(avdName); avdManager.updateAvd(avdName, mSdkLog);
} catch (AndroidLocationException e) { } catch (AndroidLocationException e) {
errorAndExit(e.getMessage()); errorAndExit(e.getMessage());
} catch (IOException e) { } catch (IOException e) {

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.sdklib;
/**
* Dummy implementation of an {@link ISdkLog}.
* <p/>
* Use {@link #getLogger()} to get a default instance of this {@link NullSdkLog}.
*
*/
public class NullSdkLog implements ISdkLog {
private static final ISdkLog sThis = new NullSdkLog();
public static ISdkLog getLogger() {
return sThis;
}
public void error(Throwable t, String errorFormat, Object... args) {
// ignore
}
public void printf(String msgFormat, Object... args) {
// ignore
}
public void warning(String warningFormat, Object... args) {
// ignore
}
}

View File

@@ -314,19 +314,14 @@ public final class AvdManager {
private final SdkManager mSdkManager; private final SdkManager mSdkManager;
/** /**
* TODO remove this field. Each caller should give its own logger to the methods * Creates an AVD Manager for a given SDK represented by a {@link SdkManager}.
* here instead of relying on a global logger. Otherwise that means that each * @param sdkManager The SDK.
* caller needs to re-instantiate this just to change the logger, which is plain * @param log The log object to receive the log of the initial loading of the AVDs.
* ugly. * @throws AndroidLocationException
*
* We'll revisit this in the final AVD Manager UI for donut.
*/ */
private ISdkLog mSdkLog; public AvdManager(SdkManager sdkManager, ISdkLog log) throws AndroidLocationException {
public AvdManager(SdkManager sdkManager, ISdkLog sdkLog) throws AndroidLocationException {
mSdkManager = sdkManager; mSdkManager = sdkManager;
mSdkLog = sdkLog; buildAvdList(mAllAvdList, log);
buildAvdList(mAllAvdList);
} }
/** /**
@@ -336,20 +331,6 @@ public final class AvdManager {
return mSdkManager; return mSdkManager;
} }
/**
* Changes the current {@link ISdkLog}.
*
* This method should not exist. See comments for {@link #mSdkLog}.
*
* @return The {@link ISdkLog} that was currently being used.
* @see #mSdkLog
*/
public ISdkLog setSdkLog(ISdkLog sdkLog) {
ISdkLog oldLogger = mSdkLog;
mSdkLog = sdkLog;
return oldLogger;
}
/** /**
* Returns all the existing AVDs. * Returns all the existing AVDs.
* @return a newly allocated array containing all the AVDs. * @return a newly allocated array containing all the AVDs.
@@ -430,11 +411,11 @@ public final class AvdManager {
* @throws AndroidLocationException if there was an error finding the location of the * @throws AndroidLocationException if there was an error finding the location of the
* AVD folder. * AVD folder.
*/ */
public void reloadAvds() throws AndroidLocationException { public void reloadAvds(ISdkLog log) throws AndroidLocationException {
// build the list in a temp list first, in case the method throws an exception. // build the list in a temp list first, in case the method throws an exception.
// It's better than deleting the whole list before reading the new one. // It's better than deleting the whole list before reading the new one.
ArrayList<AvdInfo> allList = new ArrayList<AvdInfo>(); ArrayList<AvdInfo> allList = new ArrayList<AvdInfo>();
buildAvdList(allList); buildAvdList(allList, log);
synchronized (mAllAvdList) { synchronized (mAllAvdList) {
mAllAvdList.clear(); mAllAvdList.clear();
@@ -454,12 +435,16 @@ public final class AvdManager {
* an existing sdcard image or a sdcard size (\d+, \d+K, \dM). * an existing sdcard image or a sdcard size (\d+, \d+K, \dM).
* @param hardwareConfig the hardware setup for the AVD. Can be null to use defaults. * @param hardwareConfig the hardware setup for the AVD. Can be null to use defaults.
* @param removePrevious If true remove any previous files. * @param removePrevious If true remove any previous files.
* @param log the log object to receive action logs. Cannot be null.
* @return The new {@link AvdInfo} in case of success (which has just been added to the * @return The new {@link AvdInfo} in case of success (which has just been added to the
* internal list) or null in case of failure. * internal list) or null in case of failure.
*/ */
public AvdInfo createAvd(File avdFolder, String name, IAndroidTarget target, public AvdInfo createAvd(File avdFolder, String name, IAndroidTarget target,
String skinName, String sdcard, Map<String,String> hardwareConfig, String skinName, String sdcard, Map<String,String> hardwareConfig,
boolean removePrevious) { boolean removePrevious, ISdkLog log) {
if (log == null) {
throw new IllegalArgumentException("log cannot be null");
}
File iniFile = null; File iniFile = null;
boolean needCleanup = false; boolean needCleanup = false;
@@ -471,11 +456,9 @@ public final class AvdManager {
recursiveDelete(avdFolder); recursiveDelete(avdFolder);
} else { } else {
// AVD shouldn't already exist if removePrevious is false. // AVD shouldn't already exist if removePrevious is false.
if (mSdkLog != null) { log.error(null,
mSdkLog.error(null, "Folder %1$s is in the way. Use --force if you want to overwrite.",
"Folder %1$s is in the way. Use --force if you want to overwrite.", avdFolder.getAbsolutePath());
avdFolder.getAbsolutePath());
}
return null; return null;
} }
} else { } else {
@@ -496,7 +479,7 @@ public final class AvdManager {
} }
if (userdataSrc.exists() == false) { if (userdataSrc.exists() == false) {
mSdkLog.error(null, "Unable to find a '%1$s' file to copy into the AVD folder.", log.error(null, "Unable to find a '%1$s' file to copy into the AVD folder.",
USERDATA_IMG); USERDATA_IMG);
needCleanup = true; needCleanup = true;
return null; return null;
@@ -519,7 +502,7 @@ public final class AvdManager {
// Config file. // Config file.
HashMap<String, String> values = new HashMap<String, String>(); HashMap<String, String> values = new HashMap<String, String>();
if (setImagePathProperties(target, values) == false) { if (setImagePathProperties(target, values, log) == false) {
needCleanup = true; needCleanup = true;
return null; return null;
} }
@@ -538,7 +521,7 @@ public final class AvdManager {
} else { } else {
// get the path of the skin (relative to the SDK) // get the path of the skin (relative to the SDK)
// assume skin name is valid // assume skin name is valid
String skinPath = getSkinRelativePath(skinName, target); String skinPath = getSkinRelativePath(skinName, target, log);
if (skinPath == null) { if (skinPath == null) {
needCleanup = true; needCleanup = true;
return null; return null;
@@ -565,17 +548,18 @@ public final class AvdManager {
String path = sdcardFile.getAbsolutePath(); String path = sdcardFile.getAbsolutePath();
// execute mksdcard with the proper parameters. // execute mksdcard with the proper parameters.
File toolsFolder = new File(mSdkManager.getLocation(), SdkConstants.FD_TOOLS); File toolsFolder = new File(mSdkManager.getLocation(),
SdkConstants.FD_TOOLS);
File mkSdCard = new File(toolsFolder, SdkConstants.mkSdCardCmdName()); File mkSdCard = new File(toolsFolder, SdkConstants.mkSdCardCmdName());
if (mkSdCard.isFile() == false) { if (mkSdCard.isFile() == false) {
mSdkLog.error(null, "'%1$s' is missing from the SDK tools folder.", log.error(null, "'%1$s' is missing from the SDK tools folder.",
mkSdCard.getName()); mkSdCard.getName());
needCleanup = true; needCleanup = true;
return null; return null;
} }
if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path) == false) { if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path, log) == false) {
needCleanup = true; needCleanup = true;
return null; // mksdcard output has already been displayed, no need to return null; // mksdcard output has already been displayed, no need to
// output anything else. // output anything else.
@@ -585,7 +569,7 @@ public final class AvdManager {
// only when the dev does 'android list avd' // only when the dev does 'android list avd'
values.put(AVD_INI_SDCARD_SIZE, sdcard); values.put(AVD_INI_SDCARD_SIZE, sdcard);
} else { } else {
mSdkLog.error(null, log.error(null,
"'%1$s' is not recognized as a valid sdcard value.\n" + "'%1$s' is not recognized as a valid sdcard value.\n" +
"Value should be:\n" + "Value should be:\n" +
"1. path to an sdcard.\n" + "1. path to an sdcard.\n" +
@@ -612,7 +596,7 @@ public final class AvdManager {
File targetHardwareFile = new File(target.getLocation(), AvdManager.HARDWARE_INI); File targetHardwareFile = new File(target.getLocation(), AvdManager.HARDWARE_INI);
if (targetHardwareFile.isFile()) { if (targetHardwareFile.isFile()) {
Map<String, String> targetHardwareConfig = SdkManager.parsePropertyFile( Map<String, String> targetHardwareConfig = SdkManager.parsePropertyFile(
targetHardwareFile, mSdkLog); targetHardwareFile, log);
if (targetHardwareConfig != null) { if (targetHardwareConfig != null) {
finalHardwareValues.putAll(targetHardwareConfig); finalHardwareValues.putAll(targetHardwareConfig);
values.putAll(targetHardwareConfig); values.putAll(targetHardwareConfig);
@@ -624,7 +608,7 @@ public final class AvdManager {
File skinHardwareFile = new File(skinFolder, AvdManager.HARDWARE_INI); File skinHardwareFile = new File(skinFolder, AvdManager.HARDWARE_INI);
if (skinHardwareFile.isFile()) { if (skinHardwareFile.isFile()) {
Map<String, String> skinHardwareConfig = SdkManager.parsePropertyFile( Map<String, String> skinHardwareConfig = SdkManager.parsePropertyFile(
skinHardwareFile, mSdkLog); skinHardwareFile, log);
if (skinHardwareConfig != null) { if (skinHardwareConfig != null) {
finalHardwareValues.putAll(skinHardwareConfig); finalHardwareValues.putAll(skinHardwareConfig);
values.putAll(skinHardwareConfig); values.putAll(skinHardwareConfig);
@@ -640,23 +624,21 @@ public final class AvdManager {
File configIniFile = new File(avdFolder, CONFIG_INI); File configIniFile = new File(avdFolder, CONFIG_INI);
writeIniFile(configIniFile, values); writeIniFile(configIniFile, values);
if (mSdkLog != null) { if (target.isPlatform()) {
if (target.isPlatform()) { log.printf("Created AVD '%1$s' based on %2$s", name, target.getName());
mSdkLog.printf("Created AVD '%1$s' based on %2$s", name, target.getName()); } else {
} else { log.printf("Created AVD '%1$s' based on %2$s (%3$s)", name,
mSdkLog.printf("Created AVD '%1$s' based on %2$s (%3$s)", name, target.getName(), target.getVendor());
target.getName(), target.getVendor()); }
}
// display the chosen hardware config // display the chosen hardware config
if (finalHardwareValues.size() > 0) { if (finalHardwareValues.size() > 0) {
mSdkLog.printf(", with the following hardware config:\n"); log.printf(", with the following hardware config:\n");
for (Entry<String, String> entry : finalHardwareValues.entrySet()) { for (Entry<String, String> entry : finalHardwareValues.entrySet()) {
mSdkLog.printf("%s=%s\n",entry.getKey(), entry.getValue()); log.printf("%s=%s\n",entry.getKey(), entry.getValue());
}
} else {
mSdkLog.printf("\n");
} }
} else {
log.printf("\n");
} }
// create the AvdInfo object, and add it to the list // create the AvdInfo object, and add it to the list
@@ -679,7 +661,7 @@ public final class AvdManager {
newAvdInfo != null && newAvdInfo != null &&
oldAvdInfo != null && oldAvdInfo != null &&
!oldAvdInfo.getPath().equals(newAvdInfo.getPath())) { !oldAvdInfo.getPath().equals(newAvdInfo.getPath())) {
mSdkLog.warning("Removing previous AVD directory at %s", oldAvdInfo.getPath()); log.warning("Removing previous AVD directory at %s", oldAvdInfo.getPath());
// Remove the old data directory // Remove the old data directory
File dir = new File(oldAvdInfo.getPath()); File dir = new File(oldAvdInfo.getPath());
recursiveDelete(dir); recursiveDelete(dir);
@@ -688,13 +670,9 @@ public final class AvdManager {
return newAvdInfo; return newAvdInfo;
} catch (AndroidLocationException e) { } catch (AndroidLocationException e) {
if (mSdkLog != null) { log.error(e, null);
mSdkLog.error(e, null);
}
} catch (IOException e) { } catch (IOException e) {
if (mSdkLog != null) { log.error(e, null);
mSdkLog.error(e, null);
}
} finally { } finally {
if (needCleanup) { if (needCleanup) {
if (iniFile != null && iniFile.exists()) { if (iniFile != null && iniFile.exists()) {
@@ -750,13 +728,17 @@ public final class AvdManager {
/** /**
* Returns the path to the skin, as a relative path to the SDK. * Returns the path to the skin, as a relative path to the SDK.
*/ */
public String getSkinRelativePath(String skinName, IAndroidTarget target) { public String getSkinRelativePath(String skinName, IAndroidTarget target, ISdkLog log) {
if (log == null) {
throw new IllegalArgumentException("log cannot be null");
}
// first look to see if the skin is in the target // first look to see if the skin is in the target
File skin = getSkinPath(skinName, target); File skin = getSkinPath(skinName, target);
// skin really does not exist! // skin really does not exist!
if (skin.exists() == false) { if (skin.exists() == false) {
mSdkLog.error(null, "Skin '%1$s' does not exist.", skinName); log.error(null, "Skin '%1$s' does not exist.", skinName);
return null; return null;
} }
@@ -767,7 +749,7 @@ public final class AvdManager {
String sdkLocation = mSdkManager.getLocation(); String sdkLocation = mSdkManager.getLocation();
if (path.startsWith(sdkLocation) == false) { if (path.startsWith(sdkLocation) == false) {
// this really really should not happen. // this really really should not happen.
mSdkLog.error(null, "Target location is not inside the SDK."); log.error(null, "Target location is not inside the SDK.");
assert false; assert false;
return null; return null;
} }
@@ -840,6 +822,7 @@ public final class AvdManager {
* these operations fail. * these operations fail.
* *
* @param avdInfo the information on the AVD to delete * @param avdInfo the information on the AVD to delete
* @param log the log object to receive action logs.
* @return True if the AVD was deleted with no error. * @return True if the AVD was deleted with no error.
*/ */
public boolean deleteAvd(AvdInfo avdInfo, ISdkLog log) { public boolean deleteAvd(AvdInfo avdInfo, ISdkLog log) {
@@ -896,6 +879,7 @@ public final class AvdManager {
* @param avdInfo the information on the AVD to move. * @param avdInfo the information on the AVD to move.
* @param newName the new name of the AVD if non null. * @param newName the new name of the AVD if non null.
* @param paramFolderPath the new data folder if non null. * @param paramFolderPath the new data folder if non null.
* @param log the log object to receive action logs.
* @return True if the move succeeded or there was nothing to do. * @return True if the move succeeded or there was nothing to do.
* If false, this method will have had already output error in the log. * If false, this method will have had already output error in the log.
*/ */
@@ -1008,11 +992,12 @@ public final class AvdManager {
* *
* @throws AndroidLocationException if there's a problem getting android root directory. * @throws AndroidLocationException if there's a problem getting android root directory.
*/ */
private void buildAvdList(ArrayList<AvdInfo> allList) throws AndroidLocationException { private void buildAvdList(ArrayList<AvdInfo> allList, ISdkLog log)
throws AndroidLocationException {
File[] avds = buildAvdFilesList(); File[] avds = buildAvdFilesList();
if (avds != null) { if (avds != null) {
for (File avd : avds) { for (File avd : avds) {
AvdInfo info = parseAvdInfo(avd); AvdInfo info = parseAvdInfo(avd, log);
if (info != null) { if (info != null) {
allList.add(info); allList.add(info);
} }
@@ -1027,8 +1012,8 @@ public final class AvdManager {
* @return A new {@link AvdInfo} with an {@link AvdStatus} indicating whether this AVD is * @return A new {@link AvdInfo} with an {@link AvdStatus} indicating whether this AVD is
* valid or not. * valid or not.
*/ */
private AvdInfo parseAvdInfo(File path) { private AvdInfo parseAvdInfo(File path, ISdkLog log) {
Map<String, String> map = SdkManager.parsePropertyFile(path, mSdkLog); Map<String, String> map = SdkManager.parsePropertyFile(path, log);
String avdPath = map.get(AVD_INFO_PATH); String avdPath = map.get(AVD_INFO_PATH);
String targetHash = map.get(AVD_INFO_TARGET); String targetHash = map.get(AVD_INFO_TARGET);
@@ -1047,7 +1032,7 @@ public final class AvdManager {
} }
if (configIniFile != null) { if (configIniFile != null) {
properties = SdkManager.parsePropertyFile(configIniFile, mSdkLog); properties = SdkManager.parsePropertyFile(configIniFile, log);
} }
// get name // get name
@@ -1132,7 +1117,7 @@ public final class AvdManager {
* @param location The path of the new sdcard image file to generate. * @param location The path of the new sdcard image file to generate.
* @return True if the sdcard could be created. * @return True if the sdcard could be created.
*/ */
private boolean createSdCard(String toolLocation, String size, String location) { private boolean createSdCard(String toolLocation, String size, String location, ISdkLog log) {
try { try {
String[] command = new String[3]; String[] command = new String[3];
command[0] = toolLocation; command[0] = toolLocation;
@@ -1149,7 +1134,7 @@ public final class AvdManager {
return true; return true;
} else { } else {
for (String error : errorOutput) { for (String error : errorOutput) {
mSdkLog.error(null, error); log.error(null, error);
} }
} }
@@ -1159,7 +1144,7 @@ public final class AvdManager {
// pass, print error below // pass, print error below
} }
mSdkLog.error(null, "Failed to create the SD card."); log.error(null, "Failed to create the SD card.");
return false; return false;
} }
@@ -1266,10 +1251,10 @@ public final class AvdManager {
/** /**
* Updates an AVD with new path to the system image folders. * Updates an AVD with new path to the system image folders.
* @param name the name of the AVD to update. * @param name the name of the AVD to update.
* @param log the log object to receive action logs.
* @throws IOException * @throws IOException
* @throws AndroidLocationException
*/ */
public void updateAvd(String name) throws IOException, AndroidLocationException { public void updateAvd(String name, ISdkLog log) throws IOException {
// find the AVD to update. It should be be in the broken list. // find the AVD to update. It should be be in the broken list.
AvdInfo avd = null; AvdInfo avd = null;
synchronized (mAllAvdList) { synchronized (mAllAvdList) {
@@ -1283,10 +1268,21 @@ public final class AvdManager {
if (avd == null) { if (avd == null) {
// not in the broken list, just return. // not in the broken list, just return.
mSdkLog.error(null, "There is no Android Virtual Device named '%s'.", name); log.error(null, "There is no Android Virtual Device named '%s'.", name);
return; return;
} }
updateAvd(avd, log);
}
/**
* Updates an AVD with new path to the system image folders.
* @param avdInfo the AVD to update.
* @param log the log object to receive action logs.
* @throws IOException
*/
public void updateAvd(AvdInfo avd, ISdkLog log) throws IOException {
// get the properties. This is a unmodifiable Map. // get the properties. This is a unmodifiable Map.
Map<String, String> oldProperties = avd.getProperties(); Map<String, String> oldProperties = avd.getProperties();
@@ -1299,20 +1295,21 @@ public final class AvdManager {
AvdStatus status; AvdStatus status;
// create the path to the new system images. // create the path to the new system images.
if (setImagePathProperties(avd.getTarget(), properties)) { if (setImagePathProperties(avd.getTarget(), properties, log)) {
if (properties.containsKey(AVD_INI_IMAGES_1)) { if (properties.containsKey(AVD_INI_IMAGES_1)) {
mSdkLog.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_1, log.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_1,
properties.get(AVD_INI_IMAGES_1)); properties.get(AVD_INI_IMAGES_1));
} }
if (properties.containsKey(AVD_INI_IMAGES_2)) { if (properties.containsKey(AVD_INI_IMAGES_2)) {
mSdkLog.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_2, log.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_2,
properties.get(AVD_INI_IMAGES_2)); properties.get(AVD_INI_IMAGES_2));
} }
status = AvdStatus.OK; status = AvdStatus.OK;
} else { } else {
mSdkLog.error(null, "Unable to find non empty system images folders for %1$s", name); log.error(null, "Unable to find non empty system images folders for %1$s",
avd.getName());
//FIXME: display paths to empty image folders? //FIXME: display paths to empty image folders?
status = AvdStatus.ERROR_IMAGE_DIR; status = AvdStatus.ERROR_IMAGE_DIR;
} }
@@ -1326,7 +1323,7 @@ public final class AvdManager {
// errors // errors
// FIXME: We may want to create this AvdInfo by reparsing the AVD instead. This could detect other errors. // FIXME: We may want to create this AvdInfo by reparsing the AVD instead. This could detect other errors.
AvdInfo newAvd = new AvdInfo( AvdInfo newAvd = new AvdInfo(
name, avd.getName(),
avd.getPath(), avd.getPath(),
avd.getTargetHash(), avd.getTargetHash(),
avd.getTarget(), avd.getTarget(),
@@ -1342,7 +1339,8 @@ public final class AvdManager {
* @param properties the properties in which to set the paths. * @param properties the properties in which to set the paths.
* @return true if success, false if some path are missing. * @return true if success, false if some path are missing.
*/ */
private boolean setImagePathProperties(IAndroidTarget target, Map<String, String> properties) { private boolean setImagePathProperties(IAndroidTarget target, Map<String, String> properties,
ISdkLog log) {
properties.remove(AVD_INI_IMAGES_1); properties.remove(AVD_INI_IMAGES_1);
properties.remove(AVD_INI_IMAGES_2); properties.remove(AVD_INI_IMAGES_2);
@@ -1369,7 +1367,7 @@ public final class AvdManager {
// we need at least one path! // we need at least one path!
return properties.containsKey(AVD_INI_IMAGES_1); return properties.containsKey(AVD_INI_IMAGES_1);
} catch (InvalidTargetPathException e) { } catch (InvalidTargetPathException e) {
mSdkLog.error(e, e.getMessage()); log.error(e, e.getMessage());
} }
return false; return false;

View File

@@ -195,7 +195,7 @@ class UpdaterData {
// reload AVDs // reload AVDs
if (mAvdManager != null) { if (mAvdManager != null) {
try { try {
mAvdManager.reloadAvds(); mAvdManager.reloadAvds(mSdkLog);
} catch (AndroidLocationException e) { } catch (AndroidLocationException e) {
// FIXME // FIXME
} }
@@ -217,7 +217,7 @@ class UpdaterData {
// reload AVDs // reload AVDs
if (mAvdManager != null) { if (mAvdManager != null) {
try { try {
mAvdManager.reloadAvds(); mAvdManager.reloadAvds(mSdkLog);
} catch (AndroidLocationException e) { } catch (AndroidLocationException e) {
mSdkLog.error(e, null); mSdkLog.error(e, null);
} }

View File

@@ -441,28 +441,18 @@ final class AvdCreationDialog extends Dialog {
return false; return false;
} }
ISdkLog oldLog = null;
boolean success = false; boolean success = false;
try { AvdInfo avdInfo = mAvdManager.createAvd(
// Temporarily change the AvdManager's logger for ours, since the API no longer avdFolder,
// takes a logger argument. avdName,
// TODO revisit this later. See comments in AvdManager#mSdkLog. target,
oldLog = mAvdManager.setSdkLog(log); skinName,
sdName,
null, // hardwareConfig,
force,
log);
AvdInfo avdInfo = mAvdManager.createAvd( success = avdInfo != null;
avdFolder,
avdName,
target,
skinName,
sdName,
null, // hardwareConfig,
force);
success = avdInfo != null;
} finally {
mAvdManager.setSdkLog(oldLog);
}
log.displayResult(success); log.displayResult(success);

View File

@@ -19,6 +19,7 @@ package com.android.sdkuilib.internal.widgets;
import com.android.prefs.AndroidLocation.AndroidLocationException; import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.IAndroidTarget; import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.ISdkLog; import com.android.sdklib.ISdkLog;
import com.android.sdklib.NullSdkLog;
import com.android.sdklib.internal.avd.AvdManager; import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.internal.avd.AvdManager.AvdInfo; import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
import com.android.sdklib.internal.avd.AvdManager.AvdInfo.AvdStatus; import com.android.sdklib.internal.avd.AvdManager.AvdInfo.AvdStatus;
@@ -48,6 +49,7 @@ import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.TableItem;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -71,6 +73,7 @@ public final class AvdSelector {
private Button mNewButton; private Button mNewButton;
private Button mRefreshButton; private Button mRefreshButton;
private Button mManagerButton; private Button mManagerButton;
private Button mUpdateButton;
private SelectionListener mSelectionListener; private SelectionListener mSelectionListener;
private IAvdFilter mTargetFilter; private IAvdFilter mTargetFilter;
@@ -227,7 +230,7 @@ public final class AvdSelector {
mDeleteButton = new Button(buttons, SWT.PUSH | SWT.FLAT); mDeleteButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
mDeleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); mDeleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mDeleteButton.setText("Delete"); mDeleteButton.setText("Delete...");
mDeleteButton.setToolTipText("Deletes the selected AVD."); mDeleteButton.setToolTipText("Deletes the selected AVD.");
mDeleteButton.addSelectionListener(new SelectionAdapter() { mDeleteButton.addSelectionListener(new SelectionAdapter() {
@Override @Override
@@ -236,6 +239,17 @@ public final class AvdSelector {
} }
}); });
mUpdateButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
mUpdateButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mUpdateButton.setText("Update...");
mUpdateButton.setToolTipText("Updates the path of the selected AVD.");
mUpdateButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent arg0) {
onUpdate();
}
});
Label l = new Label(buttons, SWT.SEPARATOR | SWT.HORIZONTAL); Label l = new Label(buttons, SWT.SEPARATOR | SWT.HORIZONTAL);
l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
} }
@@ -366,7 +380,7 @@ public final class AvdSelector {
public boolean refresh(boolean reload) { public boolean refresh(boolean reload) {
if (reload) { if (reload) {
try { try {
mAvdManager.reloadAvds(); mAvdManager.reloadAvds(NullSdkLog.getLogger());
} catch (AndroidLocationException e) { } catch (AndroidLocationException e) {
return false; return false;
} }
@@ -720,12 +734,29 @@ public final class AvdSelector {
return null; return null;
} }
/**
* Updates the enable state of the Details, Delete and Update buttons.
*/
private void enableActionButtons() { private void enableActionButtons() {
boolean enabled = mIsEnabled == false ? false : getTableSelection() != null; if (mIsEnabled == false) {
mDetailsButton.setEnabled(false);
if (mDeleteButton != null) {
mDeleteButton.setEnabled(false);
}
if (mUpdateButton != null) {
mUpdateButton.setEnabled(false);
}
} else {
AvdInfo selection = getTableSelection();
mDetailsButton.setEnabled(enabled); mDetailsButton.setEnabled(selection != null);
if (mDeleteButton != null) { if (mDeleteButton != null) {
mDeleteButton.setEnabled(enabled); mDeleteButton.setEnabled(selection != null);
}
if (mUpdateButton != null) {
mUpdateButton.setEnabled(selection != null &&
selection.getStatus() == AvdStatus.ERROR_IMAGE_DIR);
}
} }
} }
@@ -783,6 +814,31 @@ public final class AvdSelector {
} }
} }
private void onUpdate() {
final AvdInfo avdInfo = getTableSelection();
// get the current Display
final Display display = mTable.getDisplay();
// log for this action.
SdkLog log = new SdkLog(
String.format("Result of updating AVD '%s':", avdInfo.getName()),
display);
// delete the AVD
try {
mAvdManager.updateAvd(avdInfo, log);
// display the result
log.displayResult(true /* success */);
refresh(false /*reload*/);
} catch (IOException e) {
log.error(e, null);
log.displayResult(false /* success */);
}
}
private void onManager() { private void onManager() {
UpdaterWindow window = new UpdaterWindow( UpdaterWindow window = new UpdaterWindow(
mTable.getShell(), mTable.getShell(),