diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java index 2b674534..a429154f 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java @@ -43,97 +43,97 @@ import org.yaml.snakeyaml.Yaml; * @author Ryszard Wiśniewski */ public class Androlib { - private final AndrolibResources mAndRes = new AndrolibResources(); + private final AndrolibResources mAndRes = new AndrolibResources(); - public ResTable getResTable(ExtFile apkFile) throws AndrolibException { - return mAndRes.getResTable(apkFile, true); - } + public ResTable getResTable(ExtFile apkFile) throws AndrolibException { + return mAndRes.getResTable(apkFile, true); + } - public ResTable getResTable(ExtFile apkFile, boolean loadMainPkg) - throws AndrolibException { - return mAndRes.getResTable(apkFile, loadMainPkg); - } + public ResTable getResTable(ExtFile apkFile, boolean loadMainPkg) + throws AndrolibException { + return mAndRes.getResTable(apkFile, loadMainPkg); + } - public void decodeSourcesRaw(ExtFile apkFile, File outDir, boolean debug) - throws AndrolibException { - try { - Directory apk = apkFile.getDirectory(); - LOGGER.info("Copying raw classes.dex file..."); - apkFile.getDirectory().copyToDir(outDir, "classes.dex"); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } - } + public void decodeSourcesRaw(ExtFile apkFile, File outDir, boolean debug) + throws AndrolibException { + try { + Directory apk = apkFile.getDirectory(); + LOGGER.info("Copying raw classes.dex file..."); + apkFile.getDirectory().copyToDir(outDir, "classes.dex"); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + } - public void decodeSourcesSmali(File apkFile, File outDir, boolean debug, String debugLinePrefix, - boolean bakdeb, int api) throws AndrolibException { - try { - File smaliDir = new File(outDir, SMALI_DIRNAME); - OS.rmdir(smaliDir); - smaliDir.mkdirs(); - LOGGER.info("Baksmaling..."); - SmaliDecoder.decode(apkFile, smaliDir, debug, debugLinePrefix, bakdeb, api); - } catch (BrutException ex) { - throw new AndrolibException(ex); - } - } + public void decodeSourcesSmali(File apkFile, File outDir, boolean debug, String debugLinePrefix, + boolean bakdeb, int api) throws AndrolibException { + try { + File smaliDir = new File(outDir, SMALI_DIRNAME); + OS.rmdir(smaliDir); + smaliDir.mkdirs(); + LOGGER.info("Baksmaling..."); + SmaliDecoder.decode(apkFile, smaliDir, debug, debugLinePrefix, bakdeb, api); + } catch (BrutException ex) { + throw new AndrolibException(ex); + } + } - public void decodeSourcesJava(ExtFile apkFile, File outDir, boolean debug) - throws AndrolibException { - LOGGER.info("Decoding Java sources..."); - new AndrolibJava().decode(apkFile, outDir); - } + public void decodeSourcesJava(ExtFile apkFile, File outDir, boolean debug) + throws AndrolibException { + LOGGER.info("Decoding Java sources..."); + new AndrolibJava().decode(apkFile, outDir); + } - public void decodeManifestRaw(ExtFile apkFile, File outDir) - throws AndrolibException { - try { - Directory apk = apkFile.getDirectory(); - LOGGER.info("Copying raw manifest..."); - apkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } - } + public void decodeManifestRaw(ExtFile apkFile, File outDir) + throws AndrolibException { + try { + Directory apk = apkFile.getDirectory(); + LOGGER.info("Copying raw manifest..."); + apkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + } - public void decodeManifestFull(ExtFile apkFile, File outDir, - ResTable resTable) throws AndrolibException { - mAndRes.decodeManifest(resTable, apkFile, outDir); - } + public void decodeManifestFull(ExtFile apkFile, File outDir, + ResTable resTable) throws AndrolibException { + mAndRes.decodeManifest(resTable, apkFile, outDir); + } - public void decodeResourcesRaw(ExtFile apkFile, File outDir) - throws AndrolibException { - try { - // Directory apk = apkFile.getDirectory(); - LOGGER.info("Copying raw resources..."); - apkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } - } + public void decodeResourcesRaw(ExtFile apkFile, File outDir) + throws AndrolibException { + try { + // Directory apk = apkFile.getDirectory(); + LOGGER.info("Copying raw resources..."); + apkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + } - public void decodeResourcesFull(ExtFile apkFile, File outDir, - ResTable resTable) throws AndrolibException { - mAndRes.decode(resTable, apkFile, outDir); - } + public void decodeResourcesFull(ExtFile apkFile, File outDir, + ResTable resTable) throws AndrolibException { + mAndRes.decode(resTable, apkFile, outDir); + } - public void decodeRawFiles(ExtFile apkFile, File outDir) - throws AndrolibException { - LOGGER.info("Copying assets and libs..."); - try { - Directory in = apkFile.getDirectory(); - if (in.containsDir("assets")) { - in.copyToDir(outDir, "assets"); - } - if (in.containsDir("lib")) { - in.copyToDir(outDir, "lib"); - } + public void decodeRawFiles(ExtFile apkFile, File outDir) + throws AndrolibException { + LOGGER.info("Copying assets and libs..."); + try { + Directory in = apkFile.getDirectory(); + if (in.containsDir("assets")) { + in.copyToDir(outDir, "assets"); + } + if (in.containsDir("lib")) { + in.copyToDir(outDir, "lib"); + } if (in.containsDir("libs")) { in.copyToDir(outDir, "libs"); } - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } - } + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + } private boolean isAPKFileNames(String file) { for (String apkFile : APK_STANDARD_ALL_FILENAMES) { @@ -189,354 +189,354 @@ public class Androlib { } } - public void writeOriginalFiles(ExtFile apkFile, File outDir) - throws AndrolibException { - LOGGER.info("Copying original files..."); - File originalDir = new File(outDir, "original"); - if (!originalDir.exists()) { - originalDir.mkdirs(); - } + public void writeOriginalFiles(ExtFile apkFile, File outDir) + throws AndrolibException { + LOGGER.info("Copying original files..."); + File originalDir = new File(outDir, "original"); + if (!originalDir.exists()) { + originalDir.mkdirs(); + } - try { - Directory in = apkFile.getDirectory(); - if(in.containsFile("AndroidManifest.xml")) { - in.copyToDir(originalDir, "AndroidManifest.xml"); - } - if (in.containsDir("META-INF")) { - in.copyToDir(originalDir, "META-INF"); - } - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } - } + try { + Directory in = apkFile.getDirectory(); + if(in.containsFile("AndroidManifest.xml")) { + in.copyToDir(originalDir, "AndroidManifest.xml"); + } + if (in.containsDir("META-INF")) { + in.copyToDir(originalDir, "META-INF"); + } + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + } - public void writeMetaFile(File mOutDir, Map meta) - throws AndrolibException { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - // options.setIndent(4); - Yaml yaml = new Yaml(options); + public void writeMetaFile(File mOutDir, Map meta) + throws AndrolibException { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + // options.setIndent(4); + Yaml yaml = new Yaml(options); - FileWriter writer = null; - try { - writer = new FileWriter(new File(mOutDir, "apktool.yml")); - yaml.dump(meta, writer); - } catch (IOException ex) { - throw new AndrolibException(ex); - } finally { - if (writer != null) { - try { - writer.close(); - } catch (IOException ex) { - } - } - } - } + FileWriter writer = null; + try { + writer = new FileWriter(new File(mOutDir, "apktool.yml")); + yaml.dump(meta, writer); + } catch (IOException ex) { + throw new AndrolibException(ex); + } finally { + if (writer != null) { + try { + writer.close(); + } catch (IOException ex) { + } + } + } + } - public Map readMetaFile(ExtFile appDir) - throws AndrolibException { - InputStream in = null; - try { - in = appDir.getDirectory().getFileInput("apktool.yml"); - Yaml yaml = new Yaml(); - return (Map) yaml.load(in); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException ex) { - } - } - } - } + public Map readMetaFile(ExtFile appDir) + throws AndrolibException { + InputStream in = null; + try { + in = appDir.getDirectory().getFileInput("apktool.yml"); + Yaml yaml = new Yaml(); + return (Map) yaml.load(in); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException ex) { + } + } + } + } - public void build(File appDir, File outFile, - HashMap flags, String aaptPath) - throws BrutException { - build(new ExtFile(appDir), outFile, flags, aaptPath); - } + public void build(File appDir, File outFile, + HashMap flags, String aaptPath) + throws BrutException { + build(new ExtFile(appDir), outFile, flags, aaptPath); + } - public void build(ExtFile appDir, File outFile, - HashMap flags, String aaptPath) - throws BrutException { + public void build(ExtFile appDir, File outFile, + HashMap flags, String aaptPath) + throws BrutException { LOGGER.info("Using Apktool " + Androlib.getVersion() + " on " + appDir.getName()); mAaptPath = aaptPath; - Map meta = readMetaFile(appDir); - Object t1 = meta.get("isFrameworkApk"); - flags.put("framework", t1 == null ? false : (Boolean) t1); - flags.put("compression", meta.get("compressionType") == null ? false - : Boolean.valueOf(meta.get("compressionType").toString())); - mAndRes.setSdkInfo((Map) meta.get("sdkInfo")); - mAndRes.setPackageId((Map) meta.get("packageInfo")); + Map meta = readMetaFile(appDir); + Object t1 = meta.get("isFrameworkApk"); + flags.put("framework", t1 == null ? false : (Boolean) t1); + flags.put("compression", meta.get("compressionType") == null ? false + : Boolean.valueOf(meta.get("compressionType").toString())); + mAndRes.setSdkInfo((Map) meta.get("sdkInfo")); + mAndRes.setPackageId((Map) meta.get("packageInfo")); mAndRes.setPackageInfo((Map) meta.get("packageInfo")); - mAndRes.setVersionInfo((Map) meta.get("versionInfo")); + mAndRes.setVersionInfo((Map) meta.get("versionInfo")); - if (outFile == null) { - String outFileName = (String) meta.get("apkFileName"); - outFile = new File(appDir, "dist" + File.separator - + (outFileName == null ? "out.apk" : outFileName)); - } + if (outFile == null) { + String outFileName = (String) meta.get("apkFileName"); + outFile = new File(appDir, "dist" + File.separator + + (outFileName == null ? "out.apk" : outFileName)); + } - new File(appDir, APK_DIRNAME).mkdirs(); - buildSources(appDir, flags); - buildResources(appDir, flags, - (Map) meta.get("usesFramework")); - buildLib(appDir, flags); - buildCopyOriginalFiles(appDir, flags); - buildApk(appDir, outFile, flags); + new File(appDir, APK_DIRNAME).mkdirs(); + buildSources(appDir, flags); + buildResources(appDir, flags, + (Map) meta.get("usesFramework")); + buildLib(appDir, flags); + buildCopyOriginalFiles(appDir, flags); + buildApk(appDir, outFile, flags); // we must go after the Apk is built, and copy the files in via Zip // this is because Aapt won't add files it doesn't know (ex unknown files) buildUnknownFiles(appDir,outFile,meta); - } + } - public void buildSources(File appDir, HashMap flags) - throws AndrolibException { - if (!buildSourcesRaw(appDir, flags) - && !buildSourcesSmali(appDir, flags) - && !buildSourcesJava(appDir, flags)) { - LOGGER.warning("Could not find sources"); - } - } + public void buildSources(File appDir, HashMap flags) + throws AndrolibException { + if (!buildSourcesRaw(appDir, flags) + && !buildSourcesSmali(appDir, flags) + && !buildSourcesJava(appDir, flags)) { + LOGGER.warning("Could not find sources"); + } + } - public boolean buildSourcesRaw(File appDir, HashMap flags) - throws AndrolibException { - try { - File working = new File(appDir, "classes.dex"); - if (!working.exists()) { - return false; - } - File stored = new File(appDir, APK_DIRNAME + "/classes.dex"); - if (flags.get("forceBuildAll") || isModified(working, stored)) { - LOGGER.info("Copying classes.dex file..."); - BrutIO.copyAndClose(new FileInputStream(working), - new FileOutputStream(stored)); - } - return true; - } catch (IOException ex) { - throw new AndrolibException(ex); - } - } + public boolean buildSourcesRaw(File appDir, HashMap flags) + throws AndrolibException { + try { + File working = new File(appDir, "classes.dex"); + if (!working.exists()) { + return false; + } + File stored = new File(appDir, APK_DIRNAME + "/classes.dex"); + if (flags.get("forceBuildAll") || isModified(working, stored)) { + LOGGER.info("Copying classes.dex file..."); + BrutIO.copyAndClose(new FileInputStream(working), + new FileOutputStream(stored)); + } + return true; + } catch (IOException ex) { + throw new AndrolibException(ex); + } + } - public boolean buildSourcesSmali(File appDir, HashMap flags) - throws AndrolibException { - ExtFile smaliDir = new ExtFile(appDir, "smali"); - if (!smaliDir.exists()) { - return false; - } - File dex = new File(appDir, APK_DIRNAME + "/classes.dex"); - if (!flags.get("forceBuildAll")) { - LOGGER.info("Checking whether sources has changed..."); - } - if (flags.get("forceBuildAll") || isModified(smaliDir, dex)) { - LOGGER.info("Smaling..."); - dex.delete(); - SmaliBuilder.build(smaliDir, dex, flags); - } - return true; - } + public boolean buildSourcesSmali(File appDir, HashMap flags) + throws AndrolibException { + ExtFile smaliDir = new ExtFile(appDir, "smali"); + if (!smaliDir.exists()) { + return false; + } + File dex = new File(appDir, APK_DIRNAME + "/classes.dex"); + if (!flags.get("forceBuildAll")) { + LOGGER.info("Checking whether sources has changed..."); + } + if (flags.get("forceBuildAll") || isModified(smaliDir, dex)) { + LOGGER.info("Smaling..."); + dex.delete(); + SmaliBuilder.build(smaliDir, dex, flags); + } + return true; + } - public boolean buildSourcesJava(File appDir, HashMap flags) - throws AndrolibException { - File javaDir = new File(appDir, "src"); - if (!javaDir.exists()) { - return false; - } - File dex = new File(appDir, APK_DIRNAME + "/classes.dex"); - if (!flags.get("forceBuildAll")) { - LOGGER.info("Checking whether sources has changed..."); - } - if (flags.get("forceBuildAll") || isModified(javaDir, dex)) { - LOGGER.info("Building java sources..."); - dex.delete(); - new AndrolibJava().build(javaDir, dex); - } - return true; - } + public boolean buildSourcesJava(File appDir, HashMap flags) + throws AndrolibException { + File javaDir = new File(appDir, "src"); + if (!javaDir.exists()) { + return false; + } + File dex = new File(appDir, APK_DIRNAME + "/classes.dex"); + if (!flags.get("forceBuildAll")) { + LOGGER.info("Checking whether sources has changed..."); + } + if (flags.get("forceBuildAll") || isModified(javaDir, dex)) { + LOGGER.info("Building java sources..."); + dex.delete(); + new AndrolibJava().build(javaDir, dex); + } + return true; + } - public void buildResources(ExtFile appDir, HashMap flags, - Map usesFramework) throws BrutException { - if (!buildResourcesRaw(appDir, flags) - && !buildResourcesFull(appDir, flags, usesFramework) - && !buildManifest(appDir, flags, usesFramework)) { - LOGGER.warning("Could not find resources"); - } - } + public void buildResources(ExtFile appDir, HashMap flags, + Map usesFramework) throws BrutException { + if (!buildResourcesRaw(appDir, flags) + && !buildResourcesFull(appDir, flags, usesFramework) + && !buildManifest(appDir, flags, usesFramework)) { + LOGGER.warning("Could not find resources"); + } + } - public boolean buildResourcesRaw(ExtFile appDir, - HashMap flags) throws AndrolibException { - try { - if (!new File(appDir, "resources.arsc").exists()) { - return false; - } - File apkDir = new File(appDir, APK_DIRNAME); - if (!flags.get("forceBuildAll")) { - LOGGER.info("Checking whether resources has changed..."); - } - if (flags.get("forceBuildAll") - || isModified(newFiles(APK_RESOURCES_FILENAMES, appDir), - newFiles(APK_RESOURCES_FILENAMES, apkDir))) { - LOGGER.info("Copying raw resources..."); - appDir.getDirectory() - .copyToDir(apkDir, APK_RESOURCES_FILENAMES); - } - return true; - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } - } + public boolean buildResourcesRaw(ExtFile appDir, + HashMap flags) throws AndrolibException { + try { + if (!new File(appDir, "resources.arsc").exists()) { + return false; + } + File apkDir = new File(appDir, APK_DIRNAME); + if (!flags.get("forceBuildAll")) { + LOGGER.info("Checking whether resources has changed..."); + } + if (flags.get("forceBuildAll") + || isModified(newFiles(APK_RESOURCES_FILENAMES, appDir), + newFiles(APK_RESOURCES_FILENAMES, apkDir))) { + LOGGER.info("Copying raw resources..."); + appDir.getDirectory() + .copyToDir(apkDir, APK_RESOURCES_FILENAMES); + } + return true; + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + } - public boolean buildResourcesFull(File appDir, - HashMap flags, Map usesFramework) - throws AndrolibException { - try { - if (!new File(appDir, "res").exists()) { - return false; - } - if (!flags.get("forceBuildAll")) { - LOGGER.info("Checking whether resources has changed..."); - } - File apkDir = new File(appDir, APK_DIRNAME); - if (flags.get("forceBuildAll") - || isModified(newFiles(APP_RESOURCES_FILENAMES, appDir), - newFiles(APK_RESOURCES_FILENAMES, apkDir))) { - LOGGER.info("Building resources..."); + public boolean buildResourcesFull(File appDir, + HashMap flags, Map usesFramework) + throws AndrolibException { + try { + if (!new File(appDir, "res").exists()) { + return false; + } + if (!flags.get("forceBuildAll")) { + LOGGER.info("Checking whether resources has changed..."); + } + File apkDir = new File(appDir, APK_DIRNAME); + if (flags.get("forceBuildAll") + || isModified(newFiles(APP_RESOURCES_FILENAMES, appDir), + newFiles(APK_RESOURCES_FILENAMES, apkDir))) { + LOGGER.info("Building resources..."); - File apkFile = File.createTempFile("APKTOOL", null); - apkFile.delete(); + File apkFile = File.createTempFile("APKTOOL", null); + apkFile.delete(); - File ninePatch = new File(appDir, "9patch"); - if (!ninePatch.exists()) { - ninePatch = null; - } - mAndRes.aaptPackage(apkFile, new File(appDir, - "AndroidManifest.xml"), new File(appDir, "res"), - ninePatch, null, parseUsesFramework(usesFramework), - flags, mAaptPath); + File ninePatch = new File(appDir, "9patch"); + if (!ninePatch.exists()) { + ninePatch = null; + } + mAndRes.aaptPackage(apkFile, new File(appDir, + "AndroidManifest.xml"), new File(appDir, "res"), + ninePatch, null, parseUsesFramework(usesFramework), + flags, mAaptPath); - Directory tmpDir = new ExtFile(apkFile).getDirectory(); - tmpDir.copyToDir(apkDir, - tmpDir.containsDir("res") ? APK_RESOURCES_FILENAMES - : APK_RESOURCES_WITHOUT_RES_FILENAMES); + Directory tmpDir = new ExtFile(apkFile).getDirectory(); + tmpDir.copyToDir(apkDir, + tmpDir.containsDir("res") ? APK_RESOURCES_FILENAMES + : APK_RESOURCES_WITHOUT_RES_FILENAMES); - // delete tmpDir - apkFile.delete(); - } - return true; - } catch (IOException ex) { - throw new AndrolibException(ex); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } catch (BrutException ex) { - throw new AndrolibException(ex); - } - } + // delete tmpDir + apkFile.delete(); + } + return true; + } catch (IOException ex) { + throw new AndrolibException(ex); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } catch (BrutException ex) { + throw new AndrolibException(ex); + } + } - public boolean buildManifestRaw(ExtFile appDir, - HashMap flags) throws AndrolibException { - try { - File apkDir = new File(appDir, APK_DIRNAME); - LOGGER.info("Copying raw AndroidManifest.xml..."); - appDir.getDirectory().copyToDir(apkDir, APK_MANIFEST_FILENAMES); - return true; - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } - } + public boolean buildManifestRaw(ExtFile appDir, + HashMap flags) throws AndrolibException { + try { + File apkDir = new File(appDir, APK_DIRNAME); + LOGGER.info("Copying raw AndroidManifest.xml..."); + appDir.getDirectory().copyToDir(apkDir, APK_MANIFEST_FILENAMES); + return true; + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + } - public boolean buildManifest(ExtFile appDir, - HashMap flags, Map usesFramework) - throws BrutException { - try { - if (!new File(appDir, "AndroidManifest.xml").exists()) { - return false; - } - if (!flags.get("forceBuildAll")) { - LOGGER.info("Checking whether resources has changed..."); - } - - File apkDir = new File(appDir, APK_DIRNAME); - - if (flags.get("debug")) { - mAndRes.remove_application_debug(new File(apkDir,"AndroidManifest.xml").getAbsolutePath()); - } + public boolean buildManifest(ExtFile appDir, + HashMap flags, Map usesFramework) + throws BrutException { + try { + if (!new File(appDir, "AndroidManifest.xml").exists()) { + return false; + } + if (!flags.get("forceBuildAll")) { + LOGGER.info("Checking whether resources has changed..."); + } - if (flags.get("forceBuildAll") - || isModified(newFiles(APK_MANIFEST_FILENAMES, appDir), - newFiles(APK_MANIFEST_FILENAMES, apkDir))) { - LOGGER.info("Building AndroidManifest.xml..."); + File apkDir = new File(appDir, APK_DIRNAME); - File apkFile = File.createTempFile("APKTOOL", null); - apkFile.delete(); + if (flags.get("debug")) { + mAndRes.remove_application_debug(new File(apkDir,"AndroidManifest.xml").getAbsolutePath()); + } - File ninePatch = new File(appDir, "9patch"); - if (!ninePatch.exists()) { - ninePatch = null; - } + if (flags.get("forceBuildAll") + || isModified(newFiles(APK_MANIFEST_FILENAMES, appDir), + newFiles(APK_MANIFEST_FILENAMES, apkDir))) { + LOGGER.info("Building AndroidManifest.xml..."); - mAndRes.aaptPackage(apkFile, new File(appDir, - "AndroidManifest.xml"), null, ninePatch, null, - parseUsesFramework(usesFramework), flags, mAaptPath); + File apkFile = File.createTempFile("APKTOOL", null); + apkFile.delete(); - Directory tmpDir = new ExtFile(apkFile).getDirectory(); - tmpDir.copyToDir(apkDir, APK_MANIFEST_FILENAMES); + File ninePatch = new File(appDir, "9patch"); + if (!ninePatch.exists()) { + ninePatch = null; + } - } - return true; - } catch (IOException ex) { - throw new AndrolibException(ex); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } catch (AndrolibException ex) { - LOGGER.warning("Parse AndroidManifest.xml failed, treat it as raw file."); - return buildManifestRaw(appDir, flags); - } - } + mAndRes.aaptPackage(apkFile, new File(appDir, + "AndroidManifest.xml"), null, ninePatch, null, + parseUsesFramework(usesFramework), flags, mAaptPath); - public void buildLib(File appDir, HashMap flags) - throws AndrolibException { - File working = new File(appDir, "lib"); - if (!working.exists()) { - return; - } - File stored = new File(appDir, APK_DIRNAME + "/lib"); - if (flags.get("forceBuildAll") || isModified(working, stored)) { - LOGGER.info("Copying libs..."); - try { - OS.rmdir(stored); - OS.cpdir(working, stored); - } catch (BrutException ex) { - throw new AndrolibException(ex); - } - } - } + Directory tmpDir = new ExtFile(apkFile).getDirectory(); + tmpDir.copyToDir(apkDir, APK_MANIFEST_FILENAMES); - public void buildCopyOriginalFiles(File appDir, - HashMap flags) throws AndrolibException { - if (flags.get("copyOriginal")) { - File originalDir = new File(appDir, "original"); - if(originalDir.exists()) { - try { - LOGGER.info("Copy original files..."); - Directory in = (new ExtFile(originalDir)).getDirectory(); - if(in.containsFile("AndroidManifest.xml")) { - LOGGER.info("Copy AndroidManifest.xml..."); - in.copyToDir(new File(appDir, APK_DIRNAME), "AndroidManifest.xml"); - } - if (in.containsDir("META-INF")) { - LOGGER.info("Copy META-INF..."); - in.copyToDir(new File(appDir, APK_DIRNAME), "META-INF"); - } - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } - } - } - } + } + return true; + } catch (IOException ex) { + throw new AndrolibException(ex); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } catch (AndrolibException ex) { + LOGGER.warning("Parse AndroidManifest.xml failed, treat it as raw file."); + return buildManifestRaw(appDir, flags); + } + } + + public void buildLib(File appDir, HashMap flags) + throws AndrolibException { + File working = new File(appDir, "lib"); + if (!working.exists()) { + return; + } + File stored = new File(appDir, APK_DIRNAME + "/lib"); + if (flags.get("forceBuildAll") || isModified(working, stored)) { + LOGGER.info("Copying libs..."); + try { + OS.rmdir(stored); + OS.cpdir(working, stored); + } catch (BrutException ex) { + throw new AndrolibException(ex); + } + } + } + + public void buildCopyOriginalFiles(File appDir, + HashMap flags) throws AndrolibException { + if (flags.get("copyOriginal")) { + File originalDir = new File(appDir, "original"); + if(originalDir.exists()) { + try { + LOGGER.info("Copy original files..."); + Directory in = (new ExtFile(originalDir)).getDirectory(); + if(in.containsFile("AndroidManifest.xml")) { + LOGGER.info("Copy AndroidManifest.xml..."); + in.copyToDir(new File(appDir, APK_DIRNAME), "AndroidManifest.xml"); + } + if (in.containsDir("META-INF")) { + LOGGER.info("Copy META-INF..."); + in.copyToDir(new File(appDir, APK_DIRNAME), "META-INF"); + } + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + } + } + } public void buildUnknownFiles(File appDir, File outFile, Map meta) throws AndrolibException { @@ -611,115 +611,115 @@ public class Androlib { fs.close(); } } - - public void buildApk(File appDir, File outApk, - HashMap flags) throws AndrolibException { - LOGGER.info("Building apk file..."); - if (outApk.exists()) { - outApk.delete(); - } else { - File outDir = outApk.getParentFile(); - if (outDir != null && !outDir.exists()) { - outDir.mkdirs(); - } - } - File assetDir = new File(appDir, "assets"); - if (!assetDir.exists()) { - assetDir = null; - } - mAndRes.aaptPackage(outApk, null, null, new File(appDir, APK_DIRNAME), - assetDir, null, flags, mAaptPath); - } - public void publicizeResources(File arscFile) throws AndrolibException { - mAndRes.publicizeResources(arscFile); - } + public void buildApk(File appDir, File outApk, + HashMap flags) throws AndrolibException { + LOGGER.info("Building apk file..."); + if (outApk.exists()) { + outApk.delete(); + } else { + File outDir = outApk.getParentFile(); + if (outDir != null && !outDir.exists()) { + outDir.mkdirs(); + } + } + File assetDir = new File(appDir, "assets"); + if (!assetDir.exists()) { + assetDir = null; + } + mAndRes.aaptPackage(outApk, null, null, new File(appDir, APK_DIRNAME), + assetDir, null, flags, mAaptPath); + } - public void installFramework(File frameFile, String tag, String frame_path) - throws AndrolibException { - mAndRes.setFrameworkFolder(frame_path); - mAndRes.installFramework(frameFile, tag); - } + public void publicizeResources(File arscFile) throws AndrolibException { + mAndRes.publicizeResources(arscFile); + } - public boolean isFrameworkApk(ResTable resTable) { - for (ResPackage pkg : resTable.listMainPackages()) { - if (pkg.getId() < 64) { - return true; - } - } - return false; - } + public void installFramework(File frameFile, String tag, String frame_path) + throws AndrolibException { + mAndRes.setFrameworkFolder(frame_path); + mAndRes.installFramework(frameFile, tag); + } - public static String getVersion() { - return ApktoolProperties.get("application.version"); - } + public boolean isFrameworkApk(ResTable resTable) { + for (ResPackage pkg : resTable.listMainPackages()) { + if (pkg.getId() < 64) { + return true; + } + } + return false; + } - private File[] parseUsesFramework(Map usesFramework) - throws AndrolibException { - if (usesFramework == null) { - return null; - } + public static String getVersion() { + return ApktoolProperties.get("application.version"); + } - List ids = (List) usesFramework.get("ids"); - if (ids == null || ids.isEmpty()) { - return null; - } + private File[] parseUsesFramework(Map usesFramework) + throws AndrolibException { + if (usesFramework == null) { + return null; + } - String tag = (String) usesFramework.get("tag"); - File[] files = new File[ids.size()]; - int i = 0; - for (int id : ids) { - files[i++] = mAndRes.getFrameworkApk(id, tag); - } - return files; - } + List ids = (List) usesFramework.get("ids"); + if (ids == null || ids.isEmpty()) { + return null; + } - private boolean isModified(File working, File stored) { - if (!stored.exists()) { - return true; - } - return BrutIO.recursiveModifiedTime(working) > BrutIO - .recursiveModifiedTime(stored); - } + String tag = (String) usesFramework.get("tag"); + File[] files = new File[ids.size()]; + int i = 0; + for (int id : ids) { + files[i++] = mAndRes.getFrameworkApk(id, tag); + } + return files; + } - private boolean isModified(File[] working, File[] stored) { - for (int i = 0; i < stored.length; i++) { - if (!stored[i].exists()) { - return true; - } - } - return BrutIO.recursiveModifiedTime(working) > BrutIO - .recursiveModifiedTime(stored); - } + private boolean isModified(File working, File stored) { + if (!stored.exists()) { + return true; + } + return BrutIO.recursiveModifiedTime(working) > BrutIO + .recursiveModifiedTime(stored); + } - private File[] newFiles(String[] names, File dir) { - File[] files = new File[names.length]; - for (int i = 0; i < names.length; i++) { - files[i] = new File(dir, names[i]); - } - return files; - } - - public void setFrameworkFolder(String path) { - mAndRes.setFrameworkFolder(path); - } + private boolean isModified(File[] working, File[] stored) { + for (int i = 0; i < stored.length; i++) { + if (!stored[i].exists()) { + return true; + } + } + return BrutIO.recursiveModifiedTime(working) > BrutIO + .recursiveModifiedTime(stored); + } - private String mAaptPath = null; + private File[] newFiles(String[] names, File dir) { + File[] files = new File[names.length]; + for (int i = 0; i < names.length; i++) { + files[i] = new File(dir, names[i]); + } + return files; + } + + public void setFrameworkFolder(String path) { + mAndRes.setFrameworkFolder(path); + } + + private String mAaptPath = null; private Path mPath = null; - private final static Logger LOGGER = Logger.getLogger(Androlib.class - .getName()); + private final static Logger LOGGER = Logger.getLogger(Androlib.class + .getName()); - private final static String SMALI_DIRNAME = "smali"; - private final static String APK_DIRNAME = "build/apk"; + private final static String SMALI_DIRNAME = "smali"; + private final static String APK_DIRNAME = "build/apk"; private final static String UNK_DIRNAME = "unknown"; - private final static String[] APK_RESOURCES_FILENAMES = new String[] { - "resources.arsc", "AndroidManifest.xml", "res" }; - private final static String[] APK_RESOURCES_WITHOUT_RES_FILENAMES = new String[] { - "resources.arsc", "AndroidManifest.xml" }; - private final static String[] APP_RESOURCES_FILENAMES = new String[] { - "AndroidManifest.xml", "res" }; - private final static String[] APK_MANIFEST_FILENAMES = new String[] { + private final static String[] APK_RESOURCES_FILENAMES = new String[] { + "resources.arsc", "AndroidManifest.xml", "res" }; + private final static String[] APK_RESOURCES_WITHOUT_RES_FILENAMES = new String[] { + "resources.arsc", "AndroidManifest.xml" }; + private final static String[] APP_RESOURCES_FILENAMES = new String[] { + "AndroidManifest.xml", "res" }; + private final static String[] APK_MANIFEST_FILENAMES = new String[] { "AndroidManifest.xml" }; private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] { "classes.dex", "AndroidManifest.xml", "resources.arsc","res","lib", "libs","assets","META-INF" }; diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/AndrolibException.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/AndrolibException.java index a68e4680..d1601341 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/AndrolibException.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/AndrolibException.java @@ -22,18 +22,18 @@ import brut.common.BrutException; * @author Ryszard Wiśniewski */ public class AndrolibException extends BrutException { - public AndrolibException() { - } + public AndrolibException() { + } - public AndrolibException(String message) { - super(message); - } + public AndrolibException(String message) { + super(message); + } - public AndrolibException(String message, Throwable cause) { - super(message, cause); - } + public AndrolibException(String message, Throwable cause) { + super(message, cause); + } - public AndrolibException(Throwable cause) { - super(cause); - } + public AndrolibException(Throwable cause) { + super(cause); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java index 398c7efb..3169d5b1 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java @@ -107,25 +107,25 @@ public class ApkDecoder { zef.close(); switch (mDecodeResources) { - case DECODE_RESOURCES_NONE: - mAndrolib.decodeResourcesRaw(mApkFile, outDir); - break; - case DECODE_RESOURCES_FULL: - mAndrolib.decodeResourcesFull(mApkFile, outDir, getResTable()); - break; + case DECODE_RESOURCES_NONE: + mAndrolib.decodeResourcesRaw(mApkFile, outDir); + break; + case DECODE_RESOURCES_FULL: + mAndrolib.decodeResourcesFull(mApkFile, outDir, getResTable()); + break; } } else { // if there's no resources.asrc, decode the manifest without looking // up attribute references if (hasManifest()) { switch (mDecodeResources) { - case DECODE_RESOURCES_NONE: - mAndrolib.decodeManifestRaw(mApkFile, outDir); - break; - case DECODE_RESOURCES_FULL: - mAndrolib.decodeManifestFull(mApkFile, outDir, - getResTable()); - break; + case DECODE_RESOURCES_NONE: + mAndrolib.decodeManifestRaw(mApkFile, outDir); + break; + case DECODE_RESOURCES_FULL: + mAndrolib.decodeManifestFull(mApkFile, outDir, + getResTable()); + break; } } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResSmaliUpdater.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResSmaliUpdater.java index 22845a00..be17d824 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResSmaliUpdater.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResSmaliUpdater.java @@ -36,128 +36,128 @@ import org.apache.commons.io.IOUtils; * @author Ryszard Wiśniewski */ public class ResSmaliUpdater { - public void tagResIDs(ResTable resTable, File smaliDir) - throws AndrolibException { - Directory dir = null; - try { - dir = new FileDirectory(smaliDir); - } catch (DirectoryException ex) { - throw new AndrolibException("Could not tag res IDs", ex); - } - for (String fileName : dir.getFiles(true)) { - try { - tagResIdsForFile(resTable, dir, fileName); - } catch (IOException ex) { - throw new AndrolibException("Could not tag resIDs for file: " - + fileName, ex); - } catch (DirectoryException ex) { - throw new AndrolibException("Could not tag resIDs for file: " - + fileName, ex); - } catch (AndrolibException ex) { - throw new AndrolibException("Could not tag resIDs for file: " - + fileName, ex); - } - } - } + public void tagResIDs(ResTable resTable, File smaliDir) + throws AndrolibException { + Directory dir = null; + try { + dir = new FileDirectory(smaliDir); + } catch (DirectoryException ex) { + throw new AndrolibException("Could not tag res IDs", ex); + } + for (String fileName : dir.getFiles(true)) { + try { + tagResIdsForFile(resTable, dir, fileName); + } catch (IOException ex) { + throw new AndrolibException("Could not tag resIDs for file: " + + fileName, ex); + } catch (DirectoryException ex) { + throw new AndrolibException("Could not tag resIDs for file: " + + fileName, ex); + } catch (AndrolibException ex) { + throw new AndrolibException("Could not tag resIDs for file: " + + fileName, ex); + } + } + } - public void updateResIDs(ResTable resTable, File smaliDir) - throws AndrolibException { - try { - Directory dir = new FileDirectory(smaliDir); - for (String fileName : dir.getFiles(true)) { - Iterator it = IOUtils.readLines( - dir.getFileInput(fileName)).iterator(); - PrintWriter out = new PrintWriter(dir.getFileOutput(fileName)); - while (it.hasNext()) { - String line = it.next(); - out.println(line); - Matcher m1 = RES_NAME_PATTERN.matcher(line); - if (!m1.matches()) { - continue; - } - Matcher m2 = RES_ID_PATTERN.matcher(it.next()); - if (!m2.matches()) { - throw new AndrolibException(); - } - int resID = resTable.getPackage(m1.group(1)) - .getType(m1.group(2)).getResSpec(m1.group(3)) - .getId().id; - if (m2.group(1) != null) { - out.println(String.format(RES_ID_FORMAT_FIELD, - m2.group(1), resID)); - } else { - out.println(String.format(RES_ID_FORMAT_CONST, - m2.group(2), resID)); - } - } - out.close(); - } - } catch (IOException ex) { - throw new AndrolibException("Could not tag res IDs for: " - + smaliDir.getAbsolutePath(), ex); - } catch (DirectoryException ex) { - throw new AndrolibException("Could not tag res IDs for: " - + smaliDir.getAbsolutePath(), ex); - } - } + public void updateResIDs(ResTable resTable, File smaliDir) + throws AndrolibException { + try { + Directory dir = new FileDirectory(smaliDir); + for (String fileName : dir.getFiles(true)) { + Iterator it = IOUtils.readLines( + dir.getFileInput(fileName)).iterator(); + PrintWriter out = new PrintWriter(dir.getFileOutput(fileName)); + while (it.hasNext()) { + String line = it.next(); + out.println(line); + Matcher m1 = RES_NAME_PATTERN.matcher(line); + if (!m1.matches()) { + continue; + } + Matcher m2 = RES_ID_PATTERN.matcher(it.next()); + if (!m2.matches()) { + throw new AndrolibException(); + } + int resID = resTable.getPackage(m1.group(1)) + .getType(m1.group(2)).getResSpec(m1.group(3)) + .getId().id; + if (m2.group(1) != null) { + out.println(String.format(RES_ID_FORMAT_FIELD, + m2.group(1), resID)); + } else { + out.println(String.format(RES_ID_FORMAT_CONST, + m2.group(2), resID)); + } + } + out.close(); + } + } catch (IOException ex) { + throw new AndrolibException("Could not tag res IDs for: " + + smaliDir.getAbsolutePath(), ex); + } catch (DirectoryException ex) { + throw new AndrolibException("Could not tag res IDs for: " + + smaliDir.getAbsolutePath(), ex); + } + } - private void tagResIdsForFile(ResTable resTable, Directory dir, - String fileName) throws IOException, DirectoryException, - AndrolibException { - Iterator it = IOUtils.readLines(dir.getFileInput(fileName)) - .iterator(); - PrintWriter out = new PrintWriter(dir.getFileOutput(fileName)); - while (it.hasNext()) { - String line = it.next(); - if (RES_NAME_PATTERN.matcher(line).matches()) { - out.println(line); - out.println(it.next()); - continue; - } - Matcher m = RES_ID_PATTERN.matcher(line); - if (m.matches()) { - int resID = parseResID(m.group(3)); - if (resID != -1) { - try { - ResResSpec spec = resTable.getResSpec(resID); - out.println(String.format(RES_NAME_FORMAT, - spec.getFullName())); - } catch (UndefinedResObject ex) { - if (!R_FILE_PATTERN.matcher(fileName).matches()) { - LOGGER.warning(String.format( - "Undefined resource spec in %s: 0x%08x", - fileName, resID)); - } - } - } - } - out.println(line); - } - out.close(); - } + private void tagResIdsForFile(ResTable resTable, Directory dir, + String fileName) throws IOException, DirectoryException, + AndrolibException { + Iterator it = IOUtils.readLines(dir.getFileInput(fileName)) + .iterator(); + PrintWriter out = new PrintWriter(dir.getFileOutput(fileName)); + while (it.hasNext()) { + String line = it.next(); + if (RES_NAME_PATTERN.matcher(line).matches()) { + out.println(line); + out.println(it.next()); + continue; + } + Matcher m = RES_ID_PATTERN.matcher(line); + if (m.matches()) { + int resID = parseResID(m.group(3)); + if (resID != -1) { + try { + ResResSpec spec = resTable.getResSpec(resID); + out.println(String.format(RES_NAME_FORMAT, + spec.getFullName())); + } catch (UndefinedResObject ex) { + if (!R_FILE_PATTERN.matcher(fileName).matches()) { + LOGGER.warning(String.format( + "Undefined resource spec in %s: 0x%08x", + fileName, resID)); + } + } + } + } + out.println(line); + } + out.close(); + } - private int parseResID(String resIDHex) { - if (resIDHex.endsWith("ff")) { - return -1; - } - int resID = Integer.valueOf(resIDHex, 16); - if (resIDHex.length() == 4) { - resID = resID << 16; - } - return resID; - } + private int parseResID(String resIDHex) { + if (resIDHex.endsWith("ff")) { + return -1; + } + int resID = Integer.valueOf(resIDHex, 16); + if (resIDHex.length() == 4) { + resID = resID << 16; + } + return resID; + } - private final static String RES_ID_FORMAT_FIELD = ".field %s:I = 0x%08x"; - private final static String RES_ID_FORMAT_CONST = " const %s, 0x%08x"; - private final static Pattern RES_ID_PATTERN = Pattern - .compile("^(?:\\.field (.+?):I =| const(?:|/(?:|high)16) ([pv]\\d+?),) 0x(7[a-f]0[1-9a-f](?:|[0-9a-f]{4}))$"); - private final static String RES_NAME_FORMAT = "# APKTOOL/RES_NAME: %s"; - private final static Pattern RES_NAME_PATTERN = Pattern - .compile("^# APKTOOL/RES_NAME: ([a-zA-Z0-9.]+):([a-z]+)/([a-zA-Z0-9._]+)$"); + private final static String RES_ID_FORMAT_FIELD = ".field %s:I = 0x%08x"; + private final static String RES_ID_FORMAT_CONST = " const %s, 0x%08x"; + private final static Pattern RES_ID_PATTERN = Pattern + .compile("^(?:\\.field (.+?):I =| const(?:|/(?:|high)16) ([pv]\\d+?),) 0x(7[a-f]0[1-9a-f](?:|[0-9a-f]{4}))$"); + private final static String RES_NAME_FORMAT = "# APKTOOL/RES_NAME: %s"; + private final static Pattern RES_NAME_PATTERN = Pattern + .compile("^# APKTOOL/RES_NAME: ([a-zA-Z0-9.]+):([a-z]+)/([a-zA-Z0-9._]+)$"); - private final static Pattern R_FILE_PATTERN = Pattern - .compile(".*R\\$[a-z]+\\.smali$"); + private final static Pattern R_FILE_PATTERN = Pattern + .compile(".*R\\$[a-z]+\\.smali$"); - private final static Logger LOGGER = Logger.getLogger(ResSmaliUpdater.class - .getName()); + private final static Logger LOGGER = Logger.getLogger(ResSmaliUpdater.class + .getName()); } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfig.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfig.java index 2d7f7bbd..73b1bcdc 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfig.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfig.java @@ -24,49 +24,49 @@ import java.util.*; * @author Ryszard Wiśniewski */ public class ResConfig { - private final ResConfigFlags mFlags; - private final Map mResources = new LinkedHashMap(); + private final ResConfigFlags mFlags; + private final Map mResources = new LinkedHashMap(); - public ResConfig(ResConfigFlags flags) { - this.mFlags = flags; - } + public ResConfig(ResConfigFlags flags) { + this.mFlags = flags; + } - public Set listResources() { - return new LinkedHashSet(mResources.values()); - } + public Set listResources() { + return new LinkedHashSet(mResources.values()); + } - public ResResource getResource(ResResSpec spec) throws AndrolibException { - ResResource res = mResources.get(spec); - if (res == null) { - throw new UndefinedResObject(String.format( - "resource: spec=%s, config=%s", spec, this)); - } - return res; - } + public ResResource getResource(ResResSpec spec) throws AndrolibException { + ResResource res = mResources.get(spec); + if (res == null) { + throw new UndefinedResObject(String.format( + "resource: spec=%s, config=%s", spec, this)); + } + return res; + } - public Set listResSpecs() { - return mResources.keySet(); - } + public Set listResSpecs() { + return mResources.keySet(); + } - public ResConfigFlags getFlags() { - return mFlags; - } + public ResConfigFlags getFlags() { + return mFlags; + } - public void addResource(ResResource res) throws AndrolibException { - addResource(res, false); - } + public void addResource(ResResource res) throws AndrolibException { + addResource(res, false); + } - public void addResource(ResResource res, boolean overwrite) - throws AndrolibException { - ResResSpec spec = res.getResSpec(); - if (mResources.put(spec, res) != null && !overwrite) { - throw new AndrolibException(String.format( - "Multiple resources: spec=%s, config=%s", spec, this)); - } - } + public void addResource(ResResource res, boolean overwrite) + throws AndrolibException { + ResResSpec spec = res.getResSpec(); + if (mResources.put(spec, res) != null && !overwrite) { + throw new AndrolibException(String.format( + "Multiple resources: spec=%s, config=%s", spec, this)); + } + } - @Override - public String toString() { - return mFlags.toString(); - } + @Override + public String toString() { + return mFlags.toString(); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java index 43f4ee83..24158030 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java @@ -20,51 +20,51 @@ package brut.androlib.res.data; * @author Ryszard Wiśniewski */ public class ResID { - public final int package_; - public final int type; - public final int entry; + public final int package_; + public final int type; + public final int entry; - public final int id; + public final int id; - public ResID(int package_, int type, int entry) { - this(package_, type, entry, (package_ << 24) + (type << 16) + entry); - } + public ResID(int package_, int type, int entry) { + this(package_, type, entry, (package_ << 24) + (type << 16) + entry); + } - public ResID(int id) { - this(id >> 24, (id >> 16) & 0x000000ff, id & 0x0000ffff, id); - } + public ResID(int id) { + this(id >> 24, (id >> 16) & 0x000000ff, id & 0x0000ffff, id); + } - public ResID(int package_, int type, int entry, int id) { - this.package_ = package_; - this.type = type; - this.entry = entry; - this.id = id; - } + public ResID(int package_, int type, int entry, int id) { + this.package_ = package_; + this.type = type; + this.entry = entry; + this.id = id; + } - @Override - public String toString() { - return String.format("0x%08x", id); - } + @Override + public String toString() { + return String.format("0x%08x", id); + } - @Override - public int hashCode() { - int hash = 17; - hash = 31 * hash + this.id; - return hash; - } + @Override + public int hashCode() { + int hash = 17; + hash = 31 * hash + this.id; + return hash; + } - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final ResID other = (ResID) obj; - if (this.id != other.id) { - return false; - } - return true; - } + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ResID other = (ResID) obj; + if (this.id != other.id) { + return false; + } + return true; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResPackage.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResPackage.java index d0d77697..de0a6e21 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResPackage.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResPackage.java @@ -29,200 +29,200 @@ import java.util.logging.Logger; * @author Ryszard Wiśniewski */ public class ResPackage { - private final ResTable mResTable; - private final int mId; - private final String mName; - private final Map mResSpecs = new LinkedHashMap(); - private final Map mConfigs = new LinkedHashMap(); - private final Map mTypes = new LinkedHashMap(); - private final Set mSynthesizedRes = new HashSet(); + private final ResTable mResTable; + private final int mId; + private final String mName; + private final Map mResSpecs = new LinkedHashMap(); + private final Map mConfigs = new LinkedHashMap(); + private final Map mTypes = new LinkedHashMap(); + private final Set mSynthesizedRes = new HashSet(); - private ResValueFactory mValueFactory; + private ResValueFactory mValueFactory; - public ResPackage(ResTable resTable, int id, String name) { - this.mResTable = resTable; - this.mId = id; - this.mName = name; - } + public ResPackage(ResTable resTable, int id, String name) { + this.mResTable = resTable; + this.mId = id; + this.mName = name; + } - public List listResSpecs() { - return new ArrayList(mResSpecs.values()); - } + public List listResSpecs() { + return new ArrayList(mResSpecs.values()); + } - public boolean hasResSpec(ResID resID) { - return mResSpecs.containsKey(resID); - } + public boolean hasResSpec(ResID resID) { + return mResSpecs.containsKey(resID); + } - public ResResSpec getResSpec(ResID resID) throws UndefinedResObject { - ResResSpec spec = mResSpecs.get(resID); - if (spec == null) { - throw new UndefinedResObject("resource spec: " + resID.toString()); - } - return spec; - } + public ResResSpec getResSpec(ResID resID) throws UndefinedResObject { + ResResSpec spec = mResSpecs.get(resID); + if (spec == null) { + throw new UndefinedResObject("resource spec: " + resID.toString()); + } + return spec; + } - public List getConfigs() { - return new ArrayList(mConfigs.values()); - } + public List getConfigs() { + return new ArrayList(mConfigs.values()); + } - public boolean hasConfig(ResConfigFlags flags) { - return mConfigs.containsKey(flags); - } + public boolean hasConfig(ResConfigFlags flags) { + return mConfigs.containsKey(flags); + } - public ResConfig getConfig(ResConfigFlags flags) throws AndrolibException { - ResConfig config = mConfigs.get(flags); - if (config == null) { - throw new UndefinedResObject("config: " + flags); - } - return config; - } + public ResConfig getConfig(ResConfigFlags flags) throws AndrolibException { + ResConfig config = mConfigs.get(flags); + if (config == null) { + throw new UndefinedResObject("config: " + flags); + } + return config; + } public int getResSpecCount() { return mResSpecs.size(); } - public ResConfig getOrCreateConfig(ResConfigFlags flags) - throws AndrolibException { - ResConfig config = mConfigs.get(flags); - if (config == null) { - config = new ResConfig(flags); - mConfigs.put(flags, config); - } - return config; - } + public ResConfig getOrCreateConfig(ResConfigFlags flags) + throws AndrolibException { + ResConfig config = mConfigs.get(flags); + if (config == null) { + config = new ResConfig(flags); + mConfigs.put(flags, config); + } + return config; + } - public List listTypes() { - return new ArrayList(mTypes.values()); - } + public List listTypes() { + return new ArrayList(mTypes.values()); + } - public boolean hasType(String typeName) { - return mTypes.containsKey(typeName); - } + public boolean hasType(String typeName) { + return mTypes.containsKey(typeName); + } - public ResType getType(String typeName) throws AndrolibException { - ResType type = mTypes.get(typeName); - if (type == null) { - throw new UndefinedResObject("type: " + typeName); - } - return type; - } + public ResType getType(String typeName) throws AndrolibException { + ResType type = mTypes.get(typeName); + if (type == null) { + throw new UndefinedResObject("type: " + typeName); + } + return type; + } - public Set listFiles() { - Set ret = new HashSet(); - for (ResResSpec spec : mResSpecs.values()) { - for (ResResource res : spec.listResources()) { - if (res.getValue() instanceof ResFileValue) { - ret.add(res); - } - } - } - return ret; - } + public Set listFiles() { + Set ret = new HashSet(); + for (ResResSpec spec : mResSpecs.values()) { + for (ResResource res : spec.listResources()) { + if (res.getValue() instanceof ResFileValue) { + ret.add(res); + } + } + } + return ret; + } - public Collection listValuesFiles() { - Map, ResValuesFile> ret = new HashMap, ResValuesFile>(); - for (ResResSpec spec : mResSpecs.values()) { - for (ResResource res : spec.listResources()) { - if (res.getValue() instanceof ResValuesXmlSerializable) { - ResType type = res.getResSpec().getType(); - ResConfig config = res.getConfig(); - Duo key = new Duo( - type, config); - ResValuesFile values = ret.get(key); - if (values == null) { - values = new ResValuesFile(this, type, config); - ret.put(key, values); - } - values.addResource(res); - } - } - } - return ret.values(); - } + public Collection listValuesFiles() { + Map, ResValuesFile> ret = new HashMap, ResValuesFile>(); + for (ResResSpec spec : mResSpecs.values()) { + for (ResResource res : spec.listResources()) { + if (res.getValue() instanceof ResValuesXmlSerializable) { + ResType type = res.getResSpec().getType(); + ResConfig config = res.getConfig(); + Duo key = new Duo( + type, config); + ResValuesFile values = ret.get(key); + if (values == null) { + values = new ResValuesFile(this, type, config); + ret.put(key, values); + } + values.addResource(res); + } + } + } + return ret.values(); + } - public ResTable getResTable() { - return mResTable; - } + public ResTable getResTable() { + return mResTable; + } - public int getId() { - return mId; - } + public int getId() { + return mId; + } - public String getName() { - return mName; - } + public String getName() { + return mName; + } - boolean isSynthesized(ResID resId) { - return mSynthesizedRes.contains(resId); - } + boolean isSynthesized(ResID resId) { + return mSynthesizedRes.contains(resId); + } - public void addResSpec(ResResSpec spec) throws AndrolibException { - if (mResSpecs.put(spec.getId(), spec) != null) { - throw new AndrolibException("Multiple resource specs: " + spec); - } - } + public void addResSpec(ResResSpec spec) throws AndrolibException { + if (mResSpecs.put(spec.getId(), spec) != null) { + throw new AndrolibException("Multiple resource specs: " + spec); + } + } - public void addConfig(ResConfig config) throws AndrolibException { - if (mConfigs.put(config.getFlags(), config) != null) { - throw new AndrolibException("Multiple configs: " + config); - } - } + public void addConfig(ResConfig config) throws AndrolibException { + if (mConfigs.put(config.getFlags(), config) != null) { + throw new AndrolibException("Multiple configs: " + config); + } + } - public void addType(ResType type) throws AndrolibException { + public void addType(ResType type) throws AndrolibException { if (mTypes.containsKey(type.getName())) { LOGGER.warning("Multiple types detected! " + type + " ignored!"); } else { mTypes.put(type.getName(), type); } - } + } - public void addResource(ResResource res) { - } + public void addResource(ResResource res) { + } - public void addSynthesizedRes(int resId) { - mSynthesizedRes.add(new ResID(resId)); - } + public void addSynthesizedRes(int resId) { + mSynthesizedRes.add(new ResID(resId)); + } - @Override - public String toString() { - return mName; - } + @Override + public String toString() { + return mName; + } - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final ResPackage other = (ResPackage) obj; - if (this.mResTable != other.mResTable - && (this.mResTable == null || !this.mResTable - .equals(other.mResTable))) { - return false; - } - if (this.mId != other.mId) { - return false; - } - return true; - } + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ResPackage other = (ResPackage) obj; + if (this.mResTable != other.mResTable + && (this.mResTable == null || !this.mResTable + .equals(other.mResTable))) { + return false; + } + if (this.mId != other.mId) { + return false; + } + return true; + } - @Override - public int hashCode() { - int hash = 17; - hash = 31 * hash - + (this.mResTable != null ? this.mResTable.hashCode() : 0); - hash = 31 * hash + this.mId; - return hash; - } + @Override + public int hashCode() { + int hash = 17; + hash = 31 * hash + + (this.mResTable != null ? this.mResTable.hashCode() : 0); + hash = 31 * hash + this.mId; + return hash; + } - public ResValueFactory getValueFactory() { - if (mValueFactory == null) { - mValueFactory = new ResValueFactory(this); - } - return mValueFactory; - } + public ResValueFactory getValueFactory() { + if (mValueFactory == null) { + mValueFactory = new ResValueFactory(this); + } + return mValueFactory; + } private final static Logger LOGGER = Logger .getLogger(ResPackage.class.getName()); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java index 658c9166..013d4454 100755 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java @@ -25,97 +25,97 @@ import org.apache.commons.lang3.StringUtils; * @author Ryszard Wiśniewski */ public class ResResSpec { - private final ResID mId; - private final String mName; - private final ResPackage mPackage; - private final ResType mType; - private final Map mResources = new LinkedHashMap(); + private final ResID mId; + private final String mName; + private final ResPackage mPackage; + private final ResType mType; + private final Map mResources = new LinkedHashMap(); - public ResResSpec(ResID id, String name, ResPackage pkg, ResType type) { - this.mId = id; - this.mName = name; - this.mPackage = pkg; - this.mType = type; - } + public ResResSpec(ResID id, String name, ResPackage pkg, ResType type) { + this.mId = id; + this.mName = name; + this.mPackage = pkg; + this.mType = type; + } - public Set listResources() { - return new LinkedHashSet(mResources.values()); - } + public Set listResources() { + return new LinkedHashSet(mResources.values()); + } - public ResResource getResource(ResConfig config) throws AndrolibException { - return getResource(config.getFlags()); - } + public ResResource getResource(ResConfig config) throws AndrolibException { + return getResource(config.getFlags()); + } - public ResResource getResource(ResConfigFlags config) - throws AndrolibException { - ResResource res = mResources.get(config); - if (res == null) { - throw new UndefinedResObject(String.format( - "resource: spec=%s, config=%s", this, config)); - } - return res; - } + public ResResource getResource(ResConfigFlags config) + throws AndrolibException { + ResResource res = mResources.get(config); + if (res == null) { + throw new UndefinedResObject(String.format( + "resource: spec=%s, config=%s", this, config)); + } + return res; + } - public boolean hasResource(ResConfig config) { - return hasResource(config.getFlags()); - } + public boolean hasResource(ResConfig config) { + return hasResource(config.getFlags()); + } - private boolean hasResource(ResConfigFlags flags) { - return mResources.containsKey(flags); - } + private boolean hasResource(ResConfigFlags flags) { + return mResources.containsKey(flags); + } - public ResResource getDefaultResource() throws AndrolibException { - return getResource(new ResConfigFlags()); - } + public ResResource getDefaultResource() throws AndrolibException { + return getResource(new ResConfigFlags()); + } - public boolean hasDefaultResource() { - return mResources.containsKey(new ResConfigFlags()); - } + public boolean hasDefaultResource() { + return mResources.containsKey(new ResConfigFlags()); + } - public String getFullName() { - return getFullName(false, false); - } + public String getFullName() { + return getFullName(false, false); + } - public String getFullName(ResPackage relativeToPackage, boolean excludeType) { - return getFullName(getPackage().equals(relativeToPackage), excludeType); - } + public String getFullName(ResPackage relativeToPackage, boolean excludeType) { + return getFullName(getPackage().equals(relativeToPackage), excludeType); + } - public String getFullName(boolean excludePackage, boolean excludeType) { - return (excludePackage ? "" : getPackage().getName() + ":") - + (excludeType ? "" : getType().getName() + "/") + getName(); - } + public String getFullName(boolean excludePackage, boolean excludeType) { + return (excludePackage ? "" : getPackage().getName() + ":") + + (excludeType ? "" : getType().getName() + "/") + getName(); + } - public ResID getId() { - return mId; - } + public ResID getId() { + return mId; + } - public String getName() { - return StringUtils.replace(mName, "\"", "q"); - } + public String getName() { + return StringUtils.replace(mName, "\"", "q"); + } - public ResPackage getPackage() { - return mPackage; - } + public ResPackage getPackage() { + return mPackage; + } - public ResType getType() { - return mType; - } + public ResType getType() { + return mType; + } - public void addResource(ResResource res) throws AndrolibException { - addResource(res, false); - } + public void addResource(ResResource res) throws AndrolibException { + addResource(res, false); + } - public void addResource(ResResource res, boolean overwrite) - throws AndrolibException { - ResConfigFlags flags = res.getConfig().getFlags(); - if (mResources.put(flags, res) != null && !overwrite) { - throw new AndrolibException(String.format( - "Multiple resources: spec=%s, config=%s", this, flags)); - } - } + public void addResource(ResResource res, boolean overwrite) + throws AndrolibException { + ResConfigFlags flags = res.getConfig().getFlags(); + if (mResources.put(flags, res) != null && !overwrite) { + throw new AndrolibException(String.format( + "Multiple resources: spec=%s, config=%s", this, flags)); + } + } - @Override - public String toString() { - return mId.toString() + " " + mType.toString() + "/" + mName; - } + @Override + public String toString() { + return mId.toString() + " " + mType.toString() + "/" + mName; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResource.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResource.java index 38c35d68..a9301dbf 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResource.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResource.java @@ -23,41 +23,41 @@ import brut.androlib.res.data.value.ResValue; * @author Ryszard Wiśniewski */ public class ResResource { - private final ResConfig mConfig; - private final ResResSpec mResSpec; - private final ResValue mValue; + private final ResConfig mConfig; + private final ResResSpec mResSpec; + private final ResValue mValue; - public ResResource(ResConfig config, ResResSpec spec, ResValue value) { - this.mConfig = config; - this.mResSpec = spec; - this.mValue = value; - } + public ResResource(ResConfig config, ResResSpec spec, ResValue value) { + this.mConfig = config; + this.mResSpec = spec; + this.mValue = value; + } - public String getFilePath() { - return mResSpec.getType().getName() - + mConfig.getFlags().getQualifiers() + "/" + mResSpec.getName(); - } + public String getFilePath() { + return mResSpec.getType().getName() + + mConfig.getFlags().getQualifiers() + "/" + mResSpec.getName(); + } - public ResConfig getConfig() { - return mConfig; - } + public ResConfig getConfig() { + return mConfig; + } - public ResResSpec getResSpec() { - return mResSpec; - } + public ResResSpec getResSpec() { + return mResSpec; + } - public ResValue getValue() { - return mValue; - } + public ResValue getValue() { + return mValue; + } - public void replace(ResValue value) throws AndrolibException { - ResResource res = new ResResource(mConfig, mResSpec, value); - mConfig.addResource(res, true); - mResSpec.addResource(res, true); - } + public void replace(ResValue value) throws AndrolibException { + ResResource res = new ResResource(mConfig, mResSpec, value); + mConfig.addResource(res, true); + mResSpec.addResource(res, true); + } - @Override - public String toString() { - return getFilePath(); - } + @Override + public String toString() { + return getFilePath(); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java index d637ec5a..e55ded7c 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java @@ -26,57 +26,57 @@ import java.util.*; * @author Ryszard Wiśniewski */ public class ResTable { - private final AndrolibResources mAndRes; + private final AndrolibResources mAndRes; - private final Map mPackagesById = new HashMap(); - private final Map mPackagesByName = new HashMap(); - private final Set mMainPackages = new LinkedHashSet(); - private final Set mFramePackages = new LinkedHashSet(); + private final Map mPackagesById = new HashMap(); + private final Map mPackagesByName = new HashMap(); + private final Set mMainPackages = new LinkedHashSet(); + private final Set mFramePackages = new LinkedHashSet(); - private String mFrameTag; + private String mFrameTag; private String mPackageRenamed; private String mPackageOriginal; private int mPackageId; private boolean mAnalysisMode = false; - private Map mSdkInfo = new LinkedHashMap(); - private Map mVersionInfo = new LinkedHashMap(); + private Map mSdkInfo = new LinkedHashMap(); + private Map mVersionInfo = new LinkedHashMap(); private Map mUnknownFiles = new LinkedHashMap(); - public ResTable() { - mAndRes = null; - } + public ResTable() { + mAndRes = null; + } - public ResTable(AndrolibResources andRes) { - mAndRes = andRes; - } + public ResTable(AndrolibResources andRes) { + mAndRes = andRes; + } - public ResResSpec getResSpec(int resID) throws AndrolibException { - return getResSpec(new ResID(resID)); - } + public ResResSpec getResSpec(int resID) throws AndrolibException { + return getResSpec(new ResID(resID)); + } - public ResResSpec getResSpec(ResID resID) throws AndrolibException { - return getPackage(resID.package_).getResSpec(resID); - } + public ResResSpec getResSpec(ResID resID) throws AndrolibException { + return getPackage(resID.package_).getResSpec(resID); + } - public Set listMainPackages() { - return mMainPackages; - } + public Set listMainPackages() { + return mMainPackages; + } - public Set listFramePackages() { - return mFramePackages; - } + public Set listFramePackages() { + return mFramePackages; + } - public ResPackage getPackage(int id) throws AndrolibException { - ResPackage pkg = mPackagesById.get(id); - if (pkg != null) { - return pkg; - } - if (mAndRes != null) { - return mAndRes.loadFrameworkPkg(this, id, mFrameTag); - } - throw new UndefinedResObject(String.format("package: id=%d", id)); - } + public ResPackage getPackage(int id) throws AndrolibException { + ResPackage pkg = mPackagesById.get(id); + if (pkg != null) { + return pkg; + } + if (mAndRes != null) { + return mAndRes.loadFrameworkPkg(this, id, mFrameTag); + } + throw new UndefinedResObject(String.format("package: id=%d", id)); + } public ResPackage getHighestSpecPackage() throws AndrolibException { int id = 0; @@ -91,52 +91,52 @@ public class ResTable { return (id == 0) ? getPackage(1) : getPackage(id); } - public ResPackage getPackage(String name) throws AndrolibException { - ResPackage pkg = mPackagesByName.get(name); - if (pkg == null) { - throw new UndefinedResObject("package: name=" + name); - } - return pkg; - } + public ResPackage getPackage(String name) throws AndrolibException { + ResPackage pkg = mPackagesByName.get(name); + if (pkg == null) { + throw new UndefinedResObject("package: name=" + name); + } + return pkg; + } - public boolean hasPackage(int id) { - return mPackagesById.containsKey(id); - } + public boolean hasPackage(int id) { + return mPackagesById.containsKey(id); + } - public boolean hasPackage(String name) { - return mPackagesByName.containsKey(name); - } + public boolean hasPackage(String name) { + return mPackagesByName.containsKey(name); + } - public ResValue getValue(String package_, String type, String name) - throws AndrolibException { - return getPackage(package_).getType(type).getResSpec(name) - .getDefaultResource().getValue(); - } + public ResValue getValue(String package_, String type, String name) + throws AndrolibException { + return getPackage(package_).getType(type).getResSpec(name) + .getDefaultResource().getValue(); + } - public void addPackage(ResPackage pkg, boolean main) - throws AndrolibException { - Integer id = pkg.getId(); - if (mPackagesById.containsKey(id)) { - throw new AndrolibException("Multiple packages: id=" - + id.toString()); - } - String name = pkg.getName(); - if (mPackagesByName.containsKey(name)) { - throw new AndrolibException("Multiple packages: name=" + name); - } + public void addPackage(ResPackage pkg, boolean main) + throws AndrolibException { + Integer id = pkg.getId(); + if (mPackagesById.containsKey(id)) { + throw new AndrolibException("Multiple packages: id=" + + id.toString()); + } + String name = pkg.getName(); + if (mPackagesByName.containsKey(name)) { + throw new AndrolibException("Multiple packages: name=" + name); + } - mPackagesById.put(id, pkg); - mPackagesByName.put(name, pkg); - if (main) { - mMainPackages.add(pkg); - } else { - mFramePackages.add(pkg); - } - } + mPackagesById.put(id, pkg); + mPackagesByName.put(name, pkg); + if (main) { + mMainPackages.add(pkg); + } else { + mFramePackages.add(pkg); + } + } - public void setFrameTag(String tag) { - mFrameTag = tag; - } + public void setFrameTag(String tag) { + mFrameTag = tag; + } public void setAnalysisMode(boolean mode) { mAnalysisMode = mode; @@ -153,30 +153,30 @@ public class ResTable { public void setPackageId(int id) { mPackageId = id; } - - public void clearSdkInfo() { - mSdkInfo.clear(); - } - public void addSdkInfo(String key, String value) { - mSdkInfo.put(key, value); - } - - public void addVersionInfo(String key, String value) { - mVersionInfo.put(key, value); - } + public void clearSdkInfo() { + mSdkInfo.clear(); + } + + public void addSdkInfo(String key, String value) { + mSdkInfo.put(key, value); + } + + public void addVersionInfo(String key, String value) { + mVersionInfo.put(key, value); + } public void addUnknownFileInfo(String file, String value) { mUnknownFiles.put(file,value); } - public Map getVersionInfo() { - return mVersionInfo; - } - - public Map getSdkInfo() { - return mSdkInfo; - } + public Map getVersionInfo() { + return mVersionInfo; + } + + public Map getSdkInfo() { + return mSdkInfo; + } public boolean getAnalysisMode() { return mAnalysisMode; diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResType.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResType.java index e87615bf..3624b965 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResType.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResType.java @@ -24,44 +24,44 @@ import java.util.*; * @author Ryszard Wiśniewski */ public final class ResType { - private final String mName; - private final Map mResSpecs = new LinkedHashMap(); + private final String mName; + private final Map mResSpecs = new LinkedHashMap(); - private final ResTable mResTable; - private final ResPackage mPackage; + private final ResTable mResTable; + private final ResPackage mPackage; - public ResType(String name, ResTable resTable, ResPackage package_) { - this.mName = name; - this.mResTable = resTable; - this.mPackage = package_; - } + public ResType(String name, ResTable resTable, ResPackage package_) { + this.mName = name; + this.mResTable = resTable; + this.mPackage = package_; + } - public String getName() { - return mName; - } + public String getName() { + return mName; + } - public Set listResSpecs() { - return new LinkedHashSet(mResSpecs.values()); - } + public Set listResSpecs() { + return new LinkedHashSet(mResSpecs.values()); + } - public ResResSpec getResSpec(String name) throws AndrolibException { - ResResSpec spec = mResSpecs.get(name); - if (spec == null) { - throw new UndefinedResObject(String.format("resource spec: %s/%s", - getName(), name)); - } - return spec; - } + public ResResSpec getResSpec(String name) throws AndrolibException { + ResResSpec spec = mResSpecs.get(name); + if (spec == null) { + throw new UndefinedResObject(String.format("resource spec: %s/%s", + getName(), name)); + } + return spec; + } - public void addResSpec(ResResSpec spec) throws AndrolibException { - if (mResSpecs.put(spec.getName(), spec) != null) { - throw new AndrolibException(String.format( - "Multiple res specs: %s/%s", getName(), spec.getName())); - } - } + public void addResSpec(ResResSpec spec) throws AndrolibException { + if (mResSpecs.put(spec.getName(), spec) != null) { + throw new AndrolibException(String.format( + "Multiple res specs: %s/%s", getName(), spec.getName())); + } + } - @Override - public String toString() { - return mName; - } + @Override + public String toString() { + return mName; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResValuesFile.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResValuesFile.java index c1be40c8..4c4af0a6 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResValuesFile.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResValuesFile.java @@ -23,68 +23,68 @@ import java.util.Set; * @author Ryszard Wiśniewski */ public class ResValuesFile { - private final ResPackage mPackage; - private final ResType mType; - private final ResConfig mConfig; - private final Set mResources = new LinkedHashSet(); + private final ResPackage mPackage; + private final ResType mType; + private final ResConfig mConfig; + private final Set mResources = new LinkedHashSet(); - public ResValuesFile(ResPackage pkg, ResType type, ResConfig config) { - this.mPackage = pkg; - this.mType = type; - this.mConfig = config; - } + public ResValuesFile(ResPackage pkg, ResType type, ResConfig config) { + this.mPackage = pkg; + this.mType = type; + this.mConfig = config; + } - public String getPath() { - return "values" + mConfig.getFlags().getQualifiers() + "/" - + mType.getName() + (mType.getName().endsWith("s") ? "" : "s") - + ".xml"; - } + public String getPath() { + return "values" + mConfig.getFlags().getQualifiers() + "/" + + mType.getName() + (mType.getName().endsWith("s") ? "" : "s") + + ".xml"; + } - public Set listResources() { - return mResources; - } + public Set listResources() { + return mResources; + } - public ResType getType() { - return mType; - } + public ResType getType() { + return mType; + } - public ResConfig getConfig() { - return mConfig; - } + public ResConfig getConfig() { + return mConfig; + } - public boolean isSynthesized(ResResource res) { - return mPackage.isSynthesized(res.getResSpec().getId()); - } + public boolean isSynthesized(ResResource res) { + return mPackage.isSynthesized(res.getResSpec().getId()); + } - public void addResource(ResResource res) { - mResources.add(res); - } + public void addResource(ResResource res) { + mResources.add(res); + } - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final ResValuesFile other = (ResValuesFile) obj; - if (this.mType != other.mType - && (this.mType == null || !this.mType.equals(other.mType))) { - return false; - } - if (this.mConfig != other.mConfig - && (this.mConfig == null || !this.mConfig.equals(other.mConfig))) { - return false; - } - return true; - } + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ResValuesFile other = (ResValuesFile) obj; + if (this.mType != other.mType + && (this.mType == null || !this.mType.equals(other.mType))) { + return false; + } + if (this.mConfig != other.mConfig + && (this.mConfig == null || !this.mConfig.equals(other.mConfig))) { + return false; + } + return true; + } - @Override - public int hashCode() { - int hash = 17; - hash = 31 * hash + (this.mType != null ? this.mType.hashCode() : 0); - hash = 31 * hash + (this.mConfig != null ? this.mConfig.hashCode() : 0); - return hash; - } + @Override + public int hashCode() { + int hash = 17; + hash = 31 * hash + (this.mType != null ? this.mType.hashCode() : 0); + hash = 31 * hash + (this.mConfig != null ? this.mConfig.hashCode() : 0); + return hash; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResAttr.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResAttr.java index 3fac36d5..e35664c8 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResAttr.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResAttr.java @@ -28,148 +28,148 @@ import org.xmlpull.v1.XmlSerializer; * @author Ryszard Wiśniewski */ public class ResAttr extends ResBagValue implements ResValuesXmlSerializable { - ResAttr(ResReferenceValue parentVal, int type, Integer min, Integer max, - Boolean l10n) { - super(parentVal); - mType = type; - mMin = min; - mMax = max; - mL10n = l10n; - } + ResAttr(ResReferenceValue parentVal, int type, Integer min, Integer max, + Boolean l10n) { + super(parentVal); + mType = type; + mMin = min; + mMax = max; + mL10n = l10n; + } - public String convertToResXmlFormat(ResScalarValue value) - throws AndrolibException { - return null; - } + public String convertToResXmlFormat(ResScalarValue value) + throws AndrolibException { + return null; + } - @Override - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException { - String type = getTypeAsString(); + @Override + public void serializeToResValuesXml(XmlSerializer serializer, + ResResource res) throws IOException, AndrolibException { + String type = getTypeAsString(); - serializer.startTag(null, "attr"); - serializer.attribute(null, "name", res.getResSpec().getName()); - if (type != null) { - serializer.attribute(null, "format", type); - } - if (mMin != null) { - serializer.attribute(null, "min", mMin.toString()); - } - if (mMax != null) { - serializer.attribute(null, "max", mMax.toString()); - } - if (mL10n != null && mL10n) { - serializer.attribute(null, "localization", "suggested"); - } - serializeBody(serializer, res); - serializer.endTag(null, "attr"); - } + serializer.startTag(null, "attr"); + serializer.attribute(null, "name", res.getResSpec().getName()); + if (type != null) { + serializer.attribute(null, "format", type); + } + if (mMin != null) { + serializer.attribute(null, "min", mMin.toString()); + } + if (mMax != null) { + serializer.attribute(null, "max", mMax.toString()); + } + if (mL10n != null && mL10n) { + serializer.attribute(null, "localization", "suggested"); + } + serializeBody(serializer, res); + serializer.endTag(null, "attr"); + } - public static ResAttr factory(ResReferenceValue parent, - Duo[] items, ResValueFactory factory, - ResPackage pkg) throws AndrolibException { + public static ResAttr factory(ResReferenceValue parent, + Duo[] items, ResValueFactory factory, + ResPackage pkg) throws AndrolibException { - int type = ((ResIntValue) items[0].m2).getValue(); - int scalarType = type & 0xffff; - Integer min = null, max = null; - Boolean l10n = null; - int i; - for (i = 1; i < items.length; i++) { - switch (items[i].m1) { - case BAG_KEY_ATTR_MIN: - min = ((ResIntValue) items[i].m2).getValue(); - continue; - case BAG_KEY_ATTR_MAX: - max = ((ResIntValue) items[i].m2).getValue(); - continue; - case BAG_KEY_ATTR_L10N: - l10n = ((ResIntValue) items[i].m2).getValue() != 0; - continue; - } - break; - } + int type = ((ResIntValue) items[0].m2).getValue(); + int scalarType = type & 0xffff; + Integer min = null, max = null; + Boolean l10n = null; + int i; + for (i = 1; i < items.length; i++) { + switch (items[i].m1) { + case BAG_KEY_ATTR_MIN: + min = ((ResIntValue) items[i].m2).getValue(); + continue; + case BAG_KEY_ATTR_MAX: + max = ((ResIntValue) items[i].m2).getValue(); + continue; + case BAG_KEY_ATTR_L10N: + l10n = ((ResIntValue) items[i].m2).getValue() != 0; + continue; + } + break; + } - if (i == items.length) { - return new ResAttr(parent, scalarType, min, max, l10n); - } - Duo[] attrItems = new Duo[items.length - - i]; - int j = 0; - for (; i < items.length; i++) { - int resId = items[i].m1; - pkg.addSynthesizedRes(resId); - attrItems[j++] = new Duo( - factory.newReference(resId, null), - (ResIntValue) items[i].m2); - } - switch (type & 0xff0000) { - case TYPE_ENUM: - return new ResEnumAttr(parent, scalarType, min, max, l10n, - attrItems); - case TYPE_FLAGS: - return new ResFlagsAttr(parent, scalarType, min, max, l10n, - attrItems); - } + if (i == items.length) { + return new ResAttr(parent, scalarType, min, max, l10n); + } + Duo[] attrItems = new Duo[items.length + - i]; + int j = 0; + for (; i < items.length; i++) { + int resId = items[i].m1; + pkg.addSynthesizedRes(resId); + attrItems[j++] = new Duo( + factory.newReference(resId, null), + (ResIntValue) items[i].m2); + } + switch (type & 0xff0000) { + case TYPE_ENUM: + return new ResEnumAttr(parent, scalarType, min, max, l10n, + attrItems); + case TYPE_FLAGS: + return new ResFlagsAttr(parent, scalarType, min, max, l10n, + attrItems); + } - throw new AndrolibException("Could not decode attr value"); - } + throw new AndrolibException("Could not decode attr value"); + } - protected void serializeBody(XmlSerializer serializer, ResResource res) - throws AndrolibException, IOException { - } + protected void serializeBody(XmlSerializer serializer, ResResource res) + throws AndrolibException, IOException { + } - protected String getTypeAsString() { - String s = ""; - if ((mType & TYPE_REFERENCE) != 0) { - s += "|reference"; - } - if ((mType & TYPE_STRING) != 0) { - s += "|string"; - } - if ((mType & TYPE_INT) != 0) { - s += "|integer"; - } - if ((mType & TYPE_BOOL) != 0) { - s += "|boolean"; - } - if ((mType & TYPE_COLOR) != 0) { - s += "|color"; - } - if ((mType & TYPE_FLOAT) != 0) { - s += "|float"; - } - if ((mType & TYPE_DIMEN) != 0) { - s += "|dimension"; - } - if ((mType & TYPE_FRACTION) != 0) { - s += "|fraction"; - } - if (s.isEmpty()) { - return null; - } - return s.substring(1); - } + protected String getTypeAsString() { + String s = ""; + if ((mType & TYPE_REFERENCE) != 0) { + s += "|reference"; + } + if ((mType & TYPE_STRING) != 0) { + s += "|string"; + } + if ((mType & TYPE_INT) != 0) { + s += "|integer"; + } + if ((mType & TYPE_BOOL) != 0) { + s += "|boolean"; + } + if ((mType & TYPE_COLOR) != 0) { + s += "|color"; + } + if ((mType & TYPE_FLOAT) != 0) { + s += "|float"; + } + if ((mType & TYPE_DIMEN) != 0) { + s += "|dimension"; + } + if ((mType & TYPE_FRACTION) != 0) { + s += "|fraction"; + } + if (s.isEmpty()) { + return null; + } + return s.substring(1); + } - private final int mType; - private final Integer mMin; - private final Integer mMax; - private final Boolean mL10n; + private final int mType; + private final Integer mMin; + private final Integer mMax; + private final Boolean mL10n; - public static final int BAG_KEY_ATTR_TYPE = 0x01000000; - private static final int BAG_KEY_ATTR_MIN = 0x01000001; - private static final int BAG_KEY_ATTR_MAX = 0x01000002; - private static final int BAG_KEY_ATTR_L10N = 0x01000003; + public static final int BAG_KEY_ATTR_TYPE = 0x01000000; + private static final int BAG_KEY_ATTR_MIN = 0x01000001; + private static final int BAG_KEY_ATTR_MAX = 0x01000002; + private static final int BAG_KEY_ATTR_L10N = 0x01000003; - private final static int TYPE_REFERENCE = 0x01; - private final static int TYPE_STRING = 0x02; - private final static int TYPE_INT = 0x04; - private final static int TYPE_BOOL = 0x08; - private final static int TYPE_COLOR = 0x10; - private final static int TYPE_FLOAT = 0x20; - private final static int TYPE_DIMEN = 0x40; - private final static int TYPE_FRACTION = 0x80; - private final static int TYPE_ANY_STRING = 0xee; + private final static int TYPE_REFERENCE = 0x01; + private final static int TYPE_STRING = 0x02; + private final static int TYPE_INT = 0x04; + private final static int TYPE_BOOL = 0x08; + private final static int TYPE_COLOR = 0x10; + private final static int TYPE_FLOAT = 0x20; + private final static int TYPE_DIMEN = 0x40; + private final static int TYPE_FRACTION = 0x80; + private final static int TYPE_ANY_STRING = 0xee; - private static final int TYPE_ENUM = 0x00010000; - private static final int TYPE_FLAGS = 0x00020000; + private static final int TYPE_ENUM = 0x00010000; + private static final int TYPE_FLAGS = 0x00020000; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBagValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBagValue.java index 0e01624c..fa280690 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBagValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBagValue.java @@ -27,39 +27,39 @@ import org.xmlpull.v1.XmlSerializer; * @author Ryszard Wiśniewski */ public class ResBagValue extends ResValue implements ResValuesXmlSerializable { - protected final ResReferenceValue mParent; + protected final ResReferenceValue mParent; - public ResBagValue(ResReferenceValue parent) { - this.mParent = parent; - } + public ResBagValue(ResReferenceValue parent) { + this.mParent = parent; + } - @Override - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException { - String type = res.getResSpec().getType().getName(); - if ("style".equals(type)) { - new ResStyleValue(mParent, new Duo[0], null) - .serializeToResValuesXml(serializer, res); - return; - } - if ("array".equals(type)) { - new ResArrayValue(mParent, new Duo[0]).serializeToResValuesXml( - serializer, res); - return; - } - if ("plurals".equals(type)) { - new ResPluralsValue(mParent, new Duo[0]).serializeToResValuesXml( - serializer, res); - return; - } + @Override + public void serializeToResValuesXml(XmlSerializer serializer, + ResResource res) throws IOException, AndrolibException { + String type = res.getResSpec().getType().getName(); + if ("style".equals(type)) { + new ResStyleValue(mParent, new Duo[0], null) + .serializeToResValuesXml(serializer, res); + return; + } + if ("array".equals(type)) { + new ResArrayValue(mParent, new Duo[0]).serializeToResValuesXml( + serializer, res); + return; + } + if ("plurals".equals(type)) { + new ResPluralsValue(mParent, new Duo[0]).serializeToResValuesXml( + serializer, res); + return; + } - serializer.startTag(null, "item"); - serializer.attribute(null, "type", type); - serializer.attribute(null, "name", res.getResSpec().getName()); - serializer.endTag(null, "item"); - } + serializer.startTag(null, "item"); + serializer.attribute(null, "type", type); + serializer.attribute(null, "name", res.getResSpec().getName()); + serializer.endTag(null, "item"); + } - public ResReferenceValue getParent() { - return mParent; - } + public ResReferenceValue getParent() { + return mParent; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBoolValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBoolValue.java index c8334eeb..724a59c2 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBoolValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBoolValue.java @@ -20,19 +20,19 @@ package brut.androlib.res.data.value; * @author Ryszard Wiśniewski */ public class ResBoolValue extends ResScalarValue { - private final boolean mValue; + private final boolean mValue; - public ResBoolValue(boolean value, String rawValue) { - super("bool", rawValue); - this.mValue = value; - } + public ResBoolValue(boolean value, String rawValue) { + super("bool", rawValue); + this.mValue = value; + } - public boolean getValue() { - return mValue; - } + public boolean getValue() { + return mValue; + } - @Override - protected String encodeAsResXml() { - return mValue ? "true" : "false"; - } + @Override + protected String encodeAsResXml() { + return mValue ? "true" : "false"; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResColorValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResColorValue.java index fc83da95..224186f3 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResColorValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResColorValue.java @@ -20,12 +20,12 @@ package brut.androlib.res.data.value; * @author Ryszard Wiśniewski */ public class ResColorValue extends ResIntValue { - public ResColorValue(int value, String rawValue) { - super(value, rawValue, "color"); - } + public ResColorValue(int value, String rawValue) { + super(value, rawValue, "color"); + } - @Override - protected String encodeAsResXml() { - return String.format("#%08x", mValue); - } + @Override + protected String encodeAsResXml() { + return String.format("#%08x", mValue); + } } \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResDimenValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResDimenValue.java index 24959a44..d00a6077 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResDimenValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResDimenValue.java @@ -23,12 +23,12 @@ import brut.androlib.AndrolibException; * @author Ryszard Wiśniewski */ public class ResDimenValue extends ResIntValue { - public ResDimenValue(int value, String rawValue) { - super(value, rawValue, "dimen"); - } + public ResDimenValue(int value, String rawValue) { + super(value, rawValue, "dimen"); + } - @Override - protected String encodeAsResXml() throws AndrolibException { - return TypedValue.coerceToString(TypedValue.TYPE_DIMENSION, mValue); - } + @Override + protected String encodeAsResXml() throws AndrolibException { + return TypedValue.coerceToString(TypedValue.TYPE_DIMENSION, mValue); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java index 1dd5410b..5dba59ed 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java @@ -28,55 +28,55 @@ import org.xmlpull.v1.XmlSerializer; * @author Ryszard Wiśniewski */ public class ResEnumAttr extends ResAttr { - ResEnumAttr(ResReferenceValue parent, int type, Integer min, Integer max, - Boolean l10n, Duo[] items) { - super(parent, type, min, max, l10n); - mItems = items; - } + ResEnumAttr(ResReferenceValue parent, int type, Integer min, Integer max, + Boolean l10n, Duo[] items) { + super(parent, type, min, max, l10n); + mItems = items; + } - @Override - public String convertToResXmlFormat(ResScalarValue value) - throws AndrolibException { - if (value instanceof ResIntValue) { - String ret = decodeValue(((ResIntValue) value).getValue()); - if (ret != null) { - return ret; - } - } - return super.convertToResXmlFormat(value); - } + @Override + public String convertToResXmlFormat(ResScalarValue value) + throws AndrolibException { + if (value instanceof ResIntValue) { + String ret = decodeValue(((ResIntValue) value).getValue()); + if (ret != null) { + return ret; + } + } + return super.convertToResXmlFormat(value); + } - @Override - protected void serializeBody(XmlSerializer serializer, ResResource res) - throws AndrolibException, IOException { - for (Duo duo : mItems) { - int intVal = duo.m2.getValue(); + @Override + protected void serializeBody(XmlSerializer serializer, ResResource res) + throws AndrolibException, IOException { + for (Duo duo : mItems) { + int intVal = duo.m2.getValue(); - serializer.startTag(null, "enum"); - serializer.attribute(null, "name", duo.m1.getReferent().getName()); - serializer.attribute(null, "value", String.valueOf(intVal)); - serializer.endTag(null, "enum"); - } - } + serializer.startTag(null, "enum"); + serializer.attribute(null, "name", duo.m1.getReferent().getName()); + serializer.attribute(null, "value", String.valueOf(intVal)); + serializer.endTag(null, "enum"); + } + } - private String decodeValue(int value) throws AndrolibException { - String value2 = mItemsCache.get(value); - if (value2 == null) { - ResReferenceValue ref = null; - for (Duo duo : mItems) { - if (duo.m2.getValue() == value) { - ref = duo.m1; - break; - } - } - if (ref != null) { - value2 = ref.getReferent().getName(); - mItemsCache.put(value, value2); - } - } - return value2; - } + private String decodeValue(int value) throws AndrolibException { + String value2 = mItemsCache.get(value); + if (value2 == null) { + ResReferenceValue ref = null; + for (Duo duo : mItems) { + if (duo.m2.getValue() == value) { + ref = duo.m1; + break; + } + } + if (ref != null) { + value2 = ref.getReferent().getName(); + mItemsCache.put(value, value2); + } + } + return value2; + } - private final Duo[] mItems; - private final Map mItemsCache = new HashMap(); + private final Duo[] mItems; + private final Map mItemsCache = new HashMap(); } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFileValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFileValue.java index 21656e29..d09a19e7 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFileValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFileValue.java @@ -22,21 +22,21 @@ import brut.androlib.AndrolibException; * @author Ryszard Wiśniewski */ public class ResFileValue extends ResValue { - private final String mPath; + private final String mPath; - public ResFileValue(String path) { - this.mPath = path; - } + public ResFileValue(String path) { + this.mPath = path; + } - public String getPath() { - return mPath; - } + public String getPath() { + return mPath; + } - public String getStrippedPath() throws AndrolibException { - if (!mPath.startsWith("res/")) { - throw new AndrolibException( - "File path does not start with \"res/\": " + mPath); - } - return mPath.substring(4); - } + public String getStrippedPath() throws AndrolibException { + if (!mPath.startsWith("res/")) { + throw new AndrolibException( + "File path does not start with \"res/\": " + mPath); + } + return mPath.substring(4); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFlagsAttr.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFlagsAttr.java index f73b85b9..a2052424 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFlagsAttr.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFlagsAttr.java @@ -28,133 +28,133 @@ import org.xmlpull.v1.XmlSerializer; * @author Ryszard Wiśniewski */ public class ResFlagsAttr extends ResAttr { - ResFlagsAttr(ResReferenceValue parent, int type, Integer min, Integer max, - Boolean l10n, Duo[] items) { - super(parent, type, min, max, l10n); + ResFlagsAttr(ResReferenceValue parent, int type, Integer min, Integer max, + Boolean l10n, Duo[] items) { + super(parent, type, min, max, l10n); - mItems = new FlagItem[items.length]; - for (int i = 0; i < items.length; i++) { - mItems[i] = new FlagItem(items[i].m1, items[i].m2.getValue()); - } - } + mItems = new FlagItem[items.length]; + for (int i = 0; i < items.length; i++) { + mItems[i] = new FlagItem(items[i].m1, items[i].m2.getValue()); + } + } - @Override - public String convertToResXmlFormat(ResScalarValue value) - throws AndrolibException { - if (!(value instanceof ResIntValue)) { - return super.convertToResXmlFormat(value); - } - loadFlags(); - int intVal = ((ResIntValue) value).getValue(); + @Override + public String convertToResXmlFormat(ResScalarValue value) + throws AndrolibException { + if (!(value instanceof ResIntValue)) { + return super.convertToResXmlFormat(value); + } + loadFlags(); + int intVal = ((ResIntValue) value).getValue(); - if (intVal == 0) { - return renderFlags(mZeroFlags); - } + if (intVal == 0) { + return renderFlags(mZeroFlags); + } - FlagItem[] flagItems = new FlagItem[mFlags.length]; - int[] flags = new int[mFlags.length]; - int flagsCount = 0; - for (int i = 0; i < mFlags.length; i++) { - FlagItem flagItem = mFlags[i]; - int flag = flagItem.flag; + FlagItem[] flagItems = new FlagItem[mFlags.length]; + int[] flags = new int[mFlags.length]; + int flagsCount = 0; + for (int i = 0; i < mFlags.length; i++) { + FlagItem flagItem = mFlags[i]; + int flag = flagItem.flag; - if ((intVal & flag) != flag) { - continue; - } + if ((intVal & flag) != flag) { + continue; + } - if (!isSubpartOf(flag, flags)) { - flags[flagsCount] = flag; - flagItems[flagsCount++] = flagItem; - } - } - return renderFlags(Arrays.copyOf(flagItems, flagsCount)); - } + if (!isSubpartOf(flag, flags)) { + flags[flagsCount] = flag; + flagItems[flagsCount++] = flagItem; + } + } + return renderFlags(Arrays.copyOf(flagItems, flagsCount)); + } - @Override - protected void serializeBody(XmlSerializer serializer, ResResource res) - throws AndrolibException, IOException { - for (int i = 0; i < mItems.length; i++) { - FlagItem item = mItems[i]; + @Override + protected void serializeBody(XmlSerializer serializer, ResResource res) + throws AndrolibException, IOException { + for (int i = 0; i < mItems.length; i++) { + FlagItem item = mItems[i]; - serializer.startTag(null, "flag"); - serializer.attribute(null, "name", item.getValue()); - serializer.attribute(null, "value", - String.format("0x%08x", item.flag)); - serializer.endTag(null, "flag"); - } - } + serializer.startTag(null, "flag"); + serializer.attribute(null, "name", item.getValue()); + serializer.attribute(null, "value", + String.format("0x%08x", item.flag)); + serializer.endTag(null, "flag"); + } + } - private boolean isSubpartOf(int flag, int[] flags) { - for (int i = 0; i < flags.length; i++) { - if ((flags[i] & flag) == flag) { - return true; - } - } - return false; - } + private boolean isSubpartOf(int flag, int[] flags) { + for (int i = 0; i < flags.length; i++) { + if ((flags[i] & flag) == flag) { + return true; + } + } + return false; + } - private String renderFlags(FlagItem[] flags) throws AndrolibException { - String ret = ""; - for (int i = 0; i < flags.length; i++) { - ret += "|" + flags[i].getValue(); - } - if (ret.isEmpty()) { - return ret; - } - return ret.substring(1); - } + private String renderFlags(FlagItem[] flags) throws AndrolibException { + String ret = ""; + for (int i = 0; i < flags.length; i++) { + ret += "|" + flags[i].getValue(); + } + if (ret.isEmpty()) { + return ret; + } + return ret.substring(1); + } - private void loadFlags() { - if (mFlags != null) { - return; - } + private void loadFlags() { + if (mFlags != null) { + return; + } - FlagItem[] zeroFlags = new FlagItem[mItems.length]; - int zeroFlagsCount = 0; - FlagItem[] flags = new FlagItem[mItems.length]; - int flagsCount = 0; + FlagItem[] zeroFlags = new FlagItem[mItems.length]; + int zeroFlagsCount = 0; + FlagItem[] flags = new FlagItem[mItems.length]; + int flagsCount = 0; - for (int i = 0; i < mItems.length; i++) { - FlagItem item = mItems[i]; - if (item.flag == 0) { - zeroFlags[zeroFlagsCount++] = item; - } else { - flags[flagsCount++] = item; - } - } + for (int i = 0; i < mItems.length; i++) { + FlagItem item = mItems[i]; + if (item.flag == 0) { + zeroFlags[zeroFlagsCount++] = item; + } else { + flags[flagsCount++] = item; + } + } - mZeroFlags = Arrays.copyOf(zeroFlags, zeroFlagsCount); - mFlags = Arrays.copyOf(flags, flagsCount); + mZeroFlags = Arrays.copyOf(zeroFlags, zeroFlagsCount); + mFlags = Arrays.copyOf(flags, flagsCount); - Arrays.sort(mFlags, new Comparator() { - @Override - public int compare(FlagItem o1, FlagItem o2) { - return Integer.valueOf(Integer.bitCount(o2.flag)).compareTo( - Integer.bitCount(o1.flag)); - } - }); - } + Arrays.sort(mFlags, new Comparator() { + @Override + public int compare(FlagItem o1, FlagItem o2) { + return Integer.valueOf(Integer.bitCount(o2.flag)).compareTo( + Integer.bitCount(o1.flag)); + } + }); + } - private final FlagItem[] mItems; + private final FlagItem[] mItems; - private FlagItem[] mZeroFlags; - private FlagItem[] mFlags; + private FlagItem[] mZeroFlags; + private FlagItem[] mFlags; - private static class FlagItem { - public final ResReferenceValue ref; - public final int flag; - public String value; + private static class FlagItem { + public final ResReferenceValue ref; + public final int flag; + public String value; - public FlagItem(ResReferenceValue ref, int flag) { - this.ref = ref; - this.flag = flag; - } + public FlagItem(ResReferenceValue ref, int flag) { + this.ref = ref; + this.flag = flag; + } - public String getValue() throws AndrolibException { - if (value == null) { - value = ref.getReferent().getName(); - } - return value; - } - } + public String getValue() throws AndrolibException { + if (value == null) { + value = ref.getReferent().getName(); + } + return value; + } + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFloatValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFloatValue.java index c7680e6e..f50b3d7c 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFloatValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFloatValue.java @@ -20,19 +20,19 @@ package brut.androlib.res.data.value; * @author Ryszard Wiśniewski */ public class ResFloatValue extends ResScalarValue { - private final float mValue; + private final float mValue; - public ResFloatValue(float value, String rawValue) { - super("float", rawValue); - this.mValue = value; - } + public ResFloatValue(float value, String rawValue) { + super("float", rawValue); + this.mValue = value; + } - public float getValue() { - return mValue; - } + public float getValue() { + return mValue; + } - @Override - protected String encodeAsResXml() { - return String.valueOf(mValue); - } + @Override + protected String encodeAsResXml() { + return String.valueOf(mValue); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFractionValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFractionValue.java index 3fddbfad..c3325834 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFractionValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFractionValue.java @@ -23,12 +23,12 @@ import brut.androlib.AndrolibException; * @author Ryszard Wiśniewski */ public class ResFractionValue extends ResIntValue { - public ResFractionValue(int value, String rawValue) { - super(value, rawValue, "fraction"); - } + public ResFractionValue(int value, String rawValue) { + super(value, rawValue, "fraction"); + } - @Override - protected String encodeAsResXml() throws AndrolibException { - return TypedValue.coerceToString(TypedValue.TYPE_FRACTION, mValue); - } + @Override + protected String encodeAsResXml() throws AndrolibException { + return TypedValue.coerceToString(TypedValue.TYPE_FRACTION, mValue); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIdValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIdValue.java index 38eaaed9..9f1dd33f 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIdValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIdValue.java @@ -26,13 +26,13 @@ import org.xmlpull.v1.XmlSerializer; * @author Ryszard Wiśniewski */ public class ResIdValue extends ResValue implements ResValuesXmlSerializable { - @Override - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException { - serializer.startTag(null, "item"); - serializer - .attribute(null, "type", res.getResSpec().getType().getName()); - serializer.attribute(null, "name", res.getResSpec().getName()); - serializer.endTag(null, "item"); - } + @Override + public void serializeToResValuesXml(XmlSerializer serializer, + ResResource res) throws IOException, AndrolibException { + serializer.startTag(null, "item"); + serializer + .attribute(null, "type", res.getResSpec().getType().getName()); + serializer.attribute(null, "name", res.getResSpec().getName()); + serializer.endTag(null, "item"); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntValue.java index d1662657..7193d196 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntValue.java @@ -23,25 +23,25 @@ import brut.androlib.AndrolibException; * @author Ryszard Wiśniewski */ public class ResIntValue extends ResScalarValue { - protected final int mValue; - private int type; + protected final int mValue; + private int type; - public ResIntValue(int value, String rawValue, int type) { - this(value, rawValue, "integer"); - this.type = type; - } + public ResIntValue(int value, String rawValue, int type) { + this(value, rawValue, "integer"); + this.type = type; + } - public ResIntValue(int value, String rawValue, String type) { - super(type, rawValue); - this.mValue = value; - } + public ResIntValue(int value, String rawValue, String type) { + super(type, rawValue); + this.mValue = value; + } - public int getValue() { - return mValue; - } + public int getValue() { + return mValue; + } - @Override - protected String encodeAsResXml() throws AndrolibException { - return TypedValue.coerceToString(type, mValue); - } + @Override + protected String encodeAsResXml() throws AndrolibException { + return TypedValue.coerceToString(type, mValue); + } } \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java index d93a3f1b..1f5eaad0 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java @@ -29,42 +29,42 @@ import org.xmlpull.v1.XmlSerializer; * @author Ryszard Wiśniewski */ public class ResPluralsValue extends ResBagValue implements - ResValuesXmlSerializable { - ResPluralsValue(ResReferenceValue parent, - Duo[] items) { - super(parent); + ResValuesXmlSerializable { + ResPluralsValue(ResReferenceValue parent, + Duo[] items) { + super(parent); - mItems = new ResScalarValue[6]; - for (int i = 0; i < items.length; i++) { - mItems[items[i].m1 - BAG_KEY_PLURALS_START] = items[i].m2; - } - } + mItems = new ResScalarValue[6]; + for (int i = 0; i < items.length; i++) { + mItems[items[i].m1 - BAG_KEY_PLURALS_START] = items[i].m2; + } + } - @Override - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException { - serializer.startTag(null, "plurals"); - serializer.attribute(null, "name", res.getResSpec().getName()); - for (int i = 0; i < mItems.length; i++) { - ResScalarValue item = mItems[i]; - if (item == null) { - continue; - } + @Override + public void serializeToResValuesXml(XmlSerializer serializer, + ResResource res) throws IOException, AndrolibException { + serializer.startTag(null, "plurals"); + serializer.attribute(null, "name", res.getResSpec().getName()); + for (int i = 0; i < mItems.length; i++) { + ResScalarValue item = mItems[i]; + if (item == null) { + continue; + } - ResScalarValue rawValue = item; + ResScalarValue rawValue = item; - serializer.startTag(null, "item"); - serializer.attribute(null, "quantity", QUANTITY_MAP[i]); + serializer.startTag(null, "item"); + serializer.attribute(null, "quantity", QUANTITY_MAP[i]); serializer.text(ResXmlEncoders.enumerateNonPositionalSubstitutionsIfRequired(item.encodeAsResXmlValue())); - serializer.endTag(null, "item"); - } - serializer.endTag(null, "plurals"); - } + serializer.endTag(null, "item"); + } + serializer.endTag(null, "plurals"); + } - private final ResScalarValue[] mItems; + private final ResScalarValue[] mItems; - public static final int BAG_KEY_PLURALS_START = 0x01000004; - public static final int BAG_KEY_PLURALS_END = 0x01000009; - private static final String[] QUANTITY_MAP = new String[] { "other", - "zero", "one", "two", "few", "many" }; + public static final int BAG_KEY_PLURALS_START = 0x01000004; + public static final int BAG_KEY_PLURALS_END = 0x01000009; + private static final String[] QUANTITY_MAP = new String[] { "other", + "zero", "one", "two", "few", "many" }; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResReferenceValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResReferenceValue.java index f299dce3..1d037610 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResReferenceValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResReferenceValue.java @@ -24,43 +24,43 @@ import brut.androlib.res.data.ResResSpec; * @author Ryszard Wiśniewski */ public class ResReferenceValue extends ResIntValue { - private final ResPackage mPackage; - private final boolean mTheme; + private final ResPackage mPackage; + private final boolean mTheme; - public ResReferenceValue(ResPackage package_, int value, String rawValue) { - this(package_, value, rawValue, false); - } + public ResReferenceValue(ResPackage package_, int value, String rawValue) { + this(package_, value, rawValue, false); + } - public ResReferenceValue(ResPackage package_, int value, String rawValue, - boolean theme) { - super(value, rawValue, "reference"); - mPackage = package_; - mTheme = theme; - } + public ResReferenceValue(ResPackage package_, int value, String rawValue, + boolean theme) { + super(value, rawValue, "reference"); + mPackage = package_; + mTheme = theme; + } - @Override - protected String encodeAsResXml() throws AndrolibException { - if (isNull()) { - return "@null"; - } + @Override + protected String encodeAsResXml() throws AndrolibException { + if (isNull()) { + return "@null"; + } - ResResSpec spec = getReferent(); - boolean newId = spec.hasDefaultResource() - && spec.getDefaultResource().getValue() instanceof ResIdValue; + ResResSpec spec = getReferent(); + boolean newId = spec.hasDefaultResource() + && spec.getDefaultResource().getValue() instanceof ResIdValue; - // generate the beginning to fix @android - String mStart = (mTheme ? '?' : '@') + (newId ? "+" : ""); + // generate the beginning to fix @android + String mStart = (mTheme ? '?' : '@') + (newId ? "+" : ""); - return mStart - + spec.getFullName(mPackage, mTheme - && spec.getType().getName().equals("attr")); - } + return mStart + + spec.getFullName(mPackage, mTheme + && spec.getType().getName().equals("attr")); + } - public ResResSpec getReferent() throws AndrolibException { - return mPackage.getResTable().getResSpec(getValue()); - } + public ResResSpec getReferent() throws AndrolibException { + return mPackage.getResTable().getResSpec(getValue()); + } - public boolean isNull() { - return mValue == 0; - } + public boolean isNull() { + return mValue == 0; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java index 6a58ef42..ff8c3f18 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java @@ -28,48 +28,48 @@ import org.xmlpull.v1.XmlSerializer; * @author Ryszard Wiśniewski */ public abstract class ResScalarValue extends ResValue implements - ResXmlEncodable, ResValuesXmlSerializable { - protected final String mType; - protected final String mRawValue; + ResXmlEncodable, ResValuesXmlSerializable { + protected final String mType; + protected final String mRawValue; - protected ResScalarValue(String type, String rawValue) { - mType = type; - mRawValue = rawValue; - } + protected ResScalarValue(String type, String rawValue) { + mType = type; + mRawValue = rawValue; + } - @Override - public String encodeAsResXmlAttr() throws AndrolibException { - if (mRawValue != null) { - return mRawValue; - } - return encodeAsResXml(); - } + @Override + public String encodeAsResXmlAttr() throws AndrolibException { + if (mRawValue != null) { + return mRawValue; + } + return encodeAsResXml(); + } - public String encodeAsResXmlItemValue() throws AndrolibException { - return encodeAsResXmlValue(); - } + public String encodeAsResXmlItemValue() throws AndrolibException { + return encodeAsResXmlValue(); + } - @Override - public String encodeAsResXmlValue() throws AndrolibException { - if (mRawValue != null) { - return mRawValue; - } - return encodeAsResXml(); - } + @Override + public String encodeAsResXmlValue() throws AndrolibException { + if (mRawValue != null) { + return mRawValue; + } + return encodeAsResXml(); + } public String encodeAsResXmlNonEscapedItemValue() throws AndrolibException { return encodeAsResXmlValue().replace("&", "&").replace("<","<"); } - @Override - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException { - String type = res.getResSpec().getType().getName(); - boolean item = !"reference".equals(mType) && !type.equals(mType); + @Override + public void serializeToResValuesXml(XmlSerializer serializer, + ResResource res) throws IOException, AndrolibException { + String type = res.getResSpec().getType().getName(); + boolean item = !"reference".equals(mType) && !type.equals(mType); - String body = encodeAsResXmlValue(); + String body = encodeAsResXmlValue(); - // check for resource reference + // check for resource reference if (!type.equalsIgnoreCase("color")) { if (body.contains("@")) { if (!res.getFilePath().contains("string")) { @@ -78,31 +78,31 @@ public abstract class ResScalarValue extends ResValue implements } } - // check for using attrib as node or item - String tagName = item ? "item" : type; + // check for using attrib as node or item + String tagName = item ? "item" : type; - serializer.startTag(null, tagName); - if (item) { - serializer.attribute(null, "type", type); - } - serializer.attribute(null, "name", res.getResSpec().getName()); + serializer.startTag(null, tagName); + if (item) { + serializer.attribute(null, "type", type); + } + serializer.attribute(null, "name", res.getResSpec().getName()); - serializeExtraXmlAttrs(serializer, res); + serializeExtraXmlAttrs(serializer, res); - if (!body.isEmpty()) { - serializer.ignorableWhitespace(body); - } + if (!body.isEmpty()) { + serializer.ignorableWhitespace(body); + } - serializer.endTag(null, tagName); - } + serializer.endTag(null, tagName); + } - public String getType() { - return mType; - } + public String getType() { + return mType; + } - protected void serializeExtraXmlAttrs(XmlSerializer serializer, - ResResource res) throws IOException { - } + protected void serializeExtraXmlAttrs(XmlSerializer serializer, + ResResource res) throws IOException { + } - protected abstract String encodeAsResXml() throws AndrolibException; + protected abstract String encodeAsResXml() throws AndrolibException; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStringValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStringValue.java index 0683aa25..c248cc5d 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStringValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStringValue.java @@ -27,41 +27,41 @@ import org.xmlpull.v1.XmlSerializer; */ public class ResStringValue extends ResScalarValue { - public ResStringValue(String value) { - this(value, "string"); - } + public ResStringValue(String value) { + this(value, "string"); + } - public ResStringValue(String value, String type) { - super(type, value); - } + public ResStringValue(String value, String type) { + super(type, value); + } - @Override - public String encodeAsResXmlAttr() { - return ResXmlEncoders.encodeAsResXmlAttr(mRawValue); - } + @Override + public String encodeAsResXmlAttr() { + return ResXmlEncoders.encodeAsResXmlAttr(mRawValue); + } - @Override - public String encodeAsResXmlItemValue() { - return ResXmlEncoders - .enumerateNonPositionalSubstitutionsIfRequired(ResXmlEncoders - .encodeAsXmlValue(mRawValue)); - } + @Override + public String encodeAsResXmlItemValue() { + return ResXmlEncoders + .enumerateNonPositionalSubstitutionsIfRequired(ResXmlEncoders + .encodeAsXmlValue(mRawValue)); + } - @Override - public String encodeAsResXmlValue() { - return ResXmlEncoders.encodeAsXmlValue(mRawValue); - } + @Override + public String encodeAsResXmlValue() { + return ResXmlEncoders.encodeAsXmlValue(mRawValue); + } - @Override - protected String encodeAsResXml() throws AndrolibException { - throw new UnsupportedOperationException(); - } + @Override + protected String encodeAsResXml() throws AndrolibException { + throw new UnsupportedOperationException(); + } - @Override - protected void serializeExtraXmlAttrs(XmlSerializer serializer, - ResResource res) throws IOException { - if (ResXmlEncoders.hasMultipleNonPositionalSubstitutions(mRawValue)) { - serializer.attribute(null, "formatted", "false"); - } - } + @Override + protected void serializeExtraXmlAttrs(XmlSerializer serializer, + ResResource res) throws IOException { + if (ResXmlEncoders.hasMultipleNonPositionalSubstitutions(mRawValue)) { + serializer.attribute(null, "formatted", "false"); + } + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java index 6c34021d..35c38c5e 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java @@ -28,55 +28,55 @@ import org.xmlpull.v1.XmlSerializer; * @author Ryszard Wiśniewski */ public class ResStyleValue extends ResBagValue implements - ResValuesXmlSerializable { - ResStyleValue(ResReferenceValue parent, - Duo[] items, ResValueFactory factory) { - super(parent); + ResValuesXmlSerializable { + ResStyleValue(ResReferenceValue parent, + Duo[] items, ResValueFactory factory) { + super(parent); - mItems = new Duo[items.length]; - for (int i = 0; i < items.length; i++) { - mItems[i] = new Duo( - factory.newReference(items[i].m1, null), items[i].m2); - } - } + mItems = new Duo[items.length]; + for (int i = 0; i < items.length; i++) { + mItems[i] = new Duo( + factory.newReference(items[i].m1, null), items[i].m2); + } + } - @Override - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException { - serializer.startTag(null, "style"); - serializer.attribute(null, "name", res.getResSpec().getName()); - if (!mParent.isNull()) { - serializer.attribute(null, "parent", mParent.encodeAsResXmlAttr()); - } else if (res.getResSpec().getName().indexOf('.') != -1) { + @Override + public void serializeToResValuesXml(XmlSerializer serializer, + ResResource res) throws IOException, AndrolibException { + serializer.startTag(null, "style"); + serializer.attribute(null, "name", res.getResSpec().getName()); + if (!mParent.isNull()) { + serializer.attribute(null, "parent", mParent.encodeAsResXmlAttr()); + } else if (res.getResSpec().getName().indexOf('.') != -1) { serializer.attribute(null, "parent", ""); } - for (int i = 0; i < mItems.length; i++) { - ResResSpec spec = mItems[i].m1.getReferent(); + for (int i = 0; i < mItems.length; i++) { + ResResSpec spec = mItems[i].m1.getReferent(); - // hacky-fix remove bad ReferenceVars - if (spec.getDefaultResource().getValue().toString() - .contains("ResReferenceValue@")) { - continue; - } - ResAttr attr = (ResAttr) spec.getDefaultResource().getValue(); - String value = attr.convertToResXmlFormat(mItems[i].m2); + // hacky-fix remove bad ReferenceVars + if (spec.getDefaultResource().getValue().toString() + .contains("ResReferenceValue@")) { + continue; + } + ResAttr attr = (ResAttr) spec.getDefaultResource().getValue(); + String value = attr.convertToResXmlFormat(mItems[i].m2); - if (value == null) { - value = mItems[i].m2.encodeAsResXmlValue(); - } + if (value == null) { + value = mItems[i].m2.encodeAsResXmlValue(); + } - if (value == null) { - continue; - } + if (value == null) { + continue; + } - serializer.startTag(null, "item"); - serializer.attribute(null, "name", - spec.getFullName(res.getResSpec().getPackage(), true)); - serializer.text(value); - serializer.endTag(null, "item"); - } - serializer.endTag(null, "style"); - } + serializer.startTag(null, "item"); + serializer.attribute(null, "name", + spec.getFullName(res.getResSpec().getPackage(), true)); + serializer.text(value); + serializer.endTag(null, "item"); + } + serializer.endTag(null, "style"); + } - private final Duo[] mItems; + private final Duo[] mItems; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java index 3c4693f6..0331112d 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java @@ -25,77 +25,77 @@ import brut.util.Duo; * @author Ryszard Wiśniewski */ public class ResValueFactory { - private final ResPackage mPackage; + private final ResPackage mPackage; - public ResValueFactory(ResPackage pakage_) { - this.mPackage = pakage_; - } + public ResValueFactory(ResPackage pakage_) { + this.mPackage = pakage_; + } - public ResScalarValue factory(int type, int value, String rawValue) - throws AndrolibException { - switch (type) { - case TypedValue.TYPE_REFERENCE: - return newReference(value, rawValue); - case TypedValue.TYPE_ATTRIBUTE: - return newReference(value, rawValue, true); - case TypedValue.TYPE_STRING: - return new ResStringValue(rawValue); - case TypedValue.TYPE_FLOAT: - return new ResFloatValue(Float.intBitsToFloat(value), rawValue); - case TypedValue.TYPE_DIMENSION: - return new ResDimenValue(value, rawValue); - case TypedValue.TYPE_FRACTION: - return new ResFractionValue(value, rawValue); - case TypedValue.TYPE_INT_BOOLEAN: - return new ResBoolValue(value != 0, rawValue); - } + public ResScalarValue factory(int type, int value, String rawValue) + throws AndrolibException { + switch (type) { + case TypedValue.TYPE_REFERENCE: + return newReference(value, rawValue); + case TypedValue.TYPE_ATTRIBUTE: + return newReference(value, rawValue, true); + case TypedValue.TYPE_STRING: + return new ResStringValue(rawValue); + case TypedValue.TYPE_FLOAT: + return new ResFloatValue(Float.intBitsToFloat(value), rawValue); + case TypedValue.TYPE_DIMENSION: + return new ResDimenValue(value, rawValue); + case TypedValue.TYPE_FRACTION: + return new ResFractionValue(value, rawValue); + case TypedValue.TYPE_INT_BOOLEAN: + return new ResBoolValue(value != 0, rawValue); + } - if (type >= TypedValue.TYPE_FIRST_COLOR_INT - && type <= TypedValue.TYPE_LAST_COLOR_INT) { - return new ResColorValue(value, rawValue); - } - if (type >= TypedValue.TYPE_FIRST_INT - && type <= TypedValue.TYPE_LAST_INT) { - return new ResIntValue(value, rawValue, type); - } + if (type >= TypedValue.TYPE_FIRST_COLOR_INT + && type <= TypedValue.TYPE_LAST_COLOR_INT) { + return new ResColorValue(value, rawValue); + } + if (type >= TypedValue.TYPE_FIRST_INT + && type <= TypedValue.TYPE_LAST_INT) { + return new ResIntValue(value, rawValue, type); + } - throw new AndrolibException("Invalid value type: " + type); - } + throw new AndrolibException("Invalid value type: " + type); + } - public ResValue factory(String value) { - if (value.startsWith("res/")) { - return new ResFileValue(value); - } - return new ResStringValue(value); - } + public ResValue factory(String value) { + if (value.startsWith("res/")) { + return new ResFileValue(value); + } + return new ResStringValue(value); + } - public ResBagValue bagFactory(int parent, - Duo[] items) throws AndrolibException { - ResReferenceValue parentVal = newReference(parent, null); + public ResBagValue bagFactory(int parent, + Duo[] items) throws AndrolibException { + ResReferenceValue parentVal = newReference(parent, null); - if (items.length == 0) { - return new ResBagValue(parentVal); - } - int key = items[0].m1; - if (key == ResAttr.BAG_KEY_ATTR_TYPE) { - return ResAttr.factory(parentVal, items, this, mPackage); - } - if (key == ResArrayValue.BAG_KEY_ARRAY_START) { - return new ResArrayValue(parentVal, items); - } - if (key >= ResPluralsValue.BAG_KEY_PLURALS_START - && key <= ResPluralsValue.BAG_KEY_PLURALS_END) { - return new ResPluralsValue(parentVal, items); - } - return new ResStyleValue(parentVal, items, this); - } + if (items.length == 0) { + return new ResBagValue(parentVal); + } + int key = items[0].m1; + if (key == ResAttr.BAG_KEY_ATTR_TYPE) { + return ResAttr.factory(parentVal, items, this, mPackage); + } + if (key == ResArrayValue.BAG_KEY_ARRAY_START) { + return new ResArrayValue(parentVal, items); + } + if (key >= ResPluralsValue.BAG_KEY_PLURALS_START + && key <= ResPluralsValue.BAG_KEY_PLURALS_END) { + return new ResPluralsValue(parentVal, items); + } + return new ResStyleValue(parentVal, items, this); + } - public ResReferenceValue newReference(int resID, String rawValue) { - return newReference(resID, rawValue, false); - } + public ResReferenceValue newReference(int resID, String rawValue) { + return newReference(resID, rawValue, false); + } - public ResReferenceValue newReference(int resID, String rawValue, - boolean theme) { - return new ResReferenceValue(mPackage, resID, rawValue, theme); - } + public ResReferenceValue newReference(int resID, String rawValue, + boolean theme) { + return new ResReferenceValue(mPackage, resID, rawValue, theme); + } } \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java index 93f1b8f2..2c619984 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java @@ -34,391 +34,391 @@ import org.apache.commons.io.input.CountingInputStream; * @author Ryszard Wiśniewski */ public class ARSCDecoder { - public static ARSCData decode(InputStream arscStream, - boolean findFlagsOffsets, boolean keepBroken) - throws AndrolibException { - return decode(arscStream, findFlagsOffsets, keepBroken, new ResTable()); - } + public static ARSCData decode(InputStream arscStream, + boolean findFlagsOffsets, boolean keepBroken) + throws AndrolibException { + return decode(arscStream, findFlagsOffsets, keepBroken, new ResTable()); + } - public static ARSCData decode(InputStream arscStream, - boolean findFlagsOffsets, boolean keepBroken, ResTable resTable) - throws AndrolibException { - try { - ARSCDecoder decoder = new ARSCDecoder(arscStream, resTable, - findFlagsOffsets, keepBroken); - ResPackage[] pkgs = decoder.readTable(); - return new ARSCData(pkgs, decoder.mFlagsOffsets == null ? null - : decoder.mFlagsOffsets.toArray(new FlagsOffset[0]), - resTable); - } catch (IOException ex) { - throw new AndrolibException("Could not decode arsc file", ex); - } - } + public static ARSCData decode(InputStream arscStream, + boolean findFlagsOffsets, boolean keepBroken, ResTable resTable) + throws AndrolibException { + try { + ARSCDecoder decoder = new ARSCDecoder(arscStream, resTable, + findFlagsOffsets, keepBroken); + ResPackage[] pkgs = decoder.readTable(); + return new ARSCData(pkgs, decoder.mFlagsOffsets == null ? null + : decoder.mFlagsOffsets.toArray(new FlagsOffset[0]), + resTable); + } catch (IOException ex) { + throw new AndrolibException("Could not decode arsc file", ex); + } + } - private ARSCDecoder(InputStream arscStream, ResTable resTable, - boolean storeFlagsOffsets, boolean keepBroken) { - if (storeFlagsOffsets) { - arscStream = mCountIn = new CountingInputStream(arscStream); - mFlagsOffsets = new ArrayList(); - } else { - mCountIn = null; - mFlagsOffsets = null; - } - mIn = new ExtDataInput(new LEDataInputStream(arscStream)); - mResTable = resTable; - mKeepBroken = keepBroken; - } + private ARSCDecoder(InputStream arscStream, ResTable resTable, + boolean storeFlagsOffsets, boolean keepBroken) { + if (storeFlagsOffsets) { + arscStream = mCountIn = new CountingInputStream(arscStream); + mFlagsOffsets = new ArrayList(); + } else { + mCountIn = null; + mFlagsOffsets = null; + } + mIn = new ExtDataInput(new LEDataInputStream(arscStream)); + mResTable = resTable; + mKeepBroken = keepBroken; + } - private ResPackage[] readTable() throws IOException, AndrolibException { - nextChunkCheckType(Header.TYPE_TABLE); - int packageCount = mIn.readInt(); + private ResPackage[] readTable() throws IOException, AndrolibException { + nextChunkCheckType(Header.TYPE_TABLE); + int packageCount = mIn.readInt(); - mTableStrings = StringBlock.read(mIn); - ResPackage[] packages = new ResPackage[packageCount]; + mTableStrings = StringBlock.read(mIn); + ResPackage[] packages = new ResPackage[packageCount]; - nextChunk(); - for (int i = 0; i < packageCount; i++) { - packages[i] = readPackage(); - } - return packages; - } + nextChunk(); + for (int i = 0; i < packageCount; i++) { + packages[i] = readPackage(); + } + return packages; + } - private ResPackage readPackage() throws IOException, AndrolibException { - checkChunkType(Header.TYPE_PACKAGE); - int id = (byte) mIn.readInt(); - String name = mIn.readNulEndedString(128, true); + private ResPackage readPackage() throws IOException, AndrolibException { + checkChunkType(Header.TYPE_PACKAGE); + int id = (byte) mIn.readInt(); + String name = mIn.readNulEndedString(128, true); /* typeNameStrings */mIn.skipInt(); /* typeNameCount */mIn.skipInt(); /* specNameStrings */mIn.skipInt(); /* specNameCount */mIn.skipInt(); - mTypeNames = StringBlock.read(mIn); - mSpecNames = StringBlock.read(mIn); + mTypeNames = StringBlock.read(mIn); + mSpecNames = StringBlock.read(mIn); - mResId = id << 24; - mPkg = new ResPackage(mResTable, id, name); + mResId = id << 24; + mPkg = new ResPackage(mResTable, id, name); - nextChunk(); - while (mHeader.type == Header.TYPE_TYPE) { - readType(); - } + nextChunk(); + while (mHeader.type == Header.TYPE_TYPE) { + readType(); + } - return mPkg; - } + return mPkg; + } - private ResType readType() throws AndrolibException, IOException { - checkChunkType(Header.TYPE_TYPE); - byte id = mIn.readByte(); - mIn.skipBytes(3); - int entryCount = mIn.readInt(); + private ResType readType() throws AndrolibException, IOException { + checkChunkType(Header.TYPE_TYPE); + byte id = mIn.readByte(); + mIn.skipBytes(3); + int entryCount = mIn.readInt(); - mMissingResSpecs = new boolean[entryCount]; - Arrays.fill(mMissingResSpecs, true); + mMissingResSpecs = new boolean[entryCount]; + Arrays.fill(mMissingResSpecs, true); - if (mFlagsOffsets != null) { - mFlagsOffsets.add(new FlagsOffset(mCountIn.getCount(), entryCount)); - } + if (mFlagsOffsets != null) { + mFlagsOffsets.add(new FlagsOffset(mCountIn.getCount(), entryCount)); + } /* flags */mIn.skipBytes(entryCount * 4); - mResId = (0xff000000 & mResId) | id << 16; - mType = new ResType(mTypeNames.getString(id - 1), mResTable, mPkg); - mPkg.addType(mType); + mResId = (0xff000000 & mResId) | id << 16; + mType = new ResType(mTypeNames.getString(id - 1), mResTable, mPkg); + mPkg.addType(mType); - while (nextChunk().type == Header.TYPE_CONFIG) { - readConfig(); - } + while (nextChunk().type == Header.TYPE_CONFIG) { + readConfig(); + } - addMissingResSpecs(); + addMissingResSpecs(); - return mType; - } + return mType; + } - private ResConfig readConfig() throws IOException, AndrolibException { - checkChunkType(Header.TYPE_CONFIG); + private ResConfig readConfig() throws IOException, AndrolibException { + checkChunkType(Header.TYPE_CONFIG); /* typeId */mIn.skipInt(); - int entryCount = mIn.readInt(); + int entryCount = mIn.readInt(); /* entriesStart */mIn.skipInt(); - ResConfigFlags flags = readConfigFlags(); - int[] entryOffsets = mIn.readIntArray(entryCount); + ResConfigFlags flags = readConfigFlags(); + int[] entryOffsets = mIn.readIntArray(entryCount); - if (flags.isInvalid) { - String resName = mType.getName() + flags.getQualifiers(); - if (mKeepBroken) { - LOGGER.warning("Invalid config flags detected: " + resName); - } else { - LOGGER.warning("Invalid config flags detected. Dropping resources: " - + resName); - } - } + if (flags.isInvalid) { + String resName = mType.getName() + flags.getQualifiers(); + if (mKeepBroken) { + LOGGER.warning("Invalid config flags detected: " + resName); + } else { + LOGGER.warning("Invalid config flags detected. Dropping resources: " + + resName); + } + } - mConfig = flags.isInvalid && !mKeepBroken ? null : mPkg - .getOrCreateConfig(flags); + mConfig = flags.isInvalid && !mKeepBroken ? null : mPkg + .getOrCreateConfig(flags); - for (int i = 0; i < entryOffsets.length; i++) { - if (entryOffsets[i] != -1) { - mMissingResSpecs[i] = false; - mResId = (mResId & 0xffff0000) | i; - readEntry(); - } - } + for (int i = 0; i < entryOffsets.length; i++) { + if (entryOffsets[i] != -1) { + mMissingResSpecs[i] = false; + mResId = (mResId & 0xffff0000) | i; + readEntry(); + } + } - return mConfig; - } + return mConfig; + } - private void readEntry() throws IOException, AndrolibException { + private void readEntry() throws IOException, AndrolibException { /* size */mIn.skipBytes(2); - short flags = mIn.readShort(); - int specNamesId = mIn.readInt(); + short flags = mIn.readShort(); + int specNamesId = mIn.readInt(); - ResValue value = (flags & ENTRY_FLAG_COMPLEX) == 0 ? readValue() - : readComplexEntry(); + ResValue value = (flags & ENTRY_FLAG_COMPLEX) == 0 ? readValue() + : readComplexEntry(); - if (mConfig == null) { - return; - } + if (mConfig == null) { + return; + } - ResID resId = new ResID(mResId); - ResResSpec spec; - if (mPkg.hasResSpec(resId)) { - spec = mPkg.getResSpec(resId); - } else { - spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), - mPkg, mType); - mPkg.addResSpec(spec); - mType.addResSpec(spec); - } - ResResource res = new ResResource(mConfig, spec, value); + ResID resId = new ResID(mResId); + ResResSpec spec; + if (mPkg.hasResSpec(resId)) { + spec = mPkg.getResSpec(resId); + } else { + spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), + mPkg, mType); + mPkg.addResSpec(spec); + mType.addResSpec(spec); + } + ResResource res = new ResResource(mConfig, spec, value); - mConfig.addResource(res); - spec.addResource(res); - mPkg.addResource(res); - } + mConfig.addResource(res); + spec.addResource(res); + mPkg.addResource(res); + } - private ResBagValue readComplexEntry() throws IOException, - AndrolibException { - int parent = mIn.readInt(); - int count = mIn.readInt(); + private ResBagValue readComplexEntry() throws IOException, + AndrolibException { + int parent = mIn.readInt(); + int count = mIn.readInt(); - ResValueFactory factory = mPkg.getValueFactory(); - Duo[] items = new Duo[count]; - for (int i = 0; i < count; i++) { - items[i] = new Duo(mIn.readInt(), - (ResScalarValue) readValue()); - } + ResValueFactory factory = mPkg.getValueFactory(); + Duo[] items = new Duo[count]; + for (int i = 0; i < count; i++) { + items[i] = new Duo(mIn.readInt(), + (ResScalarValue) readValue()); + } - return factory.bagFactory(parent, items); - } + return factory.bagFactory(parent, items); + } - private ResValue readValue() throws IOException, AndrolibException { + private ResValue readValue() throws IOException, AndrolibException { /* size */mIn.skipCheckShort((short) 8); /* zero */mIn.skipCheckByte((byte) 0); - byte type = mIn.readByte(); - int data = mIn.readInt(); + byte type = mIn.readByte(); + int data = mIn.readInt(); - return type == TypedValue.TYPE_STRING ? mPkg.getValueFactory().factory( - mTableStrings.getHTML(data)) : mPkg.getValueFactory().factory( - type, data, null); - } + return type == TypedValue.TYPE_STRING ? mPkg.getValueFactory().factory( + mTableStrings.getHTML(data)) : mPkg.getValueFactory().factory( + type, data, null); + } - private ResConfigFlags readConfigFlags() throws IOException, - AndrolibException { - int size = mIn.readInt(); - if (size < 28) { - throw new AndrolibException("Config size < 28"); - } + private ResConfigFlags readConfigFlags() throws IOException, + AndrolibException { + int size = mIn.readInt(); + if (size < 28) { + throw new AndrolibException("Config size < 28"); + } - boolean isInvalid = false; + boolean isInvalid = false; - short mcc = mIn.readShort(); - short mnc = mIn.readShort(); + short mcc = mIn.readShort(); + short mnc = mIn.readShort(); - char[] language = new char[] { (char) mIn.readByte(), - (char) mIn.readByte() }; - char[] country = new char[] { (char) mIn.readByte(), - (char) mIn.readByte() }; + char[] language = new char[] { (char) mIn.readByte(), + (char) mIn.readByte() }; + char[] country = new char[] { (char) mIn.readByte(), + (char) mIn.readByte() }; - byte orientation = mIn.readByte(); - byte touchscreen = mIn.readByte(); + byte orientation = mIn.readByte(); + byte touchscreen = mIn.readByte(); - int density = mIn.readUnsignedShort(); + int density = mIn.readUnsignedShort(); - byte keyboard = mIn.readByte(); - byte navigation = mIn.readByte(); - byte inputFlags = mIn.readByte(); + byte keyboard = mIn.readByte(); + byte navigation = mIn.readByte(); + byte inputFlags = mIn.readByte(); /* inputPad0 */mIn.skipBytes(1); - short screenWidth = mIn.readShort(); - short screenHeight = mIn.readShort(); + short screenWidth = mIn.readShort(); + short screenHeight = mIn.readShort(); - short sdkVersion = mIn.readShort(); + short sdkVersion = mIn.readShort(); /* minorVersion, now must always be 0 */mIn.skipBytes(2); - byte screenLayout = 0; - byte uiMode = 0; - short smallestScreenWidthDp = 0; - if (size >= 32) { - screenLayout = mIn.readByte(); - uiMode = mIn.readByte(); - smallestScreenWidthDp = mIn.readShort(); - } + byte screenLayout = 0; + byte uiMode = 0; + short smallestScreenWidthDp = 0; + if (size >= 32) { + screenLayout = mIn.readByte(); + uiMode = mIn.readByte(); + smallestScreenWidthDp = mIn.readShort(); + } - short screenWidthDp = 0; - short screenHeightDp = 0; - if (size >= 36) { - screenWidthDp = mIn.readShort(); - screenHeightDp = mIn.readShort(); - } + short screenWidthDp = 0; + short screenHeightDp = 0; + if (size >= 36) { + screenWidthDp = mIn.readShort(); + screenHeightDp = mIn.readShort(); + } - short layoutDirection = 0; - if (size >= 38) { - layoutDirection = mIn.readShort(); - } + short layoutDirection = 0; + if (size >= 38) { + layoutDirection = mIn.readShort(); + } - int exceedingSize = size - KNOWN_CONFIG_BYTES; - if (exceedingSize > 0) { - byte[] buf = new byte[exceedingSize]; - mIn.readFully(buf); - BigInteger exceedingBI = new BigInteger(1, buf); + int exceedingSize = size - KNOWN_CONFIG_BYTES; + if (exceedingSize > 0) { + byte[] buf = new byte[exceedingSize]; + mIn.readFully(buf); + BigInteger exceedingBI = new BigInteger(1, buf); - if (exceedingBI.equals(BigInteger.ZERO)) { - LOGGER.fine(String - .format("Config flags size > %d, but exceeding bytes are all zero, so it should be ok.", - KNOWN_CONFIG_BYTES)); - } else { - LOGGER.warning(String.format( - "Config flags size > %d. Exceeding bytes: 0x%X.", - KNOWN_CONFIG_BYTES, exceedingBI)); - isInvalid = true; - } - } + if (exceedingBI.equals(BigInteger.ZERO)) { + LOGGER.fine(String + .format("Config flags size > %d, but exceeding bytes are all zero, so it should be ok.", + KNOWN_CONFIG_BYTES)); + } else { + LOGGER.warning(String.format( + "Config flags size > %d. Exceeding bytes: 0x%X.", + KNOWN_CONFIG_BYTES, exceedingBI)); + isInvalid = true; + } + } - return new ResConfigFlags(mcc, mnc, language, country, layoutDirection, - orientation, touchscreen, density, keyboard, navigation, - inputFlags, screenWidth, screenHeight, sdkVersion, - screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp, - screenHeightDp, isInvalid); - } + return new ResConfigFlags(mcc, mnc, language, country, layoutDirection, + orientation, touchscreen, density, keyboard, navigation, + inputFlags, screenWidth, screenHeight, sdkVersion, + screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp, + screenHeightDp, isInvalid); + } - private void addMissingResSpecs() throws AndrolibException { - int resId = mResId & 0xffff0000; + private void addMissingResSpecs() throws AndrolibException { + int resId = mResId & 0xffff0000; - for (int i = 0; i < mMissingResSpecs.length; i++) { - if (!mMissingResSpecs[i]) { - continue; - } + for (int i = 0; i < mMissingResSpecs.length; i++) { + if (!mMissingResSpecs[i]) { + continue; + } - ResResSpec spec = new ResResSpec(new ResID(resId | i), - String.format("APKTOOL_DUMMY_%04x", i), mPkg, mType); - mPkg.addResSpec(spec); - mType.addResSpec(spec); + ResResSpec spec = new ResResSpec(new ResID(resId | i), + String.format("APKTOOL_DUMMY_%04x", i), mPkg, mType); + mPkg.addResSpec(spec); + mType.addResSpec(spec); - if (mConfig == null) { - mConfig = mPkg.getOrCreateConfig(new ResConfigFlags()); - } + if (mConfig == null) { + mConfig = mPkg.getOrCreateConfig(new ResConfigFlags()); + } - ResValue value = new ResBoolValue(false, null); - ResResource res = new ResResource(mConfig, spec, value); + ResValue value = new ResBoolValue(false, null); + ResResource res = new ResResource(mConfig, spec, value); - mPkg.addResource(res); - mConfig.addResource(res); - spec.addResource(res); - } - } + mPkg.addResource(res); + mConfig.addResource(res); + spec.addResource(res); + } + } - private Header nextChunk() throws IOException { - return mHeader = Header.read(mIn); - } + private Header nextChunk() throws IOException { + return mHeader = Header.read(mIn); + } - private void checkChunkType(int expectedType) throws AndrolibException { - if (mHeader.type != expectedType) { - throw new AndrolibException(String.format( - "Invalid chunk type: expected=0x%08x, got=0x%08x", - expectedType, mHeader.type)); - } - } + private void checkChunkType(int expectedType) throws AndrolibException { + if (mHeader.type != expectedType) { + throw new AndrolibException(String.format( + "Invalid chunk type: expected=0x%08x, got=0x%08x", + expectedType, mHeader.type)); + } + } - private void nextChunkCheckType(int expectedType) throws IOException, - AndrolibException { - nextChunk(); - checkChunkType(expectedType); - } + private void nextChunkCheckType(int expectedType) throws IOException, + AndrolibException { + nextChunk(); + checkChunkType(expectedType); + } - private final ExtDataInput mIn; - private final ResTable mResTable; - private final CountingInputStream mCountIn; - private final List mFlagsOffsets; - private final boolean mKeepBroken; + private final ExtDataInput mIn; + private final ResTable mResTable; + private final CountingInputStream mCountIn; + private final List mFlagsOffsets; + private final boolean mKeepBroken; - private Header mHeader; - private StringBlock mTableStrings; - private StringBlock mTypeNames; - private StringBlock mSpecNames; - private ResPackage mPkg; - private ResType mType; - private ResConfig mConfig; - private int mResId; - private boolean[] mMissingResSpecs; + private Header mHeader; + private StringBlock mTableStrings; + private StringBlock mTypeNames; + private StringBlock mSpecNames; + private ResPackage mPkg; + private ResType mType; + private ResConfig mConfig; + private int mResId; + private boolean[] mMissingResSpecs; - private final static short ENTRY_FLAG_COMPLEX = 0x0001; + private final static short ENTRY_FLAG_COMPLEX = 0x0001; - public static class Header { - public final short type; - public final int chunkSize; + public static class Header { + public final short type; + public final int chunkSize; - public Header(short type, int size) { - this.type = type; - this.chunkSize = size; - } + public Header(short type, int size) { + this.type = type; + this.chunkSize = size; + } - public static Header read(ExtDataInput in) throws IOException { - short type; - try { - type = in.readShort(); - } catch (EOFException ex) { - return new Header(TYPE_NONE, 0); - } - in.skipBytes(2); - return new Header(type, in.readInt()); - } + public static Header read(ExtDataInput in) throws IOException { + short type; + try { + type = in.readShort(); + } catch (EOFException ex) { + return new Header(TYPE_NONE, 0); + } + in.skipBytes(2); + return new Header(type, in.readInt()); + } - public final static short TYPE_NONE = -1, TYPE_TABLE = 0x0002, - TYPE_PACKAGE = 0x0200, TYPE_TYPE = 0x0202, - TYPE_CONFIG = 0x0201; - } + public final static short TYPE_NONE = -1, TYPE_TABLE = 0x0002, + TYPE_PACKAGE = 0x0200, TYPE_TYPE = 0x0202, + TYPE_CONFIG = 0x0201; + } - public static class FlagsOffset { - public final int offset; - public final int count; + public static class FlagsOffset { + public final int offset; + public final int count; - public FlagsOffset(int offset, int count) { - this.offset = offset; - this.count = count; - } - } + public FlagsOffset(int offset, int count) { + this.offset = offset; + this.count = count; + } + } - private static final Logger LOGGER = Logger.getLogger(ARSCDecoder.class - .getName()); - private static final int KNOWN_CONFIG_BYTES = 38; + private static final Logger LOGGER = Logger.getLogger(ARSCDecoder.class + .getName()); + private static final int KNOWN_CONFIG_BYTES = 38; - public static class ARSCData { + public static class ARSCData { - public ARSCData(ResPackage[] packages, FlagsOffset[] flagsOffsets, - ResTable resTable) { - mPackages = packages; - mFlagsOffsets = flagsOffsets; - mResTable = resTable; - } + public ARSCData(ResPackage[] packages, FlagsOffset[] flagsOffsets, + ResTable resTable) { + mPackages = packages; + mFlagsOffsets = flagsOffsets; + mResTable = resTable; + } - public FlagsOffset[] getFlagsOffsets() { - return mFlagsOffsets; - } + public FlagsOffset[] getFlagsOffsets() { + return mFlagsOffsets; + } - public ResPackage[] getPackages() { - return mPackages; - } + public ResPackage[] getPackages() { + return mPackages; + } - public ResPackage getOnePackage() throws AndrolibException { + public ResPackage getOnePackage() throws AndrolibException { if (mPackages.length <= 0) { throw new AndrolibException( "Arsc file contains zero packages"); @@ -426,9 +426,9 @@ public class ARSCDecoder { int id = findPackageWithMostResSpecs(); LOGGER.warning("Arsc file contains multiple packages. Using package " + mPackages[id].getName() + " as default."); return mPackages[id]; - } - return mPackages[0]; - } + } + return mPackages[0]; + } public int findPackageWithMostResSpecs() { int count = -1; @@ -448,12 +448,12 @@ public class ARSCDecoder { return id; } - public ResTable getResTable() { - return mResTable; - } + public ResTable getResTable() { + return mResTable; + } - private final ResPackage[] mPackages; - private final FlagsOffset[] mFlagsOffsets; - private final ResTable mResTable; - } + private final ResPackage[] mPackages; + private final FlagsOffset[] mFlagsOffsets; + private final ResTable mResTable; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java index 337fccb9..17a21644 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java @@ -45,985 +45,985 @@ import org.xmlpull.v1.XmlPullParserException; */ public class AXmlResourceParser implements XmlResourceParser { - public AXmlResourceParser() { - resetEventInfo(); - } - - public AXmlResourceParser(InputStream stream) { - this(); - open(stream); - } - - public AndrolibException getFirstError() { - return mFirstError; - } - - public ResAttrDecoder getAttrDecoder() { - return mAttrDecoder; - } - - public void setAttrDecoder(ResAttrDecoder attrDecoder) { - mAttrDecoder = attrDecoder; - } - - public void open(InputStream stream) { - close(); - if (stream != null) { - m_reader = new ExtDataInput(new LEDataInputStream(stream)); - } - } - - @Override - public void close() { - if (!m_operational) { - return; - } - m_operational = false; - // m_reader.close(); - m_reader = null; - m_strings = null; - m_resourceIDs = null; - m_namespaces.reset(); - resetEventInfo(); - } - - // ///////////////////////////////// iteration - @Override - public int next() throws XmlPullParserException, IOException { - if (m_reader == null) { - throw new XmlPullParserException("Parser is not opened.", this, - null); - } - try { - doNext(); - return m_event; - } catch (IOException e) { - close(); - throw e; - } - } - - @Override - public int nextToken() throws XmlPullParserException, IOException { - return next(); - } - - @Override - public int nextTag() throws XmlPullParserException, IOException { - int eventType = next(); - if (eventType == TEXT && isWhitespace()) { - eventType = next(); - } - if (eventType != START_TAG && eventType != END_TAG) { - throw new XmlPullParserException("Expected start or end tag.", - this, null); - } - return eventType; - } - - @Override - public String nextText() throws XmlPullParserException, IOException { - if (getEventType() != START_TAG) { - throw new XmlPullParserException( - "Parser must be on START_TAG to read next text.", this, - null); - } - int eventType = next(); - if (eventType == TEXT) { - String result = getText(); - eventType = next(); - if (eventType != END_TAG) { - throw new XmlPullParserException( - "Event TEXT must be immediately followed by END_TAG.", - this, null); - } - return result; - } else if (eventType == END_TAG) { - return ""; - } else { - throw new XmlPullParserException( - "Parser must be on START_TAG or TEXT to read text.", this, - null); - } - } - - @Override - public void require(int type, String namespace, String name) - throws XmlPullParserException, IOException { - if (type != getEventType() - || (namespace != null && !namespace.equals(getNamespace())) - || (name != null && !name.equals(getName()))) { - throw new XmlPullParserException(TYPES[type] + " is expected.", - this, null); - } - } - - @Override - public int getDepth() { - return m_namespaces.getDepth() - 1; - } - - @Override - public int getEventType() throws XmlPullParserException { - return m_event; - } - - @Override - public int getLineNumber() { - return m_lineNumber; - } - - @Override - public String getName() { - if (m_name == -1 || (m_event != START_TAG && m_event != END_TAG)) { - return null; - } - return m_strings.getString(m_name); - } - - @Override - public String getText() { - if (m_name == -1 || m_event != TEXT) { - return null; - } - return m_strings.getString(m_name); - } - - @Override - public char[] getTextCharacters(int[] holderForStartAndLength) { - String text = getText(); - if (text == null) { - return null; - } - holderForStartAndLength[0] = 0; - holderForStartAndLength[1] = text.length(); - char[] chars = new char[text.length()]; - text.getChars(0, text.length(), chars, 0); - return chars; - } - - @Override - public String getNamespace() { - return m_strings.getString(m_namespaceUri); - } - - @Override - public String getPrefix() { - int prefix = m_namespaces.findPrefix(m_namespaceUri); - return m_strings.getString(prefix); - } - - @Override - public String getPositionDescription() { - return "XML line #" + getLineNumber(); - } - - @Override - public int getNamespaceCount(int depth) throws XmlPullParserException { - return m_namespaces.getAccumulatedCount(depth); - } - - @Override - public String getNamespacePrefix(int pos) throws XmlPullParserException { - int prefix = m_namespaces.getPrefix(pos); - return m_strings.getString(prefix); - } - - @Override - public String getNamespaceUri(int pos) throws XmlPullParserException { - int uri = m_namespaces.getUri(pos); - return m_strings.getString(uri); - } - - // ///////////////////////////////// attributes - @Override - public String getClassAttribute() { - if (m_classAttribute == -1) { - return null; - } - int offset = getAttributeOffset(m_classAttribute); - int value = m_attributes[offset + ATTRIBUTE_IX_VALUE_STRING]; - return m_strings.getString(value); - } - - @Override - public String getIdAttribute() { - if (m_idAttribute == -1) { - return null; - } - int offset = getAttributeOffset(m_idAttribute); - int value = m_attributes[offset + ATTRIBUTE_IX_VALUE_STRING]; - return m_strings.getString(value); - } - - @Override - public int getIdAttributeResourceValue(int defaultValue) { - if (m_idAttribute == -1) { - return defaultValue; - } - int offset = getAttributeOffset(m_idAttribute); - int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; - if (valueType != TypedValue.TYPE_REFERENCE) { - return defaultValue; - } - return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; - } - - @Override - public int getStyleAttribute() { - if (m_styleAttribute == -1) { - return 0; - } - int offset = getAttributeOffset(m_styleAttribute); - return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; - } - - @Override - public int getAttributeCount() { - if (m_event != START_TAG) { - return -1; - } - return m_attributes.length / ATTRIBUTE_LENGTH; - } - - @Override - public String getAttributeNamespace(int index) { - int offset = getAttributeOffset(index); - int namespace = m_attributes[offset + ATTRIBUTE_IX_NAMESPACE_URI]; - if (namespace == -1) { - return ""; - } - return m_strings.getString(namespace); - } - - @Override - public String getAttributePrefix(int index) { - int offset = getAttributeOffset(index); - int uri = m_attributes[offset + ATTRIBUTE_IX_NAMESPACE_URI]; - int prefix = m_namespaces.findPrefix(uri); - if (prefix == -1) { - return ""; - } - return m_strings.getString(prefix); - } - - @Override - public String getAttributeName(int index) { - int offset = getAttributeOffset(index); - int name = m_attributes[offset + ATTRIBUTE_IX_NAME]; - if (name == -1) { - return ""; - } - return m_strings.getString(name); - } - - @Override - public int getAttributeNameResource(int index) { - int offset = getAttributeOffset(index); - int name = m_attributes[offset + ATTRIBUTE_IX_NAME]; - if (m_resourceIDs == null || name < 0 || name >= m_resourceIDs.length) { - return 0; - } - return m_resourceIDs[name]; - } - - @Override - public int getAttributeValueType(int index) { - int offset = getAttributeOffset(index); - return m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; - } - - @Override - public int getAttributeValueData(int index) { - int offset = getAttributeOffset(index); - return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; - } - - @Override - public String getAttributeValue(int index) { - int offset = getAttributeOffset(index); - int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; - int valueData = m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; - int valueRaw = m_attributes[offset + ATTRIBUTE_IX_VALUE_STRING]; - - if (mAttrDecoder != null) { - try { - return mAttrDecoder.decode( - valueType, - valueData, - valueRaw == -1 ? null : ResXmlEncoders - .escapeXmlChars(m_strings.getString(valueRaw)), - getAttributeNameResource(index)); - } catch (AndrolibException ex) { - setFirstError(ex); - LOGGER.log(Level.WARNING, String.format( - "Could not decode attr value, using undecoded value " - + "instead: ns=%s, name=%s, value=0x%08x", - getAttributePrefix(index), getAttributeName(index), - valueData), ex); - } - } - return TypedValue.coerceToString(valueType, valueData); - } - - @Override - public boolean getAttributeBooleanValue(int index, boolean defaultValue) { - return getAttributeIntValue(index, defaultValue ? 1 : 0) != 0; - } - - @Override - public float getAttributeFloatValue(int index, float defaultValue) { - int offset = getAttributeOffset(index); - int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; - if (valueType == TypedValue.TYPE_FLOAT) { - int valueData = m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; - return Float.intBitsToFloat(valueData); - } - return defaultValue; - } - - @Override - public int getAttributeIntValue(int index, int defaultValue) { - int offset = getAttributeOffset(index); - int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; - if (valueType >= TypedValue.TYPE_FIRST_INT - && valueType <= TypedValue.TYPE_LAST_INT) { - return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; - } - return defaultValue; - } - - @Override - public int getAttributeUnsignedIntValue(int index, int defaultValue) { - return getAttributeIntValue(index, defaultValue); - } - - @Override - public int getAttributeResourceValue(int index, int defaultValue) { - int offset = getAttributeOffset(index); - int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; - if (valueType == TypedValue.TYPE_REFERENCE) { - return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; - } - return defaultValue; - } - - @Override - public String getAttributeValue(String namespace, String attribute) { - int index = findAttribute(namespace, attribute); - if (index == -1) { - return ""; - } - return getAttributeValue(index); - } - - @Override - public boolean getAttributeBooleanValue(String namespace, String attribute, - boolean defaultValue) { - int index = findAttribute(namespace, attribute); - if (index == -1) { - return defaultValue; - } - return getAttributeBooleanValue(index, defaultValue); - } - - @Override - public float getAttributeFloatValue(String namespace, String attribute, - float defaultValue) { - int index = findAttribute(namespace, attribute); - if (index == -1) { - return defaultValue; - } - return getAttributeFloatValue(index, defaultValue); - } - - @Override - public int getAttributeIntValue(String namespace, String attribute, - int defaultValue) { - int index = findAttribute(namespace, attribute); - if (index == -1) { - return defaultValue; - } - return getAttributeIntValue(index, defaultValue); - } - - @Override - public int getAttributeUnsignedIntValue(String namespace, String attribute, - int defaultValue) { - int index = findAttribute(namespace, attribute); - if (index == -1) { - return defaultValue; - } - return getAttributeUnsignedIntValue(index, defaultValue); - } - - @Override - public int getAttributeResourceValue(String namespace, String attribute, - int defaultValue) { - int index = findAttribute(namespace, attribute); - if (index == -1) { - return defaultValue; - } - return getAttributeResourceValue(index, defaultValue); - } - - @Override - public int getAttributeListValue(int index, String[] options, - int defaultValue) { - // TODO implement - return 0; - } - - @Override - public int getAttributeListValue(String namespace, String attribute, - String[] options, int defaultValue) { - // TODO implement - return 0; - } - - @Override - public String getAttributeType(int index) { - return "CDATA"; - } - - @Override - public boolean isAttributeDefault(int index) { - return false; - } - - // ///////////////////////////////// dummies - @Override - public void setInput(InputStream stream, String inputEncoding) - throws XmlPullParserException { - open(stream); - } - - @Override - public void setInput(Reader reader) throws XmlPullParserException { - throw new XmlPullParserException(E_NOT_SUPPORTED); - } - - @Override - public String getInputEncoding() { - return null; - } - - @Override - public int getColumnNumber() { - return -1; - } - - @Override - public boolean isEmptyElementTag() throws XmlPullParserException { - return false; - } - - @Override - public boolean isWhitespace() throws XmlPullParserException { - return false; - } - - @Override - public void defineEntityReplacementText(String entityName, - String replacementText) throws XmlPullParserException { - throw new XmlPullParserException(E_NOT_SUPPORTED); - } - - @Override - public String getNamespace(String prefix) { - throw new RuntimeException(E_NOT_SUPPORTED); - } - - @Override - public Object getProperty(String name) { - return null; - } - - @Override - public void setProperty(String name, Object value) - throws XmlPullParserException { - throw new XmlPullParserException(E_NOT_SUPPORTED); - } - - @Override - public boolean getFeature(String feature) { - return false; - } - - @Override - public void setFeature(String name, boolean value) - throws XmlPullParserException { - throw new XmlPullParserException(E_NOT_SUPPORTED); - } - - // /////////////////////////////////////////// implementation - /** - * Namespace stack, holds prefix+uri pairs, as well as depth information. - * All information is stored in one int[] array. Array consists of depth - * frames: Data=DepthFrame*; DepthFrame=Count+[Prefix+Uri]*+Count; - * Count='count of Prefix+Uri pairs'; Yes, count is stored twice, to enable - * bottom-up traversal. increaseDepth adds depth frame, decreaseDepth - * removes it. push/pop operations operate only in current depth frame. - * decreaseDepth removes any remaining (not pop'ed) namespace pairs. findXXX - * methods search all depth frames starting from the last namespace pair of - * current depth frame. All functions that operate with int, use -1 as - * 'invalid value'. - * - * !! functions expect 'prefix'+'uri' pairs, not 'uri'+'prefix' !! - * - */ - private static final class NamespaceStack { - - public NamespaceStack() { - m_data = new int[32]; - } - - public final void reset() { - m_dataLength = 0; - m_count = 0; - m_depth = 0; - } - - public final int getTotalCount() { - return m_count; - } - - public final int getCurrentCount() { - if (m_dataLength == 0) { - return 0; - } - int offset = m_dataLength - 1; - return m_data[offset]; - } - - public final int getAccumulatedCount(int depth) { - if (m_dataLength == 0 || depth < 0) { - return 0; - } - if (depth > m_depth) { - depth = m_depth; - } - int accumulatedCount = 0; - int offset = 0; - for (; depth != 0; --depth) { - int count = m_data[offset]; - accumulatedCount += count; - offset += (2 + count * 2); - } - return accumulatedCount; - } - - public final void push(int prefix, int uri) { - if (m_depth == 0) { - increaseDepth(); - } - ensureDataCapacity(2); - int offset = m_dataLength - 1; - int count = m_data[offset]; - m_data[offset - 1 - count * 2] = count + 1; - m_data[offset] = prefix; - m_data[offset + 1] = uri; - m_data[offset + 2] = count + 1; - m_dataLength += 2; - m_count += 1; - } - - public final boolean pop(int prefix, int uri) { - if (m_dataLength == 0) { - return false; - } - int offset = m_dataLength - 1; - int count = m_data[offset]; - for (int i = 0, o = offset - 2; i != count; ++i, o -= 2) { - if (m_data[o] != prefix || m_data[o + 1] != uri) { - continue; - } - count -= 1; - if (i == 0) { - m_data[o] = count; - o -= (1 + count * 2); - m_data[o] = count; - } else { - m_data[offset] = count; - offset -= (1 + 2 + count * 2); - m_data[offset] = count; - System.arraycopy(m_data, o + 2, m_data, o, m_dataLength - o); - } - m_dataLength -= 2; - m_count -= 1; - return true; - } - return false; - } - - public final boolean pop() { - if (m_dataLength == 0) { - return false; - } - int offset = m_dataLength - 1; - int count = m_data[offset]; - if (count == 0) { - return false; - } - count -= 1; - offset -= 2; - m_data[offset] = count; - offset -= (1 + count * 2); - m_data[offset] = count; - m_dataLength -= 2; - m_count -= 1; - return true; - } - - public final int getPrefix(int index) { - return get(index, true); - } - - public final int getUri(int index) { - return get(index, false); - } - - public final int findPrefix(int uri) { - return find(uri, false); - } - - public final int findUri(int prefix) { - return find(prefix, true); - } - - public final int getDepth() { - return m_depth; - } - - public final void increaseDepth() { - ensureDataCapacity(2); - int offset = m_dataLength; - m_data[offset] = 0; - m_data[offset + 1] = 0; - m_dataLength += 2; - m_depth += 1; - } - - public final void decreaseDepth() { - if (m_dataLength == 0) { - return; - } - int offset = m_dataLength - 1; - int count = m_data[offset]; - if ((offset - 1 - count * 2) == 0) { - return; - } - m_dataLength -= 2 + count * 2; - m_count -= count; - m_depth -= 1; - } - - private void ensureDataCapacity(int capacity) { - int available = (m_data.length - m_dataLength); - if (available > capacity) { - return; - } - int newLength = (m_data.length + available) * 2; - int[] newData = new int[newLength]; - System.arraycopy(m_data, 0, newData, 0, m_dataLength); - m_data = newData; - } - - private final int find(int prefixOrUri, boolean prefix) { - if (m_dataLength == 0) { - return -1; - } - int offset = m_dataLength - 1; - for (int i = m_depth; i != 0; --i) { - int count = m_data[offset]; - offset -= 2; - for (; count != 0; --count) { - if (prefix) { - if (m_data[offset] == prefixOrUri) { - return m_data[offset + 1]; - } - } else { - if (m_data[offset + 1] == prefixOrUri) { - return m_data[offset]; - } - } - offset -= 2; - } - } - return -1; - } - - private final int get(int index, boolean prefix) { - if (m_dataLength == 0 || index < 0) { - return -1; - } - int offset = 0; - for (int i = m_depth; i != 0; --i) { - int count = m_data[offset]; - if (index >= count) { - index -= count; - offset += (2 + count * 2); - continue; - } - offset += (1 + index * 2); - if (!prefix) { - offset += 1; - } - return m_data[offset]; - } - return -1; - } - - private int[] m_data; - private int m_dataLength; - private int m_count; - private int m_depth; - } - - // ///////////////////////////////// package-visible - // final void fetchAttributes(int[] styleableIDs,TypedArray result) { - // result.resetIndices(); - // if (m_attributes==null || m_resourceIDs==null) { - // return; - // } - // boolean needStrings=false; - // for (int i=0,e=styleableIDs.length;i!=e;++i) { - // int id=styleableIDs[i]; - // for (int o=0;o!=m_attributes.length;o+=ATTRIBUTE_LENGHT) { - // int name=m_attributes[o+ATTRIBUTE_IX_NAME]; - // if (name>=m_resourceIDs.length || - // m_resourceIDs[name]!=id) - // { - // continue; - // } - // int valueType=m_attributes[o+ATTRIBUTE_IX_VALUE_TYPE]; - // int valueData; - // int assetCookie; - // if (valueType==TypedValue.TYPE_STRING) { - // valueData=m_attributes[o+ATTRIBUTE_IX_VALUE_STRING]; - // assetCookie=-1; - // needStrings=true; - // } else { - // valueData=m_attributes[o+ATTRIBUTE_IX_VALUE_DATA]; - // assetCookie=0; - // } - // result.addValue(i,valueType,valueData,assetCookie,id,0); - // } - // } - // if (needStrings) { - // result.setStrings(m_strings); - // } - // } - final StringBlock getStrings() { - return m_strings; - } - - // ///////////////////////////////// - private final int getAttributeOffset(int index) { - if (m_event != START_TAG) { - throw new IndexOutOfBoundsException( - "Current event is not START_TAG."); - } - int offset = index * ATTRIBUTE_LENGTH; - if (offset >= m_attributes.length) { - throw new IndexOutOfBoundsException("Invalid attribute index (" - + index + ")."); - } - return offset; - } - - private final int findAttribute(String namespace, String attribute) { - if (m_strings == null || attribute == null) { - return -1; - } - int name = m_strings.find(attribute); - if (name == -1) { - return -1; - } - int uri = (namespace != null) ? m_strings.find(namespace) : -1; - for (int o = 0; o != m_attributes.length; o += ATTRIBUTE_LENGTH) { - if (name == m_attributes[o + ATTRIBUTE_IX_NAME] - && (uri == -1 || uri == m_attributes[o - + ATTRIBUTE_IX_NAMESPACE_URI])) { - return o / ATTRIBUTE_LENGTH; - } - } - return -1; - } - - private final void resetEventInfo() { - m_event = -1; - m_lineNumber = -1; - m_name = -1; - m_namespaceUri = -1; - m_attributes = null; - m_idAttribute = -1; - m_classAttribute = -1; - m_styleAttribute = -1; - } - - private final void doNext() throws IOException { - // Delayed initialization. - if (m_strings == null) { - m_reader.skipCheckInt(CHUNK_AXML_FILE); + public AXmlResourceParser() { + resetEventInfo(); + } + + public AXmlResourceParser(InputStream stream) { + this(); + open(stream); + } + + public AndrolibException getFirstError() { + return mFirstError; + } + + public ResAttrDecoder getAttrDecoder() { + return mAttrDecoder; + } + + public void setAttrDecoder(ResAttrDecoder attrDecoder) { + mAttrDecoder = attrDecoder; + } + + public void open(InputStream stream) { + close(); + if (stream != null) { + m_reader = new ExtDataInput(new LEDataInputStream(stream)); + } + } + + @Override + public void close() { + if (!m_operational) { + return; + } + m_operational = false; + // m_reader.close(); + m_reader = null; + m_strings = null; + m_resourceIDs = null; + m_namespaces.reset(); + resetEventInfo(); + } + + // ///////////////////////////////// iteration + @Override + public int next() throws XmlPullParserException, IOException { + if (m_reader == null) { + throw new XmlPullParserException("Parser is not opened.", this, + null); + } + try { + doNext(); + return m_event; + } catch (IOException e) { + close(); + throw e; + } + } + + @Override + public int nextToken() throws XmlPullParserException, IOException { + return next(); + } + + @Override + public int nextTag() throws XmlPullParserException, IOException { + int eventType = next(); + if (eventType == TEXT && isWhitespace()) { + eventType = next(); + } + if (eventType != START_TAG && eventType != END_TAG) { + throw new XmlPullParserException("Expected start or end tag.", + this, null); + } + return eventType; + } + + @Override + public String nextText() throws XmlPullParserException, IOException { + if (getEventType() != START_TAG) { + throw new XmlPullParserException( + "Parser must be on START_TAG to read next text.", this, + null); + } + int eventType = next(); + if (eventType == TEXT) { + String result = getText(); + eventType = next(); + if (eventType != END_TAG) { + throw new XmlPullParserException( + "Event TEXT must be immediately followed by END_TAG.", + this, null); + } + return result; + } else if (eventType == END_TAG) { + return ""; + } else { + throw new XmlPullParserException( + "Parser must be on START_TAG or TEXT to read text.", this, + null); + } + } + + @Override + public void require(int type, String namespace, String name) + throws XmlPullParserException, IOException { + if (type != getEventType() + || (namespace != null && !namespace.equals(getNamespace())) + || (name != null && !name.equals(getName()))) { + throw new XmlPullParserException(TYPES[type] + " is expected.", + this, null); + } + } + + @Override + public int getDepth() { + return m_namespaces.getDepth() - 1; + } + + @Override + public int getEventType() throws XmlPullParserException { + return m_event; + } + + @Override + public int getLineNumber() { + return m_lineNumber; + } + + @Override + public String getName() { + if (m_name == -1 || (m_event != START_TAG && m_event != END_TAG)) { + return null; + } + return m_strings.getString(m_name); + } + + @Override + public String getText() { + if (m_name == -1 || m_event != TEXT) { + return null; + } + return m_strings.getString(m_name); + } + + @Override + public char[] getTextCharacters(int[] holderForStartAndLength) { + String text = getText(); + if (text == null) { + return null; + } + holderForStartAndLength[0] = 0; + holderForStartAndLength[1] = text.length(); + char[] chars = new char[text.length()]; + text.getChars(0, text.length(), chars, 0); + return chars; + } + + @Override + public String getNamespace() { + return m_strings.getString(m_namespaceUri); + } + + @Override + public String getPrefix() { + int prefix = m_namespaces.findPrefix(m_namespaceUri); + return m_strings.getString(prefix); + } + + @Override + public String getPositionDescription() { + return "XML line #" + getLineNumber(); + } + + @Override + public int getNamespaceCount(int depth) throws XmlPullParserException { + return m_namespaces.getAccumulatedCount(depth); + } + + @Override + public String getNamespacePrefix(int pos) throws XmlPullParserException { + int prefix = m_namespaces.getPrefix(pos); + return m_strings.getString(prefix); + } + + @Override + public String getNamespaceUri(int pos) throws XmlPullParserException { + int uri = m_namespaces.getUri(pos); + return m_strings.getString(uri); + } + + // ///////////////////////////////// attributes + @Override + public String getClassAttribute() { + if (m_classAttribute == -1) { + return null; + } + int offset = getAttributeOffset(m_classAttribute); + int value = m_attributes[offset + ATTRIBUTE_IX_VALUE_STRING]; + return m_strings.getString(value); + } + + @Override + public String getIdAttribute() { + if (m_idAttribute == -1) { + return null; + } + int offset = getAttributeOffset(m_idAttribute); + int value = m_attributes[offset + ATTRIBUTE_IX_VALUE_STRING]; + return m_strings.getString(value); + } + + @Override + public int getIdAttributeResourceValue(int defaultValue) { + if (m_idAttribute == -1) { + return defaultValue; + } + int offset = getAttributeOffset(m_idAttribute); + int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; + if (valueType != TypedValue.TYPE_REFERENCE) { + return defaultValue; + } + return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; + } + + @Override + public int getStyleAttribute() { + if (m_styleAttribute == -1) { + return 0; + } + int offset = getAttributeOffset(m_styleAttribute); + return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; + } + + @Override + public int getAttributeCount() { + if (m_event != START_TAG) { + return -1; + } + return m_attributes.length / ATTRIBUTE_LENGTH; + } + + @Override + public String getAttributeNamespace(int index) { + int offset = getAttributeOffset(index); + int namespace = m_attributes[offset + ATTRIBUTE_IX_NAMESPACE_URI]; + if (namespace == -1) { + return ""; + } + return m_strings.getString(namespace); + } + + @Override + public String getAttributePrefix(int index) { + int offset = getAttributeOffset(index); + int uri = m_attributes[offset + ATTRIBUTE_IX_NAMESPACE_URI]; + int prefix = m_namespaces.findPrefix(uri); + if (prefix == -1) { + return ""; + } + return m_strings.getString(prefix); + } + + @Override + public String getAttributeName(int index) { + int offset = getAttributeOffset(index); + int name = m_attributes[offset + ATTRIBUTE_IX_NAME]; + if (name == -1) { + return ""; + } + return m_strings.getString(name); + } + + @Override + public int getAttributeNameResource(int index) { + int offset = getAttributeOffset(index); + int name = m_attributes[offset + ATTRIBUTE_IX_NAME]; + if (m_resourceIDs == null || name < 0 || name >= m_resourceIDs.length) { + return 0; + } + return m_resourceIDs[name]; + } + + @Override + public int getAttributeValueType(int index) { + int offset = getAttributeOffset(index); + return m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; + } + + @Override + public int getAttributeValueData(int index) { + int offset = getAttributeOffset(index); + return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; + } + + @Override + public String getAttributeValue(int index) { + int offset = getAttributeOffset(index); + int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; + int valueData = m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; + int valueRaw = m_attributes[offset + ATTRIBUTE_IX_VALUE_STRING]; + + if (mAttrDecoder != null) { + try { + return mAttrDecoder.decode( + valueType, + valueData, + valueRaw == -1 ? null : ResXmlEncoders + .escapeXmlChars(m_strings.getString(valueRaw)), + getAttributeNameResource(index)); + } catch (AndrolibException ex) { + setFirstError(ex); + LOGGER.log(Level.WARNING, String.format( + "Could not decode attr value, using undecoded value " + + "instead: ns=%s, name=%s, value=0x%08x", + getAttributePrefix(index), getAttributeName(index), + valueData), ex); + } + } + return TypedValue.coerceToString(valueType, valueData); + } + + @Override + public boolean getAttributeBooleanValue(int index, boolean defaultValue) { + return getAttributeIntValue(index, defaultValue ? 1 : 0) != 0; + } + + @Override + public float getAttributeFloatValue(int index, float defaultValue) { + int offset = getAttributeOffset(index); + int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; + if (valueType == TypedValue.TYPE_FLOAT) { + int valueData = m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; + return Float.intBitsToFloat(valueData); + } + return defaultValue; + } + + @Override + public int getAttributeIntValue(int index, int defaultValue) { + int offset = getAttributeOffset(index); + int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; + if (valueType >= TypedValue.TYPE_FIRST_INT + && valueType <= TypedValue.TYPE_LAST_INT) { + return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; + } + return defaultValue; + } + + @Override + public int getAttributeUnsignedIntValue(int index, int defaultValue) { + return getAttributeIntValue(index, defaultValue); + } + + @Override + public int getAttributeResourceValue(int index, int defaultValue) { + int offset = getAttributeOffset(index); + int valueType = m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]; + if (valueType == TypedValue.TYPE_REFERENCE) { + return m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]; + } + return defaultValue; + } + + @Override + public String getAttributeValue(String namespace, String attribute) { + int index = findAttribute(namespace, attribute); + if (index == -1) { + return ""; + } + return getAttributeValue(index); + } + + @Override + public boolean getAttributeBooleanValue(String namespace, String attribute, + boolean defaultValue) { + int index = findAttribute(namespace, attribute); + if (index == -1) { + return defaultValue; + } + return getAttributeBooleanValue(index, defaultValue); + } + + @Override + public float getAttributeFloatValue(String namespace, String attribute, + float defaultValue) { + int index = findAttribute(namespace, attribute); + if (index == -1) { + return defaultValue; + } + return getAttributeFloatValue(index, defaultValue); + } + + @Override + public int getAttributeIntValue(String namespace, String attribute, + int defaultValue) { + int index = findAttribute(namespace, attribute); + if (index == -1) { + return defaultValue; + } + return getAttributeIntValue(index, defaultValue); + } + + @Override + public int getAttributeUnsignedIntValue(String namespace, String attribute, + int defaultValue) { + int index = findAttribute(namespace, attribute); + if (index == -1) { + return defaultValue; + } + return getAttributeUnsignedIntValue(index, defaultValue); + } + + @Override + public int getAttributeResourceValue(String namespace, String attribute, + int defaultValue) { + int index = findAttribute(namespace, attribute); + if (index == -1) { + return defaultValue; + } + return getAttributeResourceValue(index, defaultValue); + } + + @Override + public int getAttributeListValue(int index, String[] options, + int defaultValue) { + // TODO implement + return 0; + } + + @Override + public int getAttributeListValue(String namespace, String attribute, + String[] options, int defaultValue) { + // TODO implement + return 0; + } + + @Override + public String getAttributeType(int index) { + return "CDATA"; + } + + @Override + public boolean isAttributeDefault(int index) { + return false; + } + + // ///////////////////////////////// dummies + @Override + public void setInput(InputStream stream, String inputEncoding) + throws XmlPullParserException { + open(stream); + } + + @Override + public void setInput(Reader reader) throws XmlPullParserException { + throw new XmlPullParserException(E_NOT_SUPPORTED); + } + + @Override + public String getInputEncoding() { + return null; + } + + @Override + public int getColumnNumber() { + return -1; + } + + @Override + public boolean isEmptyElementTag() throws XmlPullParserException { + return false; + } + + @Override + public boolean isWhitespace() throws XmlPullParserException { + return false; + } + + @Override + public void defineEntityReplacementText(String entityName, + String replacementText) throws XmlPullParserException { + throw new XmlPullParserException(E_NOT_SUPPORTED); + } + + @Override + public String getNamespace(String prefix) { + throw new RuntimeException(E_NOT_SUPPORTED); + } + + @Override + public Object getProperty(String name) { + return null; + } + + @Override + public void setProperty(String name, Object value) + throws XmlPullParserException { + throw new XmlPullParserException(E_NOT_SUPPORTED); + } + + @Override + public boolean getFeature(String feature) { + return false; + } + + @Override + public void setFeature(String name, boolean value) + throws XmlPullParserException { + throw new XmlPullParserException(E_NOT_SUPPORTED); + } + + // /////////////////////////////////////////// implementation + /** + * Namespace stack, holds prefix+uri pairs, as well as depth information. + * All information is stored in one int[] array. Array consists of depth + * frames: Data=DepthFrame*; DepthFrame=Count+[Prefix+Uri]*+Count; + * Count='count of Prefix+Uri pairs'; Yes, count is stored twice, to enable + * bottom-up traversal. increaseDepth adds depth frame, decreaseDepth + * removes it. push/pop operations operate only in current depth frame. + * decreaseDepth removes any remaining (not pop'ed) namespace pairs. findXXX + * methods search all depth frames starting from the last namespace pair of + * current depth frame. All functions that operate with int, use -1 as + * 'invalid value'. + * + * !! functions expect 'prefix'+'uri' pairs, not 'uri'+'prefix' !! + * + */ + private static final class NamespaceStack { + + public NamespaceStack() { + m_data = new int[32]; + } + + public final void reset() { + m_dataLength = 0; + m_count = 0; + m_depth = 0; + } + + public final int getTotalCount() { + return m_count; + } + + public final int getCurrentCount() { + if (m_dataLength == 0) { + return 0; + } + int offset = m_dataLength - 1; + return m_data[offset]; + } + + public final int getAccumulatedCount(int depth) { + if (m_dataLength == 0 || depth < 0) { + return 0; + } + if (depth > m_depth) { + depth = m_depth; + } + int accumulatedCount = 0; + int offset = 0; + for (; depth != 0; --depth) { + int count = m_data[offset]; + accumulatedCount += count; + offset += (2 + count * 2); + } + return accumulatedCount; + } + + public final void push(int prefix, int uri) { + if (m_depth == 0) { + increaseDepth(); + } + ensureDataCapacity(2); + int offset = m_dataLength - 1; + int count = m_data[offset]; + m_data[offset - 1 - count * 2] = count + 1; + m_data[offset] = prefix; + m_data[offset + 1] = uri; + m_data[offset + 2] = count + 1; + m_dataLength += 2; + m_count += 1; + } + + public final boolean pop(int prefix, int uri) { + if (m_dataLength == 0) { + return false; + } + int offset = m_dataLength - 1; + int count = m_data[offset]; + for (int i = 0, o = offset - 2; i != count; ++i, o -= 2) { + if (m_data[o] != prefix || m_data[o + 1] != uri) { + continue; + } + count -= 1; + if (i == 0) { + m_data[o] = count; + o -= (1 + count * 2); + m_data[o] = count; + } else { + m_data[offset] = count; + offset -= (1 + 2 + count * 2); + m_data[offset] = count; + System.arraycopy(m_data, o + 2, m_data, o, m_dataLength - o); + } + m_dataLength -= 2; + m_count -= 1; + return true; + } + return false; + } + + public final boolean pop() { + if (m_dataLength == 0) { + return false; + } + int offset = m_dataLength - 1; + int count = m_data[offset]; + if (count == 0) { + return false; + } + count -= 1; + offset -= 2; + m_data[offset] = count; + offset -= (1 + count * 2); + m_data[offset] = count; + m_dataLength -= 2; + m_count -= 1; + return true; + } + + public final int getPrefix(int index) { + return get(index, true); + } + + public final int getUri(int index) { + return get(index, false); + } + + public final int findPrefix(int uri) { + return find(uri, false); + } + + public final int findUri(int prefix) { + return find(prefix, true); + } + + public final int getDepth() { + return m_depth; + } + + public final void increaseDepth() { + ensureDataCapacity(2); + int offset = m_dataLength; + m_data[offset] = 0; + m_data[offset + 1] = 0; + m_dataLength += 2; + m_depth += 1; + } + + public final void decreaseDepth() { + if (m_dataLength == 0) { + return; + } + int offset = m_dataLength - 1; + int count = m_data[offset]; + if ((offset - 1 - count * 2) == 0) { + return; + } + m_dataLength -= 2 + count * 2; + m_count -= count; + m_depth -= 1; + } + + private void ensureDataCapacity(int capacity) { + int available = (m_data.length - m_dataLength); + if (available > capacity) { + return; + } + int newLength = (m_data.length + available) * 2; + int[] newData = new int[newLength]; + System.arraycopy(m_data, 0, newData, 0, m_dataLength); + m_data = newData; + } + + private final int find(int prefixOrUri, boolean prefix) { + if (m_dataLength == 0) { + return -1; + } + int offset = m_dataLength - 1; + for (int i = m_depth; i != 0; --i) { + int count = m_data[offset]; + offset -= 2; + for (; count != 0; --count) { + if (prefix) { + if (m_data[offset] == prefixOrUri) { + return m_data[offset + 1]; + } + } else { + if (m_data[offset + 1] == prefixOrUri) { + return m_data[offset]; + } + } + offset -= 2; + } + } + return -1; + } + + private final int get(int index, boolean prefix) { + if (m_dataLength == 0 || index < 0) { + return -1; + } + int offset = 0; + for (int i = m_depth; i != 0; --i) { + int count = m_data[offset]; + if (index >= count) { + index -= count; + offset += (2 + count * 2); + continue; + } + offset += (1 + index * 2); + if (!prefix) { + offset += 1; + } + return m_data[offset]; + } + return -1; + } + + private int[] m_data; + private int m_dataLength; + private int m_count; + private int m_depth; + } + + // ///////////////////////////////// package-visible + // final void fetchAttributes(int[] styleableIDs,TypedArray result) { + // result.resetIndices(); + // if (m_attributes==null || m_resourceIDs==null) { + // return; + // } + // boolean needStrings=false; + // for (int i=0,e=styleableIDs.length;i!=e;++i) { + // int id=styleableIDs[i]; + // for (int o=0;o!=m_attributes.length;o+=ATTRIBUTE_LENGHT) { + // int name=m_attributes[o+ATTRIBUTE_IX_NAME]; + // if (name>=m_resourceIDs.length || + // m_resourceIDs[name]!=id) + // { + // continue; + // } + // int valueType=m_attributes[o+ATTRIBUTE_IX_VALUE_TYPE]; + // int valueData; + // int assetCookie; + // if (valueType==TypedValue.TYPE_STRING) { + // valueData=m_attributes[o+ATTRIBUTE_IX_VALUE_STRING]; + // assetCookie=-1; + // needStrings=true; + // } else { + // valueData=m_attributes[o+ATTRIBUTE_IX_VALUE_DATA]; + // assetCookie=0; + // } + // result.addValue(i,valueType,valueData,assetCookie,id,0); + // } + // } + // if (needStrings) { + // result.setStrings(m_strings); + // } + // } + final StringBlock getStrings() { + return m_strings; + } + + // ///////////////////////////////// + private final int getAttributeOffset(int index) { + if (m_event != START_TAG) { + throw new IndexOutOfBoundsException( + "Current event is not START_TAG."); + } + int offset = index * ATTRIBUTE_LENGTH; + if (offset >= m_attributes.length) { + throw new IndexOutOfBoundsException("Invalid attribute index (" + + index + ")."); + } + return offset; + } + + private final int findAttribute(String namespace, String attribute) { + if (m_strings == null || attribute == null) { + return -1; + } + int name = m_strings.find(attribute); + if (name == -1) { + return -1; + } + int uri = (namespace != null) ? m_strings.find(namespace) : -1; + for (int o = 0; o != m_attributes.length; o += ATTRIBUTE_LENGTH) { + if (name == m_attributes[o + ATTRIBUTE_IX_NAME] + && (uri == -1 || uri == m_attributes[o + + ATTRIBUTE_IX_NAMESPACE_URI])) { + return o / ATTRIBUTE_LENGTH; + } + } + return -1; + } + + private final void resetEventInfo() { + m_event = -1; + m_lineNumber = -1; + m_name = -1; + m_namespaceUri = -1; + m_attributes = null; + m_idAttribute = -1; + m_classAttribute = -1; + m_styleAttribute = -1; + } + + private final void doNext() throws IOException { + // Delayed initialization. + if (m_strings == null) { + m_reader.skipCheckInt(CHUNK_AXML_FILE); /* * chunkSize */ m_reader.skipInt(); - m_strings = StringBlock.read(m_reader); - m_namespaces.increaseDepth(); - m_operational = true; - } + m_strings = StringBlock.read(m_reader); + m_namespaces.increaseDepth(); + m_operational = true; + } - if (m_event == END_DOCUMENT) { - return; - } + if (m_event == END_DOCUMENT) { + return; + } - int event = m_event; - resetEventInfo(); + int event = m_event; + resetEventInfo(); - while (true) { - if (m_decreaseDepth) { - m_decreaseDepth = false; - m_namespaces.decreaseDepth(); - } + while (true) { + if (m_decreaseDepth) { + m_decreaseDepth = false; + m_namespaces.decreaseDepth(); + } - // Fake END_DOCUMENT event. - if (event == END_TAG && m_namespaces.getDepth() == 1 - && m_namespaces.getCurrentCount() == 0) { - m_event = END_DOCUMENT; - break; - } + // Fake END_DOCUMENT event. + if (event == END_TAG && m_namespaces.getDepth() == 1 + && m_namespaces.getCurrentCount() == 0) { + m_event = END_DOCUMENT; + break; + } - int chunkType; - if (event == START_DOCUMENT) { - // Fake event, see CHUNK_XML_START_TAG handler. - chunkType = CHUNK_XML_START_TAG; - } else { - chunkType = m_reader.readInt(); - } + int chunkType; + if (event == START_DOCUMENT) { + // Fake event, see CHUNK_XML_START_TAG handler. + chunkType = CHUNK_XML_START_TAG; + } else { + chunkType = m_reader.readInt(); + } - if (chunkType == CHUNK_RESOURCEIDS) { - int chunkSize = m_reader.readInt(); - if (chunkSize < 8 || (chunkSize % 4) != 0) { - throw new IOException("Invalid resource ids size (" - + chunkSize + ")."); - } - m_resourceIDs = m_reader.readIntArray(chunkSize / 4 - 2); - continue; - } + if (chunkType == CHUNK_RESOURCEIDS) { + int chunkSize = m_reader.readInt(); + if (chunkSize < 8 || (chunkSize % 4) != 0) { + throw new IOException("Invalid resource ids size (" + + chunkSize + ")."); + } + m_resourceIDs = m_reader.readIntArray(chunkSize / 4 - 2); + continue; + } - if (chunkType < CHUNK_XML_FIRST || chunkType > CHUNK_XML_LAST) { - throw new IOException("Invalid chunk type (" + chunkType + ")."); - } + if (chunkType < CHUNK_XML_FIRST || chunkType > CHUNK_XML_LAST) { + throw new IOException("Invalid chunk type (" + chunkType + ")."); + } - // Fake START_DOCUMENT event. - if (chunkType == CHUNK_XML_START_TAG && event == -1) { - m_event = START_DOCUMENT; - break; - } + // Fake START_DOCUMENT event. + if (chunkType == CHUNK_XML_START_TAG && event == -1) { + m_event = START_DOCUMENT; + break; + } - // Common header. + // Common header. /* chunkSize */m_reader.skipInt(); - int lineNumber = m_reader.readInt(); + int lineNumber = m_reader.readInt(); /* 0xFFFFFFFF */m_reader.skipInt(); - if (chunkType == CHUNK_XML_START_NAMESPACE - || chunkType == CHUNK_XML_END_NAMESPACE) { - if (chunkType == CHUNK_XML_START_NAMESPACE) { - int prefix = m_reader.readInt(); - int uri = m_reader.readInt(); - m_namespaces.push(prefix, uri); - } else { + if (chunkType == CHUNK_XML_START_NAMESPACE + || chunkType == CHUNK_XML_END_NAMESPACE) { + if (chunkType == CHUNK_XML_START_NAMESPACE) { + int prefix = m_reader.readInt(); + int uri = m_reader.readInt(); + m_namespaces.push(prefix, uri); + } else { /* prefix */m_reader.skipInt(); /* uri */m_reader.skipInt(); - m_namespaces.pop(); - } - continue; - } + m_namespaces.pop(); + } + continue; + } - m_lineNumber = lineNumber; + m_lineNumber = lineNumber; - if (chunkType == CHUNK_XML_START_TAG) { - m_namespaceUri = m_reader.readInt(); - m_name = m_reader.readInt(); + if (chunkType == CHUNK_XML_START_TAG) { + m_namespaceUri = m_reader.readInt(); + m_name = m_reader.readInt(); /* flags? */m_reader.skipInt(); - int attributeCount = m_reader.readInt(); - m_idAttribute = (attributeCount >>> 16) - 1; - attributeCount &= 0xFFFF; - m_classAttribute = m_reader.readInt(); - m_styleAttribute = (m_classAttribute >>> 16) - 1; - m_classAttribute = (m_classAttribute & 0xFFFF) - 1; - m_attributes = m_reader.readIntArray(attributeCount - * ATTRIBUTE_LENGTH); - for (int i = ATTRIBUTE_IX_VALUE_TYPE; i < m_attributes.length;) { - m_attributes[i] = (m_attributes[i] >>> 24); - i += ATTRIBUTE_LENGTH; - } - m_namespaces.increaseDepth(); - m_event = START_TAG; - break; - } + int attributeCount = m_reader.readInt(); + m_idAttribute = (attributeCount >>> 16) - 1; + attributeCount &= 0xFFFF; + m_classAttribute = m_reader.readInt(); + m_styleAttribute = (m_classAttribute >>> 16) - 1; + m_classAttribute = (m_classAttribute & 0xFFFF) - 1; + m_attributes = m_reader.readIntArray(attributeCount + * ATTRIBUTE_LENGTH); + for (int i = ATTRIBUTE_IX_VALUE_TYPE; i < m_attributes.length;) { + m_attributes[i] = (m_attributes[i] >>> 24); + i += ATTRIBUTE_LENGTH; + } + m_namespaces.increaseDepth(); + m_event = START_TAG; + break; + } - if (chunkType == CHUNK_XML_END_TAG) { - m_namespaceUri = m_reader.readInt(); - m_name = m_reader.readInt(); - m_event = END_TAG; - m_decreaseDepth = true; - break; - } + if (chunkType == CHUNK_XML_END_TAG) { + m_namespaceUri = m_reader.readInt(); + m_name = m_reader.readInt(); + m_event = END_TAG; + m_decreaseDepth = true; + break; + } - if (chunkType == CHUNK_XML_TEXT) { - m_name = m_reader.readInt(); + if (chunkType == CHUNK_XML_TEXT) { + m_name = m_reader.readInt(); /* ? */m_reader.skipInt(); /* ? */m_reader.skipInt(); - m_event = TEXT; - break; - } - } - } + m_event = TEXT; + break; + } + } + } - private void setFirstError(AndrolibException error) { - if (mFirstError == null) { - mFirstError = error; - } - } + private void setFirstError(AndrolibException error) { + if (mFirstError == null) { + mFirstError = error; + } + } - // ///////////////////////////////// data + // ///////////////////////////////// data /* * All values are essentially indices, e.g. m_name is an index of name in * m_strings. */ - private ExtDataInput m_reader; - private ResAttrDecoder mAttrDecoder; - private AndrolibException mFirstError; + private ExtDataInput m_reader; + private ResAttrDecoder mAttrDecoder; + private AndrolibException mFirstError; - private boolean m_operational = false; - private StringBlock m_strings; - private int[] m_resourceIDs; - private NamespaceStack m_namespaces = new NamespaceStack(); - private boolean m_decreaseDepth; - private int m_event; - private int m_lineNumber; - private int m_name; - private int m_namespaceUri; - private int[] m_attributes; - private int m_idAttribute; - private int m_classAttribute; - private int m_styleAttribute; + private boolean m_operational = false; + private StringBlock m_strings; + private int[] m_resourceIDs; + private NamespaceStack m_namespaces = new NamespaceStack(); + private boolean m_decreaseDepth; + private int m_event; + private int m_lineNumber; + private int m_name; + private int m_namespaceUri; + private int[] m_attributes; + private int m_idAttribute; + private int m_classAttribute; + private int m_styleAttribute; - private final static Logger LOGGER = Logger - .getLogger(AXmlResourceParser.class.getName()); - private static final String E_NOT_SUPPORTED = "Method is not supported."; - private static final int ATTRIBUTE_IX_NAMESPACE_URI = 0, - ATTRIBUTE_IX_NAME = 1, ATTRIBUTE_IX_VALUE_STRING = 2, - ATTRIBUTE_IX_VALUE_TYPE = 3, ATTRIBUTE_IX_VALUE_DATA = 4, - ATTRIBUTE_LENGTH = 5; + private final static Logger LOGGER = Logger + .getLogger(AXmlResourceParser.class.getName()); + private static final String E_NOT_SUPPORTED = "Method is not supported."; + private static final int ATTRIBUTE_IX_NAMESPACE_URI = 0, + ATTRIBUTE_IX_NAME = 1, ATTRIBUTE_IX_VALUE_STRING = 2, + ATTRIBUTE_IX_VALUE_TYPE = 3, ATTRIBUTE_IX_VALUE_DATA = 4, + ATTRIBUTE_LENGTH = 5; - private static final int CHUNK_AXML_FILE = 0x00080003, - CHUNK_RESOURCEIDS = 0x00080180, CHUNK_XML_FIRST = 0x00100100, - CHUNK_XML_START_NAMESPACE = 0x00100100, - CHUNK_XML_END_NAMESPACE = 0x00100101, - CHUNK_XML_START_TAG = 0x00100102, CHUNK_XML_END_TAG = 0x00100103, - CHUNK_XML_TEXT = 0x00100104, CHUNK_XML_LAST = 0x00100104; + private static final int CHUNK_AXML_FILE = 0x00080003, + CHUNK_RESOURCEIDS = 0x00080180, CHUNK_XML_FIRST = 0x00100100, + CHUNK_XML_START_NAMESPACE = 0x00100100, + CHUNK_XML_END_NAMESPACE = 0x00100101, + CHUNK_XML_START_TAG = 0x00100102, CHUNK_XML_END_TAG = 0x00100103, + CHUNK_XML_TEXT = 0x00100104, CHUNK_XML_LAST = 0x00100104; } \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java index a9e35ac4..531c90b6 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java @@ -30,113 +30,113 @@ import org.apache.commons.io.IOUtils; * @author Ryszard Wiśniewski */ public class Res9patchStreamDecoder implements ResStreamDecoder { - @Override - public void decode(InputStream in, OutputStream out) - throws AndrolibException { - try { - byte[] data = IOUtils.toByteArray(in); + @Override + public void decode(InputStream in, OutputStream out) + throws AndrolibException { + try { + byte[] data = IOUtils.toByteArray(in); - BufferedImage im = ImageIO.read(new ByteArrayInputStream(data)); - int w = im.getWidth(), h = im.getHeight(); + BufferedImage im = ImageIO.read(new ByteArrayInputStream(data)); + int w = im.getWidth(), h = im.getHeight(); ImageTypeSpecifier its = ImageTypeSpecifier.createFromRenderedImage( im ); BufferedImage im2 = its.createBufferedImage( w+2, h+2 ); im2.getRaster().setRect(1, 1, im.getRaster()); - NinePatch np = getNinePatch(data); - drawHLine(im2, h + 1, np.padLeft + 1, w - np.padRight); - drawVLine(im2, w + 1, np.padTop + 1, h - np.padBottom); + NinePatch np = getNinePatch(data); + drawHLine(im2, h + 1, np.padLeft + 1, w - np.padRight); + drawVLine(im2, w + 1, np.padTop + 1, h - np.padBottom); - int[] xDivs = np.xDivs; - for (int i = 0; i < xDivs.length; i += 2) { - drawHLine(im2, 0, xDivs[i] + 1, xDivs[i + 1]); - } + int[] xDivs = np.xDivs; + for (int i = 0; i < xDivs.length; i += 2) { + drawHLine(im2, 0, xDivs[i] + 1, xDivs[i + 1]); + } - int[] yDivs = np.yDivs; - for (int i = 0; i < yDivs.length; i += 2) { - drawVLine(im2, 0, yDivs[i] + 1, yDivs[i + 1]); - } + int[] yDivs = np.yDivs; + for (int i = 0; i < yDivs.length; i += 2) { + drawVLine(im2, 0, yDivs[i] + 1, yDivs[i + 1]); + } - ImageIO.write(im2, "png", out); - } catch (IOException ex) { - throw new AndrolibException(ex); - } catch (NullPointerException ex) { - // In my case this was triggered because a .png file was - // containing a html document instead of an image. - // This could be more verbose and try to MIME ? - throw new AndrolibException(ex); - } - } + ImageIO.write(im2, "png", out); + } catch (IOException ex) { + throw new AndrolibException(ex); + } catch (NullPointerException ex) { + // In my case this was triggered because a .png file was + // containing a html document instead of an image. + // This could be more verbose and try to MIME ? + throw new AndrolibException(ex); + } + } - private NinePatch getNinePatch(byte[] data) throws AndrolibException, - IOException { - ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data)); - find9patchChunk(di); - return NinePatch.decode(di); - } + private NinePatch getNinePatch(byte[] data) throws AndrolibException, + IOException { + ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data)); + find9patchChunk(di); + return NinePatch.decode(di); + } - private void find9patchChunk(DataInput di) throws AndrolibException, - IOException { - di.skipBytes(8); - while (true) { - int size; - try { - size = di.readInt(); - } catch (IOException ex) { - throw new CantFind9PatchChunk("Cant find nine patch chunk", ex); - } - if (di.readInt() == NP_CHUNK_TYPE) { - return; - } - di.skipBytes(size + 4); - } - } + private void find9patchChunk(DataInput di) throws AndrolibException, + IOException { + di.skipBytes(8); + while (true) { + int size; + try { + size = di.readInt(); + } catch (IOException ex) { + throw new CantFind9PatchChunk("Cant find nine patch chunk", ex); + } + if (di.readInt() == NP_CHUNK_TYPE) { + return; + } + di.skipBytes(size + 4); + } + } - private void drawHLine(BufferedImage im, int y, int x1, int x2) { - for (int x = x1; x <= x2; x++) { - im.setRGB(x, y, NP_COLOR); - } - } + private void drawHLine(BufferedImage im, int y, int x1, int x2) { + for (int x = x1; x <= x2; x++) { + im.setRGB(x, y, NP_COLOR); + } + } - private void drawVLine(BufferedImage im, int x, int y1, int y2) { - for (int y = y1; y <= y2; y++) { - im.setRGB(x, y, NP_COLOR); - } - } + private void drawVLine(BufferedImage im, int x, int y1, int y2) { + for (int y = y1; y <= y2; y++) { + im.setRGB(x, y, NP_COLOR); + } + } - private static final int NP_CHUNK_TYPE = 0x6e705463; // npTc - private static final int NP_COLOR = 0xff000000; + private static final int NP_CHUNK_TYPE = 0x6e705463; // npTc + private static final int NP_COLOR = 0xff000000; - private static class NinePatch { - public final int padLeft, padRight, padTop, padBottom; - public final int[] xDivs, yDivs; + private static class NinePatch { + public final int padLeft, padRight, padTop, padBottom; + public final int[] xDivs, yDivs; - public NinePatch(int padLeft, int padRight, int padTop, int padBottom, - int[] xDivs, int[] yDivs) { - this.padLeft = padLeft; - this.padRight = padRight; - this.padTop = padTop; - this.padBottom = padBottom; - this.xDivs = xDivs; - this.yDivs = yDivs; - } + public NinePatch(int padLeft, int padRight, int padTop, int padBottom, + int[] xDivs, int[] yDivs) { + this.padLeft = padLeft; + this.padRight = padRight; + this.padTop = padTop; + this.padBottom = padBottom; + this.xDivs = xDivs; + this.yDivs = yDivs; + } - public static NinePatch decode(ExtDataInput di) throws IOException { - di.skipBytes(1); - byte numXDivs = di.readByte(); - byte numYDivs = di.readByte(); - di.skipBytes(1); - di.skipBytes(8); - int padLeft = di.readInt(); - int padRight = di.readInt(); - int padTop = di.readInt(); - int padBottom = di.readInt(); - di.skipBytes(4); - int[] xDivs = di.readIntArray(numXDivs); - int[] yDivs = di.readIntArray(numYDivs); + public static NinePatch decode(ExtDataInput di) throws IOException { + di.skipBytes(1); + byte numXDivs = di.readByte(); + byte numYDivs = di.readByte(); + di.skipBytes(1); + di.skipBytes(8); + int padLeft = di.readInt(); + int padRight = di.readInt(); + int padTop = di.readInt(); + int padBottom = di.readInt(); + di.skipBytes(4); + int[] xDivs = di.readIntArray(numXDivs); + int[] yDivs = di.readIntArray(numYDivs); - return new NinePatch(padLeft, padRight, padTop, padBottom, xDivs, - yDivs); - } - } + return new NinePatch(padLeft, padRight, padTop, padBottom, xDivs, + yDivs); + } + } } \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResAttrDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResAttrDecoder.java index 8287d613..dda44168 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResAttrDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResAttrDecoder.java @@ -25,31 +25,31 @@ import brut.androlib.res.data.value.ResScalarValue; * @author Ryszard Wiśniewski */ public class ResAttrDecoder { - public String decode(int type, int value, String rawValue, int attrResId) - throws AndrolibException { - ResScalarValue resValue = mCurrentPackage.getValueFactory().factory( - type, value, rawValue); + public String decode(int type, int value, String rawValue, int attrResId) + throws AndrolibException { + ResScalarValue resValue = mCurrentPackage.getValueFactory().factory( + type, value, rawValue); - String decoded = null; - if (attrResId != 0) { - ResAttr attr = (ResAttr) getCurrentPackage().getResTable() - .getResSpec(attrResId).getDefaultResource().getValue(); - decoded = attr.convertToResXmlFormat(resValue); - } + String decoded = null; + if (attrResId != 0) { + ResAttr attr = (ResAttr) getCurrentPackage().getResTable() + .getResSpec(attrResId).getDefaultResource().getValue(); + decoded = attr.convertToResXmlFormat(resValue); + } - return decoded != null ? decoded : resValue.encodeAsResXmlAttr(); - } + return decoded != null ? decoded : resValue.encodeAsResXmlAttr(); + } - public ResPackage getCurrentPackage() throws AndrolibException { - if (mCurrentPackage == null) { - throw new AndrolibException("Current package not set"); - } - return mCurrentPackage; - } + public ResPackage getCurrentPackage() throws AndrolibException { + if (mCurrentPackage == null) { + throw new AndrolibException("Current package not set"); + } + return mCurrentPackage; + } - public void setCurrentPackage(ResPackage currentPackage) { - mCurrentPackage = currentPackage; - } + public void setCurrentPackage(ResPackage currentPackage) { + mCurrentPackage = currentPackage; + } - private ResPackage mCurrentPackage; + private ResPackage mCurrentPackage; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java index 18575630..89f89fd2 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java @@ -31,121 +31,121 @@ import java.util.logging.Logger; * @author Ryszard Wiśniewski */ public class ResFileDecoder { - private final ResStreamDecoderContainer mDecoders; + private final ResStreamDecoderContainer mDecoders; - public ResFileDecoder(ResStreamDecoderContainer decoders) { - this.mDecoders = decoders; - } + public ResFileDecoder(ResStreamDecoderContainer decoders) { + this.mDecoders = decoders; + } - public void decode(ResResource res, Directory inDir, Directory outDir) - throws AndrolibException { + public void decode(ResResource res, Directory inDir, Directory outDir) + throws AndrolibException { - ResFileValue fileValue = (ResFileValue) res.getValue(); - String inFileName = fileValue.getStrippedPath(); - String outResName = res.getFilePath(); - String typeName = res.getResSpec().getType().getName(); + ResFileValue fileValue = (ResFileValue) res.getValue(); + String inFileName = fileValue.getStrippedPath(); + String outResName = res.getFilePath(); + String typeName = res.getResSpec().getType().getName(); - String ext = null; - String outFileName; - int extPos = inFileName.lastIndexOf("."); - if (extPos == -1) { - outFileName = outResName; - } else { - ext = inFileName.substring(extPos); - outFileName = outResName + ext; - } + String ext = null; + String outFileName; + int extPos = inFileName.lastIndexOf("."); + if (extPos == -1) { + outFileName = outResName; + } else { + ext = inFileName.substring(extPos); + outFileName = outResName + ext; + } - try { - if (typeName.equals("raw")) { - decode(inDir, inFileName, outDir, outFileName, "raw"); - return; - } - if (typeName.equals("drawable") || typeName.equals("mipmap")) { - if (inFileName.toLowerCase().endsWith(".9.png")) { - outFileName = outResName + ".9" + ext; + try { + if (typeName.equals("raw")) { + decode(inDir, inFileName, outDir, outFileName, "raw"); + return; + } + if (typeName.equals("drawable") || typeName.equals("mipmap")) { + if (inFileName.toLowerCase().endsWith(".9.png")) { + outFileName = outResName + ".9" + ext; - // check for htc .r.9.png - if (inFileName.toLowerCase().endsWith(".r.9.png")) { - outFileName = outResName + ".r.9" + ext; - } + // check for htc .r.9.png + if (inFileName.toLowerCase().endsWith(".r.9.png")) { + outFileName = outResName + ".r.9" + ext; + } - try { - decode(inDir, inFileName, outDir, outFileName, "9patch"); - return; - } catch (CantFind9PatchChunk ex) { - LOGGER.log( - Level.WARNING, - String.format( - "Cant find 9patch chunk in file: \"%s\". Renaming it to *.png.", - inFileName), ex); - outDir.removeFile(outFileName); - outFileName = outResName + ext; - } - } - if (!".xml".equals(ext)) { - decode(inDir, inFileName, outDir, outFileName, "raw"); - return; - } - } + try { + decode(inDir, inFileName, outDir, outFileName, "9patch"); + return; + } catch (CantFind9PatchChunk ex) { + LOGGER.log( + Level.WARNING, + String.format( + "Cant find 9patch chunk in file: \"%s\". Renaming it to *.png.", + inFileName), ex); + outDir.removeFile(outFileName); + outFileName = outResName + ext; + } + } + if (!".xml".equals(ext)) { + decode(inDir, inFileName, outDir, outFileName, "raw"); + return; + } + } - decode(inDir, inFileName, outDir, outFileName, "xml"); - } catch (AndrolibException ex) { - LOGGER.log(Level.SEVERE, String.format( - "Could not decode file, replacing by FALSE value: %s", - inFileName, outFileName), ex); - res.replace(new ResBoolValue(false, null)); - } - } + decode(inDir, inFileName, outDir, outFileName, "xml"); + } catch (AndrolibException ex) { + LOGGER.log(Level.SEVERE, String.format( + "Could not decode file, replacing by FALSE value: %s", + inFileName, outFileName), ex); + res.replace(new ResBoolValue(false, null)); + } + } - public void decode(Directory inDir, String inFileName, Directory outDir, - String outFileName, String decoder) throws AndrolibException { - InputStream in = null; - OutputStream out = null; - try { - in = inDir.getFileInput(inFileName); - out = outDir.getFileOutput(outFileName); - mDecoders.decode(in, out, decoder); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } finally { - try { - if (in != null) { - in.close(); - } - if (out != null) { - out.close(); - } - } catch (IOException ex) { - throw new AndrolibException(ex); - } - } - } + public void decode(Directory inDir, String inFileName, Directory outDir, + String outFileName, String decoder) throws AndrolibException { + InputStream in = null; + OutputStream out = null; + try { + in = inDir.getFileInput(inFileName); + out = outDir.getFileOutput(outFileName); + mDecoders.decode(in, out, decoder); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } finally { + try { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + } catch (IOException ex) { + throw new AndrolibException(ex); + } + } + } - public void decodeManifest(Directory inDir, String inFileName, - Directory outDir, String outFileName) throws AndrolibException { - InputStream in = null; - OutputStream out = null; - try { - in = inDir.getFileInput(inFileName); - out = outDir.getFileOutput(outFileName); - ((XmlPullStreamDecoder) mDecoders.getDecoder("xml")) - .decodeManifest(in, out); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); - } finally { - try { - if (in != null) { - in.close(); - } - if (out != null) { - out.close(); - } - } catch (IOException ex) { - throw new AndrolibException(ex); - } - } - } + public void decodeManifest(Directory inDir, String inFileName, + Directory outDir, String outFileName) throws AndrolibException { + InputStream in = null; + OutputStream out = null; + try { + in = inDir.getFileInput(inFileName); + out = outDir.getFileOutput(outFileName); + ((XmlPullStreamDecoder) mDecoders.getDecoder("xml")) + .decodeManifest(in, out); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } finally { + try { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + } catch (IOException ex) { + throw new AndrolibException(ex); + } + } + } - private final static Logger LOGGER = Logger.getLogger(ResFileDecoder.class - .getName()); + private final static Logger LOGGER = Logger.getLogger(ResFileDecoder.class + .getName()); } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResRawStreamDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResRawStreamDecoder.java index 3ee66657..8c515a2f 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResRawStreamDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResRawStreamDecoder.java @@ -26,13 +26,13 @@ import org.apache.commons.io.IOUtils; * @author Ryszard Wiśniewski */ public class ResRawStreamDecoder implements ResStreamDecoder { - @Override - public void decode(InputStream in, OutputStream out) - throws AndrolibException { - try { - IOUtils.copy(in, out); - } catch (IOException ex) { - throw new AndrolibException("Could not decode raw stream", ex); - } - } + @Override + public void decode(InputStream in, OutputStream out) + throws AndrolibException { + try { + IOUtils.copy(in, out); + } catch (IOException ex) { + throw new AndrolibException("Could not decode raw stream", ex); + } + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoder.java index 2541baaa..012f0254 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoder.java @@ -24,6 +24,6 @@ import java.io.OutputStream; * @author Ryszard Wiśniewski */ public interface ResStreamDecoder { - public void decode(InputStream in, OutputStream out) - throws AndrolibException; + public void decode(InputStream in, OutputStream out) + throws AndrolibException; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoderContainer.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoderContainer.java index ce26e5a2..072d1f64 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoderContainer.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoderContainer.java @@ -26,22 +26,22 @@ import java.util.Map; * @author Ryszard Wiśniewski */ public class ResStreamDecoderContainer { - private final Map mDecoders = new HashMap(); + private final Map mDecoders = new HashMap(); - public void decode(InputStream in, OutputStream out, String decoderName) - throws AndrolibException { - getDecoder(decoderName).decode(in, out); - } + public void decode(InputStream in, OutputStream out, String decoderName) + throws AndrolibException { + getDecoder(decoderName).decode(in, out); + } - public ResStreamDecoder getDecoder(String name) throws AndrolibException { - ResStreamDecoder decoder = mDecoders.get(name); - if (decoder == null) { - throw new AndrolibException("Undefined decoder: " + name); - } - return decoder; - } + public ResStreamDecoder getDecoder(String name) throws AndrolibException { + ResStreamDecoder decoder = mDecoders.get(name); + if (decoder == null) { + throw new AndrolibException("Undefined decoder: " + name); + } + return decoder; + } - public void setDecoder(String name, ResStreamDecoder decoder) { - mDecoders.put(name, decoder); - } + public void setDecoder(String name, ResStreamDecoder decoder) { + mDecoders.put(name, decoder); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java index 50bffcf6..887a5f8b 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java @@ -28,275 +28,275 @@ import java.util.logging.Logger; /** * @author Ryszard Wiśniewski * @author Dmitry Skiba - * + * * Block of strings, used in binary xml and arsc. - * + * * TODO: - implement get() - * + * */ public class StringBlock { - /** - * Reads whole (including chunk type) string block from stream. Stream must - * be at the chunk type. - */ - public static StringBlock read(ExtDataInput reader) throws IOException { - reader.skipCheckInt(CHUNK_TYPE); - int chunkSize = reader.readInt(); - int stringCount = reader.readInt(); - int styleOffsetCount = reader.readInt(); - int flags = reader.readInt(); - int stringsOffset = reader.readInt(); - int stylesOffset = reader.readInt(); + /** + * Reads whole (including chunk type) string block from stream. Stream must + * be at the chunk type. + */ + public static StringBlock read(ExtDataInput reader) throws IOException { + reader.skipCheckInt(CHUNK_TYPE); + int chunkSize = reader.readInt(); + int stringCount = reader.readInt(); + int styleOffsetCount = reader.readInt(); + int flags = reader.readInt(); + int stringsOffset = reader.readInt(); + int stylesOffset = reader.readInt(); - StringBlock block = new StringBlock(); - block.m_isUTF8 = (flags & UTF8_FLAG) != 0; - block.m_stringOffsets = reader.readIntArray(stringCount); - block.m_stringOwns = new int[stringCount]; + StringBlock block = new StringBlock(); + block.m_isUTF8 = (flags & UTF8_FLAG) != 0; + block.m_stringOffsets = reader.readIntArray(stringCount); + block.m_stringOwns = new int[stringCount]; Arrays.fill(block.m_stringOwns, -1); - if (styleOffsetCount != 0) { - block.m_styleOffsets = reader.readIntArray(styleOffsetCount); - } - { - int size = ((stylesOffset == 0) ? chunkSize : stylesOffset) - - stringsOffset; - if ((size % 4) != 0) { - throw new IOException("String data size is not multiple of 4 (" - + size + ")."); - } - block.m_strings = new byte[size]; - reader.readFully(block.m_strings); - } - if (stylesOffset != 0) { - int size = (chunkSize - stylesOffset); - if ((size % 4) != 0) { - throw new IOException("Style data size is not multiple of 4 (" - + size + ")."); - } - block.m_styles = reader.readIntArray(size / 4); - } + if (styleOffsetCount != 0) { + block.m_styleOffsets = reader.readIntArray(styleOffsetCount); + } + { + int size = ((stylesOffset == 0) ? chunkSize : stylesOffset) + - stringsOffset; + if ((size % 4) != 0) { + throw new IOException("String data size is not multiple of 4 (" + + size + ")."); + } + block.m_strings = new byte[size]; + reader.readFully(block.m_strings); + } + if (stylesOffset != 0) { + int size = (chunkSize - stylesOffset); + if ((size % 4) != 0) { + throw new IOException("Style data size is not multiple of 4 (" + + size + ")."); + } + block.m_styles = reader.readIntArray(size / 4); + } - return block; - } + return block; + } - /** - * Returns number of strings in block. - */ - public int getCount() { - return m_stringOffsets != null ? m_stringOffsets.length : 0; - } + /** + * Returns number of strings in block. + */ + public int getCount() { + return m_stringOffsets != null ? m_stringOffsets.length : 0; + } - /** - * Returns raw string (without any styling information) at specified index. - */ - public String getString(int index) { - if (index < 0 || m_stringOffsets == null || index >= m_stringOffsets.length) { - return null; - } - int offset = m_stringOffsets[index]; - int length; + /** + * Returns raw string (without any styling information) at specified index. + */ + public String getString(int index) { + if (index < 0 || m_stringOffsets == null || index >= m_stringOffsets.length) { + return null; + } + int offset = m_stringOffsets[index]; + int length; - if (m_isUTF8) { + if (m_isUTF8) { int[] val = getUtf8(m_strings, offset); offset = val[0]; length = val[1]; - } else { + } else { int[] val = getUtf16(m_strings, offset); offset += val[0]; length = val[1]; - } - return decodeString(offset, length); - } + } + return decodeString(offset, length); + } - /** - * Not yet implemented. - * - * Returns string with style information (if any). - */ - public CharSequence get(int index) { - return getString(index); - } + /** + * Not yet implemented. + * + * Returns string with style information (if any). + */ + public CharSequence get(int index) { + return getString(index); + } - /** - * Returns string with style tags (html-like). - */ - public String getHTML(int index) { - String raw = getString(index); - if (raw == null) { - return raw; - } - int[] style = getStyle(index); - if (style == null) { - return ResXmlEncoders.escapeXmlChars(raw); - } - StringBuilder html = new StringBuilder(raw.length() + 32); - int[] opened = new int[style.length / 3]; - int offset = 0, depth = 0; - while (true) { - int i = -1, j; - for (j = 0; j != style.length; j += 3) { - if (style[j + 1] == -1) { - continue; - } - if (i == -1 || style[i + 1] > style[j + 1]) { - i = j; - } - } - int start = ((i != -1) ? style[i + 1] : raw.length()); - for (j = depth - 1; j >= 0; j--) { - int last = opened[j]; - int end = style[last + 2]; - if (end >= start) { - break; - } - if (offset <= end) { - html.append(ResXmlEncoders.escapeXmlChars(raw.substring( - offset, end + 1))); - offset = end + 1; - } - outputStyleTag(getString(style[last]), html, true); - } - depth = j + 1; - if (offset < start) { - html.append(ResXmlEncoders.escapeXmlChars(raw.substring(offset, - start))); - offset = start; - } - if (i == -1) { - break; - } - outputStyleTag(getString(style[i]), html, false); - style[i + 1] = -1; - opened[depth++] = i; - } - return html.toString(); - } + /** + * Returns string with style tags (html-like). + */ + public String getHTML(int index) { + String raw = getString(index); + if (raw == null) { + return raw; + } + int[] style = getStyle(index); + if (style == null) { + return ResXmlEncoders.escapeXmlChars(raw); + } + StringBuilder html = new StringBuilder(raw.length() + 32); + int[] opened = new int[style.length / 3]; + int offset = 0, depth = 0; + while (true) { + int i = -1, j; + for (j = 0; j != style.length; j += 3) { + if (style[j + 1] == -1) { + continue; + } + if (i == -1 || style[i + 1] > style[j + 1]) { + i = j; + } + } + int start = ((i != -1) ? style[i + 1] : raw.length()); + for (j = depth - 1; j >= 0; j--) { + int last = opened[j]; + int end = style[last + 2]; + if (end >= start) { + break; + } + if (offset <= end) { + html.append(ResXmlEncoders.escapeXmlChars(raw.substring( + offset, end + 1))); + offset = end + 1; + } + outputStyleTag(getString(style[last]), html, true); + } + depth = j + 1; + if (offset < start) { + html.append(ResXmlEncoders.escapeXmlChars(raw.substring(offset, + start))); + offset = start; + } + if (i == -1) { + break; + } + outputStyleTag(getString(style[i]), html, false); + style[i + 1] = -1; + opened[depth++] = i; + } + return html.toString(); + } - private void outputStyleTag(String tag, StringBuilder builder, boolean close) { - builder.append('<'); - if (close) { - builder.append('/'); - } + private void outputStyleTag(String tag, StringBuilder builder, boolean close) { + builder.append('<'); + if (close) { + builder.append('/'); + } - int pos = tag.indexOf(';'); - if (pos == -1) { - builder.append(tag); - } else { - builder.append(tag.substring(0, pos)); - if (!close) { - boolean loop = true; - while (loop) { - int pos2 = tag.indexOf('=', pos + 1); - builder.append(' ').append(tag.substring(pos + 1, pos2)) - .append("=\""); - pos = tag.indexOf(';', pos2 + 1); + int pos = tag.indexOf(';'); + if (pos == -1) { + builder.append(tag); + } else { + builder.append(tag.substring(0, pos)); + if (!close) { + boolean loop = true; + while (loop) { + int pos2 = tag.indexOf('=', pos + 1); + builder.append(' ').append(tag.substring(pos + 1, pos2)) + .append("=\""); + pos = tag.indexOf(';', pos2 + 1); - String val; - if (pos != -1) { - val = tag.substring(pos2 + 1, pos); - } else { - loop = false; - val = tag.substring(pos2 + 1); - } + String val; + if (pos != -1) { + val = tag.substring(pos2 + 1, pos); + } else { + loop = false; + val = tag.substring(pos2 + 1); + } - builder.append(ResXmlEncoders.escapeXmlChars(val)).append( - '"'); - } - } - } - builder.append('>'); - } + builder.append(ResXmlEncoders.escapeXmlChars(val)).append( + '"'); + } + } + } + builder.append('>'); + } - /** - * Finds index of the string. Returns -1 if the string was not found. - */ - public int find(String string) { - if (string == null) { - return -1; - } - for (int i = 0; i != m_stringOffsets.length; ++i) { - int offset = m_stringOffsets[i]; - int length = getShort(m_strings, offset); - if (length != string.length()) { - continue; - } - int j = 0; - for (; j != length; ++j) { - offset += 2; - if (string.charAt(j) != getShort(m_strings, offset)) { - break; - } - } - if (j == length) { - return i; - } - } - return -1; - } + /** + * Finds index of the string. Returns -1 if the string was not found. + */ + public int find(String string) { + if (string == null) { + return -1; + } + for (int i = 0; i != m_stringOffsets.length; ++i) { + int offset = m_stringOffsets[i]; + int length = getShort(m_strings, offset); + if (length != string.length()) { + continue; + } + int j = 0; + for (; j != length; ++j) { + offset += 2; + if (string.charAt(j) != getShort(m_strings, offset)) { + break; + } + } + if (j == length) { + return i; + } + } + return -1; + } - // /////////////////////////////////////////// implementation - private StringBlock() { - } + // /////////////////////////////////////////// implementation + private StringBlock() { + } - /** - * Returns style information - array of int triplets, where in each triplet: - * * first int is index of tag name ('b','i', etc.) * second int is tag - * start index in string * third int is tag end index in string - */ - private int[] getStyle(int index) { - if (m_styleOffsets == null || m_styles == null - || index >= m_styleOffsets.length) { - return null; - } - int offset = m_styleOffsets[index] / 4; - int style[]; - { - int count = 0; - for (int i = offset; i < m_styles.length; ++i) { - if (m_styles[i] == -1) { - break; - } - count += 1; - } - if (count == 0 || (count % 3) != 0) { - return null; - } - style = new int[count]; - } - for (int i = offset, j = 0; i < m_styles.length;) { - if (m_styles[i] == -1) { - break; - } - style[j++] = m_styles[i++]; - } - return style; - } + /** + * Returns style information - array of int triplets, where in each triplet: + * * first int is index of tag name ('b','i', etc.) * second int is tag + * start index in string * third int is tag end index in string + */ + private int[] getStyle(int index) { + if (m_styleOffsets == null || m_styles == null + || index >= m_styleOffsets.length) { + return null; + } + int offset = m_styleOffsets[index] / 4; + int style[]; + { + int count = 0; + for (int i = offset; i < m_styles.length; ++i) { + if (m_styles[i] == -1) { + break; + } + count += 1; + } + if (count == 0 || (count % 3) != 0) { + return null; + } + style = new int[count]; + } + for (int i = offset, j = 0; i < m_styles.length;) { + if (m_styles[i] == -1) { + break; + } + style[j++] = m_styles[i++]; + } + return style; + } - private String decodeString(int offset, int length) { - try { - return (m_isUTF8 ? UTF8_DECODER : UTF16LE_DECODER).decode( - ByteBuffer.wrap(m_strings, offset, length)).toString(); - } catch (CharacterCodingException ex) { - LOGGER.log(Level.WARNING, null, ex); - return null; - } - } + private String decodeString(int offset, int length) { + try { + return (m_isUTF8 ? UTF8_DECODER : UTF16LE_DECODER).decode( + ByteBuffer.wrap(m_strings, offset, length)).toString(); + } catch (CharacterCodingException ex) { + LOGGER.log(Level.WARNING, null, ex); + return null; + } + } - private static final int getShort(byte[] array, int offset) { - return (array[offset + 1] & 0xff) << 8 | array[offset] & 0xff; - } + private static final int getShort(byte[] array, int offset) { + return (array[offset + 1] & 0xff) << 8 | array[offset] & 0xff; + } - private static final int getShort(int[] array, int offset) { - int value = array[offset / 4]; - if ((offset % 4) / 2 == 0) { - return (value & 0xFFFF); - } else { - return (value >>> 16); - } - } + private static final int getShort(int[] array, int offset) { + int value = array[offset / 4]; + if ((offset % 4) / 2 == 0) { + return (value & 0xFFFF); + } else { + return (value >>> 16); + } + } - private static final int[] getUtf8(byte[] array, int offset) { + private static final int[] getUtf8(byte[] array, int offset) { int val = array[offset]; int length; @@ -315,8 +315,8 @@ public class StringBlock { while (array[offset + length] != 0) { length++; } - return new int[] { offset, length}; - } + return new int[] { offset, length}; + } private static final int[] getUtf16(byte[] array, int offset) { int val = ((array[offset + 1] & 0xFF) << 8 | array[offset] & 0xFF); @@ -329,20 +329,20 @@ public class StringBlock { return new int[] {2, val * 2}; } - private int[] m_stringOffsets; - private byte[] m_strings; - private int[] m_styleOffsets; - private int[] m_styles; - private boolean m_isUTF8; - private int[] m_stringOwns; - private final CharsetDecoder UTF16LE_DECODER = Charset.forName( - "UTF-16LE").newDecoder(); - private final CharsetDecoder UTF8_DECODER = Charset.forName("UTF-8") - .newDecoder(); - private static final Logger LOGGER = Logger.getLogger(StringBlock.class - .getName()); + private int[] m_stringOffsets; + private byte[] m_strings; + private int[] m_styleOffsets; + private int[] m_styles; + private boolean m_isUTF8; + private int[] m_stringOwns; + private final CharsetDecoder UTF16LE_DECODER = Charset.forName( + "UTF-16LE").newDecoder(); + private final CharsetDecoder UTF8_DECODER = Charset.forName("UTF-8") + .newDecoder(); + private static final Logger LOGGER = Logger.getLogger(StringBlock.class + .getName()); // ResChunk_header = header.type (0x0001) + header.headerSize (0x001C) - private static final int CHUNK_TYPE = 0x001C0001; - private static final int UTF8_FLAG = 0x00000100; + private static final int CHUNK_TYPE = 0x001C0001; + private static final int UTF8_FLAG = 0x00000100; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java index e6774ccc..4234cf20 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java @@ -36,56 +36,56 @@ import brut.androlib.res.util.ExtXmlSerializer; * @author Ryszard Wiśniewski */ public class XmlPullStreamDecoder implements ResStreamDecoder { - public XmlPullStreamDecoder(XmlPullParser parser, - ExtXmlSerializer serializer) { - this.mParser = parser; - this.mSerial = serializer; - } + public XmlPullStreamDecoder(XmlPullParser parser, + ExtXmlSerializer serializer) { + this.mParser = parser; + this.mSerial = serializer; + } - @Override - public void decode(InputStream in, OutputStream out) - throws AndrolibException { - try { - XmlPullWrapperFactory factory = XmlPullWrapperFactory.newInstance(); - XmlPullParserWrapper par = factory.newPullParserWrapper(mParser); - final ResTable resTable = ((AXmlResourceParser) mParser) - .getAttrDecoder().getCurrentPackage().getResTable(); + @Override + public void decode(InputStream in, OutputStream out) + throws AndrolibException { + try { + XmlPullWrapperFactory factory = XmlPullWrapperFactory.newInstance(); + XmlPullParserWrapper par = factory.newPullParserWrapper(mParser); + final ResTable resTable = ((AXmlResourceParser) mParser) + .getAttrDecoder().getCurrentPackage().getResTable(); - XmlSerializerWrapper ser = new StaticXmlSerializerWrapper(mSerial, - factory) { - boolean hideSdkInfo = false; - boolean hidePackageInfo = false; + XmlSerializerWrapper ser = new StaticXmlSerializerWrapper(mSerial, + factory) { + boolean hideSdkInfo = false; + boolean hidePackageInfo = false; - @Override - public void event(XmlPullParser pp) - throws XmlPullParserException, IOException { - int type = pp.getEventType(); + @Override + public void event(XmlPullParser pp) + throws XmlPullParserException, IOException { + int type = pp.getEventType(); - if (type == XmlPullParser.START_TAG) { - if ("manifest".equalsIgnoreCase(pp.getName())) { - try { - hidePackageInfo = parseManifest(pp); - } catch (AndrolibException e) { - } - } else if ("uses-sdk".equalsIgnoreCase(pp.getName())) { - try { - hideSdkInfo = parseAttr(pp); - if (hideSdkInfo) { - return; - } - } catch (AndrolibException e) { - } - } - } else if (hideSdkInfo && type == XmlPullParser.END_TAG - && "uses-sdk".equalsIgnoreCase(pp.getName())) { - return; - } else if (hidePackageInfo && type == XmlPullParser.END_TAG - && "manifest".equalsIgnoreCase(pp.getName())) { - super.event(pp); - return; - } - super.event(pp); - } + if (type == XmlPullParser.START_TAG) { + if ("manifest".equalsIgnoreCase(pp.getName())) { + try { + hidePackageInfo = parseManifest(pp); + } catch (AndrolibException e) { + } + } else if ("uses-sdk".equalsIgnoreCase(pp.getName())) { + try { + hideSdkInfo = parseAttr(pp); + if (hideSdkInfo) { + return; + } + } catch (AndrolibException e) { + } + } + } else if (hideSdkInfo && type == XmlPullParser.END_TAG + && "uses-sdk".equalsIgnoreCase(pp.getName())) { + return; + } else if (hidePackageInfo && type == XmlPullParser.END_TAG + && "manifest".equalsIgnoreCase(pp.getName())) { + super.event(pp); + return; + } + super.event(pp); + } private boolean parseManifest(XmlPullParser pp) throws AndrolibException { @@ -103,71 +103,71 @@ public class XmlPullStreamDecoder implements ResStreamDecoder { return true; } - private boolean parseAttr(XmlPullParser pp) - throws AndrolibException { - ResTable restable = resTable; - for (int i = 0; i < pp.getAttributeCount(); i++) { - final String a_ns = "http://schemas.android.com/apk/res/android"; - String ns = pp.getAttributeNamespace(i); + private boolean parseAttr(XmlPullParser pp) + throws AndrolibException { + ResTable restable = resTable; + for (int i = 0; i < pp.getAttributeCount(); i++) { + final String a_ns = "http://schemas.android.com/apk/res/android"; + String ns = pp.getAttributeNamespace(i); - if (a_ns.equalsIgnoreCase(ns)) { - String name = pp.getAttributeName(i); - String value = pp.getAttributeValue(i); - if (name != null && value != null) { - if (name.equalsIgnoreCase("minSdkVersion") - || name.equalsIgnoreCase("targetSdkVersion") - || name.equalsIgnoreCase("maxSdkVersion")) { - restable.addSdkInfo(name, value); - } else { - restable.clearSdkInfo(); - return false;// Found unknown flags - } - } - } else { - resTable.clearSdkInfo(); + if (a_ns.equalsIgnoreCase(ns)) { + String name = pp.getAttributeName(i); + String value = pp.getAttributeValue(i); + if (name != null && value != null) { + if (name.equalsIgnoreCase("minSdkVersion") + || name.equalsIgnoreCase("targetSdkVersion") + || name.equalsIgnoreCase("maxSdkVersion")) { + restable.addSdkInfo(name, value); + } else { + restable.clearSdkInfo(); + return false;// Found unknown flags + } + } + } else { + resTable.clearSdkInfo(); - if (i >= pp.getAttributeCount()) { - return false;// Found unknown flags - } - } - } + if (i >= pp.getAttributeCount()) { + return false;// Found unknown flags + } + } + } if (resTable.getAnalysisMode() == true) { return false; } else { return true; } - } - }; + } + }; - par.setInput(in, null); - ser.setOutput(out, null); + par.setInput(in, null); + ser.setOutput(out, null); - while (par.nextToken() != XmlPullParser.END_DOCUMENT) { - ser.event(par); - } - ser.flush(); - } catch (XmlPullParserException ex) { - throw new AndrolibException("Could not decode XML", ex); - } catch (IOException ex) { - throw new AndrolibException("Could not decode XML", ex); - } - } + while (par.nextToken() != XmlPullParser.END_DOCUMENT) { + ser.event(par); + } + ser.flush(); + } catch (XmlPullParserException ex) { + throw new AndrolibException("Could not decode XML", ex); + } catch (IOException ex) { + throw new AndrolibException("Could not decode XML", ex); + } + } - public void decodeManifest(InputStream in, OutputStream out) - throws AndrolibException { - mOptimizeForManifest = true; - try { - decode(in, out); - } finally { - mOptimizeForManifest = false; - } - } + public void decodeManifest(InputStream in, OutputStream out) + throws AndrolibException { + mOptimizeForManifest = true; + try { + decode(in, out); + } finally { + mOptimizeForManifest = false; + } + } - private final XmlPullParser mParser; - private final ExtXmlSerializer mSerial; + private final XmlPullParser mParser; + private final ExtXmlSerializer mSerial; - private boolean mOptimizeForManifest = false; + private boolean mOptimizeForManifest = false; - private final static Logger LOGGER = Logger - .getLogger(XmlPullStreamDecoder.class.getName()); + private final static Logger LOGGER = Logger + .getLogger(XmlPullStreamDecoder.class.getName()); } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtFile.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtFile.java index 0532c524..e7e45e64 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtFile.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtFile.java @@ -27,36 +27,36 @@ import java.net.URI; * @author Ryszard Wiśniewski */ public class ExtFile extends File { - public ExtFile(File file) { - super(file.getPath()); - } + public ExtFile(File file) { + super(file.getPath()); + } - public ExtFile(URI uri) { - super(uri); - } + public ExtFile(URI uri) { + super(uri); + } - public ExtFile(File parent, String child) { - super(parent, child); - } + public ExtFile(File parent, String child) { + super(parent, child); + } - public ExtFile(String parent, String child) { - super(parent, child); - } + public ExtFile(String parent, String child) { + super(parent, child); + } - public ExtFile(String pathname) { - super(pathname); - } + public ExtFile(String pathname) { + super(pathname); + } - public Directory getDirectory() throws DirectoryException { - if (mDirectory == null) { - if (isDirectory()) { - mDirectory = new FileDirectory(this); - } else { - mDirectory = new ZipRODirectory(this); - } - } - return mDirectory; - } + public Directory getDirectory() throws DirectoryException { + if (mDirectory == null) { + if (isDirectory()) { + mDirectory = new FileDirectory(this); + } else { + mDirectory = new ZipRODirectory(this); + } + } + return mDirectory; + } - private Directory mDirectory; + private Directory mDirectory; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtMXSerializer.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtMXSerializer.java index b776919b..ad422c62 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtMXSerializer.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtMXSerializer.java @@ -23,59 +23,59 @@ import org.xmlpull.mxp1_serializer.MXSerializer; * @author Ryszard Wiśniewski */ public class ExtMXSerializer extends MXSerializer implements ExtXmlSerializer { - @Override - public void startDocument(String encoding, Boolean standalone) - throws IOException, IllegalArgumentException, IllegalStateException { - super.startDocument(encoding != null ? encoding : mDefaultEncoding, - standalone); - this.newLine(); - } + @Override + public void startDocument(String encoding, Boolean standalone) + throws IOException, IllegalArgumentException, IllegalStateException { + super.startDocument(encoding != null ? encoding : mDefaultEncoding, + standalone); + this.newLine(); + } - @Override - protected void writeAttributeValue(String value, Writer out) - throws IOException { - if (mIsDisabledAttrEscape) { - out.write(value); - return; - } - super.writeAttributeValue(value, out); - } + @Override + protected void writeAttributeValue(String value, Writer out) + throws IOException { + if (mIsDisabledAttrEscape) { + out.write(value); + return; + } + super.writeAttributeValue(value, out); + } - @Override - public void setOutput(OutputStream os, String encoding) throws IOException { - super.setOutput(os, encoding != null ? encoding : mDefaultEncoding); - } + @Override + public void setOutput(OutputStream os, String encoding) throws IOException { + super.setOutput(os, encoding != null ? encoding : mDefaultEncoding); + } - @Override - public Object getProperty(String name) throws IllegalArgumentException { - if (PROPERTY_DEFAULT_ENCODING.equals(name)) { - return mDefaultEncoding; - } - return super.getProperty(name); - } + @Override + public Object getProperty(String name) throws IllegalArgumentException { + if (PROPERTY_DEFAULT_ENCODING.equals(name)) { + return mDefaultEncoding; + } + return super.getProperty(name); + } - @Override - public void setProperty(String name, Object value) - throws IllegalArgumentException, IllegalStateException { - if (PROPERTY_DEFAULT_ENCODING.equals(name)) { - mDefaultEncoding = (String) value; - } else { - super.setProperty(name, value); - } - } + @Override + public void setProperty(String name, Object value) + throws IllegalArgumentException, IllegalStateException { + if (PROPERTY_DEFAULT_ENCODING.equals(name)) { + mDefaultEncoding = (String) value; + } else { + super.setProperty(name, value); + } + } - @Override - public ExtXmlSerializer newLine() throws IOException { - super.out.write(lineSeparator); - return this; - } + @Override + public ExtXmlSerializer newLine() throws IOException { + super.out.write(lineSeparator); + return this; + } - @Override - public void setDisabledAttrEscape(boolean disabled) { - mIsDisabledAttrEscape = disabled; - } + @Override + public void setDisabledAttrEscape(boolean disabled) { + mIsDisabledAttrEscape = disabled; + } - private String mDefaultEncoding; - private boolean mIsDisabledAttrEscape = false; + private String mDefaultEncoding; + private boolean mIsDisabledAttrEscape = false; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtXmlSerializer.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtXmlSerializer.java index 0fdeb9b5..1fdee01c 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtXmlSerializer.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtXmlSerializer.java @@ -24,11 +24,11 @@ import org.xmlpull.v1.XmlSerializer; */ public interface ExtXmlSerializer extends XmlSerializer { - public ExtXmlSerializer newLine() throws IOException; + public ExtXmlSerializer newLine() throws IOException; - public void setDisabledAttrEscape(boolean disabled); + public void setDisabledAttrEscape(boolean disabled); - public static final String PROPERTY_SERIALIZER_INDENTATION = "http://xmlpull.org/v1/doc/properties.html#serializer-indentation"; - public static final String PROPERTY_SERIALIZER_LINE_SEPARATOR = "http://xmlpull.org/v1/doc/properties.html#serializer-line-separator"; - public static final String PROPERTY_DEFAULT_ENCODING = "DEFAULT_ENCODING"; + public static final String PROPERTY_SERIALIZER_INDENTATION = "http://xmlpull.org/v1/doc/properties.html#serializer-indentation"; + public static final String PROPERTY_SERIALIZER_LINE_SEPARATOR = "http://xmlpull.org/v1/doc/properties.html#serializer-line-separator"; + public static final String PROPERTY_DEFAULT_ENCODING = "DEFAULT_ENCODING"; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResValuesXmlSerializable.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResValuesXmlSerializable.java index 39764c20..aca8e8a3 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResValuesXmlSerializable.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResValuesXmlSerializable.java @@ -25,6 +25,6 @@ import org.xmlpull.v1.XmlSerializer; * @author Ryszard Wiśniewski */ public interface ResValuesXmlSerializable { - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException; + public void serializeToResValuesXml(XmlSerializer serializer, + ResResource res) throws IOException, AndrolibException; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncodable.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncodable.java index 6d26fe22..fe7ce628 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncodable.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncodable.java @@ -22,7 +22,7 @@ import brut.androlib.AndrolibException; * @author Ryszard Wiśniewski */ public interface ResXmlEncodable { - public String encodeAsResXmlAttr() throws AndrolibException; + public String encodeAsResXmlAttr() throws AndrolibException; - public String encodeAsResXmlValue() throws AndrolibException; + public String encodeAsResXmlValue() throws AndrolibException; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java index 0d2fa7db..4eae8e1f 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java @@ -27,187 +27,187 @@ import java.util.List; */ public final class ResXmlEncoders { - public static String escapeXmlChars(String str) { - return str.replace("&", "&").replace("<", "<"); - } + public static String escapeXmlChars(String str) { + return str.replace("&", "&").replace("<", "<"); + } - public static String encodeAsResXmlAttr(String str) { - if (str.isEmpty()) { - return str; - } + public static String encodeAsResXmlAttr(String str) { + if (str.isEmpty()) { + return str; + } - char[] chars = str.toCharArray(); - StringBuilder out = new StringBuilder(str.length() + 10); + char[] chars = str.toCharArray(); + StringBuilder out = new StringBuilder(str.length() + 10); - switch (chars[0]) { - case '#': - case '@': - case '?': - out.append('\\'); - } + switch (chars[0]) { + case '#': + case '@': + case '?': + out.append('\\'); + } - for (char c : chars) { - switch (c) { - case '\\': - out.append('\\'); - break; - case '"': - out.append("""); - continue; - case '\n': - out.append("\\n"); - continue; - default: - if (!isPrintableChar(c)) { - out.append(String.format("\\u%04x", (int) c)); - continue; - } - } - out.append(c); - } + for (char c : chars) { + switch (c) { + case '\\': + out.append('\\'); + break; + case '"': + out.append("""); + continue; + case '\n': + out.append("\\n"); + continue; + default: + if (!isPrintableChar(c)) { + out.append(String.format("\\u%04x", (int) c)); + continue; + } + } + out.append(c); + } - return out.toString(); - } + return out.toString(); + } - public static String encodeAsXmlValue(String str) { - if (str.isEmpty()) { - return str; - } + public static String encodeAsXmlValue(String str) { + if (str.isEmpty()) { + return str; + } - char[] chars = str.toCharArray(); - StringBuilder out = new StringBuilder(str.length() + 10); + char[] chars = str.toCharArray(); + StringBuilder out = new StringBuilder(str.length() + 10); - switch (chars[0]) { - case '#': - case '@': - case '?': - out.append('\\'); - } + switch (chars[0]) { + case '#': + case '@': + case '?': + out.append('\\'); + } - boolean isInStyleTag = false; - int startPos = 0; - boolean enclose = false; - boolean wasSpace = true; - for (char c : chars) { - if (isInStyleTag) { - if (c == '>') { - isInStyleTag = false; - startPos = out.length() + 1; - enclose = false; - } - } else if (c == ' ') { - if (wasSpace) { - enclose = true; - } - wasSpace = true; - } else { - wasSpace = false; - switch (c) { - case '\\': - out.append('\\'); - break; - case '\'': - case '\n': - enclose = true; - break; - case '"': - out.append('\\'); - break; - case '<': - isInStyleTag = true; - if (enclose) { - out.insert(startPos, '"').append('"'); - } - break; - default: - if (!isPrintableChar(c)) { + boolean isInStyleTag = false; + int startPos = 0; + boolean enclose = false; + boolean wasSpace = true; + for (char c : chars) { + if (isInStyleTag) { + if (c == '>') { + isInStyleTag = false; + startPos = out.length() + 1; + enclose = false; + } + } else if (c == ' ') { + if (wasSpace) { + enclose = true; + } + wasSpace = true; + } else { + wasSpace = false; + switch (c) { + case '\\': + out.append('\\'); + break; + case '\'': + case '\n': + enclose = true; + break; + case '"': + out.append('\\'); + break; + case '<': + isInStyleTag = true; + if (enclose) { + out.insert(startPos, '"').append('"'); + } + break; + default: + if (!isPrintableChar(c)) { - // lets not write trailing \u0000 if we are at end of string - if ((out.length() + 1) == str.length() && c == '\u0000') { + // lets not write trailing \u0000 if we are at end of string + if ((out.length() + 1) == str.length() && c == '\u0000') { + continue; + } + out.append(String.format("\\u%04x", (int) c)); continue; } - out.append(String.format("\\u%04x", (int) c)); - continue; - } - } - } - out.append(c); - } + } + } + out.append(c); + } - if (enclose || wasSpace) { - out.insert(startPos, '"').append('"'); - } - return out.toString(); - } + if (enclose || wasSpace) { + out.insert(startPos, '"').append('"'); + } + return out.toString(); + } - public static boolean hasMultipleNonPositionalSubstitutions(String str) { + public static boolean hasMultipleNonPositionalSubstitutions(String str) { Duo, List> tuple = findSubstitutions(str, 2); return ! tuple.m1.isEmpty() && tuple.m1.size() + tuple.m2.size() > 1; - } + } - public static String enumerateNonPositionalSubstitutionsIfRequired(String str) { + public static String enumerateNonPositionalSubstitutionsIfRequired(String str) { Duo, List> tuple = findSubstitutions(str, 2); if (tuple.m1.isEmpty() || tuple.m1.size() + tuple.m2.size() < 2) { return str; } - List subs = tuple.m1; + List subs = tuple.m1; - StringBuilder out = new StringBuilder(); - int pos = 0; - int count = 0; - for (Integer sub : subs) { - out.append(str.substring(pos, ++sub)).append(++count).append('$'); - pos = sub; - } - out.append(str.substring(pos)); + StringBuilder out = new StringBuilder(); + int pos = 0; + int count = 0; + for (Integer sub : subs) { + out.append(str.substring(pos, ++sub)).append(++count).append('$'); + pos = sub; + } + out.append(str.substring(pos)); - return out.toString(); - } + return out.toString(); + } - /** - * It returns a tuple of: + /** + * It returns a tuple of: * - a list of offsets of non positional substitutions. non-pos is defined as any "%" which isn't "%%" nor "%\d+\$" * - a list of offsets of positional substitutions - */ - private static Duo, List> findSubstitutions(String str, int nonPosMax) { + */ + private static Duo, List> findSubstitutions(String str, int nonPosMax) { if (nonPosMax == -1) { nonPosMax = Integer.MAX_VALUE; } - int pos; - int pos2 = 0; - int length = str.length(); - List nonPositional = new ArrayList<>(); - List positional = new ArrayList<>(); - while ((pos = str.indexOf('%', pos2)) != -1) { + int pos; + int pos2 = 0; + int length = str.length(); + List nonPositional = new ArrayList<>(); + List positional = new ArrayList<>(); + while ((pos = str.indexOf('%', pos2)) != -1) { pos2 = pos + 1; - if (pos2 == length) { + if (pos2 == length) { nonPositional.add(pos); - break; - } - char c = str.charAt(pos2++); - if (c == '%') { - continue; - } - if (c >= '0' && c <= '9' && pos2 < length) { + break; + } + char c = str.charAt(pos2++); + if (c == '%') { + continue; + } + if (c >= '0' && c <= '9' && pos2 < length) { while ((c = str.charAt(pos2++)) >= '0' && c <= '9' && pos2 < length); if (c == '$') { positional.add(pos); continue; } - } + } - nonPositional.add(pos); - if (nonPositional.size() >= nonPosMax) { - break; - } - } + nonPositional.add(pos); + if (nonPositional.size() >= nonPosMax) { + break; + } + } - return new Duo<>(nonPositional, positional); - } + return new Duo<>(nonPositional, positional); + } - private static boolean isPrintableChar(char c) { - Character.UnicodeBlock block = Character.UnicodeBlock.of(c); - return !Character.isISOControl(c) && c != KeyEvent.CHAR_UNDEFINED - && block != null && block != Character.UnicodeBlock.SPECIALS; - } + private static boolean isPrintableChar(char c) { + Character.UnicodeBlock block = Character.UnicodeBlock.of(c); + return !Character.isISOControl(c) && c != KeyEvent.CHAR_UNDEFINED + && block != null && block != Character.UnicodeBlock.SPECIALS; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/DebugInjector.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/DebugInjector.java index fd94bc42..8f20f4a3 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/DebugInjector.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/DebugInjector.java @@ -30,30 +30,30 @@ public class DebugInjector { private int currParam; private int lastParam; - public static void inject(ListIterator it, StringBuilder out) - throws AndrolibException { - new DebugInjector(it, out).inject(); - } + public static void inject(ListIterator it, StringBuilder out) + throws AndrolibException { + new DebugInjector(it, out).inject(); + } - private DebugInjector(ListIterator it, StringBuilder out) { - mIt = it; - mOut = out; - } + private DebugInjector(ListIterator it, StringBuilder out) { + mIt = it; + mOut = out; + } - private void inject() throws AndrolibException { - String definition = nextAndAppend(); - if (definition.contains(" abstract ") - || definition.contains(" native ")) { - nextAndAppend(); - return; - } - parseParamsNumber(definition); + private void inject() throws AndrolibException { + String definition = nextAndAppend(); + if (definition.contains(" abstract ") + || definition.contains(" native ")) { + nextAndAppend(); + return; + } + parseParamsNumber(definition); - boolean end = false; - while (!end) { - end = step(); - } - } + boolean end = false; + while (!end) { + end = step(); + } + } private void parseParamsNumber(String definition) throws AndrolibException { int pos = definition.indexOf('('); @@ -78,34 +78,34 @@ public class DebugInjector { } } - private boolean step() { - String line = next(); - if (line.isEmpty()) { - return false; - } + private boolean step() { + String line = next(); + if (line.isEmpty()) { + return false; + } - switch (line.charAt(0)) { - case '#': - return processComment(line); - case ':': - append(line); - return false; - case '.': - return processDirective(line); - default: - if (! areParamsInjected) { - injectRemainingParams(); - } - return processInstruction(line); - } - } + switch (line.charAt(0)) { + case '#': + return processComment(line); + case ':': + append(line); + return false; + case '.': + return processDirective(line); + default: + if (! areParamsInjected) { + injectRemainingParams(); + } + return processInstruction(line); + } + } - private boolean processComment(String line) { - if (mFirstInstruction) { - return false; - } + private boolean processComment(String line) { + if (mFirstInstruction) { + return false; + } - Matcher m = REGISTER_INFO_PATTERN.matcher(line); + Matcher m = REGISTER_INFO_PATTERN.matcher(line); while (m.find()) { String localName = m.group(1); @@ -145,7 +145,7 @@ public class DebugInjector { break; case "Float": localType = "F"; - break; + break; case "LongHi": case "LongLo": localType = "J"; @@ -167,11 +167,11 @@ public class DebugInjector { .append('\n'); } - return false; - } + return false; + } - private boolean processDirective(String line) { - String line2 = line.substring(1); + private boolean processDirective(String line) { + String line2 = line.substring(1); if (line2.startsWith("line ") || line2.startsWith("local ") || line2.startsWith("end local ")) { return false; } @@ -191,54 +191,54 @@ public class DebugInjector { return false; } - append(line); - if (line2.equals("end method")) { - return true; - } - if (line2.startsWith("annotation ") || line2.equals("sparse-switch") - || line2.startsWith("packed-switch ") - || line2.startsWith("array-data ")) { - while (true) { - line2 = nextAndAppend(); - if (line2.startsWith(".end ")) { - break; - } - } - } - return false; - } + append(line); + if (line2.equals("end method")) { + return true; + } + if (line2.startsWith("annotation ") || line2.equals("sparse-switch") + || line2.startsWith("packed-switch ") + || line2.startsWith("array-data ")) { + while (true) { + line2 = nextAndAppend(); + if (line2.startsWith(".end ")) { + break; + } + } + } + return false; + } - private boolean processInstruction(String line) { - if (mFirstInstruction) { - mOut.append(".prologue\n"); - mFirstInstruction = false; - } - mOut.append(".line ").append(mIt.nextIndex()).append('\n').append(line) - .append('\n'); + private boolean processInstruction(String line) { + if (mFirstInstruction) { + mOut.append(".prologue\n"); + mFirstInstruction = false; + } + mOut.append(".line ").append(mIt.nextIndex()).append('\n').append(line) + .append('\n'); - return false; - } + return false; + } - private String next() { - return mIt.next().split("//", 2)[1].trim(); - } + private String next() { + return mIt.next().split("//", 2)[1].trim(); + } - private String nextAndAppend() { - String line = next(); - append(line); - return line; - } + private String nextAndAppend() { + String line = next(); + append(line); + return line; + } - private void append(String append) { - mOut.append(append).append('\n'); - } + private void append(String append) { + mOut.append(append).append('\n'); + } - private final ListIterator mIt; - private final StringBuilder mOut; + private final ListIterator mIt; + private final StringBuilder mOut; - private boolean mFirstInstruction = true; - private final Set mInitializedRegisters = new HashSet(); + private boolean mFirstInstruction = true; + private final Set mInitializedRegisters = new HashSet(); - private static final Pattern REGISTER_INFO_PATTERN = Pattern - .compile("((?:p|v)\\d+)=\\(([^,)]+)([^)]*)\\);"); + private static final Pattern REGISTER_INFO_PATTERN = Pattern + .compile("((?:p|v)\\d+)=\\(([^,)]+)([^)]*)\\);"); } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java index 31971046..29bac1be 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java @@ -36,37 +36,37 @@ import org.jf.dexlib2.writer.io.FileDataStore; */ public class SmaliBuilder { - public static void build(ExtFile smaliDir, File dexFile, - HashMap flags) throws AndrolibException { - new SmaliBuilder(smaliDir, dexFile, flags).build(); - } + public static void build(ExtFile smaliDir, File dexFile, + HashMap flags) throws AndrolibException { + new SmaliBuilder(smaliDir, dexFile, flags).build(); + } - private SmaliBuilder(ExtFile smaliDir, File dexFile, - HashMap flags) { - mSmaliDir = smaliDir; - mDexFile = dexFile; - mFlags = flags; - } + private SmaliBuilder(ExtFile smaliDir, File dexFile, + HashMap flags) { + mSmaliDir = smaliDir; + mDexFile = dexFile; + mFlags = flags; + } - private void build() throws AndrolibException { - try { + private void build() throws AndrolibException { + try { DexBuilder dexBuilder = DexBuilder.makeDexBuilder(); for (String fileName : mSmaliDir.getDirectory().getFiles(true)) { - buildFile(fileName, dexBuilder); - } + buildFile(fileName, dexBuilder); + } dexBuilder.writeTo(new FileDataStore( new File(mDexFile.getAbsolutePath()))); - } catch (IOException | DirectoryException ex) { - throw new AndrolibException(ex); - } - } + } catch (IOException | DirectoryException ex) { + throw new AndrolibException(ex); + } + } - private void buildFile(String fileName, DexBuilder dexBuilder) throws AndrolibException, - IOException { - File inFile = new File(mSmaliDir, fileName); - InputStream inStream = new FileInputStream(inFile); + private void buildFile(String fileName, DexBuilder dexBuilder) throws AndrolibException, + IOException { + File inFile = new File(mSmaliDir, fileName); + InputStream inStream = new FileInputStream(inFile); - if (fileName.endsWith(".smali")) { + if (fileName.endsWith(".smali")) { try { if (!SmaliMod.assembleSmaliFile(inFile,dexBuilder, false, false)) { throw new AndrolibException("Could not smali file: " + fileName); @@ -74,41 +74,41 @@ public class SmaliBuilder { } catch (IOException | RecognitionException ex) { throw new AndrolibException(ex); } - return; - } - if (!fileName.endsWith(".java")) { - LOGGER.warning("Unknown file type, ignoring: " + inFile); - return; - } + return; + } + if (!fileName.endsWith(".java")) { + LOGGER.warning("Unknown file type, ignoring: " + inFile); + return; + } - StringBuilder out = new StringBuilder(); - List lines = IOUtils.readLines(inStream); + StringBuilder out = new StringBuilder(); + List lines = IOUtils.readLines(inStream); - if (!mFlags.get("debug")) { - final String[] linesArray = lines.toArray(new String[0]); - for (int i = 1; i < linesArray.length - 1; i++) { - out.append(linesArray[i].split("//", 2)[1]).append('\n'); - } - } else { - lines.remove(lines.size() - 1); - ListIterator it = lines.listIterator(1); + if (!mFlags.get("debug")) { + final String[] linesArray = lines.toArray(new String[0]); + for (int i = 1; i < linesArray.length - 1; i++) { + out.append(linesArray[i].split("//", 2)[1]).append('\n'); + } + } else { + lines.remove(lines.size() - 1); + ListIterator it = lines.listIterator(1); - out.append(".source \"").append(inFile.getName()).append("\"\n"); - while (it.hasNext()) { - String line = it.next().split("//", 2)[1].trim(); - if (line.isEmpty() || line.charAt(0) == '#' - || line.startsWith(".source")) { - continue; - } - if (line.startsWith(".method ")) { - it.previous(); - DebugInjector.inject(it, out); - continue; - } + out.append(".source \"").append(inFile.getName()).append("\"\n"); + while (it.hasNext()) { + String line = it.next().split("//", 2)[1].trim(); + if (line.isEmpty() || line.charAt(0) == '#' + || line.startsWith(".source")) { + continue; + } + if (line.startsWith(".method ")) { + it.previous(); + DebugInjector.inject(it, out); + continue; + } - out.append(line).append('\n'); - } - } + out.append(line).append('\n'); + } + } try { if (!SmaliMod.assembleSmaliFile(out.toString(),dexBuilder, false, false, inFile)) { @@ -117,12 +117,12 @@ public class SmaliBuilder { } catch (IOException | RecognitionException ex) { throw new AndrolibException(ex); } - } + } - private final ExtFile mSmaliDir; - private final File mDexFile; - private final HashMap mFlags; + private final ExtFile mSmaliDir; + private final File mDexFile; + private final HashMap mFlags; - private final static Logger LOGGER = Logger.getLogger(SmaliBuilder.class - .getName()); + private final static Logger LOGGER = Logger.getLogger(SmaliBuilder.class + .getName()); } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliDecoder.java index be96716f..af43f723 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliDecoder.java @@ -41,23 +41,23 @@ import java.nio.file.attribute.BasicFileAttributes; */ public class SmaliDecoder { - public static void decode(File apkFile, File outDir, boolean debug, String debugLinePrefix, - boolean bakdeb, int api) throws AndrolibException { - new SmaliDecoder(apkFile, outDir, debug, debugLinePrefix, bakdeb, api).decode(); - } + public static void decode(File apkFile, File outDir, boolean debug, String debugLinePrefix, + boolean bakdeb, int api) throws AndrolibException { + new SmaliDecoder(apkFile, outDir, debug, debugLinePrefix, bakdeb, api).decode(); + } - private SmaliDecoder(File apkFile, File outDir, boolean debug, String debugLinePrefix, - boolean bakdeb, int api) { - mApkFile = apkFile; - mOutDir = outDir.toPath(); - mDebug = debug; + private SmaliDecoder(File apkFile, File outDir, boolean debug, String debugLinePrefix, + boolean bakdeb, int api) { + mApkFile = apkFile; + mOutDir = outDir.toPath(); + mDebug = debug; mDebugLinePrefix = debugLinePrefix; - mBakDeb = bakdeb; + mBakDeb = bakdeb; mApi = api; - } + } - private void decode() throws AndrolibException { - try { + private void decode() throws AndrolibException { + try { ClassPath.dontLoadClassPath = mDebug; baksmaliOptions options = new baksmaliOptions(); @@ -106,16 +106,16 @@ public class SmaliDecoder { if (mDebug) { Files.walkFileTree(mOutDir, new SmaliFileVisitor()); } - } catch (IOException ex) { - throw new AndrolibException(ex); - } - } + } catch (IOException ex) { + throw new AndrolibException(ex); + } + } - private final File mApkFile; - private final Path mOutDir; - private final boolean mDebug; + private final File mApkFile; + private final Path mOutDir; + private final boolean mDebug; private final String mDebugLinePrefix; - private final boolean mBakDeb; + private final boolean mBakDeb; private final int mApi; diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/TypeName.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/TypeName.java index 78aba508..29480fa3 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/TypeName.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/TypeName.java @@ -30,99 +30,99 @@ import java.util.List; * @author Ryszard Wiśniewski */ public class TypeName { - public final String package_; - public final String type; - public final String innerType; - public final int array; + public final String package_; + public final String type; + public final String innerType; + public final int array; - public TypeName(String type, int array) { - this(null, type, null, array); - } + public TypeName(String type, int array) { + this(null, type, null, array); + } - public TypeName(String package_, String type, String innerType, int array) { - this.package_ = package_; - this.type = type; - this.innerType = innerType; - this.array = array; - } + public TypeName(String package_, String type, String innerType, int array) { + this.package_ = package_; + this.type = type; + this.innerType = innerType; + this.array = array; + } - public String getShortenedName() { - return getName("java.lang".equals(package_), isFileOwner()); - } + public String getShortenedName() { + return getName("java.lang".equals(package_), isFileOwner()); + } - public String getName() { - return getName(false, false); - } + public String getName() { + return getName(false, false); + } - public String getName(boolean excludePackage, boolean separateInner) { - String name = (package_ == null || excludePackage ? "" : package_ + '.') - + type - + (innerType != null ? (separateInner ? '$' : '.') + innerType - : ""); - for (int i = 0; i < array; i++) { - name += "[]"; - } - return name; - } + public String getName(boolean excludePackage, boolean separateInner) { + String name = (package_ == null || excludePackage ? "" : package_ + '.') + + type + + (innerType != null ? (separateInner ? '$' : '.') + innerType + : ""); + for (int i = 0; i < array; i++) { + name += "[]"; + } + return name; + } - public String getJavaFilePath() { - return getFilePath(isFileOwner()) + ".java"; - } + public String getJavaFilePath() { + return getFilePath(isFileOwner()) + ".java"; + } - public String getSmaliFilePath() { - return getFilePath(true) + ".smali"; - } + public String getSmaliFilePath() { + return getFilePath(true) + ".smali"; + } - public String getFilePath(boolean separateInner) { - return package_.replace('.', File.separatorChar) + File.separatorChar - + type + (separateInner && isInner() ? "$" + innerType : ""); - } + public String getFilePath(boolean separateInner) { + return package_.replace('.', File.separatorChar) + File.separatorChar + + type + (separateInner && isInner() ? "$" + innerType : ""); + } - public boolean isInner() { - return innerType != null; - } + public boolean isInner() { + return innerType != null; + } - public boolean isArray() { - return array != 0; - } + public boolean isArray() { + return array != 0; + } - public boolean isFileOwner() { - if (mIsFileOwner == null) { - mIsFileOwner = true; - if (isInner()) { - char c = innerType.charAt(0); - if (c < '0' || c > '9') { - mIsFileOwner = false; - } - } - } - return mIsFileOwner; - } + public boolean isFileOwner() { + if (mIsFileOwner == null) { + mIsFileOwner = true; + if (isInner()) { + char c = innerType.charAt(0); + if (c < '0' || c > '9') { + mIsFileOwner = false; + } + } + } + return mIsFileOwner; + } - @Override - public String toString() { - return getName(); - } + @Override + public String toString() { + return getName(); + } - public static TypeName fromInternalName(String internal) - throws AndrolibException { - Duo duo = fetchFromInternalName(internal); - if (duo.m2 != internal.length()) { - throw new AndrolibException("Invalid internal name: " + internal); - } - return duo.m1; - } + public static TypeName fromInternalName(String internal) + throws AndrolibException { + Duo duo = fetchFromInternalName(internal); + if (duo.m2 != internal.length()) { + throw new AndrolibException("Invalid internal name: " + internal); + } + return duo.m1; + } - public static List listFromInternalName(String internal) - throws AndrolibException { - List types = new ArrayList(); - while (!internal.isEmpty()) { - Duo duo = fetchFromInternalName(internal); - types.add(duo.m1); - internal = internal.substring(duo.m2); - } - return types; - } + public static List listFromInternalName(String internal) + throws AndrolibException { + List types = new ArrayList(); + while (!internal.isEmpty()) { + Duo duo = fetchFromInternalName(internal); + types.add(duo.m1); + internal = internal.substring(duo.m2); + } + return types; + } public static TypeName fromPath(Path path) { List parts = new ArrayList<>(path.getNameCount()); @@ -145,68 +145,68 @@ public class TypeName { return new TypeName(Joiner.on('.').join(parts), type, innerType, array); } - public static Duo fetchFromInternalName(String internal) - throws AndrolibException { - String origInternal = internal; - int array = 0; + public static Duo fetchFromInternalName(String internal) + throws AndrolibException { + String origInternal = internal; + int array = 0; - boolean isArray = false; - do { - if (internal.isEmpty()) { - throw new AndrolibException("Invalid internal name: " - + origInternal); - } - isArray = internal.charAt(0) == '['; - if (isArray) { - array++; - internal = internal.substring(1); - } - } while (isArray); + boolean isArray = false; + do { + if (internal.isEmpty()) { + throw new AndrolibException("Invalid internal name: " + + origInternal); + } + isArray = internal.charAt(0) == '['; + if (isArray) { + array++; + internal = internal.substring(1); + } + } while (isArray); - int length = array + 1; - String type; - switch (internal.charAt(0)) { - case 'B': - type = "byte"; - break; - case 'C': - type = "char"; - break; - case 'D': - type = "double"; - break; - case 'F': - type = "float"; - break; - case 'I': - type = "int"; - break; - case 'J': - type = "long"; - break; - case 'S': - type = "short"; - break; - case 'Z': - type = "boolean"; - break; - case 'V': - type = "void"; - break; - case 'L': - int pos = internal.indexOf(';'); - if (pos == -1) { - throw new AndrolibException("Invalid internal name: " - + origInternal); - } - return new Duo<>(fromNameParts(Arrays.asList(internal.substring(1, pos).split("/")), array), length + pos); - default: - throw new AndrolibException("Invalid internal name: " - + origInternal); - } + int length = array + 1; + String type; + switch (internal.charAt(0)) { + case 'B': + type = "byte"; + break; + case 'C': + type = "char"; + break; + case 'D': + type = "double"; + break; + case 'F': + type = "float"; + break; + case 'I': + type = "int"; + break; + case 'J': + type = "long"; + break; + case 'S': + type = "short"; + break; + case 'Z': + type = "boolean"; + break; + case 'V': + type = "void"; + break; + case 'L': + int pos = internal.indexOf(';'); + if (pos == -1) { + throw new AndrolibException("Invalid internal name: " + + origInternal); + } + return new Duo<>(fromNameParts(Arrays.asList(internal.substring(1, pos).split("/")), array), length + pos); + default: + throw new AndrolibException("Invalid internal name: " + + origInternal); + } - return new Duo<>(new TypeName(null, type, null, array), length); - } + return new Duo<>(new TypeName(null, type, null, array), length); + } - private Boolean mIsFileOwner; + private Boolean mIsFileOwner; }