blob: 48259775bc955d34a7794aa74e159f93fba1b181 [file] [log] [blame]
/*
* 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.internal.androidTarget;
import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.sdklib.AndroidTargetHash;
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.ISystemImage;
import com.android.sdklib.SdkManager.LayoutlibVersion;
import com.android.sdklib.repository.descriptors.IdDisplay;
import com.android.utils.SparseArray;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Represents a platform target in the SDK.
*/
public final class PlatformTarget implements IAndroidTarget {
private static final String PLATFORM_VENDOR = "Android Open Source Project";
private static final String PLATFORM_NAME = "Android %s";
private static final String PLATFORM_NAME_PREVIEW = "Android %s (Preview)";
/** the OS path to the root folder of the platform component. */
private final String mRootFolderOsPath;
private final String mName;
private final AndroidVersion mVersion;
private final String mVersionName;
private final int mRevision;
private final Map<String, String> mProperties;
private final SparseArray<String> mPaths = new SparseArray<String>();
private File[] mSkins;
private final ISystemImage[] mSystemImages;
private final LayoutlibVersion mLayoutlibVersion;
private final BuildToolInfo mBuildToolInfo;
/**
* Creates a Platform target.
*
* @param sdkOsPath the root folder of the SDK
* @param platformOSPath the root folder of the platform component
* @param apiVersion the API Level + codename.
* @param versionName the version name of the platform.
* @param revision the revision of the platform component.
* @param layoutlibVersion The {@link LayoutlibVersion}. May be null.
* @param systemImages list of supported system images
* @param properties the platform properties
*/
public PlatformTarget(
String sdkOsPath,
String platformOSPath,
AndroidVersion apiVersion,
String versionName,
int revision,
LayoutlibVersion layoutlibVersion,
ISystemImage[] systemImages,
Map<String, String> properties,
@NonNull BuildToolInfo buildToolInfo) {
if (!platformOSPath.endsWith(File.separator)) {
platformOSPath = platformOSPath + File.separator;
}
mRootFolderOsPath = platformOSPath;
mProperties = Collections.unmodifiableMap(properties);
mVersion = apiVersion;
mVersionName = versionName;
mRevision = revision;
mLayoutlibVersion = layoutlibVersion;
mBuildToolInfo = buildToolInfo;
mSystemImages = systemImages == null ? new ISystemImage[0] : systemImages;
Arrays.sort(mSystemImages);
if (mVersion.isPreview()) {
mName = String.format(PLATFORM_NAME_PREVIEW, mVersionName);
} else {
mName = String.format(PLATFORM_NAME, mVersionName);
}
// pre-build the path to the platform components
mPaths.put(ANDROID_JAR, mRootFolderOsPath + SdkConstants.FN_FRAMEWORK_LIBRARY);
mPaths.put(UI_AUTOMATOR_JAR, mRootFolderOsPath + SdkConstants.FN_UI_AUTOMATOR_LIBRARY);
mPaths.put(SOURCES, mRootFolderOsPath + SdkConstants.FD_ANDROID_SOURCES);
mPaths.put(ANDROID_AIDL, mRootFolderOsPath + SdkConstants.FN_FRAMEWORK_AIDL);
mPaths.put(SAMPLES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_SAMPLES_FOLDER);
mPaths.put(SKINS, mRootFolderOsPath + SdkConstants.OS_SKINS_FOLDER);
mPaths.put(TEMPLATES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_TEMPLATES_FOLDER);
mPaths.put(DATA, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER);
mPaths.put(ATTRIBUTES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_ATTRS_XML);
mPaths.put(MANIFEST_ATTRIBUTES,
mRootFolderOsPath + SdkConstants.OS_PLATFORM_ATTRS_MANIFEST_XML);
mPaths.put(RESOURCES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_RESOURCES_FOLDER);
mPaths.put(FONTS, mRootFolderOsPath + SdkConstants.OS_PLATFORM_FONTS_FOLDER);
mPaths.put(LAYOUT_LIB, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER +
SdkConstants.FN_LAYOUTLIB_JAR);
mPaths.put(WIDGETS, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER +
SdkConstants.FN_WIDGETS);
mPaths.put(ACTIONS_ACTIVITY, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER +
SdkConstants.FN_INTENT_ACTIONS_ACTIVITY);
mPaths.put(ACTIONS_BROADCAST, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER +
SdkConstants.FN_INTENT_ACTIONS_BROADCAST);
mPaths.put(ACTIONS_SERVICE, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER +
SdkConstants.FN_INTENT_ACTIONS_SERVICE);
mPaths.put(CATEGORIES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER +
SdkConstants.FN_INTENT_CATEGORIES);
mPaths.put(ANT, mRootFolderOsPath + SdkConstants.OS_PLATFORM_ANT_FOLDER);
}
/**
* Returns the {@link LayoutlibVersion}. May be null.
*/
public LayoutlibVersion getLayoutlibVersion() {
return mLayoutlibVersion;
}
@Override
@Nullable
public ISystemImage getSystemImage(@NonNull IdDisplay tag, @NonNull String abiType) {
for (ISystemImage sysImg : mSystemImages) {
if (sysImg.getTag().equals(tag) && sysImg.getAbiType().equals(abiType)) {
return sysImg;
}
}
return null;
}
@Override
public ISystemImage[] getSystemImages() {
return mSystemImages;
}
@Override
public String getLocation() {
return mRootFolderOsPath;
}
/**
* {@inheritDoc}
* <p/>
* For Platform, the vendor name is always "Android".
*
* @see com.android.sdklib.IAndroidTarget#getVendor()
*/
@Override
public String getVendor() {
return PLATFORM_VENDOR;
}
@Override
public String getName() {
return mName;
}
@Override
public String getFullName() {
return mName;
}
@Override
public String getClasspathName() {
return mName;
}
@Override
public String getShortClasspathName() {
return mName;
}
/*
* (non-Javadoc)
*
* Description for the Android platform is dynamically generated.
*
* @see com.android.sdklib.IAndroidTarget#getDescription()
*/
@Override
public String getDescription() {
return String.format("Standard Android platform %s", mVersionName);
}
@NonNull
@Override
public AndroidVersion getVersion() {
return mVersion;
}
@Override
public String getVersionName() {
return mVersionName;
}
@Override
public int getRevision() {
return mRevision;
}
@Override
public boolean isPlatform() {
return true;
}
@Override
public IAndroidTarget getParent() {
return null;
}
@Override
public String getPath(int pathId) {
return mPaths.get(pathId);
}
@Override
public File getFile(int pathId) {
return new File(getPath(pathId));
}
@Override
public BuildToolInfo getBuildToolInfo() {
return mBuildToolInfo;
}
@Override @NonNull
public List<String> getBootClasspath() {
return Collections.singletonList(getPath(IAndroidTarget.ANDROID_JAR));
}
/**
* Returns whether the target is able to render layouts. This is always true for platforms.
*/
@Override
public boolean hasRenderingLibrary() {
return true;
}
@NonNull
@Override
public File[] getSkins() {
return mSkins;
}
@Nullable
@Override
public File getDefaultSkin() {
// only one skin? easy.
if (mSkins.length == 1) {
return mSkins[0];
}
// look for the skin name in the platform props
String skinName = mProperties.get(SdkConstants.PROP_SDK_DEFAULT_SKIN);
if (skinName == null) {
// otherwise try to find a good default.
if (mVersion.getApiLevel() >= 4) {
// at this time, this is the default skin for all older platforms that had 2+ skins.
skinName = "WVGA800"; //$NON-NLS-1$
} else {
skinName = "HVGA"; // this is for 1.5 and earlier. //$NON-NLS-1$
}
}
return new File(getFile(IAndroidTarget.SKINS), skinName);
}
/**
* Always returns null, as a standard platform ha no optional libraries.
*
* {@inheritDoc}
* @see com.android.sdklib.IAndroidTarget#getOptionalLibraries()
*/
@Override
public IOptionalLibrary[] getOptionalLibraries() {
return null;
}
/**
* Currently always return a fixed list with "android.test.runner" in it.
* <p/>
* TODO change the fixed library list to be build-dependent later.
* {@inheritDoc}
*/
@Override
public String[] getPlatformLibraries() {
return new String[] { SdkConstants.ANDROID_TEST_RUNNER_LIB };
}
/**
* The platform has no USB Vendor Id: always return {@link IAndroidTarget#NO_USB_ID}.
* {@inheritDoc}
*/
@Override
public int getUsbVendorId() {
return NO_USB_ID;
}
@Override
public boolean canRunOn(IAndroidTarget target) {
// basic test
if (target == this) {
return true;
}
// if the platform has a codename (ie it's a preview of an upcoming platform), then
// both platforms must be exactly identical.
if (mVersion.getCodename() != null) {
return mVersion.equals(target.getVersion());
}
// target is compatible wit the receiver as long as its api version number is greater or
// equal.
return target.getVersion().getApiLevel() >= mVersion.getApiLevel();
}
@Override
public String hashString() {
return AndroidTargetHash.getPlatformHashString(mVersion);
}
@Override
public int hashCode() {
return hashString().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof PlatformTarget) {
PlatformTarget platform = (PlatformTarget)obj;
return mVersion.equals(platform.getVersion());
}
return false;
}
/*
* Order by API level (preview/n count as between n and n+1).
* At the same API level, order as: Platform first, then add-on ordered by vendor and then name
* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(IAndroidTarget target) {
// quick check.
if (this == target) {
return 0;
}
int versionDiff = mVersion.compareTo(target.getVersion());
// only if the version are the same do we care about add-ons.
if (versionDiff == 0) {
// platforms go before add-ons.
if (target.isPlatform() == false) {
return -1;
}
}
return versionDiff;
}
/**
* Returns a string representation suitable for debugging.
* The representation is not intended for display to the user.
*
* The representation is also purposely compact. It does not describe _all_ the properties
* of the target, only a few key ones.
*
* @see #getDescription()
*/
@Override
public String toString() {
return String.format("PlatformTarget %1$s rev %2$d", //$NON-NLS-1$
getVersion(),
getRevision());
}
@Override
public String getProperty(String name) {
return mProperties.get(name);
}
@Override
public Integer getProperty(String name, Integer defaultValue) {
try {
String value = getProperty(name);
if (value != null) {
return Integer.decode(value);
}
} catch (NumberFormatException e) {
// ignore, return default value;
}
return defaultValue;
}
@Override
public Boolean getProperty(String name, Boolean defaultValue) {
String value = getProperty(name);
if (value != null) {
return Boolean.valueOf(value);
}
return defaultValue;
}
@Override
public Map<String, String> getProperties() {
return mProperties; // mProperties is unmodifiable.
}
// ---- platform only methods.
public void setSkins(@NonNull File[] skins) {
mSkins = skins;
Arrays.sort(mSkins);
}
public void setSamplesPath(String osLocation) {
mPaths.put(SAMPLES, osLocation);
}
public void setSourcesPath(String osLocation) {
mPaths.put(SOURCES, osLocation);
}
}