Home | History | Annotate | Download | only in export
      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.export;
     18 
     19 import com.android.sdklib.xml.ManifestData;
     20 
     21 import java.util.HashMap;
     22 import java.util.Map;
     23 
     24 /**
     25  * Class representing one apk (or more if there are soft variants) that needs to be generated.
     26  * This contains a link to the project used for the export, and which extra filters should be used.
     27  *
     28  * This class is meant to be sortable in a way that allows generation of the buildInfo
     29  * value that goes in the composite versionCode.
     30  */
     31 public final class ApkData implements Comparable<ApkData> {
     32 
     33     private static final String PROP_PROJECT = "project";
     34     private static final String PROP_BUILDINFO = "buildInfo";
     35     private static final String PROP_MINOR = "minorCode";
     36     private static final String PROP_ABI = "abi";
     37     private static final String PROP_RESOURCES = "resources";
     38 
     39     /**
     40      * List of ABI order.
     41      * This is meant to be a list of CPU/CPU2 to indicate the order required by the build info.
     42      * If the ABIs being compared in {@link #compareTo(ApkData)} are in the same String array,
     43      * then the value returned must ensure that the {@link ApkData} will ordered the same as the
     44      * array.
     45      * If the ABIs are not in the same array, any order can be returned.
     46      */
     47     private static final String[][] ABI_SORTING = new String[][] {
     48         new String[] { "armeabi", "armeabi-v7a" }
     49     };
     50 
     51     private final ProjectConfig mProjectConfig;
     52     private final HashMap<String, String> mOutputNames = new HashMap<String, String>();
     53     private int mBuildInfo;
     54     private int mMinorCode;
     55 
     56     // the following are used to sort the export data and generate buildInfo
     57     private final String mAbi;
     58     private final Map<String, String> mSoftVariantMap = new HashMap<String, String>();
     59 
     60     ApkData(ProjectConfig projectConfig, String abi, Map<String, String> softVariants) {
     61         mProjectConfig = projectConfig;
     62         mAbi = abi;
     63         if (softVariants != null) {
     64             mSoftVariantMap.putAll(softVariants);
     65         }
     66     }
     67 
     68     ApkData(ProjectConfig projectConfig, String abi) {
     69         this(projectConfig, abi, null /*softVariants*/);
     70     }
     71 
     72     ApkData(ProjectConfig projectConfig, Map<String, String> softVariants) {
     73         this(projectConfig, null /*abi*/, softVariants);
     74     }
     75 
     76     ApkData(ProjectConfig projectConfig) {
     77         this(projectConfig, null /*abi*/, null /*softVariants*/);
     78     }
     79 
     80     public ProjectConfig getProjectConfig() {
     81         return mProjectConfig;
     82     }
     83 
     84     public String getOutputName(String key) {
     85         return mOutputNames.get(key);
     86     }
     87 
     88     public void setOutputName(String key, String outputName) {
     89         mOutputNames.put(key, outputName);
     90     }
     91 
     92     public int getBuildInfo() {
     93         return mBuildInfo;
     94     }
     95 
     96     void setBuildInfo(int buildInfo) {
     97         mBuildInfo = buildInfo;
     98     }
     99 
    100     public int getMinorCode() {
    101         return mMinorCode;
    102     }
    103 
    104     void setMinorCode(int minor) {
    105         mMinorCode = minor;
    106     }
    107 
    108     public String getAbi() {
    109         return mAbi;
    110     }
    111 
    112     public Map<String, String> getSoftVariantMap() {
    113         return mSoftVariantMap;
    114     }
    115 
    116     /**
    117      * Computes and returns the composite version code
    118      * @param versionCode the major version code.
    119      * @return the composite versionCode to be used in the manifest.
    120      */
    121     public int getCompositeVersionCode(int versionCode) {
    122         int trueVersionCode = versionCode * MultiApkExportHelper.OFFSET_VERSION_CODE;
    123         trueVersionCode += getBuildInfo() * MultiApkExportHelper.OFFSET_BUILD_INFO;
    124         trueVersionCode += getMinorCode();
    125 
    126         return trueVersionCode;
    127     }
    128 
    129     @Override
    130     public String toString() {
    131         return getLogLine(null);
    132     }
    133 
    134     public String getLogLine(String key) {
    135         StringBuilder sb = new StringBuilder();
    136         sb.append(getOutputName(key)).append(':');
    137 
    138         LogHelper.write(sb, PROP_BUILDINFO, mBuildInfo);
    139         LogHelper.write(sb, PROP_MINOR, mMinorCode);
    140         LogHelper.write(sb, PROP_PROJECT, mProjectConfig.getRelativePath());
    141         sb.append(mProjectConfig.getConfigString(true /*onlyManifestData*/));
    142 
    143         if (mAbi != null) {
    144             LogHelper.write(sb, PROP_ABI, mAbi);
    145         }
    146 
    147         String filter = mSoftVariantMap.get(key);
    148         if (filter != null) {
    149             LogHelper.write(sb, PROP_RESOURCES, filter);
    150         }
    151 
    152         return sb.toString();
    153     }
    154 
    155     public int compareTo(ApkData o) {
    156         // compare only the hard properties, and in a specific order:
    157 
    158         // 1. minSdkVersion
    159         int minSdkDiff = mProjectConfig.getMinSdkVersion() - o.mProjectConfig.getMinSdkVersion();
    160         if (minSdkDiff != 0) {
    161             return minSdkDiff;
    162         }
    163 
    164         // 2. <supports-screens>
    165         // only compare if they have don't have the same size support. This is because
    166         // this compare method throws an exception if the values cannot be compared.
    167         if (mProjectConfig.getSupportsScreens().hasSameScreenSupportAs(
    168                 o.mProjectConfig.getSupportsScreens()) == false) {
    169             return mProjectConfig.getSupportsScreens().compareScreenSizesWith(
    170                     o.mProjectConfig.getSupportsScreens());
    171         }
    172 
    173         // 3. glEsVersion
    174         int comp;
    175         if (mProjectConfig.getGlEsVersion() != ManifestData.GL_ES_VERSION_NOT_SET) {
    176             if (o.mProjectConfig.getGlEsVersion() != ManifestData.GL_ES_VERSION_NOT_SET) {
    177                 comp = mProjectConfig.getGlEsVersion() - o.mProjectConfig.getGlEsVersion();
    178                 if (comp != 0) return comp;
    179             } else {
    180                 return -1;
    181             }
    182         } else if (o.mProjectConfig.getGlEsVersion() != ManifestData.GL_ES_VERSION_NOT_SET) {
    183             return 1;
    184         }
    185 
    186         // 4. ABI
    187         // here the returned value is only important if both abi are non null.
    188         if (mAbi != null && o.mAbi != null) {
    189             comp = compareAbi(mAbi, o.mAbi);
    190             if (comp != 0) return comp;
    191         }
    192 
    193         return 0;
    194     }
    195 
    196     private int compareAbi(String abi, String abi2) {
    197         // look for the abis in each of the ABI sorting array
    198         for (String[] abiArray : ABI_SORTING) {
    199             int abiIndex = -1, abiIndex2 = -1;
    200             final int count = abiArray.length;
    201             for (int i = 0 ; i < count ; i++) {
    202                 if (abiArray[i].equals(abi)) {
    203                     abiIndex = i;
    204                 }
    205                 if (abiArray[i].equals(abi2)) {
    206                     abiIndex2 = i;
    207                 }
    208             }
    209 
    210             // if both were found
    211             if (abiIndex != -1 && abiIndex != -1) {
    212                 return abiIndex - abiIndex2;
    213             }
    214         }
    215 
    216         return 0;
    217     }
    218 }
    219