diff --git a/src/main/java/com/reandroid/lib/apk/ApkModuleXmlDecoder.java b/src/main/java/com/reandroid/lib/apk/ApkModuleXmlDecoder.java index 3a45aaa..0416e53 100644 --- a/src/main/java/com/reandroid/lib/apk/ApkModuleXmlDecoder.java +++ b/src/main/java/com/reandroid/lib/apk/ApkModuleXmlDecoder.java @@ -29,6 +29,7 @@ import com.reandroid.lib.arsc.value.*; import com.reandroid.lib.common.EntryStore; import com.reandroid.lib.common.Frameworks; import com.reandroid.lib.common.TableEntryStore; +import com.reandroid.lib.json.JSONObject; import com.reandroid.xml.XMLAttribute; import com.reandroid.xml.XMLDocument; import com.reandroid.xml.XMLElement; @@ -58,6 +59,9 @@ import java.util.*; entryStore.add(Frameworks.getAndroid()); TableBlock tableBlock=apkModule.getTableBlock(); entryStore.add(tableBlock); + + decodePackageInfo(outDir, tableBlock); + xmlBagDecoder=new XMLBagDecoder(entryStore); decodePublicXml(tableBlock, outDir); @@ -75,6 +79,17 @@ import java.util.*; extractRootFiles(outDir); } + private void decodePackageInfo(File outDir, TableBlock tableBlock) throws IOException { + for(PackageBlock packageBlock:tableBlock.listPackages()){ + decodePackageInfo(outDir, packageBlock); + } + } + private void decodePackageInfo(File outDir, PackageBlock packageBlock) throws IOException { + File pkgDir = new File(outDir, getPackageDirName(packageBlock)); + File packageJsonFile = new File(pkgDir, PackageBlock.JSON_FILE_NAME); + JSONObject jsonObject = packageBlock.toJson(false); + jsonObject.write(packageJsonFile); + } private void decodeUncompressedFiles(File outDir) throws IOException { File file=new File(outDir, UncompressedFiles.JSON_FILE); diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/PackageCreator.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/PackageCreator.java index 5232a47..73f244d 100644 --- a/src/main/java/com/reandroid/lib/apk/xmlencoder/PackageCreator.java +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/PackageCreator.java @@ -15,11 +15,16 @@ */ package com.reandroid.lib.apk.xmlencoder; +import com.reandroid.lib.apk.APKLogger; import com.reandroid.lib.apk.ResourceIds; import com.reandroid.lib.arsc.chunk.PackageBlock; import com.reandroid.lib.arsc.chunk.TableBlock; import com.reandroid.lib.arsc.pool.TypeStringPool; +import com.reandroid.lib.json.JSONObject; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -27,8 +32,14 @@ class PackageCreator { private List mSpecNames; private String mPackageName; private int mPackageId; + private File packageDirectory; + private APKLogger apkLogger; public PackageCreator(){ } + + public void setPackageDirectory(File packageDirectory) { + this.packageDirectory = packageDirectory; + } public void setPackageName(String name){ this.mPackageName=name; } @@ -37,6 +48,9 @@ class PackageCreator { PackageBlock packageBlock=new PackageBlock(); packageBlock.setName(mPackageName); packageBlock.setId(mPackageId); + + loadPackageInfoJson(packageBlock); + tableBlock.getPackageArray() .add(packageBlock); packageBlock.getSpecStringPool() @@ -46,6 +60,33 @@ class PackageCreator { return packageBlock; } + private void loadPackageInfoJson(PackageBlock packageBlock){ + File dir = this.packageDirectory; + if(dir==null || !dir.isDirectory()){ + return; + } + String simplePath = dir.getName() + File.separator + + PackageBlock.JSON_FILE_NAME; + logMessage("Loading: " + simplePath); + File file = new File(dir, PackageBlock.JSON_FILE_NAME); + if(!file.isFile()){ + logMessage("W: File not found, this could be decompiled using old version: '" + + simplePath+"'"); + return; + } + JSONObject jsonObject; + try { + FileInputStream inputStream = new FileInputStream(file); + jsonObject = new JSONObject(inputStream); + inputStream.close(); + } catch (IOException ex) { + logMessage("Error loading: '" + simplePath + + "', "+ex.getMessage()); + return; + } + packageBlock.fromJson(jsonObject); + logMessage("OK: " + simplePath); + } private void initTypeStringPool(PackageBlock packageBlock, ResourceIds.Table.Package pkgResourceIds){ @@ -68,4 +109,22 @@ class PackageCreator { mSpecNames.add(entry.getName()); } } + public void setAPKLogger(APKLogger logger) { + this.apkLogger = logger; + } + private void logMessage(String msg) { + if(apkLogger!=null){ + apkLogger.logMessage(msg); + } + } + private void logError(String msg, Throwable tr) { + if(apkLogger!=null){ + apkLogger.logError(msg, tr); + } + } + private void logVerbose(String msg) { + if(apkLogger!=null){ + apkLogger.logVerbose(msg); + } + } } diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java index 849a497..05d8d60 100644 --- a/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java @@ -79,10 +79,7 @@ ResourceIds.Table.Package pkgResourceIds=map.get(pubXmlFile); addParsedFiles(pubXmlFile); - PackageCreator packageCreator = new PackageCreator(); - packageCreator.setPackageName(pkgResourceIds.name); - - PackageBlock packageBlock = packageCreator.createNew(tableBlock, pkgResourceIds); + PackageBlock packageBlock = createPackage(pkgResourceIds, pubXmlFile); encodeMaterials.setCurrentPackage(packageBlock); packageBlockMap.put(pubXmlFile, packageBlock); @@ -109,9 +106,7 @@ PackageBlock packageBlock=packageBlockMap.get(pubXmlFile); if(packageBlock==null){ - PackageCreator packageCreator = new PackageCreator(); - packageCreator.setPackageName(pkgResourceIds.name); - packageBlock = packageCreator.createNew(tableBlock, pkgResourceIds); + packageBlock = createPackage(pkgResourceIds, pubXmlFile); } encodeMaterials.setCurrentPackage(packageBlock); @@ -135,6 +130,14 @@ } tableBlock.refresh(); } + private PackageBlock createPackage(ResourceIds.Table.Package pkgResourceIds + , File pubXmlFile){ + PackageCreator packageCreator = new PackageCreator(); + packageCreator.setPackageName(pkgResourceIds.name); + packageCreator.setAPKLogger(apkLogger); + packageCreator.setPackageDirectory(toPackageDirectory(pubXmlFile)); + return packageCreator.createNew(this.tableBlock, pkgResourceIds); + } private void preloadStringPool(List pubXmlFileList){ logMessage("Loading string pool ..."); ValuesStringPoolBuilder poolBuilder=new ValuesStringPoolBuilder(); @@ -205,6 +208,10 @@ File root = packageDirectory.getParentFile(); return new File(root, AndroidManifestBlock.FILE_NAME); } + private File toPackageDirectory(File pubXmlFile){ + return toResDirectory(pubXmlFile) + .getParentFile(); + } private File toResDirectory(File pubXmlFile){ return pubXmlFile .getParentFile() @@ -262,6 +269,7 @@ } public void setAPKLogger(APKLogger logger) { this.apkLogger = logger; + this.apkModule.setAPKLogger(logger); } private void logMessage(String msg) { if(apkLogger!=null){ diff --git a/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java b/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java index fdacb83..fb8c58e 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java @@ -228,8 +228,11 @@ public class SpecTypePairArray extends BlockArray } @Override public void fromJson(JSONArray json) { - int length= json.length(); clearChildes(); + if(json==null){ + return; + } + int length = json.length(); ensureSize(length); for (int i=0;i listStagedAlias(){ + return getStagedAliasList().getChildes(); + } public BlockList getStagedAliasList(){ return mBody.getStagedAliasList(); } @@ -150,7 +153,7 @@ package com.reandroid.lib.arsc.chunk; public void addLibraryInfo(LibraryInfo info){ getLibraryBlock().addLibraryInfo(info); } - private LibraryBlock getLibraryBlock(){ + public LibraryBlock getLibraryBlock(){ return mBody.getLibraryBlock(); } public Set listResourceIds(){ @@ -293,13 +296,18 @@ package com.reandroid.lib.arsc.chunk; @Override public JSONObject toJson() { + return toJson(true); + } + public JSONObject toJson(boolean addSpecs) { JSONObject jsonObject=new JSONObject(); jsonObject.put(BuildInfo.NAME_arsc_lib_version, BuildInfo.getVersion()); jsonObject.put(NAME_package_id, getId()); jsonObject.put(NAME_package_name, getName()); - jsonObject.put(NAME_specs, getSpecTypePairArray().toJson()); + if(addSpecs){ + jsonObject.put(NAME_specs, getSpecTypePairArray().toJson()); + } LibraryInfoArray libraryInfoArray = getLibraryBlock().getLibraryInfoArray(); if(libraryInfoArray.childesCount()>0){ jsonObject.put(NAME_libraries,libraryInfoArray.toJson()); @@ -316,7 +324,7 @@ package com.reandroid.lib.arsc.chunk; public void fromJson(JSONObject json) { setId(json.getInt(NAME_package_id)); setName(json.getString(NAME_package_name)); - getSpecTypePairArray().fromJson(json.getJSONArray(NAME_specs)); + getSpecTypePairArray().fromJson(json.optJSONArray(NAME_specs)); LibraryInfoArray libraryInfoArray = getLibraryBlock().getLibraryInfoArray(); libraryInfoArray.fromJson(json.optJSONArray(NAME_libraries)); if(json.has(NAME_staged_aliases)){ @@ -370,6 +378,6 @@ package com.reandroid.lib.arsc.chunk; public static final String NAME_package_name = "package_name"; public static final String JSON_FILE_NAME = "package.json"; private static final String NAME_specs="specs"; - private static final String NAME_libraries="libraries"; + public static final String NAME_libraries="libraries"; public static final String NAME_staged_aliases="staged_aliases"; }