| /* |
| * 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); |
| } |
| } |