Code drop from //branches/cupcake/...@124589
This commit is contained in:
18
tools/sdkmanager/Android.mk
Normal file
18
tools/sdkmanager/Android.mk
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
SDKMANAGER_LOCAL_DIR := $(call my-dir)
|
||||
include $(SDKMANAGER_LOCAL_DIR)/app/Android.mk
|
||||
include $(SDKMANAGER_LOCAL_DIR)/libs/Android.mk
|
||||
0
tools/sdkmanager/MODULE_LICENSE_APACHE2
Normal file
0
tools/sdkmanager/MODULE_LICENSE_APACHE2
Normal file
9
tools/sdkmanager/app/.classpath
Normal file
9
tools/sdkmanager/app/.classpath
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/SdkUiLib"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
tools/sdkmanager/app/.project
Normal file
17
tools/sdkmanager/app/.project
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>SdkManager</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
5
tools/sdkmanager/app/Android.mk
Normal file
5
tools/sdkmanager/app/Android.mk
Normal file
@@ -0,0 +1,5 @@
|
||||
# Copyright 2007 The Android Open Source Project
|
||||
#
|
||||
SDKMANAGERAPP_LOCAL_DIR := $(call my-dir)
|
||||
include $(SDKMANAGERAPP_LOCAL_DIR)/etc/Android.mk
|
||||
include $(SDKMANAGERAPP_LOCAL_DIR)/src/Android.mk
|
||||
8
tools/sdkmanager/app/etc/Android.mk
Normal file
8
tools/sdkmanager/app/etc/Android.mk
Normal file
@@ -0,0 +1,8 @@
|
||||
# Copyright 2008 The Android Open Source Project
|
||||
#
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_PREBUILT_EXECUTABLES := android
|
||||
include $(BUILD_HOST_PREBUILT)
|
||||
|
||||
84
tools/sdkmanager/app/etc/android
Executable file
84
tools/sdkmanager/app/etc/android
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
# Copyright 2005-2007, 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.
|
||||
|
||||
# Set up prog to be the path of this script, including following symlinks,
|
||||
# and set up progdir to be the fully-qualified pathname of its directory.
|
||||
prog="$0"
|
||||
while [ -h "${prog}" ]; do
|
||||
newProg=`/bin/ls -ld "${prog}"`
|
||||
newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
|
||||
if expr "x${newProg}" : 'x/' >/dev/null; then
|
||||
prog="${newProg}"
|
||||
else
|
||||
progdir=`dirname "${prog}"`
|
||||
prog="${progdir}/${newProg}"
|
||||
fi
|
||||
done
|
||||
oldwd=`pwd`
|
||||
progdir=`dirname "${prog}"`
|
||||
cd "${progdir}"
|
||||
progdir=`pwd`
|
||||
prog="${progdir}"/`basename "${prog}"`
|
||||
cd "${oldwd}"
|
||||
|
||||
jarfile=sdkmanager.jar
|
||||
frameworkdir="$progdir"
|
||||
libdir="$progdir"
|
||||
if [ ! -r "$frameworkdir/$jarfile" ]
|
||||
then
|
||||
frameworkdir=`dirname "$progdir"`/tools/lib
|
||||
libdir=`dirname "$progdir"`/tools/lib
|
||||
fi
|
||||
if [ ! -r "$frameworkdir/$jarfile" ]
|
||||
then
|
||||
frameworkdir=`dirname "$progdir"`/framework
|
||||
libdir=`dirname "$progdir"`/lib
|
||||
fi
|
||||
if [ ! -r "$frameworkdir/$jarfile" ]
|
||||
then
|
||||
echo `basename "$prog"`": can't find $jarfile"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Check args.
|
||||
if [ debug = "$1" ]; then
|
||||
# add this in for debugging
|
||||
java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
|
||||
shift 1
|
||||
else
|
||||
java_debug=
|
||||
fi
|
||||
|
||||
# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
|
||||
if [ `uname` = "Darwin" ]; then
|
||||
os_opts="-XstartOnFirstThread"
|
||||
#because Java 1.6 is 64 bits only and SWT doesn't support this, we force the usage of java 1.5
|
||||
java_cmd="/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Commands/java"
|
||||
else
|
||||
os_opts=
|
||||
java_cmd="java"
|
||||
fi
|
||||
|
||||
if [ "$OSTYPE" = "cygwin" ] ; then
|
||||
jarpath=`cygpath -w "$frameworkdir/$jarfile"`
|
||||
progdir=`cygpath -w "$progdir"`
|
||||
else
|
||||
jarpath="$frameworkdir/$jarfile"
|
||||
fi
|
||||
|
||||
# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
|
||||
# might need more memory, e.g. -Xmx128M
|
||||
exec "$java_cmd" -Xmx256M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -Dcom.android.sdkmanager.toolsdir="$progdir" -jar "$jarpath" "$@"
|
||||
48
tools/sdkmanager/app/etc/android.bat
Executable file
48
tools/sdkmanager/app/etc/android.bat
Executable file
@@ -0,0 +1,48 @@
|
||||
@echo off
|
||||
rem Copyright (C) 2007 The Android Open Source Project
|
||||
rem
|
||||
rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
rem you may not use this file except in compliance with the License.
|
||||
rem You may obtain a copy of the License at
|
||||
rem
|
||||
rem http://www.apache.org/licenses/LICENSE-2.0
|
||||
rem
|
||||
rem Unless required by applicable law or agreed to in writing, software
|
||||
rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
rem See the License for the specific language governing permissions and
|
||||
rem limitations under the License.
|
||||
|
||||
rem don't modify the caller's environment
|
||||
setlocal
|
||||
|
||||
rem Set up prog to be the path of this script, including following symlinks,
|
||||
rem and set up progdir to be the fully-qualified pathname of its directory.
|
||||
set prog=%~f0
|
||||
|
||||
rem Change current directory to where ddms is, to avoid issues with directories
|
||||
rem containing whitespaces.
|
||||
cd %~dp0
|
||||
|
||||
set jarfile=sdkmanager.jar
|
||||
set frameworkdir=
|
||||
set libdir=
|
||||
|
||||
if exist %frameworkdir%%jarfile% goto JarFileOk
|
||||
set frameworkdir=lib\
|
||||
set libdir=lib\
|
||||
|
||||
if exist %frameworkdir%%jarfile% goto JarFileOk
|
||||
set frameworkdir=..\framework\
|
||||
set libdir=..\lib\
|
||||
|
||||
:JarFileOk
|
||||
|
||||
if debug NEQ "%1" goto NoDebug
|
||||
set java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
|
||||
shift 1
|
||||
:NoDebug
|
||||
|
||||
set jarpath=%frameworkdir%%jarfile%
|
||||
|
||||
call java %java_debug% -Djava.ext.dirs=%frameworkdir% -Djava.library.path=%libdir% -Dcom.android.sdkmanager.toolsdir= -jar %jarpath% %*
|
||||
1
tools/sdkmanager/app/etc/manifest.txt
Normal file
1
tools/sdkmanager/app/etc/manifest.txt
Normal file
@@ -0,0 +1 @@
|
||||
Main-Class: com.android.sdkmanager.Main
|
||||
16
tools/sdkmanager/app/src/Android.mk
Normal file
16
tools/sdkmanager/app/src/Android.mk
Normal file
@@ -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)
|
||||
|
||||
487
tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
Normal file
487
tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
18
tools/sdkmanager/libs/Android.mk
Normal file
18
tools/sdkmanager/libs/Android.mk
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
SDKLIBS_LOCAL_DIR := $(call my-dir)
|
||||
include $(SDKLIBS_LOCAL_DIR)/sdklib/Android.mk
|
||||
include $(SDKLIBS_LOCAL_DIR)/sdkuilib/Android.mk
|
||||
7
tools/sdkmanager/libs/sdklib/.classpath
Normal file
7
tools/sdkmanager/libs/sdklib/.classpath
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
tools/sdkmanager/libs/sdklib/.project
Normal file
17
tools/sdkmanager/libs/sdklib/.project
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>SdkLib</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
17
tools/sdkmanager/libs/sdklib/Android.mk
Normal file
17
tools/sdkmanager/libs/sdklib/Android.mk
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
SDKLIB_LOCAL_DIR := $(call my-dir)
|
||||
include $(SDKLIB_LOCAL_DIR)/src/Android.mk
|
||||
27
tools/sdkmanager/libs/sdklib/src/Android.mk
Normal file
27
tools/sdkmanager/libs/sdklib/src/Android.mk
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
|
||||
LOCAL_JAVA_LIBRARIES := \
|
||||
androidprefs
|
||||
|
||||
LOCAL_MODULE := sdklib
|
||||
|
||||
include $(BUILD_HOST_JAVA_LIBRARY)
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Represents an add-on target in the SDK.
|
||||
* An add-on extends a standard {@link PlatformTarget}.
|
||||
*/
|
||||
final class AddOnTarget implements IAndroidTarget {
|
||||
/**
|
||||
* String to compute hash for add-on targets.
|
||||
* Format is vendor:name:apiVersion
|
||||
* */
|
||||
private final static String ADD_ON_FORMAT = "%s:%s:%d"; //$NON-NLS-1$
|
||||
|
||||
private final static class OptionalLibrary implements IOptionalLibrary {
|
||||
private final String mJarName;
|
||||
private final String mJarPath;
|
||||
private final String mName;
|
||||
|
||||
OptionalLibrary(String jarName, String jarPath, String name) {
|
||||
mJarName = jarName;
|
||||
mJarPath = jarPath;
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public String getJarName() {
|
||||
return mJarName;
|
||||
}
|
||||
|
||||
public String getJarPath() {
|
||||
return mJarPath;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
|
||||
private final String mLocation;
|
||||
private final PlatformTarget mBasePlatform;
|
||||
private final String mName;
|
||||
private final String mVendor;
|
||||
private final String mDescription;
|
||||
private String[] mSkins;
|
||||
private IOptionalLibrary[] mLibraries;
|
||||
|
||||
/**
|
||||
* Creates a new add-on
|
||||
* @param location the OS path location of the add-on
|
||||
* @param name the name of the add-on
|
||||
* @param vendor the vendor name of the add-on
|
||||
* @param description the add-on description
|
||||
* @param libMap A map containing the optional libraries. The map key is the fully-qualified
|
||||
* library name. The value is the .jar filename
|
||||
* @param basePlatform the platform the add-on is extending.
|
||||
*/
|
||||
AddOnTarget(String location, String name, String vendor, String description,
|
||||
Map<String, String> libMap, PlatformTarget basePlatform) {
|
||||
if (location.endsWith(File.separator) == false) {
|
||||
location = location + File.separator;
|
||||
}
|
||||
|
||||
mLocation = location;
|
||||
mName = name;
|
||||
mVendor = vendor;
|
||||
mDescription = description;
|
||||
mBasePlatform = basePlatform;
|
||||
|
||||
// handle the optional libraries.
|
||||
mLibraries = new IOptionalLibrary[libMap.size()];
|
||||
int index = 0;
|
||||
for (Entry<String, String> entry : libMap.entrySet()) {
|
||||
mLibraries[index++] = new OptionalLibrary(entry.getValue(),
|
||||
mLocation + SdkConstants.OS_ADDON_LIBS_FOLDER + entry.getValue(),
|
||||
entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public String getVendor() {
|
||||
return mVendor;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
public String getApiVersionName() {
|
||||
// this is always defined by the base platform
|
||||
return mBasePlatform.getApiVersionName();
|
||||
}
|
||||
|
||||
public int getApiVersionNumber() {
|
||||
// this is always defined by the base platform
|
||||
return mBasePlatform.getApiVersionNumber();
|
||||
}
|
||||
|
||||
public boolean isPlatform() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getPath(int pathId) {
|
||||
switch (pathId) {
|
||||
case IMAGES:
|
||||
return mLocation + SdkConstants.OS_IMAGES_FOLDER;
|
||||
case SKINS:
|
||||
return mLocation + SdkConstants.OS_SKINS_FOLDER;
|
||||
default :
|
||||
return mBasePlatform.getPath(pathId);
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getSkins() {
|
||||
return mSkins;
|
||||
}
|
||||
|
||||
public IOptionalLibrary[] getOptionalLibraries() {
|
||||
return mLibraries;
|
||||
}
|
||||
|
||||
public String hashString() {
|
||||
return String.format(ADD_ON_FORMAT, mVendor, mName, mBasePlatform.getApiVersionNumber());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hashString().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof AddOnTarget) {
|
||||
AddOnTarget addon = (AddOnTarget)obj;
|
||||
|
||||
return mVendor.equals(addon.mVendor) && mName.equals(addon.mName) &&
|
||||
mBasePlatform.getApiVersionNumber() == addon.mBasePlatform.getApiVersionNumber();
|
||||
}
|
||||
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* Always return +1 if the object we compare to is a platform.
|
||||
* Otherwise, do vendor then name then api version comparison.
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
public int compareTo(IAndroidTarget target) {
|
||||
if (target.isPlatform()) {
|
||||
return +1;
|
||||
}
|
||||
|
||||
// vendor
|
||||
int value = mVendor.compareTo(target.getVendor());
|
||||
|
||||
// name
|
||||
if (value == 0) {
|
||||
value = mName.compareTo(target.getName());
|
||||
}
|
||||
|
||||
// api version
|
||||
if (value == 0) {
|
||||
value = getApiVersionNumber() - target.getApiVersionNumber();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// ---- local methods.
|
||||
|
||||
|
||||
public void setSkins(String[] skins) {
|
||||
mSkins = skins;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
/**
|
||||
* A version of Android that application can target when building.
|
||||
*/
|
||||
public interface IAndroidTarget extends Comparable<IAndroidTarget> {
|
||||
|
||||
public static int ANDROID_JAR = 1;
|
||||
public static int ANDROID_AIDL = 2;
|
||||
public static int IMAGES = 3;
|
||||
public static int SAMPLES = 4;
|
||||
public static int SKINS = 5;
|
||||
public static int TEMPLATES = 6;
|
||||
public static int DATA = 7;
|
||||
public static int ATTRIBUTES = 8;
|
||||
public static int MANIFEST_ATTRIBUTES = 9;
|
||||
public static int LAYOUT_LIB = 10;
|
||||
public static int RESOURCES = 11;
|
||||
public static int FONTS = 12;
|
||||
public static int WIDGETS = 13;
|
||||
public static int ACTIONS_ACTIVITY = 14;
|
||||
public static int ACTIONS_BROADCAST = 15;
|
||||
public static int ACTIONS_SERVICE = 16;
|
||||
public static int CATEGORIES = 17;
|
||||
public static int SOURCES = 18;
|
||||
|
||||
public interface IOptionalLibrary {
|
||||
String getName();
|
||||
String getJarName();
|
||||
String getJarPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the vendor of the target.
|
||||
*/
|
||||
String getVendor();
|
||||
|
||||
/**
|
||||
* Returns the name of the target.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns the description of the target.
|
||||
*/
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* Returns the api version as an integer.
|
||||
*/
|
||||
int getApiVersionNumber();
|
||||
|
||||
/**
|
||||
* Returns the platform version as a readable string.
|
||||
*/
|
||||
String getApiVersionName();
|
||||
|
||||
/**
|
||||
* Returns true if the target is a standard Android platform.
|
||||
*/
|
||||
boolean isPlatform();
|
||||
|
||||
/**
|
||||
* Returns the path of a platform component.
|
||||
* @param pathId the id representing the path to return. Any of the constants defined in the
|
||||
* {@link ITargetDataProvider} interface can be used.
|
||||
*/
|
||||
String getPath(int pathId);
|
||||
|
||||
/**
|
||||
* Returns the available skins for this target.
|
||||
*/
|
||||
String[] getSkins();
|
||||
|
||||
/**
|
||||
* Returns the available optional libraries for this target.
|
||||
* @return an array of optional libraries or <code>null</code> if there is none.
|
||||
*/
|
||||
IOptionalLibrary[] getOptionalLibraries();
|
||||
|
||||
/**
|
||||
* Returns a string able to uniquely identify a target.
|
||||
* Typically the target will encode information such as api level, whether it's a platform
|
||||
* or add-on, and if it's an add-on vendor and add-on name.
|
||||
*/
|
||||
String hashString();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Interface used to display warnings/errors while parsing the SDK content.
|
||||
*/
|
||||
public interface ISdkLog {
|
||||
void warning(String warningFormat, Object... args);
|
||||
void error(String errorFormat, Object... args);
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a platform target in the SDK.
|
||||
*/
|
||||
final class PlatformTarget implements IAndroidTarget {
|
||||
/** String used to get a hash to the platform target */
|
||||
private final static String PLATFORM_HASH = "android-%d";
|
||||
|
||||
private final static String PLATFORM_VENDOR = "Android";
|
||||
private final static String PLATFORM_NAME = "Android %s";
|
||||
|
||||
private final String mLocation;
|
||||
private final String mName;
|
||||
private final int mApiVersionNumber;
|
||||
private final String mApiVersionName;
|
||||
private final Map<String, String> mProperties;
|
||||
private final Map<Integer, String> mPaths = new HashMap<Integer, String>();
|
||||
private String[] mSkins;
|
||||
|
||||
PlatformTarget(String location, Map<String, String> properties,
|
||||
int apiNumber, String apiName) {
|
||||
mName = String.format(PLATFORM_NAME, apiName);
|
||||
if (location.endsWith(File.separator) == false) {
|
||||
location = location + File.separator;
|
||||
}
|
||||
mLocation = location;
|
||||
mProperties = Collections.unmodifiableMap(properties);
|
||||
mApiVersionNumber = apiNumber;
|
||||
mApiVersionName = apiName;
|
||||
|
||||
// pre-build the path to the platform components
|
||||
mPaths.put(ANDROID_JAR, mLocation + SdkConstants.FN_FRAMEWORK_LIBRARY);
|
||||
mPaths.put(SOURCES, mLocation + SdkConstants.FD_ANDROID_SOURCES);
|
||||
mPaths.put(ANDROID_AIDL, mLocation + SdkConstants.FN_FRAMEWORK_AIDL);
|
||||
mPaths.put(IMAGES, mLocation + SdkConstants.OS_IMAGES_FOLDER);
|
||||
mPaths.put(SAMPLES, mLocation + SdkConstants.OS_PLATFORM_SAMPLES_FOLDER);
|
||||
mPaths.put(SKINS, mLocation + SdkConstants.OS_SKINS_FOLDER);
|
||||
mPaths.put(TEMPLATES, mLocation + SdkConstants.OS_PLATFORM_TEMPLATES_FOLDER);
|
||||
mPaths.put(DATA, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER);
|
||||
mPaths.put(ATTRIBUTES, mLocation + SdkConstants.OS_PLATFORM_ATTRS_XML);
|
||||
mPaths.put(MANIFEST_ATTRIBUTES, mLocation + SdkConstants.OS_PLATFORM_ATTRS_MANIFEST_XML);
|
||||
mPaths.put(RESOURCES, mLocation + SdkConstants.OS_PLATFORM_RESOURCES_FOLDER);
|
||||
mPaths.put(FONTS, mLocation + SdkConstants.OS_PLATFORM_FONTS_FOLDER);
|
||||
mPaths.put(LAYOUT_LIB, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
|
||||
SdkConstants.FN_LAYOUTLIB_JAR);
|
||||
mPaths.put(WIDGETS, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
|
||||
SdkConstants.FN_WIDGETS);
|
||||
mPaths.put(ACTIONS_ACTIVITY, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
|
||||
SdkConstants.FN_INTENT_ACTIONS_ACTIVITY);
|
||||
mPaths.put(ACTIONS_BROADCAST, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
|
||||
SdkConstants.FN_INTENT_ACTIONS_BROADCAST);
|
||||
mPaths.put(ACTIONS_SERVICE, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
|
||||
SdkConstants.FN_INTENT_ACTIONS_SERVICE);
|
||||
mPaths.put(CATEGORIES, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
|
||||
SdkConstants.FN_INTENT_CATEGORIES);
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return mLocation;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* For Platform, the vendor name is always "Android".
|
||||
*
|
||||
* @see com.android.sdklib.IAndroidTarget#getVendor()
|
||||
*/
|
||||
public String getVendor() {
|
||||
return PLATFORM_VENDOR;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* Description for the Android platform is dynamically generated.
|
||||
*
|
||||
* @see com.android.sdklib.IAndroidTarget#getDescription()
|
||||
*/
|
||||
public String getDescription() {
|
||||
return String.format("Standard Android platform %s", mApiVersionName);
|
||||
}
|
||||
|
||||
public int getApiVersionNumber(){
|
||||
return mApiVersionNumber;
|
||||
}
|
||||
|
||||
public String getApiVersionName() {
|
||||
return mApiVersionName;
|
||||
}
|
||||
|
||||
public boolean isPlatform() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getPath(int pathId) {
|
||||
return mPaths.get(pathId);
|
||||
}
|
||||
|
||||
public String[] getSkins() {
|
||||
return mSkins;
|
||||
}
|
||||
|
||||
/*
|
||||
* Always returns null, as a standard platforms have no optional libraries.
|
||||
*
|
||||
* (non-Javadoc)
|
||||
* @see com.android.sdklib.IAndroidTarget#getOptionalLibraries()
|
||||
*/
|
||||
public IOptionalLibrary[] getOptionalLibraries() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String hashString() {
|
||||
return String.format(PLATFORM_HASH, mApiVersionNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hashString().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof PlatformTarget) {
|
||||
return mApiVersionNumber == ((PlatformTarget)obj).mApiVersionNumber;
|
||||
}
|
||||
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* Always return -1 if the object we compare to is an addon.
|
||||
* Otherwise, compare api level.
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
public int compareTo(IAndroidTarget target) {
|
||||
if (target.isPlatform() == false) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mApiVersionNumber - target.getApiVersionNumber();
|
||||
}
|
||||
|
||||
// ---- platform only methods.
|
||||
|
||||
public String getProperty(String name) {
|
||||
return mProperties.get(name);
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return mProperties; // mProperties is unmodifiable.
|
||||
}
|
||||
|
||||
void setSkins(String[] skins) {
|
||||
mSkins = skins;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2007 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;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Constant definition class.<br>
|
||||
* <br>
|
||||
* Most constants have a prefix defining the content.
|
||||
* <ul>
|
||||
* <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
|
||||
* <li><code>FN_</code> File name constant.</li>
|
||||
* <li><code>FD_</code> Folder name constant.</li>
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
public final class SdkConstants {
|
||||
|
||||
/** Name of the framework library, i.e. "android.jar" */
|
||||
public static final String FN_FRAMEWORK_LIBRARY = "android.jar";
|
||||
/** Name of the layout attributes, i.e. "attrs.xml" */
|
||||
public static final String FN_ATTRS_XML = "attrs.xml";
|
||||
/** Name of the layout attributes, i.e. "attrs_manifest.xml" */
|
||||
public static final String FN_ATTRS_MANIFEST_XML = "attrs_manifest.xml";
|
||||
/** framework aidl import file */
|
||||
public static final String FN_FRAMEWORK_AIDL = "framework.aidl";
|
||||
/** layoutlib.jar file */
|
||||
public static final String FN_LAYOUTLIB_JAR = "layoutlib.jar";
|
||||
/** widget list file */
|
||||
public static final String FN_WIDGETS = "widgets.txt";
|
||||
/** Intent activity actions list file */
|
||||
public static final String FN_INTENT_ACTIONS_ACTIVITY = "activity_actions.txt";
|
||||
/** Intent broadcast actions list file */
|
||||
public static final String FN_INTENT_ACTIONS_BROADCAST = "broadcast_actions.txt";
|
||||
/** Intent service actions list file */
|
||||
public static final String FN_INTENT_ACTIONS_SERVICE = "service_actions.txt";
|
||||
/** Intent category list file */
|
||||
public static final String FN_INTENT_CATEGORIES = "categories.txt";
|
||||
|
||||
/** platform build property file */
|
||||
public final static String FN_BUILD_PROP = "build.prop";
|
||||
/** plugin properties file */
|
||||
public final static String FN_PLUGIN_PROP = "plugin.prop";
|
||||
/** add-on manifest file */
|
||||
public final static String FN_MANIFEST_INI = "manifest.ini";
|
||||
/** hardware properties definition file */
|
||||
public final static String FN_HARDWARE_INI = "hardware-properties.ini";
|
||||
|
||||
/** Skin layout file */
|
||||
public final static String FN_SKIN_LAYOUT = "layout";//$NON-NLS-1$
|
||||
|
||||
/* Folder Names for the Android SDK */
|
||||
|
||||
/** Name of the SDK platforms folder. */
|
||||
public final static String FD_PLATFORMS = "platforms";
|
||||
/** Name of the SDK addons folder. */
|
||||
public final static String FD_ADDONS = "add-ons";
|
||||
/** Name of the SDK tools folder. */
|
||||
public final static String FD_TOOLS = "tools";
|
||||
/** Name of the SDK tools/lib folder. */
|
||||
public final static String FD_LIB = "lib";
|
||||
/** Name of the SDK docs folder. */
|
||||
public final static String FD_DOCS = "docs";
|
||||
/** Name of the SDK images folder. */
|
||||
public final static String FD_IMAGES = "images";
|
||||
/** Name of the SDK skins folder. */
|
||||
public final static String FD_SKINS = "skins";
|
||||
/** Name of the SDK samples folder. */
|
||||
public final static String FD_SAMPLES = "samples";
|
||||
/** Name of the SDK templates folder, i.e. "templates" */
|
||||
public final static String FD_TEMPLATES = "templates";
|
||||
/** Name of the SDK data folder, i.e. "data" */
|
||||
public final static String FD_DATA = "data";
|
||||
/** Name of the SDK resources folder, i.e. "res" */
|
||||
public final static String FD_RES = "res";
|
||||
/** Name of the SDK font folder, i.e. "fonts" */
|
||||
public final static String FD_FONTS = "fonts";
|
||||
/** Default values resource folder name, i.e. "values" */
|
||||
public final static String FD_VALUES = "values";
|
||||
/** Name of the android sources directory */
|
||||
public static final String FD_ANDROID_SOURCES = "sources";
|
||||
/** Name of the addon libs folder. */
|
||||
public final static String FD_ADDON_LIBS = "libs";
|
||||
|
||||
/* Folder path relative to the SDK root */
|
||||
/** Path of the documentation directory relative to the sdk folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_SDK_DOCS_FOLDER = FD_DOCS + File.separator;
|
||||
|
||||
/** Path of the tools directory relative to the sdk folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_SDK_TOOLS_FOLDER = FD_TOOLS + File.separator;
|
||||
|
||||
/** Path of the lib directory relative to the sdk folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_SDK_TOOLS_LIB_FOLDER =
|
||||
OS_SDK_TOOLS_FOLDER + FD_LIB + File.separator;
|
||||
|
||||
/* Folder paths relative to a platform or add-on folder */
|
||||
|
||||
/** Path of the images directory relative to a platform or addon folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_IMAGES_FOLDER = FD_IMAGES + File.separator;
|
||||
|
||||
/** Path of the skin directory relative to a platform or addon folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_SKINS_FOLDER = FD_SKINS + File.separator;
|
||||
|
||||
/* Folder paths relative to a Platform folder */
|
||||
|
||||
/** Path of the data directory relative to a platform folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_PLATFORM_DATA_FOLDER = FD_DATA + File.separator;
|
||||
|
||||
/** Path of the samples directory relative to a platform folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_PLATFORM_SAMPLES_FOLDER = FD_SAMPLES + File.separator;
|
||||
|
||||
/** Path of the resources directory relative to a platform folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_PLATFORM_RESOURCES_FOLDER =
|
||||
OS_PLATFORM_DATA_FOLDER + FD_RES + File.separator;
|
||||
|
||||
/** Path of the fonts directory relative to a platform folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_PLATFORM_FONTS_FOLDER =
|
||||
OS_PLATFORM_DATA_FOLDER + FD_FONTS + File.separator;
|
||||
|
||||
/** Path of the android source directory relative to a platform folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_PLATFORM_SOURCES_FOLDER = FD_ANDROID_SOURCES + File.separator;
|
||||
|
||||
/** Path of the android templates directory relative to a platform folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_PLATFORM_TEMPLATES_FOLDER = FD_TEMPLATES + File.separator;
|
||||
|
||||
/** Path of the attrs.xml file relative to a platform folder. */
|
||||
public final static String OS_PLATFORM_ATTRS_XML =
|
||||
OS_PLATFORM_RESOURCES_FOLDER + FD_VALUES + File.separator + FN_ATTRS_XML;
|
||||
|
||||
/** Path of the attrs_manifest.xml file relative to a platform folder. */
|
||||
public final static String OS_PLATFORM_ATTRS_MANIFEST_XML =
|
||||
OS_PLATFORM_RESOURCES_FOLDER + FD_VALUES + File.separator + FN_ATTRS_MANIFEST_XML;
|
||||
|
||||
/** Path of the layoutlib.jar file relative to a platform folder. */
|
||||
public final static String OS_PLATFORM_LAYOUTLIB_JAR =
|
||||
OS_PLATFORM_DATA_FOLDER + FN_LAYOUTLIB_JAR;
|
||||
|
||||
/* Folder paths relative to a addon folder */
|
||||
|
||||
/** Path of the images directory relative to a folder folder.
|
||||
* This is an OS path, ending with a separator. */
|
||||
public final static String OS_ADDON_LIBS_FOLDER = FD_ADDON_LIBS + File.separator;
|
||||
|
||||
|
||||
/* Skin default */
|
||||
public final static String SKIN_DEFAULT = "default";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* The SDK manager parses the SDK folder and gives access to the content.
|
||||
* @see PlatformTarget
|
||||
* @see AddOnTarget
|
||||
*/
|
||||
public final class SdkManager {
|
||||
|
||||
private final static String PROP_VERSION_SDK = "ro.build.version.sdk";
|
||||
private final static String PROP_VERSION_RELEASE = "ro.build.version.release";
|
||||
|
||||
private final static String ADDON_NAME = "name";
|
||||
private final static String ADDON_VENDOR = "vendor";
|
||||
private final static String ADDON_API = "api";
|
||||
private final static String ADDON_DESCRIPTION = "description";
|
||||
private final static String ADDON_LIBRARIES = "libraries";
|
||||
|
||||
private final static Pattern PATTERN_PROP = Pattern.compile(
|
||||
"^([a-zA-Z0-9._-]+)\\s*=\\s*(.*)\\s*$");
|
||||
|
||||
/** the location of the SDK */
|
||||
private final String mSdkLocation;
|
||||
private IAndroidTarget[] mTargets;
|
||||
|
||||
/**
|
||||
* Creates an {@link SdkManager} for a given sdk location.
|
||||
* @param sdkLocation the location of the SDK.
|
||||
* @param log the ISdkLog object receiving warning/error from the parsing.
|
||||
* @return the created {@link SdkManager} or null if the location is not valid.
|
||||
*/
|
||||
public static SdkManager createManager(String sdkLocation, ISdkLog log) {
|
||||
try {
|
||||
SdkManager manager = new SdkManager(sdkLocation);
|
||||
ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
|
||||
manager.loadPlatforms(list, log);
|
||||
manager.loadAddOns(list, log);
|
||||
|
||||
// sort the targets/add-ons
|
||||
Collections.sort(list);
|
||||
|
||||
manager.setTargets(list.toArray(new IAndroidTarget[list.size()]));
|
||||
|
||||
return manager;
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (log != null) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the SDK.
|
||||
*/
|
||||
public String getLocation() {
|
||||
return mSdkLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the targets that are available in the SDK.
|
||||
*/
|
||||
public IAndroidTarget[] getTargets() {
|
||||
return mTargets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a target from a hash that was generated by {@link IAndroidTarget#hashString()}.
|
||||
* @param hash the hash
|
||||
*/
|
||||
public IAndroidTarget getTargetFromHashString(String hash) {
|
||||
if (hash != null) {
|
||||
for (IAndroidTarget target : mTargets) {
|
||||
if (hash.equals(target.hashString())) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private SdkManager(String sdkLocation) {
|
||||
mSdkLocation = sdkLocation;
|
||||
}
|
||||
|
||||
private void setTargets(IAndroidTarget[] targets) {
|
||||
mTargets = targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Platforms from the SDK.
|
||||
* @param list the list to fill with the platforms.
|
||||
* @param log the ISdkLog object receiving warning/error from the parsing.
|
||||
*/
|
||||
private void loadPlatforms(ArrayList<IAndroidTarget> list, ISdkLog log) {
|
||||
File platformFolder = new File(mSdkLocation, SdkConstants.FD_PLATFORMS);
|
||||
if (platformFolder.isDirectory()) {
|
||||
File[] platforms = platformFolder.listFiles();
|
||||
|
||||
for (File platform : platforms) {
|
||||
if (platform.isDirectory()) {
|
||||
PlatformTarget target = loadPlatform(platform, log);
|
||||
if (target != null) {
|
||||
list.add(target);
|
||||
}
|
||||
} else if (log != null) {
|
||||
log.warning("Ignoring platform '%1$s', not a folder.", platform.getName());
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
String message = null;
|
||||
if (platformFolder.exists() == false) {
|
||||
message = "%s is missing.";
|
||||
} else {
|
||||
message = "%s is not a folder.";
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format(message,
|
||||
platformFolder.getAbsolutePath()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a specific Platform at a given location.
|
||||
* @param platform the location of the platform.
|
||||
* @param log the ISdkLog object receiving warning/error from the parsing.
|
||||
*/
|
||||
private PlatformTarget loadPlatform(File platform, ISdkLog log) {
|
||||
File buildProp = new File(platform, SdkConstants.FN_BUILD_PROP);
|
||||
|
||||
if (buildProp.isFile()) {
|
||||
Map<String, String> map = parsePropertyFile(buildProp, log);
|
||||
|
||||
if (map != null) {
|
||||
// look for some specific values in the map.
|
||||
try {
|
||||
String apiNumber = map.get(PROP_VERSION_SDK);
|
||||
String apiName = map.get(PROP_VERSION_RELEASE);
|
||||
if (apiNumber != null && apiName != null) {
|
||||
// create the target.
|
||||
PlatformTarget target = new PlatformTarget(
|
||||
platform.getAbsolutePath(),
|
||||
map,
|
||||
Integer.parseInt(apiNumber),
|
||||
apiName);
|
||||
|
||||
// need to parse the skins.
|
||||
String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS));
|
||||
target.setSkins(skins);
|
||||
|
||||
return target;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// looks like apiNumber does not parse to a number.
|
||||
// Ignore this platform.
|
||||
if (log != null) {
|
||||
log.error("Ignoring platform '%1$s': %2$s is not a valid number in %3$s.",
|
||||
platform.getName(), PROP_VERSION_SDK, SdkConstants.FN_BUILD_PROP);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (log != null) {
|
||||
log.error("Ignoring platform '%1$s': %2$s is missing.", platform.getName(),
|
||||
SdkConstants.FN_BUILD_PROP);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Add-on from the SDK.
|
||||
* @param list the list to fill with the add-ons.
|
||||
* @param log the ISdkLog object receiving warning/error from the parsing.
|
||||
*/
|
||||
private void loadAddOns(ArrayList<IAndroidTarget> list, ISdkLog log) {
|
||||
File addonFolder = new File(mSdkLocation, SdkConstants.FD_ADDONS);
|
||||
if (addonFolder.isDirectory()) {
|
||||
File[] addons = addonFolder.listFiles();
|
||||
|
||||
for (File addon : addons) {
|
||||
if (addon.isDirectory()) {
|
||||
AddOnTarget target = loadAddon(addon, list, log);
|
||||
if (target != null) {
|
||||
list.add(target);
|
||||
}
|
||||
} else if (log != null) {
|
||||
log.warning("Ignoring add-on '%1$s', not a folder.", addon.getName());
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
String message = null;
|
||||
if (addonFolder.exists() == false) {
|
||||
message = "%s is missing.";
|
||||
} else {
|
||||
message = "%s is not a folder.";
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format(message,
|
||||
addonFolder.getAbsolutePath()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a specific Add-on at a given location.
|
||||
* @param addon the location of the addon.
|
||||
* @param list
|
||||
* @param log
|
||||
*/
|
||||
private AddOnTarget loadAddon(File addon, ArrayList<IAndroidTarget> list, ISdkLog log) {
|
||||
File addOnManifest = new File(addon, SdkConstants.FN_MANIFEST_INI);
|
||||
|
||||
if (addOnManifest.isFile()) {
|
||||
Map<String, String> map = parsePropertyFile(addOnManifest, log);
|
||||
|
||||
if (map != null) {
|
||||
// look for some specific values in the map.
|
||||
// we require name, vendor, and api
|
||||
String name = map.get(ADDON_NAME);
|
||||
if (name == null) {
|
||||
displayAddonManifestError(log, addon.getName(), ADDON_NAME);
|
||||
return null;
|
||||
}
|
||||
|
||||
String vendor = map.get(ADDON_VENDOR);
|
||||
if (vendor == null) {
|
||||
displayAddonManifestError(log, addon.getName(), ADDON_VENDOR);
|
||||
return null;
|
||||
}
|
||||
|
||||
String api = map.get(ADDON_API);
|
||||
PlatformTarget baseTarget = null;
|
||||
if (api == null) {
|
||||
displayAddonManifestError(log, addon.getName(), ADDON_API);
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
int apiValue = Integer.parseInt(api);
|
||||
for (IAndroidTarget target : list) {
|
||||
if (target.isPlatform() &&
|
||||
target.getApiVersionNumber() == apiValue) {
|
||||
baseTarget = (PlatformTarget)target;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (baseTarget == null) {
|
||||
if (log != null) {
|
||||
log.error(
|
||||
"Ignoring add-on '%1$s': Unable to find base platform with API level %2$d",
|
||||
addon.getName(), apiValue);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// looks like apiNumber does not parse to a number.
|
||||
// Ignore this add-on.
|
||||
if (log != null) {
|
||||
log.error(
|
||||
"Ignoring add-on '%1$s': %2$s is not a valid number in %3$s.",
|
||||
addon.getName(), ADDON_API, SdkConstants.FN_BUILD_PROP);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// get the optional description
|
||||
String description = map.get(ADDON_DESCRIPTION);
|
||||
|
||||
// get the optional libraries
|
||||
String librariesValue = map.get(ADDON_LIBRARIES);
|
||||
|
||||
// split in the string into the values we care about
|
||||
String[] libraries = librariesValue.split(";");
|
||||
Map<String, String> libMap = null;
|
||||
if (libraries.length > 0) {
|
||||
libMap = new HashMap<String, String>();
|
||||
for (String lib : libraries) {
|
||||
String[] values = lib.split(":");
|
||||
if (values.length == 2) {
|
||||
libMap.put(values[0], values[1]);
|
||||
} else {
|
||||
// TODO: log error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddOnTarget target = new AddOnTarget(addon.getAbsolutePath(), name, vendor,
|
||||
description, libMap, baseTarget);
|
||||
|
||||
// need to parse the skins.
|
||||
String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS));
|
||||
target.setSkins(skins);
|
||||
|
||||
return target;
|
||||
}
|
||||
} else if (log != null) {
|
||||
log.error("Ignoring add-on '%1$s': %2$s is missing.", addon.getName(),
|
||||
SdkConstants.FN_MANIFEST_INI);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void displayAddonManifestError(ISdkLog log, String addonName, String valueName) {
|
||||
if (log != null) {
|
||||
log.error("Ignoring add-on '%1$s': '%2$s' is missing from %3$s.",
|
||||
addonName, valueName, SdkConstants.FN_MANIFEST_INI);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a property file and returns
|
||||
* @param buildProp the property file to parse
|
||||
* @param log the ISdkLog object receiving warning/error from the parsing.
|
||||
* @return the map of (key,value) pairs, or null if the parsing failed.
|
||||
*/
|
||||
public static Map<String, String> parsePropertyFile(File buildProp, ISdkLog log) {
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(buildProp);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
|
||||
|
||||
String line = null;
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.length() > 0 && line.charAt(0) != '#') {
|
||||
|
||||
Matcher m = PATTERN_PROP.matcher(line);
|
||||
if (m.matches()) {
|
||||
map.put(m.group(1), m.group(2));
|
||||
} else {
|
||||
log.warning("Error parsing '%1$s': \"%2$s\" is not a valid syntax",
|
||||
buildProp.getAbsolutePath(), line);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
} catch (FileNotFoundException e) {
|
||||
// this should not happen since we usually test the file existence before
|
||||
// calling the method.
|
||||
// Return null below.
|
||||
} catch (IOException e) {
|
||||
if (log != null) {
|
||||
log.warning("Error parsing '%1$s': %2$s.", buildProp.getAbsolutePath(),
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the skin folder and builds the skin list.
|
||||
* @param osPath The path of the skin root folder.
|
||||
*/
|
||||
private String[] parseSkinFolder(String osPath) {
|
||||
File skinRootFolder = new File(osPath);
|
||||
|
||||
if (skinRootFolder.isDirectory()) {
|
||||
ArrayList<String> skinList = new ArrayList<String>();
|
||||
|
||||
File[] files = skinRootFolder.listFiles();
|
||||
|
||||
for (File skinFolder : files) {
|
||||
if (skinFolder.isDirectory()) {
|
||||
// check for layout file
|
||||
File layout = new File(skinFolder, SdkConstants.FN_SKIN_LAYOUT);
|
||||
|
||||
if (layout.isFile()) {
|
||||
// for now we don't parse the content of the layout and
|
||||
// simply add the directory to the list.
|
||||
skinList.add(skinFolder.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return skinList.toArray(new String[skinList.size()]);
|
||||
}
|
||||
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.project;
|
||||
|
||||
import com.android.sdklib.SdkManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Class to load and save project properties for both ADT and Ant-based build.
|
||||
*
|
||||
*/
|
||||
public final class ProjectProperties {
|
||||
/** The property name for the project target */
|
||||
public final static String PROPERTY_TARGET = "target";
|
||||
public final static String PROPERTY_SDK = "sdk-folder";
|
||||
|
||||
private final static String PROPERTIES_FILE = "default.properties";
|
||||
|
||||
private final static String PROP_HEADER =
|
||||
"# This file is automatically generated by Android Tools.\n" +
|
||||
"# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n" +
|
||||
"# For customized properties when using Ant, set new values\n" +
|
||||
"# in a \"build.properties\" file.\n\n";
|
||||
|
||||
private final static Map<String, String> COMMENT_MAP = new HashMap<String, String>();
|
||||
static {
|
||||
COMMENT_MAP.put(PROPERTY_TARGET, "# Project target.\n");
|
||||
COMMENT_MAP.put(PROPERTY_SDK, "# location of the SDK. Only used by Ant.\n");
|
||||
}
|
||||
|
||||
private final String mProjectFolderOsPath;
|
||||
private final Map<String, String> mProperties;
|
||||
|
||||
/**
|
||||
* Loads a project properties file and return a {@link ProjectProperties} object
|
||||
* containing the properties
|
||||
* @param projectFolderOsPath the project folder.
|
||||
*/
|
||||
public static ProjectProperties load(String projectFolderOsPath) {
|
||||
File projectFolder = new File(projectFolderOsPath);
|
||||
if (projectFolder.isDirectory()) {
|
||||
File defaultFile = new File(projectFolder, PROPERTIES_FILE);
|
||||
if (defaultFile.isFile()) {
|
||||
Map<String, String> map = SdkManager.parsePropertyFile(defaultFile, null /* log */);
|
||||
if (map != null) {
|
||||
return new ProjectProperties(projectFolderOsPath, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new project properties file, with no properties.
|
||||
* <p/>The file is not created until {@link #save()} is called.
|
||||
* @param projectFolderOsPath the project folder.
|
||||
*/
|
||||
public static ProjectProperties create(String projectFolderOsPath) {
|
||||
// create and return a ProjectProperties with an empty map.
|
||||
return new ProjectProperties(projectFolderOsPath, new HashMap<String, String>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new properties. If a property with the same name already exists, it is replaced.
|
||||
* @param name the name of the property.
|
||||
* @param value the value of the property.
|
||||
*/
|
||||
public void setProperty(String name, String value) {
|
||||
mProperties.put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of a property.
|
||||
* @param name the name of the property.
|
||||
* @return the property value or null if the property is not set.
|
||||
*/
|
||||
public String getProperty(String name) {
|
||||
return mProperties.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the property file.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
File toSave = new File(mProjectFolderOsPath, PROPERTIES_FILE);
|
||||
|
||||
FileWriter writer = new FileWriter(toSave);
|
||||
|
||||
// write the header
|
||||
writer.write(PROP_HEADER);
|
||||
|
||||
// write the properties.
|
||||
for (Entry<String, String> entry : mProperties.entrySet()) {
|
||||
String comment = COMMENT_MAP.get(entry.getKey());
|
||||
if (comment != null) {
|
||||
writer.write(comment);
|
||||
}
|
||||
writer.write(String.format("%s=%s\n", entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
// close the file to flush
|
||||
writer.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
* Use {@link #load(String)} or {@link #create(String)} to instantiate.
|
||||
* @param projectFolderOsPath
|
||||
* @param map
|
||||
*/
|
||||
private ProjectProperties(String projectFolderOsPath, Map<String, String> map) {
|
||||
mProjectFolderOsPath = projectFolderOsPath;
|
||||
mProperties = map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.vm;
|
||||
|
||||
import com.android.sdklib.ISdkLog;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class HardwareProperties {
|
||||
private final static Pattern PATTERN_PROP = Pattern.compile(
|
||||
"^([a-zA-Z0-9._-]+)\\s*=\\s*(.*)\\s*$");
|
||||
|
||||
private final static String HW_PROP_NAME = "name";
|
||||
private final static String HW_PROP_TYPE = "type";
|
||||
private final static String HW_PROP_DEFAULT = "default";
|
||||
private final static String HW_PROP_ABSTRACT = "abstract";
|
||||
private final static String HW_PROP_DESC = "description";
|
||||
|
||||
public enum ValueType {
|
||||
INTEGER("integer"),
|
||||
BOOLEAN("boolean"),
|
||||
DISKSIZE("diskSize");
|
||||
|
||||
private String mValue;
|
||||
|
||||
ValueType(String value) {
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
public static ValueType getEnum(String value) {
|
||||
for (ValueType type : values()) {
|
||||
if (type.mValue.equals(value)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class HardwareProperty {
|
||||
private String mName;
|
||||
private ValueType mType;
|
||||
/** the string representation of the default value. can be null. */
|
||||
private String mDefault;
|
||||
private String mAbstract;
|
||||
private String mDescription;
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public ValueType getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public String getDefault() {
|
||||
return mDefault;
|
||||
}
|
||||
|
||||
public String getAbstract() {
|
||||
return mAbstract;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return mDescription;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the harware definition file.
|
||||
* @param buildProp the property file to parse
|
||||
* @param log the ISdkLog object receiving warning/error from the parsing.
|
||||
* @return the map of (key,value) pairs, or null if the parsing failed.
|
||||
*/
|
||||
public static List<HardwareProperty> parseHardwareDefinitions(File file, ISdkLog log) {
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
|
||||
|
||||
List<HardwareProperty> map = new ArrayList<HardwareProperty>();
|
||||
|
||||
String line = null;
|
||||
HardwareProperty prop = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.length() > 0 && line.charAt(0) != '#') {
|
||||
Matcher m = PATTERN_PROP.matcher(line);
|
||||
if (m.matches()) {
|
||||
String valueName = m.group(1);
|
||||
String value = m.group(2);
|
||||
|
||||
if (HW_PROP_NAME.equals(valueName)) {
|
||||
prop = new HardwareProperty();
|
||||
prop.mName = value;
|
||||
map.add(prop);
|
||||
}
|
||||
|
||||
if (prop == null) {
|
||||
log.warning("Error parsing '%1$s': missing '%2$s'",
|
||||
file.getAbsolutePath(), HW_PROP_NAME);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (HW_PROP_TYPE.equals(valueName)) {
|
||||
prop.mType = ValueType.getEnum(value);
|
||||
} else if (HW_PROP_DEFAULT.equals(valueName)) {
|
||||
prop.mDefault = value;
|
||||
} else if (HW_PROP_ABSTRACT.equals(valueName)) {
|
||||
prop.mAbstract = value;
|
||||
} else if (HW_PROP_DESC.equals(valueName)) {
|
||||
prop.mDescription = value;
|
||||
}
|
||||
} else {
|
||||
log.warning("Error parsing '%1$s': \"%2$s\" is not a valid syntax",
|
||||
file.getAbsolutePath(), line);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
} catch (FileNotFoundException e) {
|
||||
// this should not happen since we usually test the file existence before
|
||||
// calling the method.
|
||||
// Return null below.
|
||||
} catch (IOException e) {
|
||||
if (log != null) {
|
||||
log.warning("Error parsing '%1$s': %2$s.", file.getAbsolutePath(),
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* 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.vm;
|
||||
|
||||
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 java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Virtual Machine manager to access the list of VMs or create new ones.
|
||||
*/
|
||||
public final class VmManager {
|
||||
|
||||
private final static String VM_INFO_PATH = "path";
|
||||
private final static String VM_INFO_TARGET = "target";
|
||||
|
||||
private final static String IMAGE_USERDATA = "userdata.img";
|
||||
private final static String CONFIG_INI = "config.ini";
|
||||
|
||||
private final static Pattern INI_NAME_PATTERN = Pattern.compile("(.+)\\.ini$",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static final class VmInfo {
|
||||
String name;
|
||||
String path;
|
||||
IAndroidTarget target;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public IAndroidTarget getTarget() {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
private final ArrayList<VmInfo> mVmList = new ArrayList<VmInfo>();
|
||||
private ISdkLog mSdkLog;
|
||||
|
||||
public VmManager(SdkManager sdk, ISdkLog sdkLog) throws AndroidLocationException {
|
||||
mSdkLog = sdkLog;
|
||||
buildVmList(sdk);
|
||||
}
|
||||
|
||||
public VmInfo[] getVms() {
|
||||
return mVmList.toArray(new VmInfo[mVmList.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new VM.
|
||||
* @param parentFolder the folder to contain the VM. A new folder will be created in this
|
||||
* folder with the name of the VM
|
||||
* @param name the name of the VM
|
||||
* @param target the target of the VM
|
||||
* @param skinName the name of the skin. Can be null.
|
||||
* @param sdcardPath the path to the sdCard. Can be null.
|
||||
* @param sdcardSize the size of a local sdcard to create. Can be 0 for no local sdcard.
|
||||
* @param hardwareConfig the hardware setup for the VM
|
||||
*/
|
||||
public static void createVm(String parentFolder, String name, IAndroidTarget target,
|
||||
String skinName, String sdcardPath, int sdcardSize, Map<String,String> hardwareConfig,
|
||||
ISdkLog log) {
|
||||
|
||||
// now write the ini file in the vmRoot folder.
|
||||
// get the Android prefs location.
|
||||
try {
|
||||
File rootDirectory = new File(parentFolder);
|
||||
if (rootDirectory.isDirectory() == false) {
|
||||
if (log != null) {
|
||||
log.error("%s does not exists.", parentFolder);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
File vmFolder = new File(parentFolder, name + ".avm");
|
||||
if (vmFolder.exists()) {
|
||||
if (log != null) {
|
||||
log.error("%s already exists.", vmFolder.getAbsolutePath());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// create the vm folder.
|
||||
vmFolder.mkdir();
|
||||
|
||||
HashMap<String, String> values = new HashMap<String, String>();
|
||||
|
||||
// prepare the ini file.
|
||||
String vmRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_VMS;
|
||||
File iniFile = new File(vmRoot, name + ".ini");
|
||||
values.put(VM_INFO_PATH, vmFolder.getAbsolutePath());
|
||||
values.put(VM_INFO_TARGET, target.hashString());
|
||||
createConfigIni(iniFile, values);
|
||||
|
||||
// writes the userdata.img in it.
|
||||
String imagePath = target.getPath(IAndroidTarget.IMAGES);
|
||||
File userdataSrc = new File(imagePath, IMAGE_USERDATA);
|
||||
FileInputStream fis = new FileInputStream(userdataSrc);
|
||||
|
||||
File userdataDest = new File(vmFolder, IMAGE_USERDATA);
|
||||
FileOutputStream fos = new FileOutputStream(userdataDest);
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int count;
|
||||
while ((count = fis.read(buffer)) != -1) {
|
||||
fos.write(buffer, 0, count);
|
||||
}
|
||||
|
||||
fos.close();
|
||||
fis.close();
|
||||
|
||||
// Config file
|
||||
values.clear();
|
||||
if (skinName != null) {
|
||||
values.put("skin", skinName);
|
||||
} else {
|
||||
values.put("skin", SdkConstants.SKIN_DEFAULT);
|
||||
}
|
||||
|
||||
if (sdcardPath != null) {
|
||||
values.put("sdcard", sdcardPath);
|
||||
} else if (sdcardSize != 0) {
|
||||
// TODO: create sdcard image.
|
||||
}
|
||||
|
||||
if (hardwareConfig != null) {
|
||||
values.putAll(hardwareConfig);
|
||||
}
|
||||
|
||||
File configIniFile = new File(vmFolder, CONFIG_INI);
|
||||
createConfigIni(configIniFile, values);
|
||||
|
||||
if (target.isPlatform()) {
|
||||
System.out.println(String.format(
|
||||
"Created VM '%s' based on %s", name, target.getName()));
|
||||
} else {
|
||||
System.out.println(String.format(
|
||||
"Created VM '%s' based on %s (%s)", name, target.getName(),
|
||||
target.getVendor()));
|
||||
}
|
||||
} catch (AndroidLocationException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void buildVmList(SdkManager sdk) throws AndroidLocationException {
|
||||
// get the Android prefs location.
|
||||
String vmRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_VMS;
|
||||
|
||||
// ensure folder validity.
|
||||
File folder = new File(vmRoot);
|
||||
if (folder.isFile()) {
|
||||
throw new AndroidLocationException(String.format("%s is not a valid folder.", vmRoot));
|
||||
} else if (folder.exists() == false) {
|
||||
// folder is not there, we create it and return
|
||||
folder.mkdirs();
|
||||
return;
|
||||
}
|
||||
|
||||
File[] vms = folder.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File parent, String name) {
|
||||
if (INI_NAME_PATTERN.matcher(name).matches()) {
|
||||
// check it's a file and not a folder
|
||||
return new File(parent, name).isFile();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
for (File vm : vms) {
|
||||
VmInfo info = parseVmInfo(vm, sdk);
|
||||
if (info != null) {
|
||||
mVmList.add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VmInfo parseVmInfo(File path, SdkManager sdk) {
|
||||
Map<String, String> map = SdkManager.parsePropertyFile(path, mSdkLog);
|
||||
|
||||
String vmPath = map.get(VM_INFO_PATH);
|
||||
if (vmPath == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String targetHash = map.get(VM_INFO_TARGET);
|
||||
if (targetHash == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IAndroidTarget target = sdk.getTargetFromHashString(targetHash);
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
VmInfo info = new VmInfo();
|
||||
Matcher matcher = INI_NAME_PATTERN.matcher(path.getName());
|
||||
if (matcher.matches()) {
|
||||
info.name = matcher.group(1);
|
||||
} else {
|
||||
info.name = path.getName(); // really this should not happen.
|
||||
}
|
||||
info.path = vmPath;
|
||||
info.target = target;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private static void createConfigIni(File iniFile, Map<String, String> values)
|
||||
throws IOException {
|
||||
FileWriter writer = new FileWriter(iniFile);
|
||||
|
||||
for (Entry<String, String> entry : values.entrySet()) {
|
||||
writer.write(String.format("%s=%s\n", entry.getKey(), entry.getValue()));
|
||||
}
|
||||
writer.close();
|
||||
|
||||
}
|
||||
}
|
||||
4
tools/sdkmanager/libs/sdkuilib/Android.mk
Normal file
4
tools/sdkmanager/libs/sdkuilib/Android.mk
Normal file
@@ -0,0 +1,4 @@
|
||||
# Copyright 2008 The Android Open Source Project
|
||||
#
|
||||
SDKUILIB_LOCAL_DIR := $(call my-dir)
|
||||
include $(SDKUILIB_LOCAL_DIR)/src/Android.mk
|
||||
11
tools/sdkmanager/libs/sdkuilib/README
Normal file
11
tools/sdkmanager/libs/sdkuilib/README
Normal file
@@ -0,0 +1,11 @@
|
||||
Using the Eclipse projects for ddmuilib.
|
||||
|
||||
ddmuilib requires SWT to compile.
|
||||
|
||||
SWT is available in the depot under prebuild/<platform>/swt
|
||||
|
||||
Because the build path cannot contain relative path that are not inside the project directory,
|
||||
the .classpath file references a user library called ANDROID_SWT.
|
||||
|
||||
In order to compile the project, make a user library called ANDROID_SWT containing the jar
|
||||
available at prebuild/<platform>/swt.
|
||||
21
tools/sdkmanager/libs/sdkuilib/src/Android.mk
Normal file
21
tools/sdkmanager/libs/sdkuilib/src/Android.mk
Normal file
@@ -0,0 +1,21 @@
|
||||
# Copyright 2008 The Android Open Source Project
|
||||
#
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
|
||||
# no resources yet.
|
||||
# LOCAL_JAVA_RESOURCE_DIRS := resources
|
||||
|
||||
LOCAL_JAVA_LIBRARIES := \
|
||||
sdklib \
|
||||
swt \
|
||||
org.eclipse.jface_3.2.0.I20060605-1400 \
|
||||
org.eclipse.equinox.common_3.2.0.v20060603 \
|
||||
org.eclipse.core.commands_3.2.0.I20060605-1400
|
||||
|
||||
LOCAL_MODULE := sdkuilib
|
||||
|
||||
include $(BUILD_HOST_JAVA_LIBRARY)
|
||||
|
||||
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
|
||||
*
|
||||
* 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.sdkuilib;
|
||||
|
||||
import com.android.sdklib.IAndroidTarget;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ControlAdapter;
|
||||
import org.eclipse.swt.events.ControlEvent;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableColumn;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* The SDK target selector is a table that is added to the given parent composite.
|
||||
*/
|
||||
public class SdkTargetSelector {
|
||||
|
||||
private final IAndroidTarget[] mTargets;
|
||||
private final boolean mAllowMultipleSelection;
|
||||
private SelectionListener mSelectionListener;
|
||||
private Table mTable;
|
||||
private Label mDescription;
|
||||
|
||||
public SdkTargetSelector(Composite parent, IAndroidTarget[] targets,
|
||||
boolean allowMultipleSelection) {
|
||||
mTargets = targets;
|
||||
|
||||
// Layout has 1 column
|
||||
Composite group = new Composite(parent, SWT.NONE);
|
||||
group.setLayout(new GridLayout());
|
||||
group.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||
group.setFont(parent.getFont());
|
||||
|
||||
mAllowMultipleSelection = allowMultipleSelection;
|
||||
mTable = new Table(group, SWT.CHECK | SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
|
||||
mTable.setHeaderVisible(true);
|
||||
mTable.setLinesVisible(false);
|
||||
|
||||
GridData data = new GridData();
|
||||
data.grabExcessVerticalSpace = true;
|
||||
data.grabExcessHorizontalSpace = true;
|
||||
data.horizontalAlignment = GridData.FILL;
|
||||
data.verticalAlignment = GridData.FILL;
|
||||
mTable.setLayoutData(data);
|
||||
|
||||
mDescription = new Label(group, SWT.WRAP);
|
||||
mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
|
||||
// create the table columns
|
||||
final TableColumn column0 = new TableColumn(mTable, SWT.NONE);
|
||||
column0.setText("SDK Target");
|
||||
final TableColumn column1 = new TableColumn(mTable, SWT.NONE);
|
||||
column1.setText("Vendor");
|
||||
final TableColumn column2 = new TableColumn(mTable, SWT.NONE);
|
||||
column2.setText("API Level");
|
||||
|
||||
adjustColumnsWidth(mTable, column0, column1, column2);
|
||||
setupSelectionListener(mTable);
|
||||
fillTable(mTable);
|
||||
setupTooltip(mTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a selection listener. Set it to null to remove it.
|
||||
* The listener will be called <em>after</em> this table processed its selection
|
||||
* events so that the caller can see the updated state.
|
||||
* <p/>
|
||||
* The event's item contains a {@link TableItem}.
|
||||
* The {@link TableItem#getData()} contains an {@link IAndroidTarget}.
|
||||
* <p/>
|
||||
* It is recommended that the caller uses the {@link #getFirstSelected()} and
|
||||
* {@link #getAllSelected()} methods instead.
|
||||
*
|
||||
* @param selectionListener The new listener or null to remove it.
|
||||
*/
|
||||
public void setSelectionListener(SelectionListener selectionListener) {
|
||||
mSelectionListener = selectionListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current target selection.
|
||||
* @param target the target to be selection
|
||||
* @return true if the target could be selected, false otherwise.
|
||||
*/
|
||||
public boolean setSelection(IAndroidTarget target) {
|
||||
boolean found = false;
|
||||
for (TableItem i : mTable.getItems()) {
|
||||
if ((IAndroidTarget) i.getData() == target) {
|
||||
found = true;
|
||||
i.setChecked(true);
|
||||
} else {
|
||||
i.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all selected items.
|
||||
* This is useful when the table is in multiple-selection mode.
|
||||
*
|
||||
* @see #getFirstSelected()
|
||||
* @return An array of selected items. The list can be empty but not null.
|
||||
*/
|
||||
public IAndroidTarget[] getAllSelected() {
|
||||
ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
|
||||
for (TableItem i : mTable.getItems()) {
|
||||
if (i.getChecked()) {
|
||||
list.add((IAndroidTarget) i.getData());
|
||||
}
|
||||
}
|
||||
return list.toArray(new IAndroidTarget[list.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first selected item.
|
||||
* This is useful when the table is in single-selection mode.
|
||||
*
|
||||
* @see #getAllSelected()
|
||||
* @return The first selected item or null.
|
||||
*/
|
||||
public IAndroidTarget getFirstSelected() {
|
||||
for (TableItem i : mTable.getItems()) {
|
||||
if (i.getChecked()) {
|
||||
return (IAndroidTarget) i.getData();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to adjust the columns width when the parent is resized.
|
||||
* <p/>
|
||||
* If we need something more fancy, we might want to use this:
|
||||
* http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co
|
||||
*/
|
||||
private void adjustColumnsWidth(final Table table,
|
||||
final TableColumn column0,
|
||||
final TableColumn column1,
|
||||
final TableColumn column2) {
|
||||
// Add a listener to resize the column to the full width of the table
|
||||
table.addControlListener(new ControlAdapter() {
|
||||
@Override
|
||||
public void controlResized(ControlEvent e) {
|
||||
Rectangle r = table.getClientArea();
|
||||
column0.setWidth(r.width * 3 / 10); // 30%
|
||||
column1.setWidth(r.width * 5 / 10); // 50%
|
||||
column2.setWidth(r.width * 2 / 10); // 20%
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a selection listener that will check or uncheck the whole line when
|
||||
* double-clicked (aka "the default selection").
|
||||
*/
|
||||
private void setupSelectionListener(final Table table) {
|
||||
// Add a selection listener that will check/uncheck items when they are double-clicked
|
||||
table.addSelectionListener(new SelectionListener() {
|
||||
/** Default selection means double-click on "most" platforms */
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
if (e.item instanceof TableItem) {
|
||||
TableItem i = (TableItem) e.item;
|
||||
i.setChecked(!i.getChecked());
|
||||
enforceSingleSelection(i);
|
||||
updateDescription(i);
|
||||
}
|
||||
|
||||
if (mSelectionListener != null) {
|
||||
mSelectionListener.widgetDefaultSelected(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
if (e.item instanceof TableItem) {
|
||||
TableItem i = (TableItem) e.item;
|
||||
enforceSingleSelection(i);
|
||||
updateDescription(i);
|
||||
}
|
||||
|
||||
if (mSelectionListener != null) {
|
||||
mSelectionListener.widgetSelected(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we're not in multiple selection mode, uncheck all other
|
||||
* items when this one is selected.
|
||||
*/
|
||||
private void enforceSingleSelection(TableItem item) {
|
||||
if (!mAllowMultipleSelection && item.getChecked()) {
|
||||
Table parentTable = item.getParent();
|
||||
for (TableItem i2 : parentTable.getItems()) {
|
||||
if (i2 != item && i2.getChecked()) {
|
||||
i2.setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fills the table with all SDK targets.
|
||||
* The table columns are:
|
||||
* <ul>
|
||||
* <li>column 0: sdk name
|
||||
* <li>column 1: sdk vendor
|
||||
* <li>column 2: sdk api name
|
||||
* </ul>
|
||||
*/
|
||||
private void fillTable(final Table table) {
|
||||
if (mTargets != null && mTargets.length > 0) {
|
||||
table.setEnabled(true);
|
||||
for (IAndroidTarget target : mTargets) {
|
||||
TableItem item = new TableItem(table, SWT.NONE);
|
||||
item.setData(target);
|
||||
item.setText(0, target.getName());
|
||||
item.setText(1, target.getVendor());
|
||||
item.setText(2, target.getApiVersionName());
|
||||
}
|
||||
} else {
|
||||
table.setEnabled(false);
|
||||
TableItem item = new TableItem(table, SWT.NONE);
|
||||
item.setData(null);
|
||||
item.setText(0, "--");
|
||||
item.setText(1, "No target available");
|
||||
item.setText(2, "--");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a tooltip that displays the current item description.
|
||||
* <p/>
|
||||
* Displaying a tooltip over the table looks kind of odd here. Instead we actually
|
||||
* display the description in a label under the table.
|
||||
*/
|
||||
private void setupTooltip(final Table table) {
|
||||
/*
|
||||
* Reference:
|
||||
* http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup
|
||||
*/
|
||||
|
||||
final Listener listener = new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
|
||||
switch(event.type) {
|
||||
case SWT.KeyDown:
|
||||
case SWT.MouseExit:
|
||||
case SWT.MouseDown:
|
||||
return;
|
||||
|
||||
case SWT.MouseHover:
|
||||
updateDescription(table.getItem(new Point(event.x, event.y)));
|
||||
break;
|
||||
|
||||
case SWT.Selection:
|
||||
if (event.item instanceof TableItem) {
|
||||
updateDescription((TableItem) event.item);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
table.addListener(SWT.Dispose, listener);
|
||||
table.addListener(SWT.KeyDown, listener);
|
||||
table.addListener(SWT.MouseMove, listener);
|
||||
table.addListener(SWT.MouseHover, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the description label with the description of the item's android target, if any.
|
||||
*/
|
||||
private void updateDescription(TableItem item) {
|
||||
if (item != null) {
|
||||
Object data = item.getData();
|
||||
if (data instanceof IAndroidTarget) {
|
||||
String newTooltip = ((IAndroidTarget) data).getDescription();
|
||||
mDescription.setText(newTooltip == null ? "" : newTooltip); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user