properly store package information (manifest AND resources.arsc info) in apktool.yml for renamed packages

This commit is contained in:
Connor Tumbleson 2012-12-13 21:14:41 -06:00
parent 4410e466f5
commit f065a5be92
6 changed files with 802 additions and 785 deletions

1
.gitignore vendored
View File

@ -26,3 +26,4 @@ build*
*.settings *.settings
*.setting *.setting
bin/ bin/
*.iml

View File

@ -61,11 +61,11 @@ public class ApkDecoder {
public void decode() throws AndrolibException { public void decode() throws AndrolibException {
File outDir = getOutDir(); File outDir = getOutDir();
if (! mForceDelete && outDir.exists()) { if (!mForceDelete && outDir.exists()) {
throw new OutDirExistsException(); throw new OutDirExistsException();
} }
if (! mApkFile.isFile() || ! mApkFile.canRead() ) { if (!mApkFile.isFile() || !mApkFile.canRead()) {
throw new InFileNotFoundException(); throw new InFileNotFoundException();
} }
@ -96,12 +96,12 @@ public class ApkDecoder {
mAndrolib.decodeResourcesRaw(mApkFile, outDir); mAndrolib.decodeResourcesRaw(mApkFile, outDir);
break; break;
case DECODE_RESOURCES_FULL: case DECODE_RESOURCES_FULL:
mAndrolib.decodeResourcesFull(mApkFile, outDir, mAndrolib.decodeResourcesFull(mApkFile, outDir, getResTable());
getResTable());
break; break;
} }
} else { } else {
// if there's no resources.asrc, decode the manifest without looking up // if there's no resources.asrc, decode the manifest without looking
// up
// attribute references // attribute references
if (hasManifest()) { if (hasManifest()) {
switch (mDecodeResources) { switch (mDecodeResources) {
@ -166,7 +166,7 @@ public class ApkDecoder {
if (mResTable == null) { if (mResTable == null) {
boolean hasResources = hasResources(); boolean hasResources = hasResources();
boolean hasManifest = hasManifest(); boolean hasManifest = hasManifest();
if (! (hasManifest || hasResources)) { if (!(hasManifest || hasResources)) {
throw new AndrolibException( throw new AndrolibException(
"Apk doesn't contain either AndroidManifest.xml file or resources.arsc file"); "Apk doesn't contain either AndroidManifest.xml file or resources.arsc file");
} }
@ -209,7 +209,6 @@ public class ApkDecoder {
public final static short DECODE_RESOURCES_NONE = 0x0100; public final static short DECODE_RESOURCES_NONE = 0x0100;
public final static short DECODE_RESOURCES_FULL = 0x0101; public final static short DECODE_RESOURCES_FULL = 0x0101;
private File getOutDir() throws AndrolibException { private File getOutDir() throws AndrolibException {
if (mOutDir == null) { if (mOutDir == null) {
throw new AndrolibException("Out dir not set"); throw new AndrolibException("Out dir not set");
@ -222,7 +221,8 @@ public class ApkDecoder {
meta.put("version", Androlib.getVersion()); meta.put("version", Androlib.getVersion());
meta.put("apkFileName", mApkFile.getName()); meta.put("apkFileName", mApkFile.getName());
if (mDecodeResources != DECODE_RESOURCES_NONE && (hasManifest() || hasResources())) { if (mDecodeResources != DECODE_RESOURCES_NONE
&& (hasManifest() || hasResources())) {
meta.put("isFrameworkApk", meta.put("isFrameworkApk",
Boolean.valueOf(mAndrolib.isFrameworkApk(getResTable()))); Boolean.valueOf(mAndrolib.isFrameworkApk(getResTable())));
putUsesFramework(meta); putUsesFramework(meta);
@ -257,8 +257,7 @@ public class ApkDecoder {
meta.put("usesFramework", uses); meta.put("usesFramework", uses);
} }
private void putSdkInfo(Map<String, Object> meta) private void putSdkInfo(Map<String, Object> meta) throws AndrolibException {
throws AndrolibException {
Map<String, String> info = getResTable().getSdkInfo(); Map<String, String> info = getResTable().getSdkInfo();
if (info.size() > 0) { if (info.size() > 0) {
meta.put("sdkInfo", info); meta.put("sdkInfo", info);

View File

@ -42,7 +42,8 @@ final public class AndrolibResources {
return getResTable(apkFile, true); return getResTable(apkFile, true);
} }
public ResTable getResTable(ExtFile apkFile, boolean loadMainPkg) throws AndrolibException { public ResTable getResTable(ExtFile apkFile, boolean loadMainPkg)
throws AndrolibException {
ResTable resTable = new ResTable(this); ResTable resTable = new ResTable(this);
if (loadMainPkg) { if (loadMainPkg) {
loadMainPkg(resTable, apkFile); loadMainPkg(resTable, apkFile);
@ -53,8 +54,8 @@ final public class AndrolibResources {
public ResPackage loadMainPkg(ResTable resTable, ExtFile apkFile) public ResPackage loadMainPkg(ResTable resTable, ExtFile apkFile)
throws AndrolibException { throws AndrolibException {
LOGGER.info("Loading resource table..."); LOGGER.info("Loading resource table...");
ResPackage[] pkgs = getResPackagesFromApk( ResPackage[] pkgs = getResPackagesFromApk(apkFile, resTable,
apkFile, resTable, sKeepBroken); sKeepBroken);
ResPackage pkg = null; ResPackage pkg = null;
switch (pkgs.length) { switch (pkgs.length) {
@ -87,8 +88,8 @@ final public class AndrolibResources {
File apk = getFrameworkApk(id, frameTag); File apk = getFrameworkApk(id, frameTag);
LOGGER.info("Loading resource table from file: " + apk); LOGGER.info("Loading resource table from file: " + apk);
ResPackage[] pkgs = getResPackagesFromApk( ResPackage[] pkgs = getResPackagesFromApk(new ExtFile(apk), resTable,
new ExtFile(apk), resTable, true); true);
if (pkgs.length != 1) { if (pkgs.length != 1) {
throw new AndrolibException( throw new AndrolibException(
@ -97,8 +98,8 @@ final public class AndrolibResources {
ResPackage pkg = pkgs[0]; ResPackage pkg = pkgs[0];
if (pkg.getId() != id) { if (pkg.getId() != id) {
throw new AndrolibException("Expected pkg of id: " + throw new AndrolibException("Expected pkg of id: "
String.valueOf(id) + ", got: " + pkg.getId()); + String.valueOf(id) + ", got: " + pkg.getId());
} }
resTable.addPackage(pkg, false); resTable.addPackage(pkg, false);
@ -125,8 +126,8 @@ final public class AndrolibResources {
out = new FileDirectory(outDir); out = new FileDirectory(outDir);
LOGGER.info("Decoding AndroidManifest.xml with only framework resources..."); LOGGER.info("Decoding AndroidManifest.xml with only framework resources...");
fileDecoder.decodeManifest( fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out,
inApk, "AndroidManifest.xml", out, "AndroidManifest.xml"); "AndroidManifest.xml");
} catch (DirectoryException ex) { } catch (DirectoryException ex) {
throw new AndrolibException(ex); throw new AndrolibException(ex);
@ -139,8 +140,8 @@ final public class AndrolibResources {
ResFileDecoder fileDecoder = duo.m1; ResFileDecoder fileDecoder = duo.m1;
ResAttrDecoder attrDecoder = duo.m2.getAttrDecoder(); ResAttrDecoder attrDecoder = duo.m2.getAttrDecoder();
attrDecoder.setCurrentPackage( attrDecoder.setCurrentPackage(resTable.listMainPackages().iterator()
resTable.listMainPackages().iterator().next()); .next());
Directory inApk, in = null, out; Directory inApk, in = null, out;
try { try {
@ -149,8 +150,8 @@ final public class AndrolibResources {
LOGGER.info("Decoding AndroidManifest.xml with resources..."); LOGGER.info("Decoding AndroidManifest.xml with resources...");
fileDecoder.decodeManifest( fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out,
inApk, "AndroidManifest.xml", out, "AndroidManifest.xml"); "AndroidManifest.xml");
if (inApk.containsDir("res")) { if (inApk.containsDir("res")) {
in = inApk.getDir("res"); in = inApk.getDir("res");
@ -184,7 +185,7 @@ final public class AndrolibResources {
} }
public void setSdkInfo(Map<String, String> map) { public void setSdkInfo(Map<String, String> map) {
if(map != null) { if (map != null) {
mMinSdkVersion = map.get("minSdkVersion"); mMinSdkVersion = map.get("minSdkVersion");
mTargetSdkVersion = map.get("targetSdkVersion"); mTargetSdkVersion = map.get("targetSdkVersion");
mMaxSdkVersion = map.get("maxSdkVersion"); mMaxSdkVersion = map.get("maxSdkVersion");
@ -198,21 +199,21 @@ final public class AndrolibResources {
} }
public void aaptPackage(File apkFile, File manifest, File resDir, public void aaptPackage(File apkFile, File manifest, File resDir,
File rawDir, File assetDir, File[] include, HashMap<String, Boolean> flags) File rawDir, File assetDir, File[] include,
throws AndrolibException { HashMap<String, Boolean> flags) throws AndrolibException {
List<String> cmd = new ArrayList<String>(); List<String> cmd = new ArrayList<String>();
cmd.add("aapt"); cmd.add("aapt");
cmd.add("p"); cmd.add("p");
if (flags.get("verbose")) { //output aapt verbose if (flags.get("verbose")) { // output aapt verbose
cmd.add("-v"); cmd.add("-v");
} }
if (flags.get("update")) { if (flags.get("update")) {
cmd.add("-u"); cmd.add("-u");
} }
if (flags.get("debug")) { //inject debuggable="true" into manifest if (flags.get("debug")) { // inject debuggable="true" into manifest
cmd.add("--debug-mode"); cmd.add("--debug-mode");
} }
if (mMinSdkVersion != null) { if (mMinSdkVersion != null) {
@ -237,8 +238,8 @@ final public class AndrolibResources {
if (flags.get("framework")) { if (flags.get("framework")) {
cmd.add("-x"); cmd.add("-x");
// cmd.add("-0"); // cmd.add("-0");
// cmd.add("arsc"); // cmd.add("arsc");
} }
if (include != null) { if (include != null) {
@ -273,14 +274,14 @@ final public class AndrolibResources {
public boolean detectWhetherAppIsFramework(File appDir) public boolean detectWhetherAppIsFramework(File appDir)
throws AndrolibException { throws AndrolibException {
File publicXml = new File(appDir, "res/values/public.xml"); File publicXml = new File(appDir, "res/values/public.xml");
if (! publicXml.exists()) { if (!publicXml.exists()) {
return false; return false;
} }
Iterator<String> it; Iterator<String> it;
try { try {
it = IOUtils.lineIterator( it = IOUtils.lineIterator(new FileReader(new File(appDir,
new FileReader(new File(appDir, "res/values/public.xml"))); "res/values/public.xml")));
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
throw new AndrolibException( throw new AndrolibException(
"Could not detect whether app is framework one", ex); "Could not detect whether app is framework one", ex);
@ -295,42 +296,41 @@ final public class AndrolibResources {
new ResSmaliUpdater().tagResIDs(resTable, smaliDir); new ResSmaliUpdater().tagResIDs(resTable, smaliDir);
} }
public void updateSmaliResIDs(ResTable resTable, File smaliDir) throws AndrolibException { public void updateSmaliResIDs(ResTable resTable, File smaliDir)
throws AndrolibException {
new ResSmaliUpdater().updateResIDs(resTable, smaliDir); new ResSmaliUpdater().updateResIDs(resTable, smaliDir);
} }
public Duo<ResFileDecoder, AXmlResourceParser> getResFileDecoder() { public Duo<ResFileDecoder, AXmlResourceParser> getResFileDecoder() {
ResStreamDecoderContainer decoders = ResStreamDecoderContainer decoders = new ResStreamDecoderContainer();
new ResStreamDecoderContainer();
decoders.setDecoder("raw", new ResRawStreamDecoder()); decoders.setDecoder("raw", new ResRawStreamDecoder());
decoders.setDecoder("9patch", new Res9patchStreamDecoder()); decoders.setDecoder("9patch", new Res9patchStreamDecoder());
AXmlResourceParser axmlParser = new AXmlResourceParser(); AXmlResourceParser axmlParser = new AXmlResourceParser();
axmlParser.setAttrDecoder(new ResAttrDecoder()); axmlParser.setAttrDecoder(new ResAttrDecoder());
decoders.setDecoder("xml", decoders.setDecoder("xml", new XmlPullStreamDecoder(axmlParser,
new XmlPullStreamDecoder(axmlParser, getResXmlSerializer())); getResXmlSerializer()));
return new Duo<ResFileDecoder, AXmlResourceParser>( return new Duo<ResFileDecoder, AXmlResourceParser>(new ResFileDecoder(
new ResFileDecoder(decoders), axmlParser); decoders), axmlParser);
} }
public Duo<ResFileDecoder, AXmlResourceParser> getManifestFileDecoder() { public Duo<ResFileDecoder, AXmlResourceParser> getManifestFileDecoder() {
ResStreamDecoderContainer decoders = ResStreamDecoderContainer decoders = new ResStreamDecoderContainer();
new ResStreamDecoderContainer();
AXmlResourceParser axmlParser = new AXmlResourceParser(); AXmlResourceParser axmlParser = new AXmlResourceParser();
decoders.setDecoder("xml", decoders.setDecoder("xml", new XmlPullStreamDecoder(axmlParser,
new XmlPullStreamDecoder(axmlParser, getResXmlSerializer())); getResXmlSerializer()));
return new Duo<ResFileDecoder, AXmlResourceParser>( return new Duo<ResFileDecoder, AXmlResourceParser>(new ResFileDecoder(
new ResFileDecoder(decoders), axmlParser); decoders), axmlParser);
} }
public ExtMXSerializer getResXmlSerializer() { public ExtMXSerializer getResXmlSerializer() {
ExtMXSerializer serial = new ExtMXSerializer(); ExtMXSerializer serial = new ExtMXSerializer();
serial.setProperty(ExtXmlSerializer.PROPERTY_SERIALIZER_INDENTATION serial.setProperty(ExtXmlSerializer.PROPERTY_SERIALIZER_INDENTATION,
, " "); " ");
serial.setProperty(ExtXmlSerializer.PROPERTY_SERIALIZER_LINE_SEPARATOR, serial.setProperty(ExtXmlSerializer.PROPERTY_SERIALIZER_LINE_SEPARATOR,
System.getProperty("line.separator")); System.getProperty("line.separator"));
serial.setProperty(ExtMXSerializer.PROPERTY_DEFAULT_ENCODING, "utf-8"); serial.setProperty(ExtMXSerializer.PROPERTY_DEFAULT_ENCODING, "utf-8");
@ -360,11 +360,11 @@ final public class AndrolibResources {
serial.flush(); serial.flush();
outStream.close(); outStream.close();
} catch (IOException ex) { } catch (IOException ex) {
throw new AndrolibException( throw new AndrolibException("Could not generate: "
"Could not generate: " + valuesFile.getPath(), ex); + valuesFile.getPath(), ex);
} catch (DirectoryException ex) { } catch (DirectoryException ex) {
throw new AndrolibException( throw new AndrolibException("Could not generate: "
"Could not generate: " + valuesFile.getPath(), ex); + valuesFile.getPath(), ex);
} }
} }
@ -380,8 +380,8 @@ final public class AndrolibResources {
serial.startTag(null, "public"); serial.startTag(null, "public");
serial.attribute(null, "type", spec.getType().getName()); serial.attribute(null, "type", spec.getType().getName());
serial.attribute(null, "name", spec.getName()); serial.attribute(null, "name", spec.getName());
serial.attribute(null, "id", String.format( serial.attribute(null, "id",
"0x%08x", spec.getId().id)); String.format("0x%08x", spec.getId().id));
serial.endTag(null, "public"); serial.endTag(null, "public");
} }
@ -390,11 +390,11 @@ final public class AndrolibResources {
serial.flush(); serial.flush();
outStream.close(); outStream.close();
} catch (IOException ex) { } catch (IOException ex) {
throw new AndrolibException( throw new AndrolibException("Could not generate public.xml file",
"Could not generate public.xml file", ex); ex);
} catch (DirectoryException ex) { } catch (DirectoryException ex) {
throw new AndrolibException( throw new AndrolibException("Could not generate public.xml file",
"Could not generate public.xml file", ex); ex);
} }
} }
@ -402,8 +402,8 @@ final public class AndrolibResources {
ResTable resTable, boolean keepBroken) throws AndrolibException { ResTable resTable, boolean keepBroken) throws AndrolibException {
try { try {
return ARSCDecoder.decode( return ARSCDecoder.decode(
apkFile.getDirectory().getFileInput("resources.arsc"), false, apkFile.getDirectory().getFileInput("resources.arsc"),
keepBroken, resTable).getPackages(); false, keepBroken, resTable).getPackages();
} catch (DirectoryException ex) { } catch (DirectoryException ex) {
throw new AndrolibException( throw new AndrolibException(
"Could not load resources.arsc from file: " + apkFile, ex); "Could not load resources.arsc from file: " + apkFile, ex);
@ -431,8 +431,8 @@ final public class AndrolibResources {
InputStream in = null; InputStream in = null;
OutputStream out = null; OutputStream out = null;
try { try {
in = AndrolibResources.class.getResourceAsStream( in = AndrolibResources.class
"/brut/androlib/android-framework.jar"); .getResourceAsStream("/brut/androlib/android-framework.jar");
out = new FileOutputStream(apk); out = new FileOutputStream(apk);
IOUtils.copy(in, out); IOUtils.copy(in, out);
return apk; return apk;
@ -442,12 +442,14 @@ final public class AndrolibResources {
if (in != null) { if (in != null) {
try { try {
in.close(); in.close();
} catch (IOException ex) {} } catch (IOException ex) {
}
} }
if (out != null) { if (out != null) {
try { try {
out.close(); out.close();
} catch (IOException ex) {} } catch (IOException ex) {
}
} }
} }
} }
@ -470,13 +472,14 @@ final public class AndrolibResources {
in = zip.getInputStream(entry); in = zip.getInputStream(entry);
byte[] data = IOUtils.toByteArray(in); byte[] data = IOUtils.toByteArray(in);
ARSCData arsc = ARSCDecoder.decode( ARSCData arsc = ARSCDecoder.decode(new ByteArrayInputStream(data),
new ByteArrayInputStream(data), true, true); true, true);
publicizeResources(data, arsc.getFlagsOffsets()); publicizeResources(data, arsc.getFlagsOffsets());
File outFile = new File(getFrameworkDir(), File outFile = new File(getFrameworkDir(), String.valueOf(arsc
String.valueOf(arsc.getOnePackage().getId()) + .getOnePackage().getId())
(tag == null ? "" : '-' + tag) + ".apk"); + (tag == null ? "" : '-' + tag)
+ ".apk");
out = new ZipOutputStream(new FileOutputStream(outFile)); out = new ZipOutputStream(new FileOutputStream(outFile));
out.setMethod(ZipOutputStream.STORED); out.setMethod(ZipOutputStream.STORED);
@ -496,12 +499,14 @@ final public class AndrolibResources {
if (in != null) { if (in != null) {
try { try {
in.close(); in.close();
} catch (IOException ex) {} } catch (IOException ex) {
}
} }
if (out != null) { if (out != null) {
try { try {
out.close(); out.close();
} catch (IOException ex) {} } catch (IOException ex) {
}
} }
} }
} }
@ -525,12 +530,14 @@ final public class AndrolibResources {
if (in != null) { if (in != null) {
try { try {
in.close(); in.close();
} catch (IOException ex) {} } catch (IOException ex) {
}
} }
if (out != null) { if (out != null) {
try { try {
out.close(); out.close();
} catch (IOException ex) {} } catch (IOException ex) {
}
} }
} }
} }
@ -546,7 +553,7 @@ final public class AndrolibResources {
for (FlagsOffset flags : flagsOffsets) { for (FlagsOffset flags : flagsOffsets) {
int offset = flags.offset + 3; int offset = flags.offset + 3;
int end = offset + 4 * flags.count; int end = offset + 4 * flags.count;
while(offset < end) { while (offset < end) {
arsc[offset] |= (byte) 0x40; arsc[offset] |= (byte) 0x40;
offset += 4; offset += 4;
} }
@ -561,17 +568,18 @@ final public class AndrolibResources {
path = sFrameworkFolder; path = sFrameworkFolder;
} else if (System.getProperty("os.name").equals("Mac OS X")) { } else if (System.getProperty("os.name").equals("Mac OS X")) {
/* store in user-home, for Mac OS X */ /* store in user-home, for Mac OS X */
path = System.getProperty("user.home") + File.separatorChar + path = System.getProperty("user.home") + File.separatorChar
"Library/apktool/framework"; } + "Library/apktool/framework";
else { } else {
path = System.getProperty("user.home") + File.separatorChar + path = System.getProperty("user.home") + File.separatorChar
"apktool" + File.separatorChar + "framework"; + "apktool" + File.separatorChar + "framework";
} }
File dir = new File(path); File dir = new File(path);
if (! dir.exists()) { if (!dir.exists()) {
if (! dir.mkdirs()) { if (!dir.mkdirs()) {
if (sFrameworkFolder != null) { if (sFrameworkFolder != null) {
System.out.println("Can't create Framework directory: " + dir); System.out.println("Can't create Framework directory: "
+ dir);
} }
throw new AndrolibException("Can't create directory: " + dir); throw new AndrolibException("Can't create directory: " + dir);
} }
@ -581,19 +589,19 @@ final public class AndrolibResources {
public File getAndroidResourcesFile() throws AndrolibException { public File getAndroidResourcesFile() throws AndrolibException {
try { try {
return Jar.getResourceAsFile("/brut/androlib/android-framework.jar"); return Jar
.getResourceAsFile("/brut/androlib/android-framework.jar");
} catch (BrutException ex) { } catch (BrutException ex) {
throw new AndrolibException(ex); throw new AndrolibException(ex);
} }
} }
// TODO: dirty static hack. I have to refactor decoding mechanisms. // TODO: dirty static hack. I have to refactor decoding mechanisms.
public static boolean sKeepBroken = false; public static boolean sKeepBroken = false;
public static String sFrameworkFolder = null; public static String sFrameworkFolder = null;
private final static Logger LOGGER = private final static Logger LOGGER = Logger
Logger.getLogger(AndrolibResources.class.getName()); .getLogger(AndrolibResources.class.getName());
private String mMinSdkVersion = null; private String mMinSdkVersion = null;
private String mMaxSdkVersion = null; private String mMaxSdkVersion = null;

View File

@ -143,4 +143,8 @@ public class ResTable {
public Map<String, String> getPackageInfo() { public Map<String, String> getPackageInfo() {
return mPackageInfo; return mPackageInfo;
} }
public boolean isPackageInfoValueSet(String key) {
return (mPackageInfo.containsKey(key));
}
} }

View File

@ -83,6 +83,10 @@ public class ARSCDecoder {
packages[i] = readPackage(); packages[i] = readPackage();
} }
// store package
if (this.mResTable.isPackageInfoValueSet("cur_package") != true) {
this.mResTable.addPackageInfo("cur_package", packages[0].getName());
}
return packages; return packages;
} }

View File

@ -53,30 +53,31 @@ public class XmlPullStreamDecoder implements ResStreamDecoder {
if ("manifest".equalsIgnoreCase(pp.getName())) { if ("manifest".equalsIgnoreCase(pp.getName())) {
try { try {
hidePackageInfo = parseManifest(pp); hidePackageInfo = parseManifest(pp);
if (hidePackageInfo) {
return;
}
} catch (AndrolibException e) {} } catch (AndrolibException e) {}
} }else if ("uses-sdk".equalsIgnoreCase(pp.getName())) {
if ("uses-sdk".equalsIgnoreCase(pp.getName())) {
try { try {
hideSdkInfo = parseAttr(pp); hideSdkInfo = parseAttr(pp);
if(hideSdkInfo) {
return;
}
} catch (AndrolibException e) {} } catch (AndrolibException e) {}
} }
} else if (hideSdkInfo && type == XmlPullParser.END_TAG && } else if (hideSdkInfo && type == XmlPullParser.END_TAG &&
"uses-sdk".equalsIgnoreCase(pp.getName())) { "uses-sdk".equalsIgnoreCase(pp.getName()) ||
hidePackageInfo && type == XmlPullParser.END_TAG &&
"manifest".equalsIgnoreCase(pp.getName())) {
return; return;
} }
super.event(pp); super.event(pp);
} }
private boolean parseManifest(XmlPullParser pp) throws AndrolibException { private boolean parseManifest(XmlPullParser pp) throws AndrolibException {
ResTable restable = resTable;
// @todo read <manifest> for package: // read <manifest> for package:
return false; for (int i = 0; i < pp.getAttributeCount(); i++) {
if (pp.getAttributeName(i).equalsIgnoreCase(("package"))) {
restable.addPackageInfo("orig_package", pp.getAttributeValue(i));
}
}
return true;
} }
private boolean parseAttr(XmlPullParser pp) throws AndrolibException { private boolean parseAttr(XmlPullParser pp) throws AndrolibException {