/** Updates a broken AVD. */ private void updateAvd() { try { String avdName = mSdkCommandLine.getParamName(); AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog); avdManager.updateAvd(avdName, mSdkLog); } catch (AndroidLocationException e) { errorAndExit(e.getMessage()); } catch (IOException e) { errorAndExit(e.getMessage()); } }
/** * Delete an AVD. If the AVD name is not part of the available ones look for an invalid AVD (one * not loaded due to some error) to remove it too. */ private void deleteAvd() { try { String avdName = mSdkCommandLine.getParamName(); AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog); AvdInfo info = avdManager.getAvd(avdName, false /*validAvdOnly*/); if (info == null) { errorAndExit("There is no Android Virtual Device named '%s'.", avdName); return; } avdManager.deleteAvd(info, mSdkLog); } catch (AndroidLocationException e) { errorAndExit(e.getMessage()); } }
/** * Reloads the AVDs. * * <p>This does not notify the listeners. */ public void reloadAvds() { // reload AVDs if (mAvdManager != null) { try { mAvdManager.reloadAvds(mSdkLog); } catch (AndroidLocationException e) { mSdkLog.error(e, null); } } }
/** * Reloads the SDK content (targets). * * <p>This also reloads the AVDs in case their status changed. * * <p>This does not notify the listeners ({@link ISdkChangeListener}). */ public void reloadSdk() { // reload SDK mSdkManager.reloadSdk(mSdkLog); // reload AVDs if (mAvdManager != null) { try { mAvdManager.reloadAvds(mSdkLog); } catch (AndroidLocationException e) { // FIXME } } mLocalSdkParser.clearPackages(); // notify listeners broadcastOnSdkReload(); }
/** * Initializes the {@link SdkManager} and the {@link AvdManager}. Extracted so that we can * override this in unit tests. */ @VisibleForTesting(visibility = Visibility.PRIVATE) protected void initSdk() { setSdkManager(SdkManager.createManager(mOsSdkRoot, mSdkLog)); try { mAvdManager = null; mAvdManager = AvdManager.getInstance(mSdkManager, mSdkLog); } catch (AndroidLocationException e) { mSdkLog.error(e, "Unable to read AVDs: " + e.getMessage()); // $NON-NLS-1$ // Note: we used to continue here, but the thing is that // mAvdManager==null so nothing is really going to work as // expected. Let's just display an error later in checkIfInitFailed() // and abort right there. This step is just too early in the SWT // setup process to display a message box yet. mAvdManagerInitError = e; } // notify listeners. broadcastOnSdkReload(); }
/** Moves an AVD. */ private void moveAvd() { try { String avdName = mSdkCommandLine.getParamName(); AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog); AvdInfo info = avdManager.getAvd(avdName, true /*validAvdOnly*/); if (info == null) { errorAndExit("There is no valid Android Virtual Device named '%s'.", avdName); return; } // This is a rename if there's a new name for the AVD String newName = mSdkCommandLine.getParamMoveNewName(); if (newName != null && newName.equals(info.getName())) { // same name, not actually a rename operation newName = null; } // This is a move (of the data files) if there's a new location path String paramFolderPath = mSdkCommandLine.getParamLocationPath(); if (paramFolderPath != null) { // check if paths are the same. Use File methods to account for OS idiosyncrasies. try { File f1 = new File(paramFolderPath).getCanonicalFile(); File f2 = new File(info.getPath()).getCanonicalFile(); if (f1.equals(f2)) { // same canonical path, so not actually a move paramFolderPath = null; } } catch (IOException e) { // Fail to resolve canonical path. Fail now since a move operation might fail // later and be harder to recover from. errorAndExit(e.getMessage()); return; } } if (newName == null && paramFolderPath == null) { mSdkLog.warning("Move operation aborted: same AVD name, same canonical data path"); return; } // If a rename was requested and no data move was requested, check if the original // data path is our default constructed from the AVD name. In this case we still want // to rename that folder too. if (newName != null && paramFolderPath == null) { // Compute the original data path File originalFolder = new File( AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD, info.getName() + AvdManager.AVD_FOLDER_EXTENSION); if (originalFolder.equals(info.getPath())) { try { // The AVD is using the default data folder path based on the AVD name. // That folder needs to be adjusted to use the new name. File f = new File( AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD, newName + AvdManager.AVD_FOLDER_EXTENSION); paramFolderPath = f.getCanonicalPath(); } catch (IOException e) { // Fail to resolve canonical path. Fail now rather than later. errorAndExit(e.getMessage()); } } } // Check for conflicts if (newName != null) { if (avdManager.getAvd(newName, false /*validAvdOnly*/) != null) { errorAndExit("There is already an AVD named '%s'.", newName); return; } File ini = info.getIniFile(); if (ini.equals(AvdInfo.getIniFile(newName))) { errorAndExit("The AVD file '%s' is in the way.", ini.getCanonicalPath()); return; } } if (paramFolderPath != null && new File(paramFolderPath).exists()) { errorAndExit( "There is already a file or directory at '%s'.\nUse --path to specify a different data folder.", paramFolderPath); } avdManager.moveAvd(info, newName, paramFolderPath, mSdkLog); } catch (AndroidLocationException e) { errorAndExit(e.getMessage()); } catch (IOException e) { errorAndExit(e.getMessage()); } }
/** Creates a new AVD. This is a text based creation with command line prompt. */ private void createAvd() { // find a matching target int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId()); IAndroidTarget[] targets = mSdkManager.getTargets(); if (targetId == INVALID_TARGET_ID || targetId > targets.length) { errorAndExit( "Target id is not valid. Use '%s list targets' to get the target ids.", SdkConstants.androidCmdName()); } IAndroidTarget target = targets[targetId - 1]; // target id is 1-based try { boolean removePrevious = mSdkCommandLine.getFlagForce(); AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog); String avdName = mSdkCommandLine.getParamName(); if (!AvdManager.RE_AVD_NAME.matcher(avdName).matches()) { errorAndExit( "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s", avdName, AvdManager.CHARS_AVD_NAME); return; } AvdInfo info = avdManager.getAvd(avdName, false /*validAvdOnly*/); if (info != null) { if (removePrevious) { mSdkLog.warning( "Android Virtual Device '%s' already exists and will be replaced.", avdName); } else { errorAndExit( "Android Virtual Device '%s' already exists.\n" + "Use --force if you want to replace it.", avdName); return; } } String paramFolderPath = mSdkCommandLine.getParamLocationPath(); File avdFolder = null; if (paramFolderPath != null) { avdFolder = new File(paramFolderPath); } else { avdFolder = AvdManager.AvdInfo.getAvdFolder(avdName); } // Validate skin is either default (empty) or NNNxMMM or a valid skin name. Map<String, String> skinHardwareConfig = null; String skin = mSdkCommandLine.getParamSkin(); if (skin != null && skin.length() == 0) { skin = null; } if (skin != null && target != null) { boolean valid = false; // Is it a know skin name for this target? for (String s : target.getSkins()) { if (skin.equalsIgnoreCase(s)) { skin = s; // Make skin names case-insensitive. valid = true; // get the hardware properties for this skin File skinFolder = avdManager.getSkinPath(skin, target); FileWrapper skinHardwareFile = new FileWrapper(skinFolder, AvdManager.HARDWARE_INI); if (skinHardwareFile.isFile()) { skinHardwareConfig = ProjectProperties.parsePropertyFile(skinHardwareFile, mSdkLog); } break; } } // Is it NNNxMMM? if (!valid) { valid = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin).matches(); } if (!valid) { displaySkinList(target, "Valid skins: "); errorAndExit("'%s' is not a valid skin name or size (NNNxMMM)", skin); return; } } Map<String, String> hardwareConfig = null; if (target != null && target.isPlatform()) { try { hardwareConfig = promptForHardware(target, skinHardwareConfig); } catch (IOException e) { errorAndExit(e.getMessage()); } } @SuppressWarnings("unused") // oldAvdInfo is never read, yet useful for debugging AvdInfo oldAvdInfo = null; if (removePrevious) { oldAvdInfo = avdManager.getAvd(avdName, false /*validAvdOnly*/); } @SuppressWarnings("unused") // newAvdInfo is never read, yet useful for debugging AvdInfo newAvdInfo = avdManager.createAvd( avdFolder, avdName, target, skin, mSdkCommandLine.getParamSdCard(), hardwareConfig, removePrevious, mSdkCommandLine.getFlagSnapshot(), mSdkLog); } catch (AndroidLocationException e) { errorAndExit(e.getMessage()); } }
/** * Displays the list of available AVDs for the given AvdManager. * * @param avdManager */ public void displayAvdList(AvdManager avdManager) { mSdkLog.printf("Available Android Virtual Devices:\n"); AvdInfo[] avds = avdManager.getValidAvds(); for (int index = 0; index < avds.length; index++) { AvdInfo info = avds[index]; if (index > 0) { mSdkLog.printf("---------\n"); } mSdkLog.printf(" Name: %s\n", info.getName()); mSdkLog.printf(" Path: %s\n", info.getPath()); // get the target of the AVD IAndroidTarget target = info.getTarget(); if (target.isPlatform()) { mSdkLog.printf( " Target: %s (API level %s)\n", target.getName(), target.getVersion().getApiString()); } else { mSdkLog.printf(" Target: %s (%s)\n", target.getName(), target.getVendor()); mSdkLog.printf( " Based on Android %s (API level %s)\n", target.getVersionName(), target.getVersion().getApiString()); } // display some extra values. Map<String, String> properties = info.getProperties(); if (properties != null) { String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME); if (skin != null) { mSdkLog.printf(" Skin: %s\n", skin); } String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE); if (sdcard == null) { sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH); } if (sdcard != null) { mSdkLog.printf(" Sdcard: %s\n", sdcard); } String snapshot = properties.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT); if (snapshot != null) { mSdkLog.printf("Snapshot: %s\n", snapshot); } } } // Are there some unused AVDs? AvdInfo[] badAvds = avdManager.getBrokenAvds(); if (badAvds.length == 0) { return; } mSdkLog.printf("\nThe following Android Virtual Devices could not be loaded:\n"); boolean needSeparator = false; for (AvdInfo info : badAvds) { if (needSeparator) { mSdkLog.printf("---------\n"); } mSdkLog.printf(" Name: %s\n", info.getName() == null ? "--" : info.getName()); mSdkLog.printf(" Path: %s\n", info.getPath() == null ? "--" : info.getPath()); String error = info.getErrorMessage(); mSdkLog.printf(" Error: %s\n", error == null ? "Uknown error" : error); needSeparator = true; } }
static void show(final ConfigurationChooser chooser, ToolItem combo) { Configuration configuration = chooser.getConfiguration(); Device current = configuration.getDevice(); Menu menu = new Menu(chooser.getShell(), SWT.POP_UP); List<Device> deviceList = chooser.getDeviceList(); Sdk sdk = Sdk.getCurrent(); if (sdk != null) { AvdManager avdManager = sdk.getAvdManager(); if (avdManager != null) { boolean separatorNeeded = false; AvdInfo[] avds = avdManager.getValidAvds(); for (AvdInfo avd : avds) { for (Device device : deviceList) { if (device.getManufacturer().equals(avd.getDeviceManufacturer()) && device.getName().equals(avd.getDeviceName())) { separatorNeeded = true; MenuItem item = new MenuItem(menu, SWT.CHECK); item.setText(avd.getName()); item.setSelection(current == device); item.addSelectionListener(new DeviceMenuListener(chooser, device)); } } } if (separatorNeeded) { @SuppressWarnings("unused") MenuItem separator = new MenuItem(menu, SWT.SEPARATOR); } } } // Group the devices by manufacturer, then put them in the menu. // If we don't have anything but Nexus devices, group them together rather than // make many manufacturer submenus. boolean haveNexus = false; boolean haveNonNexus = false; if (!deviceList.isEmpty()) { Map<String, List<Device>> manufacturers = new TreeMap<String, List<Device>>(); for (Device device : deviceList) { List<Device> devices; if (isNexus(device)) { haveNexus = true; } else if (!isGeneric(device)) { haveNonNexus = true; } if (manufacturers.containsKey(device.getManufacturer())) { devices = manufacturers.get(device.getManufacturer()); } else { devices = new ArrayList<Device>(); manufacturers.put(device.getManufacturer(), devices); } devices.add(device); } if (haveNonNexus) { for (List<Device> devices : manufacturers.values()) { Menu manufacturerMenu = menu; if (manufacturers.size() > 1) { MenuItem item = new MenuItem(menu, SWT.CASCADE); item.setText(devices.get(0).getManufacturer()); manufacturerMenu = new Menu(menu); item.setMenu(manufacturerMenu); } for (final Device device : devices) { MenuItem deviceItem = new MenuItem(manufacturerMenu, SWT.CHECK); deviceItem.setText(getGenericLabel(device)); deviceItem.setSelection(current == device); deviceItem.addSelectionListener(new DeviceMenuListener(chooser, device)); } } } else { List<Device> nexus = new ArrayList<Device>(); List<Device> generic = new ArrayList<Device>(); if (haveNexus) { // Nexus for (List<Device> devices : manufacturers.values()) { for (Device device : devices) { if (isNexus(device)) { if (device.getManufacturer().equals(GENERIC)) { generic.add(device); } else { nexus.add(device); } } else { generic.add(device); } } } } if (!nexus.isEmpty()) { sortNexusList(nexus); for (final Device device : nexus) { MenuItem item = new MenuItem(menu, SWT.CHECK); item.setText(getNexusLabel(device)); item.setSelection(current == device); item.addSelectionListener(new DeviceMenuListener(chooser, device)); } @SuppressWarnings("unused") MenuItem separator = new MenuItem(menu, SWT.SEPARATOR); } // Generate the generic menu. Collections.reverse(generic); for (final Device device : generic) { MenuItem item = new MenuItem(menu, SWT.CHECK); item.setText(getGenericLabel(device)); item.setSelection(current == device); item.addSelectionListener(new DeviceMenuListener(chooser, device)); } } } @SuppressWarnings("unused") MenuItem separator = new MenuItem(menu, SWT.SEPARATOR); ConfigurationMenuListener.addTogglePreviewModeAction( menu, "Preview All Screens", chooser, RenderPreviewMode.SCREENS); Rectangle bounds = combo.getBounds(); Point location = new Point(bounds.x, bounds.y + bounds.height); location = combo.getParent().toDisplay(location); menu.setLocation(location.x, location.y); menu.setVisible(true); }