fixed #401 (versionCode / versionName)

This commit is contained in:
Connor Tumbleson 2013-03-21 08:58:14 -05:00
parent c420a039e0
commit c5d2ecf96f
6 changed files with 134 additions and 31 deletions

View File

@ -2,6 +2,7 @@ v2.0.0 (TBA)
-Fixed (issue #8) - Correctly uses -c to retain original manifest and META-INF. Thanks M1cha -Fixed (issue #8) - Correctly uses -c to retain original manifest and META-INF. Thanks M1cha
-Fixed (issue #403) - Uses new usage output to cleanup organization of features. -Fixed (issue #403) - Uses new usage output to cleanup organization of features.
-Fixed (issue #359) - Correclty handles malformed 9patch images. (Thanks Felipe Richards) -Fixed (issue #359) - Correclty handles malformed 9patch images. (Thanks Felipe Richards)
-Fixed (issue #401) - Uses versionInfo meta to correctly parse versionName and versionCode
v1.5.3 (TBA) v1.5.3 (TBA)
-Updated to smali/baksmali to v1.4.2 -Updated to smali/baksmali to v1.4.2

View File

@ -32,6 +32,21 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
@ -209,6 +224,7 @@ public class Androlib {
: (Boolean) meta.get("compressionType")); : (Boolean) meta.get("compressionType"));
mAndRes.setSdkInfo((Map<String, String>) meta.get("sdkInfo")); mAndRes.setSdkInfo((Map<String, String>) meta.get("sdkInfo"));
mAndRes.setPackageId((String)meta.get("packageId")); mAndRes.setPackageId((String)meta.get("packageId"));
mAndRes.setVersionInfo((Map<String, String>) meta.get("versionInfo"));
if (outFile == null) { if (outFile == null) {
String outFileName = (String) meta.get("apkFileName"); String outFileName = (String) meta.get("apkFileName");
@ -469,6 +485,54 @@ public class Androlib {
} }
} }
public void remove_manifest_versions(String filePath)
throws AndrolibException {
File f = new File(filePath);
if (f.exists()) {
// remove versionCode and versionName
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filePath.toString());
Node manifest = doc.getFirstChild();
// load attr
NamedNodeMap attr = manifest.getAttributes();
Node vCode = attr.getNamedItem("android:versionCode");
Node vName = attr.getNamedItem("android:versionName");
// remove versionCode
if (vCode != null) {
attr.removeNamedItem("android:versionCode");
}
if (vName != null) {
attr.removeNamedItem("android:versionName");
}
// save manifest
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filePath));
transformer.transform(source, result);
} catch (ParserConfigurationException ex) {
throw new AndrolibException(ex);
} catch (SAXException ex) {
throw new AndrolibException(ex);
} catch (IOException ex) {
throw new AndrolibException(ex);
} catch (TransformerConfigurationException ex) {
throw new AndrolibException(ex);
} catch (TransformerException ex) {
throw new AndrolibException(ex);
}
}
}
public void buildApk(File appDir, File outApk, public void buildApk(File appDir, File outApk,
HashMap<String, Boolean> flags) throws AndrolibException { HashMap<String, Boolean> flags) throws AndrolibException {
LOGGER.info("Building apk file..."); LOGGER.info("Building apk file...");

View File

@ -134,6 +134,9 @@ public class ApkDecoder {
mAndrolib.decodeRawFiles(mApkFile, outDir); mAndrolib.decodeRawFiles(mApkFile, outDir);
mAndrolib.writeOriginalFiles(mApkFile, outDir); mAndrolib.writeOriginalFiles(mApkFile, outDir);
// remove version names in favour of aapt injection
mAndrolib.remove_manifest_versions(outDir.getAbsolutePath() + "/AndroidManifest.xml");
writeMetaFile(); writeMetaFile();
} }
@ -245,8 +248,9 @@ public class ApkDecoder {
putUsesFramework(meta); putUsesFramework(meta);
putSdkInfo(meta); putSdkInfo(meta);
putPackageInfo(meta); putPackageInfo(meta);
putVersionInfo(meta);
putCompressionInfo(meta); putCompressionInfo(meta);
meta.put("packageId", getResTable().getPackageInfo().get("cur_package_id")); //meta.put("packageId", getResTable().getPackageInfo().get("cur_package_id"));
} }
mAndrolib.writeMetaFile(mOutDir, meta); mAndrolib.writeMetaFile(mOutDir, meta);
@ -291,6 +295,13 @@ public class ApkDecoder {
} }
} }
private void putVersionInfo(Map<String, Object> meta) throws AndrolibException {
Map<String, String> info = getResTable().getVersionInfo();
if (info.size() > 0) {
meta.put("versionInfo", info);
}
}
private void putCompressionInfo(Map<String, Object> meta) private void putCompressionInfo(Map<String, Object> meta)
throws AndrolibException { throws AndrolibException {
meta.put("compressionType", getCompressionType()); meta.put("compressionType", getCompressionType());

View File

@ -201,10 +201,9 @@ final public class AndrolibResources {
// check if packages different, and that package is not equal to // check if packages different, and that package is not equal to
// "android" // "android"
Map<String, String> packageInfo = resTable.getPackageInfo(); Map<String, String> packageInfo = resTable.getPackageInfo();
if ((packageInfo.get("cur_package").equalsIgnoreCase( if ((packageInfo.get("cur_package").equalsIgnoreCase(packageInfo.get("orig_package")) ||
packageInfo.get("orig_package")) || ("android" ("android".equalsIgnoreCase(packageInfo.get("cur_package")) ||
.equalsIgnoreCase(packageInfo.get("cur_package")) || ("com.htc" ("com.htc".equalsIgnoreCase(packageInfo.get("cur_package")))))) {
.equalsIgnoreCase(packageInfo.get("cur_package")))))) {
LOGGER.info("Regular manifest package..."); LOGGER.info("Regular manifest package...");
} else { } else {
@ -307,6 +306,13 @@ final public class AndrolibResources {
} }
} }
public void setVersionInfo(Map<String, String> map) {
if (map != null) {
mVersionCode = map.get("versionCode");
mVersionName = map.get("versionName");
}
}
public void setPackageInfo(Map<String, String> map) { public void setPackageInfo(Map<String, String> map) {
if (map != null) { if (map != null) {
mPackageRenamed = map.get("package"); mPackageRenamed = map.get("package");
@ -379,6 +385,14 @@ final public class AndrolibResources {
cmd.add("--rename-manifest-package"); cmd.add("--rename-manifest-package");
cmd.add(mPackageRenamed); cmd.add(mPackageRenamed);
} }
if (mVersionCode != null) {
cmd.add("--version-code");
cmd.add(mVersionCode);
}
if (mVersionName != null) {
cmd.add("--version-name");
cmd.add(mVersionName);
}
cmd.add("-F"); cmd.add("-F");
cmd.add(apkFile.getAbsolutePath()); cmd.add(apkFile.getAbsolutePath());
@ -758,6 +772,8 @@ final public class AndrolibResources {
private String mMinSdkVersion = null; private String mMinSdkVersion = null;
private String mMaxSdkVersion = null; private String mMaxSdkVersion = null;
private String mTargetSdkVersion = null; private String mTargetSdkVersion = null;
private String mVersionCode = null;
private String mVersionName = null;
private String mPackageRenamed = null; private String mPackageRenamed = null;

View File

@ -37,6 +37,7 @@ public class ResTable {
private Map<String, String> mSdkInfo = new LinkedHashMap<String, String>(); private Map<String, String> mSdkInfo = new LinkedHashMap<String, String>();
private Map<String, String> mPackageInfo = new LinkedHashMap<String, String>(); private Map<String, String> mPackageInfo = new LinkedHashMap<String, String>();
private Map<String, String> mVersionInfo = new LinkedHashMap<String, String>();
public ResTable() { public ResTable() {
mAndRes = null; mAndRes = null;
@ -120,16 +121,16 @@ public class ResTable {
mFrameTag = tag; mFrameTag = tag;
} }
public Map<String, String> getSdkInfo() { public void clearSdkInfo() {
return mSdkInfo; mSdkInfo.clear();
} }
public void addSdkInfo(String key, String value) { public void addSdkInfo(String key, String value) {
mSdkInfo.put(key, value); mSdkInfo.put(key, value);
} }
public void clearSdkInfo() { public void addVersionInfo(String key, String value) {
mSdkInfo.clear(); mVersionInfo.put(key, value);
} }
public void addPackageInfo(String key, String value) { public void addPackageInfo(String key, String value) {
@ -140,6 +141,14 @@ public class ResTable {
return mPackageInfo; return mPackageInfo;
} }
public Map<String, String> getVersionInfo() {
return mVersionInfo;
}
public Map<String, String> getSdkInfo() {
return mSdkInfo;
}
public boolean isPackageInfoValueSet(String key) { public boolean isPackageInfoValueSet(String key) {
return (mPackageInfo.containsKey(key)); return (mPackageInfo.containsKey(key));
} }

View File

@ -93,10 +93,12 @@ public class XmlPullStreamDecoder implements ResStreamDecoder {
// read <manifest> for package: // read <manifest> for package:
for (int i = 0; i < pp.getAttributeCount(); i++) { for (int i = 0; i < pp.getAttributeCount(); i++) {
if (pp.getAttributeName(i) if (pp.getAttributeName(i).equalsIgnoreCase(("package"))) {
.equalsIgnoreCase(("package"))) { restable.addPackageInfo("orig_package",pp.getAttributeValue(i));
restable.addPackageInfo("orig_package", } else if (pp.getAttributeName(i).equalsIgnoreCase("versionCode")) {
pp.getAttributeValue(i)); restable.addVersionInfo("versionCode", pp.getAttributeValue(i));
} else if (pp.getAttributeName(i).equalsIgnoreCase("versionName")) {
restable.addVersionInfo("versionName", pp.getAttributeValue(i));
} }
} }
return true; return true;