2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.sdklib.internal.export;
19 import com.android.sdklib.xml.ManifestData;
21 import java.util.HashMap;
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.
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.
31 public final class ApkData implements Comparable<ApkData> {
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";
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
45 * If the ABIs are not in the same array, any order can be returned.
47 private static final String[][] ABI_SORTING = new String[][] {
48 new String[] { "armeabi", "armeabi-v7a" }
51 private final ProjectConfig mProjectConfig;
52 private final HashMap<String, String> mOutputNames = new HashMap<String, String>();
53 private int mBuildInfo;
54 private int mMinorCode;
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>();
60 ApkData(ProjectConfig projectConfig, String abi, Map<String, String> softVariants) {
61 mProjectConfig = projectConfig;
63 if (softVariants != null) {
64 mSoftVariantMap.putAll(softVariants);
68 ApkData(ProjectConfig projectConfig, String abi) {
69 this(projectConfig, abi, null /*softVariants*/);
72 ApkData(ProjectConfig projectConfig, Map<String, String> softVariants) {
73 this(projectConfig, null /*abi*/, softVariants);
76 ApkData(ProjectConfig projectConfig) {
77 this(projectConfig, null /*abi*/, null /*softVariants*/);
80 public ProjectConfig getProjectConfig() {
81 return mProjectConfig;
84 public String getOutputName(String key) {
85 return mOutputNames.get(key);
88 public void setOutputName(String key, String outputName) {
89 mOutputNames.put(key, outputName);
92 public int getBuildInfo() {
96 void setBuildInfo(int buildInfo) {
97 mBuildInfo = buildInfo;
100 public int getMinorCode() {
104 void setMinorCode(int minor) {
108 public String getAbi() {
112 public Map<String, String> getSoftVariantMap() {
113 return mSoftVariantMap;
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.
121 public int getCompositeVersionCode(int versionCode) {
122 int trueVersionCode = versionCode * MultiApkExportHelper.OFFSET_VERSION_CODE;
123 trueVersionCode += getBuildInfo() * MultiApkExportHelper.OFFSET_BUILD_INFO;
124 trueVersionCode += getMinorCode();
126 return trueVersionCode;
130 public String toString() {
131 return getLogLine(null);
134 public String getLogLine(String key) {
135 StringBuilder sb = new StringBuilder();
136 sb.append(getOutputName(key)).append(':');
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*/));
144 LogHelper.write(sb, PROP_ABI, mAbi);
147 String filter = mSoftVariantMap.get(key);
148 if (filter != null) {
149 LogHelper.write(sb, PROP_RESOURCES, filter);
152 return sb.toString();
155 public int compareTo(ApkData o) {
156 // compare only the hard properties, and in a specific order:
159 int minSdkDiff = mProjectConfig.getMinSdkVersion() - o.mProjectConfig.getMinSdkVersion();
160 if (minSdkDiff != 0) {
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());
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;
182 } else if (o.mProjectConfig.getGlEsVersion() != ManifestData.GL_ES_VERSION_NOT_SET) {
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;
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)) {
205 if (abiArray[i].equals(abi2)) {
210 // if both were found
211 if (abiIndex != -1 && abiIndex != -1) {
212 return abiIndex - abiIndex2;