Home | History | Annotate | Download | only in repository
      1 /*
      2  * Copyright (C) 2010 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.internal.repository;
     18 
     19 import com.android.annotations.VisibleForTesting;
     20 import com.android.annotations.VisibleForTesting.Visibility;
     21 import com.android.sdklib.SdkConstants;
     22 import com.android.sdklib.SdkManager;
     23 import com.android.sdklib.internal.repository.Archive.Arch;
     24 import com.android.sdklib.internal.repository.Archive.Os;
     25 
     26 import org.w3c.dom.Node;
     27 
     28 import java.io.File;
     29 import java.util.HashSet;
     30 import java.util.Map;
     31 import java.util.Properties;
     32 import java.util.Set;
     33 
     34 /**
     35  * Represents a platform-tool XML node in an SDK repository.
     36  */
     37 public class PlatformToolPackage extends Package {
     38 
     39     /** The value returned by {@link PlatformToolPackage#installId()}. */
     40     public static final String INSTALL_ID = "platform-tools";                       //$NON-NLS-1$
     41 
     42     /**
     43      * Creates a new platform-tool package from the attributes and elements of the given XML node.
     44      * This constructor should throw an exception if the package cannot be created.
     45      *
     46      * @param source The {@link SdkSource} where this is loaded from.
     47      * @param packageNode The XML element being parsed.
     48      * @param nsUri The namespace URI of the originating XML document, to be able to deal with
     49      *          parameters that vary according to the originating XML schema.
     50      * @param licenses The licenses loaded from the XML originating document.
     51      */
     52     PlatformToolPackage(SdkSource source, Node packageNode,
     53             String nsUri, Map<String,String> licenses) {
     54         super(source, packageNode, nsUri, licenses);
     55     }
     56 
     57     /**
     58      * Manually create a new package with one archive and the given attributes or properties.
     59      * This is used to create packages from local directories in which case there must be
     60      * one archive which URL is the actual target location.
     61      * <p/>
     62      * By design, this creates a package with one and only one archive.
     63      */
     64     static Package create(
     65             SdkSource source,
     66             Properties props,
     67             int revision,
     68             String license,
     69             String description,
     70             String descUrl,
     71             Os archiveOs,
     72             Arch archiveArch,
     73             String archiveOsPath) {
     74 
     75         PlatformToolPackage ptp = new PlatformToolPackage(source, props, revision, license,
     76                 description, descUrl, archiveOs, archiveArch, archiveOsPath);
     77 
     78         File platformToolsFolder = new File(archiveOsPath);
     79         String error = null;
     80         if (!platformToolsFolder.isDirectory()) {
     81             error = "platform-tools folder is missing";
     82         } else {
     83             File[] files = platformToolsFolder.listFiles();
     84             if (files == null || files.length == 0) {
     85                 error = "platform-tools folder is empty";
     86             } else {
     87                 Set<String> names = new HashSet<String>();
     88                 for (File file : files) {
     89                     names.add(file.getName());
     90                 }
     91                 for (String name : new String[] { SdkConstants.FN_ADB,
     92                                                   SdkConstants.FN_AAPT,
     93                                                   SdkConstants.FN_AIDL,
     94                                                   SdkConstants.FN_DX } ) {
     95                     if (!names.contains(name)) {
     96                         if (error == null) {
     97                             error = "platform-tools folder is missing ";
     98                         } else {
     99                             error += ", ";
    100                         }
    101                         error += name;
    102                     }
    103                 }
    104             }
    105         }
    106 
    107         if (error != null) {
    108             String shortDesc = ptp.getShortDescription() + " [*]";  //$NON-NLS-1$
    109 
    110             String longDesc = String.format(
    111                     "Broken Platform-Tools Package: %1$s\n" +
    112                     "[*] Package cannot be used due to error: %2$s",
    113                     description,
    114                     error);
    115 
    116             BrokenPackage ba = new BrokenPackage(props, shortDesc, longDesc,
    117                     IMinApiLevelDependency.MIN_API_LEVEL_NOT_SPECIFIED,
    118                     IExactApiLevelDependency.API_LEVEL_INVALID,
    119                     archiveOsPath);
    120             return ba;
    121         }
    122 
    123 
    124         return ptp;
    125     }
    126 
    127     @VisibleForTesting(visibility=Visibility.PRIVATE)
    128     protected PlatformToolPackage(
    129                 SdkSource source,
    130                 Properties props,
    131                 int revision,
    132                 String license,
    133                 String description,
    134                 String descUrl,
    135                 Os archiveOs,
    136                 Arch archiveArch,
    137                 String archiveOsPath) {
    138         super(source,
    139                 props,
    140                 revision,
    141                 license,
    142                 description,
    143                 descUrl,
    144                 archiveOs,
    145                 archiveArch,
    146                 archiveOsPath);
    147     }
    148 
    149     /**
    150      * Returns a string identifier to install this package from the command line.
    151      * For platform-tools, we use "platform-tools" since this package type is unique.
    152      * <p/>
    153      * {@inheritDoc}
    154      */
    155     @Override
    156     public String installId() {
    157         return INSTALL_ID;
    158     }
    159 
    160     /**
    161      * Returns a description of this package that is suitable for a list display.
    162      * <p/>
    163      * {@inheritDoc}
    164      */
    165     @Override
    166     public String getListDescription() {
    167         return String.format("Android SDK Platform-tools%1$s",
    168                 isObsolete() ? " (Obsolete)" : "");
    169     }
    170 
    171     /**
    172      * Returns a short description for an {@link IDescription}.
    173      */
    174     @Override
    175     public String getShortDescription() {
    176         return String.format("Android SDK Platform-tools, revision %1$d%2$s",
    177                 getRevision(),
    178                 isObsolete() ? " (Obsolete)" : "");
    179     }
    180 
    181     /** Returns a long description for an {@link IDescription}. */
    182     @Override
    183     public String getLongDescription() {
    184         String s = getDescription();
    185         if (s == null || s.length() == 0) {
    186             s = getShortDescription();
    187         }
    188 
    189         if (s.indexOf("revision") == -1) {
    190             s += String.format("\nRevision %1$d%2$s",
    191                     getRevision(),
    192                     isObsolete() ? " (Obsolete)" : "");
    193         }
    194 
    195         return s;
    196     }
    197 
    198     /**
    199      * Computes a potential installation folder if an archive of this package were
    200      * to be installed right away in the given SDK root.
    201      * <p/>
    202      * A "tool" package should always be located in SDK/tools.
    203      *
    204      * @param osSdkRoot The OS path of the SDK root folder.
    205      * @param sdkManager An existing SDK manager to list current platforms and addons.
    206      * @return A new {@link File} corresponding to the directory to use to install this package.
    207      */
    208     @Override
    209     public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) {
    210         return new File(osSdkRoot, SdkConstants.FD_PLATFORM_TOOLS);
    211     }
    212 
    213     @Override
    214     public boolean sameItemAs(Package pkg) {
    215         // only one platform-tool package so any platform-tool package is the same item.
    216         return pkg instanceof PlatformToolPackage;
    217     }
    218 
    219     /**
    220      * Hook called right before an archive is installed.
    221      * This is used here to stop ADB before trying to replace the platform-tool package.
    222      *
    223      * @param archive The archive that will be installed
    224      * @param monitor The {@link ITaskMonitor} to display errors.
    225      * @param osSdkRoot The OS path of the SDK root folder.
    226      * @param installFolder The folder where the archive will be installed. Note that this
    227      *                      is <em>not</em> the folder where the archive was temporary
    228      *                      unzipped. The installFolder, if it exists, contains the old
    229      *                      archive that will soon be replaced by the new one.
    230      * @return True if installing this archive shall continue, false if it should be skipped.
    231      */
    232     @Override
    233     public boolean preInstallHook(Archive archive, ITaskMonitor monitor,
    234             String osSdkRoot, File installFolder) {
    235         AdbWrapper aw = new AdbWrapper(osSdkRoot, monitor);
    236         aw.stopAdb();
    237         return super.preInstallHook(archive, monitor, osSdkRoot, installFolder);
    238     }
    239 
    240 }
    241