aboutsummaryrefslogtreecommitdiffstats
path: root/sdkmanager/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'sdkmanager/app/src')
-rw-r--r--sdkmanager/app/src/Android.mk16
-rw-r--r--sdkmanager/app/src/com/android/sdkmanager/Main.java487
2 files changed, 503 insertions, 0 deletions
diff --git a/sdkmanager/app/src/Android.mk b/sdkmanager/app/src/Android.mk
new file mode 100644
index 0000000..b508076
--- /dev/null
+++ b/sdkmanager/app/src/Android.mk
@@ -0,0 +1,16 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+ androidprefs \
+ sdklib \
+ sdkuilib
+LOCAL_MODULE := sdkmanager
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/sdkmanager/app/src/com/android/sdkmanager/Main.java b/sdkmanager/app/src/com/android/sdkmanager/Main.java
new file mode 100644
index 0000000..72bd2aa
--- /dev/null
+++ b/sdkmanager/app/src/com/android/sdkmanager/Main.java
@@ -0,0 +1,487 @@
+/*
+ * 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.sdkmanager;
+
+import com.android.prefs.AndroidLocation;
+import com.android.prefs.AndroidLocation.AndroidLocationException;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.ISdkLog;
+import com.android.sdklib.SdkConstants;
+import com.android.sdklib.SdkManager;
+import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
+import com.android.sdklib.vm.HardwareProperties;
+import com.android.sdklib.vm.VmManager;
+import com.android.sdklib.vm.HardwareProperties.HardwareProperty;
+import com.android.sdklib.vm.VmManager.VmInfo;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Main class for the 'android' application
+ *
+ */
+class Main {
+
+ private final static String TOOLSDIR = "com.android.sdkmanager.toolsdir";
+
+ private final static String ARG_LIST_TARGET = "target";
+ private final static String ARG_LIST_VM = "vm";
+
+ private final static String[] BOOLEAN_YES_REPLIES = new String[] { "yes", "y" };
+ private final static String[] BOOLEAN_NO_REPLIES = new String[] { "no", "n" };
+
+ private String mSdkFolder;
+ private SdkManager mSdkManager;
+ private VmManager mVmManager;
+
+ /* --list parameters */
+ private String mListObject;
+
+ /* --create parameters */
+ private boolean mCreateVm;
+ private int mCreateTargetId;
+ private IAndroidTarget mCreateTarget;
+ private String mCreateName;
+
+ public static void main(String[] args) {
+ new Main().run(args);
+ }
+
+ /**
+ * Runs the sdk manager app
+ * @param args
+ */
+ private void run(String[] args) {
+ init();
+ parseArgs(args);
+ parseSdk();
+ doAction();
+ }
+
+ /**
+ * Init the application by making sure the SDK path is available and
+ * doing basic parsing of the SDK.
+ */
+ private void init() {
+ /* We get passed a property for the tools dir */
+ String toolsDirProp = System.getProperty(TOOLSDIR);
+ if (toolsDirProp == null) {
+ // for debugging, it's easier to override using the process environment
+ toolsDirProp = System.getenv(TOOLSDIR);
+ }
+ if (toolsDirProp == null) {
+ printHelpAndExit("ERROR: The tools directory property is not set, please make sure you are executing android or android.bat");
+ }
+
+ // got back a level for the SDK folder
+ File tools = new File(toolsDirProp);
+ mSdkFolder = tools.getParent();
+
+ }
+
+ /**
+ * Parses command-line arguments, or prints help/usage and exits if error.
+ * @param args arguments passed to the program
+ */
+ private void parseArgs(String[] args) {
+ final int numArgs = args.length;
+
+ try {
+ int argPos = 0;
+ for (; argPos < numArgs; argPos++) {
+ final String arg = args[argPos];
+ if (arg.equals("-l") || arg.equals("--list")) {
+ mListObject = args[++argPos];
+ } else if (arg.equals("-c") || arg.equals("--create")) {
+ mCreateVm = true;
+ parseCreateArgs(args, ++argPos);
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ /* Any OOB triggers help */
+ printHelpAndExit("ERROR: Not enough arguments.");
+ }
+ }
+
+ private void parseCreateArgs(String[] args, int argPos) {
+ final int numArgs = args.length;
+
+ try {
+ for (; argPos < numArgs; argPos++) {
+ final String arg = args[argPos];
+ if (arg.equals("-t") || arg.equals("--target")) {
+ String targetId = args[++argPos];
+ try {
+ // get the target id
+ mCreateTargetId = Integer.parseInt(targetId);
+ } catch (NumberFormatException e) {
+ printHelpAndExit("ERROR: Target Id is not a number");
+ }
+ } else if (arg.equals("-n") || arg.equals("--name")) {
+ mCreateName = args[++argPos];
+ } else {
+ printHelpAndExit("ERROR: '%s' unknown argument for --create mode",
+ args[argPos]);
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ /* Any OOB triggers help */
+ printHelpAndExit("ERROR: Not enough arguments for --create");
+ }
+ }
+
+ /**
+ * Does the basic SDK parsing required for all actions
+ */
+ private void parseSdk() {
+ mSdkManager = SdkManager.createManager(mSdkFolder, new ISdkLog() {
+ public void error(String errorFormat, Object... args) {
+ System.err.printf("Error: " + errorFormat, args);
+ System.err.println("");
+ }
+
+ public void warning(String warningFormat, Object... args) {
+ if (false) {
+ // TODO: on display warnings in verbose mode.
+ System.out.printf("Warning: " + warningFormat, args);
+ System.out.println("");
+ }
+ }
+ });
+
+ if (mSdkManager == null) {
+ printHelpAndExit("ERROR: Unable to parse SDK content.");
+ }
+ }
+
+ /**
+ * Actually do an action...
+ */
+ private void doAction() {
+ if (mListObject != null) {
+ // list action.
+ if (ARG_LIST_TARGET.equals(mListObject)) {
+ displayTargetList();
+ } else if (ARG_LIST_VM.equals(mListObject)) {
+ displayVmList();
+ } else {
+ printHelpAndExit("'%s' is not a valid --list option", mListObject);
+ }
+ } else if (mCreateVm) {
+ createVm();
+ } else {
+ printHelpAndExit(null);
+ }
+ }
+
+ /**
+ * Displays the list of available Targets (Platforms and Add-ons)
+ */
+ private void displayTargetList() {
+ System.out.println("Available Android targets:");
+
+ int index = 1;
+ for (IAndroidTarget target : mSdkManager.getTargets()) {
+ if (target.isPlatform()) {
+ System.out.printf("[%d] %s\n", index, target.getName());
+ System.out.printf(" API level: %d\n", target.getApiVersionNumber());
+ } else {
+ System.out.printf("[%d] Add-on: %s\n", index, target.getName());
+ System.out.printf(" Vendor: %s\n", target.getVendor());
+ if (target.getDescription() != null) {
+ System.out.printf(" Description: %s\n", target.getDescription());
+ }
+ System.out.printf(" Based on Android %s (API level %d)\n",
+ target.getApiVersionName(), target.getApiVersionNumber());
+
+ // display the optional libraries.
+ IOptionalLibrary[] libraries = target.getOptionalLibraries();
+ if (libraries != null) {
+ for (IOptionalLibrary library : libraries) {
+ System.out.printf(" Library: %s (%s)\n", library.getName(),
+ library.getJarName());
+ }
+ }
+ }
+
+ // get the target skins
+ String[] skins = target.getSkins();
+ System.out.print(" Skins: ");
+ if (skins != null) {
+ boolean first = true;
+ for (String skin : skins) {
+ if (first == false) {
+ System.out.print(", ");
+ } else {
+ first = false;
+ }
+ System.out.print(skin);
+ }
+ System.out.println("");
+ } else {
+ System.out.println("no skins.");
+ }
+
+ index++;
+ }
+ }
+
+ /**
+ * Displays the list of available VMs.
+ */
+ private void displayVmList() {
+ try {
+ mVmManager = new VmManager(mSdkManager, null /* sdklog */);
+
+ System.out.println("Available Android VMs:");
+
+ int index = 1;
+ for (VmInfo info : mVmManager.getVms()) {
+ System.out.printf("[%d] %s\n", index, info.getName());
+ System.out.printf(" Path: %s\n", info.getPath());
+
+ // get the target of the Vm
+ IAndroidTarget target = info.getTarget();
+ if (target.isPlatform()) {
+ System.out.printf(" Target: %s (API level %d)\n", target.getName(),
+ target.getApiVersionNumber());
+ } else {
+ System.out.printf(" Target: %s (%s)\n", target.getName(), target
+ .getVendor());
+ System.out.printf(" Based on Android %s (API level %d)\n", target
+ .getApiVersionName(), target.getApiVersionNumber());
+
+ }
+
+ index++;
+ }
+ } catch (AndroidLocationException e) {
+ printHelpAndExit(e.getMessage());
+ }
+ }
+
+ /**
+ * Creates a new VM. This is a text based creation with command line prompt.
+ */
+ private void createVm() {
+ // find a matching target
+ if (mCreateTargetId >= 1 && mCreateTargetId <= mSdkManager.getTargets().length) {
+ mCreateTarget = mSdkManager.getTargets()[mCreateTargetId-1]; // target it is 1-based
+ } else {
+ printHelpAndExit(
+ "ERROR: Target Id is not a valid Id. Check android --list target for the list of targets.");
+ }
+
+ try {
+ // default to standard path now
+ String vmRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_VMS;
+
+ Map<String, String> hardwareConfig = null;
+ if (mCreateTarget.isPlatform()) {
+ try {
+ hardwareConfig = promptForHardware(mCreateTarget);
+ } catch (IOException e) {
+ printHelpAndExit(e.getMessage());
+ }
+ }
+
+ VmManager.createVm(vmRoot, mCreateName, mCreateTarget, null /*skinName*/,
+ null /*sdcardPath*/, 0 /*sdcardSize*/, hardwareConfig,
+ null /* sdklog */);
+ } catch (AndroidLocationException e) {
+ printHelpAndExit(e.getMessage());
+ }
+ }
+
+ /**
+ * Prompts the user to setup a hardware config for a Platform-based VM.
+ * @throws IOException
+ */
+ private Map<String, String> promptForHardware(IAndroidTarget createTarget) throws IOException {
+ byte[] readLineBuffer = new byte[256];
+ String result;
+ String defaultAnswer = "no";
+
+ System.out.print(String.format("%s is a basic Android platform.\n",
+ createTarget.getName()));
+ System.out.print(String.format("Do you which to create a custom hardware profile [%s]",
+ defaultAnswer));
+
+ result = readLine(readLineBuffer);
+ // handle default:
+ if (result.length() == 0) {
+ result = defaultAnswer;
+ }
+
+ if (getBooleanReply(result) == false) {
+ // no custom config.
+ return null;
+ }
+
+ System.out.println(""); // empty line
+
+ // get the list of possible hardware properties
+ File hardwareDefs = new File (mSdkFolder + File.separator +
+ SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI);
+ List<HardwareProperty> list = HardwareProperties.parseHardwareDefinitions(hardwareDefs,
+ null /*sdkLog*/);
+
+ HashMap<String, String> map = new HashMap<String, String>();
+
+ for (int i = 0 ; i < list.size() ;) {
+ HardwareProperty property = list.get(i);
+
+ String description = property.getDescription();
+ if (description != null) {
+ System.out.printf("%s: %s\n", property.getAbstract(), description);
+ } else {
+ System.out.println(property.getAbstract());
+ }
+
+ String defaultValue = property.getDefault();
+
+ if (defaultValue != null) {
+ System.out.printf("%s [%s]:", property.getName(), defaultValue);
+ } else {
+ System.out.printf("%s (%s):", property.getName(), property.getType());
+ }
+
+ result = readLine(readLineBuffer);
+ if (result.length() == 0) {
+ if (defaultValue != null) {
+ System.out.println(""); // 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
+ }
+ continue;
+ }
+
+ switch (property.getType()) {
+ case BOOLEAN:
+ try {
+ if (getBooleanReply(result)) {
+ map.put(property.getName(), "yes");
+ i++; // valid reply, move to next property
+ } else {
+ map.put(property.getName(), "no");
+ i++; // valid reply, move to next property
+ }
+ } catch (IOException e) {
+ // display error, and do not increment i to redo this property
+ System.out.println("\n" + e.getMessage());
+ }
+ break;
+ case INTEGER:
+ try {
+ @SuppressWarnings("unused")
+ int value = Integer.parseInt(result);
+ map.put(property.getName(), result);
+ i++; // valid reply, move to next property
+ } catch (NumberFormatException e) {
+ // display error, and do not increment i to redo this property
+ System.out.println("\n" + e.getMessage());
+ }
+ break;
+ case DISKSIZE:
+ // TODO check validity
+ map.put(property.getName(), result);
+ i++; // valid reply, move to next property
+ break;
+ }
+
+ System.out.println(""); // empty line
+ }
+
+ return map;
+ }
+
+ /**
+ * Read the line from the input stream.
+ * @param buffer
+ * @return
+ * @throws IOException
+ */
+ private String readLine(byte[] buffer) throws IOException {
+ int count = System.in.read(buffer);
+
+ // is the input longer than the buffer?
+ if (count == buffer.length && buffer[count-1] != 10) {
+ // create a new temp buffer
+ byte[] tempBuffer = new byte[256];
+
+ // and read the rest
+ String secondHalf = readLine(tempBuffer);
+
+ // return a concat of both
+ return new String(buffer, 0, count) + secondHalf;
+ }
+
+ return new String(buffer, 0, count - 1); // -1 to not include the carriage return
+ }
+
+ /**
+ * Returns the boolean value represented by the string.
+ * @throws IOException If the value is not a boolean string.
+ */
+ private boolean getBooleanReply(String reply) throws IOException {
+ for (String valid : BOOLEAN_YES_REPLIES) {
+ if (valid.equalsIgnoreCase(reply)) {
+ return true;
+ }
+ }
+
+ for (String valid : BOOLEAN_NO_REPLIES) {
+ if (valid.equalsIgnoreCase(reply)) {
+ return false;
+ }
+ }
+
+ throw new IOException(String.format("%s is not a valid reply", reply));
+ }
+
+ /**
+ * Prints the help/usage and exits.
+ * @param errorFormat Optional error message to print prior to usage using String.format
+ * @param args Arguments for String.format
+ */
+ private void printHelpAndExit(String errorFormat, Object... args) {
+ if (errorFormat != null) {
+ System.err.println(String.format(errorFormat, args));
+ }
+
+ /*
+ * usage should fit in 80 columns
+ * 12345678901234567890123456789012345678901234567890123456789012345678901234567890
+ */
+ final String usage = "\n" +
+ "Usage:\n" +
+ " android --list [target|vm]\n" +
+ " android --create --target <target id> --name <name>\n" +
+ "\n" +
+ "Options:\n" +
+ " -l [target|vm], --list [target|vm]\n" +
+ " Outputs the available targets or Virtual Machines and their Ids.\n" +
+ "\n";
+
+ System.out.println(usage);
+ System.exit(1);
+ }
+} \ No newline at end of file