• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 java.io.File;
20 import java.io.FileFilter;
21 import java.util.Arrays;
22 import java.util.HashSet;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 
26 /**
27  * Represents an add-on target in the SDK.
28  * An add-on extends a standard {@link PlatformTarget}.
29  */
30 final class AddOnTarget implements IAndroidTarget {
31     /**
32      * String to compute hash for add-on targets.
33      * Format is vendor:name:apiVersion
34      * */
35     private final static String ADD_ON_FORMAT = "%s:%s:%s"; //$NON-NLS-1$
36 
37     private final static class OptionalLibrary implements IOptionalLibrary {
38         private final String mJarName;
39         private final String mJarPath;
40         private final String mName;
41         private final String mDescription;
42 
OptionalLibrary(String jarName, String jarPath, String name, String description)43         OptionalLibrary(String jarName, String jarPath, String name, String description) {
44             mJarName = jarName;
45             mJarPath = jarPath;
46             mName = name;
47             mDescription = description;
48         }
49 
getJarName()50         public String getJarName() {
51             return mJarName;
52         }
53 
getJarPath()54         public String getJarPath() {
55             return mJarPath;
56         }
57 
getName()58         public String getName() {
59             return mName;
60         }
61 
getDescription()62         public String getDescription() {
63             return mDescription;
64         }
65     }
66 
67     private final String mLocation;
68     private final PlatformTarget mBasePlatform;
69     private final String mName;
70     private final String mVendor;
71     private final int mRevision;
72     private final String mDescription;
73     private String[] mSkins;
74     private String mDefaultSkin;
75     private IOptionalLibrary[] mLibraries;
76     private int mVendorId = NO_USB_ID;
77 
78     /**
79      * Creates a new add-on
80      * @param location the OS path location of the add-on
81      * @param name the name of the add-on
82      * @param vendor the vendor name of the add-on
83      * @param revision the revision of the add-on
84      * @param description the add-on description
85      * @param libMap A map containing the optional libraries. The map key is the fully-qualified
86      * library name. The value is a 2 string array with the .jar filename, and the description.
87      * @param basePlatform the platform the add-on is extending.
88      */
AddOnTarget(String location, String name, String vendor, int revision, String description, Map<String, String[]> libMap, PlatformTarget basePlatform)89     AddOnTarget(String location, String name, String vendor, int revision, String description,
90             Map<String, String[]> libMap, PlatformTarget basePlatform) {
91         if (location.endsWith(File.separator) == false) {
92             location = location + File.separator;
93         }
94 
95         mLocation = location;
96         mName = name;
97         mVendor = vendor;
98         mRevision = revision;
99         mDescription = description;
100         mBasePlatform = basePlatform;
101 
102         // handle the optional libraries.
103         if (libMap != null) {
104             mLibraries = new IOptionalLibrary[libMap.size()];
105             int index = 0;
106             for (Entry<String, String[]> entry : libMap.entrySet()) {
107                 String jarFile = entry.getValue()[0];
108                 String desc = entry.getValue()[1];
109                 mLibraries[index++] = new OptionalLibrary(jarFile,
110                         mLocation + SdkConstants.OS_ADDON_LIBS_FOLDER + jarFile,
111                         entry.getKey(), desc);
112             }
113         }
114     }
115 
getLocation()116     public String getLocation() {
117         return mLocation;
118     }
119 
getName()120     public String getName() {
121         return mName;
122     }
123 
getVendor()124     public String getVendor() {
125         return mVendor;
126     }
127 
getFullName()128     public String getFullName() {
129         return String.format("%1$s (%2$s)", mName, mVendor);
130     }
131 
getClasspathName()132     public String getClasspathName() {
133         return String.format("%1$s [%2$s]", mName, mBasePlatform.getName());
134     }
135 
getDescription()136     public String getDescription() {
137         return mDescription;
138     }
139 
getVersion()140     public AndroidVersion getVersion() {
141         // this is always defined by the base platform
142         return mBasePlatform.getVersion();
143     }
144 
getVersionName()145     public String getVersionName() {
146         return mBasePlatform.getVersionName();
147     }
148 
getRevision()149     public int getRevision() {
150         return mRevision;
151     }
152 
isPlatform()153     public boolean isPlatform() {
154         return false;
155     }
156 
getParent()157     public IAndroidTarget getParent() {
158         return mBasePlatform;
159     }
160 
getPath(int pathId)161     public String getPath(int pathId) {
162         switch (pathId) {
163             case IMAGES:
164                 return mLocation + SdkConstants.OS_IMAGES_FOLDER;
165             case SKINS:
166                 return mLocation + SdkConstants.OS_SKINS_FOLDER;
167             case DOCS:
168                 return mLocation + SdkConstants.FD_DOCS + File.separator
169                         + SdkConstants.FD_DOCS_REFERENCE;
170             case SAMPLES:
171                 // only return the add-on samples folder if there is actually a sample (or more)
172                 File sampleLoc = new File(mLocation, SdkConstants.FD_SAMPLES);
173                 if (sampleLoc.isDirectory()) {
174                     File[] files = sampleLoc.listFiles(new FileFilter() {
175                         public boolean accept(File pathname) {
176                             return pathname.isDirectory();
177                         }
178 
179                     });
180                     if (files != null && files.length > 0) {
181                         return sampleLoc.getAbsolutePath();
182                     }
183                 }
184                 // INTENDED FALL-THROUGH
185             default :
186                 return mBasePlatform.getPath(pathId);
187         }
188     }
189 
getSkins()190     public String[] getSkins() {
191         return mSkins;
192     }
193 
getDefaultSkin()194     public String getDefaultSkin() {
195         return mDefaultSkin;
196     }
197 
getOptionalLibraries()198     public IOptionalLibrary[] getOptionalLibraries() {
199         return mLibraries;
200     }
201 
202     /**
203      * Returns the list of libraries of the underlying platform.
204      *
205      * {@inheritDoc}
206      */
getPlatformLibraries()207     public String[] getPlatformLibraries() {
208         return mBasePlatform.getPlatformLibraries();
209     }
210 
getProperty(String name)211     public String getProperty(String name) {
212         return mBasePlatform.getProperty(name);
213     }
214 
getProperty(String name, Integer defaultValue)215     public Integer getProperty(String name, Integer defaultValue) {
216         return mBasePlatform.getProperty(name, defaultValue);
217     }
218 
getProperty(String name, Boolean defaultValue)219     public Boolean getProperty(String name, Boolean defaultValue) {
220         return mBasePlatform.getProperty(name, defaultValue);
221     }
222 
getProperties()223     public Map<String, String> getProperties() {
224         return mBasePlatform.getProperties();
225     }
226 
getUsbVendorId()227     public int getUsbVendorId() {
228         return mVendorId;
229     }
230 
canRunOn(IAndroidTarget target)231     public boolean canRunOn(IAndroidTarget target) {
232         // basic test
233         if (target == this) {
234             return true;
235         }
236 
237         /*
238          * The method javadoc indicates:
239          * Returns whether the given target is compatible with the receiver.
240          * <p/>A target is considered compatible if applications developed for the receiver can
241          * run on the given target.
242          */
243 
244         // The receiver is an add-on. There are 2 big use cases: The add-on has libraries
245         // or the add-on doesn't (in which case we consider it a platform).
246         if (mLibraries == null || mLibraries.length == 0) {
247             return mBasePlatform.canRunOn(target);
248         } else {
249             // the only targets that can run the receiver are the same add-on in the same or later
250             // versions.
251             // first check: vendor/name
252             if (mVendor.equals(target.getVendor()) == false ||
253                             mName.equals(target.getName()) == false) {
254                 return false;
255             }
256 
257             // now check the version. At this point since we checked the add-on part,
258             // we can revert to the basic check on version/codename which are done by the
259             // base platform already.
260             return mBasePlatform.canRunOn(target);
261         }
262 
263     }
264 
hashString()265     public String hashString() {
266         return String.format(ADD_ON_FORMAT, mVendor, mName,
267                 mBasePlatform.getVersion().getApiString());
268     }
269 
270     @Override
hashCode()271     public int hashCode() {
272         return hashString().hashCode();
273     }
274 
275     @Override
equals(Object obj)276     public boolean equals(Object obj) {
277         if (obj instanceof AddOnTarget) {
278             AddOnTarget addon = (AddOnTarget)obj;
279 
280             return mVendor.equals(addon.mVendor) && mName.equals(addon.mName) &&
281                 mBasePlatform.getVersion().equals(addon.mBasePlatform.getVersion());
282         }
283 
284         return false;
285     }
286 
287     /*
288      * Order by API level (preview/n count as between n and n+1).
289      * At the same API level, order as: Platform first, then add-on ordered by vendor and then name
290      * (non-Javadoc)
291      * @see java.lang.Comparable#compareTo(java.lang.Object)
292      */
compareTo(IAndroidTarget target)293     public int compareTo(IAndroidTarget target) {
294         // quick check.
295         if (this == target) {
296             return 0;
297         }
298 
299         int versionDiff = getVersion().compareTo(target.getVersion());
300 
301         // only if the version are the same do we care about platform/add-ons.
302         if (versionDiff == 0) {
303             // platforms go before add-ons.
304             if (target.isPlatform()) {
305                 return +1;
306             } else {
307                 AddOnTarget targetAddOn = (AddOnTarget)target;
308 
309                 // both are add-ons of the same version. Compare per vendor then by name
310                 int vendorDiff = mVendor.compareTo(targetAddOn.mVendor);
311                 if (vendorDiff == 0) {
312                     return mName.compareTo(targetAddOn.mName);
313                 } else {
314                     return vendorDiff;
315                 }
316             }
317 
318         }
319 
320         return versionDiff;
321     }
322 
323     // ---- local methods.
324 
setSkins(String[] skins, String defaultSkin)325     void setSkins(String[] skins, String defaultSkin) {
326         mDefaultSkin = defaultSkin;
327 
328         // we mix the add-on and base platform skins
329         HashSet<String> skinSet = new HashSet<String>();
330         skinSet.addAll(Arrays.asList(skins));
331         skinSet.addAll(Arrays.asList(mBasePlatform.getSkins()));
332 
333         mSkins = skinSet.toArray(new String[skinSet.size()]);
334     }
335 
336     /**
337      * Sets the USB vendor id in the add-on.
338      */
setUsbVendorId(int vendorId)339     void setUsbVendorId(int vendorId) {
340         if (vendorId == 0) {
341             throw new IllegalArgumentException( "VendorId must be > 0");
342         }
343 
344         mVendorId = vendorId;
345     }
346 }
347