Code drop from //branches/cupcake/...@124589

This commit is contained in:
The Android Open Source Project
2008-12-17 18:04:04 -08:00
parent 5c11852110
commit e943f2fd8e
659 changed files with 47382 additions and 9976 deletions

View 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

View 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>

View 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>

View 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

View 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)

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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";
}

View File

@@ -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];
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View 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

View 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.

View 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)

View File

@@ -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$
}
}
}
}