1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.sdklib; 18 19 import com.android.sdklib.SdkManager.LayoutlibVersion; 20 import com.android.sdklib.util.SparseArray; 21 22 import java.io.File; 23 import java.util.Arrays; 24 import java.util.Collections; 25 import java.util.Map; 26 27 /** 28 * Represents a platform target in the SDK. 29 */ 30 final class PlatformTarget implements IAndroidTarget { 31 /** String used to get a hash to the platform target */ 32 private final static String PLATFORM_HASH = "android-%s"; 33 34 private final static String PLATFORM_VENDOR = "Android Open Source Project"; 35 36 private final static String PLATFORM_NAME = "Android %s"; 37 private final static String PLATFORM_NAME_PREVIEW = "Android %s (Preview)"; 38 39 /** the OS path to the root folder of the platform component. */ 40 private final String mRootFolderOsPath; 41 private final String mName; 42 private final AndroidVersion mVersion; 43 private final String mVersionName; 44 private final int mRevision; 45 private final Map<String, String> mProperties; 46 private final SparseArray<String> mPaths = new SparseArray<String>(); 47 private String[] mSkins; 48 private final ISystemImage[] mSystemImages; 49 private final LayoutlibVersion mLayoutlibVersion; 50 51 /** 52 * Creates a Platform target. 53 * 54 * @param sdkOsPath the root folder of the SDK 55 * @param platformOSPath the root folder of the platform component 56 * @param apiLevel the API Level 57 * @param codeName the codename. can be null. 58 * @param versionName the version name of the platform. 59 * @param revision the revision of the platform component. 60 * @param layoutlibVersion The {@link LayoutlibVersion}. May be null. 61 * @param systemImages list of supported system images 62 * @param properties the platform properties 63 */ 64 @SuppressWarnings("deprecation") 65 PlatformTarget( 66 String sdkOsPath, 67 String platformOSPath, 68 int apiLevel, 69 String codeName, 70 String versionName, 71 int revision, 72 LayoutlibVersion layoutlibVersion, 73 ISystemImage[] systemImages, 74 Map<String, String> properties) { 75 if (platformOSPath.endsWith(File.separator) == false) { 76 platformOSPath = platformOSPath + File.separator; 77 } 78 mRootFolderOsPath = platformOSPath; 79 mProperties = Collections.unmodifiableMap(properties); 80 mVersion = new AndroidVersion(apiLevel, codeName); 81 mVersionName = versionName; 82 mRevision = revision; 83 mLayoutlibVersion = layoutlibVersion; 84 mSystemImages = systemImages == null ? new ISystemImage[0] : systemImages; 85 Arrays.sort(mSystemImages); 86 87 if (mVersion.isPreview()) { 88 mName = String.format(PLATFORM_NAME_PREVIEW, mVersionName); 89 } else { 90 mName = String.format(PLATFORM_NAME, mVersionName); 91 } 92 93 // pre-build the path to the platform components 94 mPaths.put(ANDROID_JAR, mRootFolderOsPath + SdkConstants.FN_FRAMEWORK_LIBRARY); 95 mPaths.put(SOURCES, mRootFolderOsPath + SdkConstants.FD_ANDROID_SOURCES); 96 mPaths.put(ANDROID_AIDL, mRootFolderOsPath + SdkConstants.FN_FRAMEWORK_AIDL); 97 mPaths.put(SAMPLES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_SAMPLES_FOLDER); 98 mPaths.put(SKINS, mRootFolderOsPath + SdkConstants.OS_SKINS_FOLDER); 99 mPaths.put(TEMPLATES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_TEMPLATES_FOLDER); 100 mPaths.put(DATA, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER); 101 mPaths.put(ATTRIBUTES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_ATTRS_XML); 102 mPaths.put(MANIFEST_ATTRIBUTES, 103 mRootFolderOsPath + SdkConstants.OS_PLATFORM_ATTRS_MANIFEST_XML); 104 mPaths.put(RESOURCES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_RESOURCES_FOLDER); 105 mPaths.put(FONTS, mRootFolderOsPath + SdkConstants.OS_PLATFORM_FONTS_FOLDER); 106 mPaths.put(LAYOUT_LIB, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + 107 SdkConstants.FN_LAYOUTLIB_JAR); 108 mPaths.put(WIDGETS, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + 109 SdkConstants.FN_WIDGETS); 110 mPaths.put(ACTIONS_ACTIVITY, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + 111 SdkConstants.FN_INTENT_ACTIONS_ACTIVITY); 112 mPaths.put(ACTIONS_BROADCAST, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + 113 SdkConstants.FN_INTENT_ACTIONS_BROADCAST); 114 mPaths.put(ACTIONS_SERVICE, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + 115 SdkConstants.FN_INTENT_ACTIONS_SERVICE); 116 mPaths.put(CATEGORIES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + 117 SdkConstants.FN_INTENT_CATEGORIES); 118 mPaths.put(ANT, mRootFolderOsPath + SdkConstants.OS_PLATFORM_ANT_FOLDER); 119 120 // location for aapt, aidl, dx is now in the platform-tools folder. 121 mPaths.put(AAPT, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + 122 SdkConstants.FN_AAPT); 123 mPaths.put(AIDL, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + 124 SdkConstants.FN_AIDL); 125 mPaths.put(DX, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + 126 SdkConstants.FN_DX); 127 mPaths.put(DX_JAR, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_LIB_FOLDER + 128 SdkConstants.FN_DX_JAR); 129 mPaths.put(ANDROID_RS, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + 130 SdkConstants.OS_FRAMEWORK_RS); 131 mPaths.put(ANDROID_RS_CLANG, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + 132 SdkConstants.OS_FRAMEWORK_RS_CLANG); 133 } 134 135 /** 136 * Returns the {@link LayoutlibVersion}. May be null. 137 */ 138 public LayoutlibVersion getLayoutlibVersion() { 139 return mLayoutlibVersion; 140 } 141 142 public ISystemImage getSystemImage(String abiType) { 143 for (ISystemImage sysImg : mSystemImages) { 144 if (sysImg.getAbiType().equals(abiType)) { 145 return sysImg; 146 } 147 } 148 return null; 149 } 150 151 public ISystemImage[] getSystemImages() { 152 return mSystemImages; 153 } 154 155 public String getLocation() { 156 return mRootFolderOsPath; 157 } 158 159 /** 160 * {@inheritDoc} 161 * <p/> 162 * For Platform, the vendor name is always "Android". 163 * 164 * @see com.android.sdklib.IAndroidTarget#getVendor() 165 */ 166 public String getVendor() { 167 return PLATFORM_VENDOR; 168 } 169 170 public String getName() { 171 return mName; 172 } 173 174 public String getFullName() { 175 return mName; 176 } 177 178 public String getClasspathName() { 179 return mName; 180 } 181 182 public String getShortClasspathName() { 183 return mName; 184 } 185 186 /* 187 * (non-Javadoc) 188 * 189 * Description for the Android platform is dynamically generated. 190 * 191 * @see com.android.sdklib.IAndroidTarget#getDescription() 192 */ 193 public String getDescription() { 194 return String.format("Standard Android platform %s", mVersionName); 195 } 196 197 public AndroidVersion getVersion() { 198 return mVersion; 199 } 200 201 public String getVersionName() { 202 return mVersionName; 203 } 204 205 public int getRevision() { 206 return mRevision; 207 } 208 209 public boolean isPlatform() { 210 return true; 211 } 212 213 public IAndroidTarget getParent() { 214 return null; 215 } 216 217 public String getPath(int pathId) { 218 return mPaths.get(pathId); 219 } 220 221 /** 222 * Returns whether the target is able to render layouts. This is always true for platforms. 223 */ 224 public boolean hasRenderingLibrary() { 225 return true; 226 } 227 228 229 public String[] getSkins() { 230 return mSkins; 231 } 232 233 public String getDefaultSkin() { 234 // only one skin? easy. 235 if (mSkins.length == 1) { 236 return mSkins[0]; 237 } 238 239 // look for the skin name in the platform props 240 String skinName = mProperties.get(SdkConstants.PROP_SDK_DEFAULT_SKIN); 241 if (skinName != null) { 242 return skinName; 243 } 244 245 // otherwise try to find a good default. 246 if (mVersion.getApiLevel() >= 4) { 247 // at this time, this is the default skin for all older platforms that had 2+ skins. 248 return "WVGA800"; 249 } 250 251 return "HVGA"; // this is for 1.5 and earlier. 252 } 253 254 /** 255 * Always returns null, as a standard platform ha no optional libraries. 256 * 257 * {@inheritDoc} 258 * @see com.android.sdklib.IAndroidTarget#getOptionalLibraries() 259 */ 260 public IOptionalLibrary[] getOptionalLibraries() { 261 return null; 262 } 263 264 /** 265 * Currently always return a fixed list with "android.test.runner" in it. 266 * <p/> 267 * TODO change the fixed library list to be build-dependent later. 268 * {@inheritDoc} 269 */ 270 public String[] getPlatformLibraries() { 271 return new String[] { SdkConstants.ANDROID_TEST_RUNNER_LIB }; 272 } 273 274 /** 275 * The platform has no USB Vendor Id: always return {@link IAndroidTarget#NO_USB_ID}. 276 * {@inheritDoc} 277 */ 278 public int getUsbVendorId() { 279 return NO_USB_ID; 280 } 281 282 public boolean canRunOn(IAndroidTarget target) { 283 // basic test 284 if (target == this) { 285 return true; 286 } 287 288 // if the platform has a codename (ie it's a preview of an upcoming platform), then 289 // both platforms must be exactly identical. 290 if (mVersion.getCodename() != null) { 291 return mVersion.equals(target.getVersion()); 292 } 293 294 // target is compatible wit the receiver as long as its api version number is greater or 295 // equal. 296 return target.getVersion().getApiLevel() >= mVersion.getApiLevel(); 297 } 298 299 public String hashString() { 300 return String.format(PLATFORM_HASH, mVersion.getApiString()); 301 } 302 303 @Override 304 public int hashCode() { 305 return hashString().hashCode(); 306 } 307 308 @Override 309 public boolean equals(Object obj) { 310 if (obj instanceof PlatformTarget) { 311 PlatformTarget platform = (PlatformTarget)obj; 312 313 return mVersion.equals(platform.getVersion()); 314 } 315 316 return false; 317 } 318 319 /* 320 * Order by API level (preview/n count as between n and n+1). 321 * At the same API level, order as: Platform first, then add-on ordered by vendor and then name 322 * (non-Javadoc) 323 * @see java.lang.Comparable#compareTo(java.lang.Object) 324 */ 325 public int compareTo(IAndroidTarget target) { 326 // quick check. 327 if (this == target) { 328 return 0; 329 } 330 331 int versionDiff = mVersion.compareTo(target.getVersion()); 332 333 // only if the version are the same do we care about add-ons. 334 if (versionDiff == 0) { 335 // platforms go before add-ons. 336 if (target.isPlatform() == false) { 337 return -1; 338 } 339 } 340 341 return versionDiff; 342 } 343 344 /** 345 * Returns a string representation suitable for debugging. 346 * The representation is not intended for display to the user. 347 * 348 * The representation is also purposely compact. It does not describe _all_ the properties 349 * of the target, only a few key ones. 350 * 351 * @see #getDescription() 352 */ 353 @Override 354 public String toString() { 355 return String.format("PlatformTarget %1$s rev %2$d", //$NON-NLS-1$ 356 getVersion(), 357 getRevision()); 358 } 359 360 public String getProperty(String name) { 361 return mProperties.get(name); 362 } 363 364 public Integer getProperty(String name, Integer defaultValue) { 365 try { 366 String value = getProperty(name); 367 if (value != null) { 368 return Integer.decode(value); 369 } 370 } catch (NumberFormatException e) { 371 // ignore, return default value; 372 } 373 374 return defaultValue; 375 } 376 377 public Boolean getProperty(String name, Boolean defaultValue) { 378 String value = getProperty(name); 379 if (value != null) { 380 return Boolean.valueOf(value); 381 } 382 383 return defaultValue; 384 } 385 386 public Map<String, String> getProperties() { 387 return mProperties; // mProperties is unmodifiable. 388 } 389 390 // ---- platform only methods. 391 392 void setSkins(String[] skins) { 393 mSkins = skins; 394 } 395 396 void setSamplesPath(String osLocation) { 397 mPaths.put(SAMPLES, osLocation); 398 } 399 } 400