Converted bools of (update,framework,debug,verbose,original) into HashMap

This commit is contained in:
Connor Tumbleson 2012-09-17 16:07:26 -05:00
parent 97d8134eb0
commit bc10186af0
5 changed files with 100 additions and 75 deletions

View File

@ -26,6 +26,7 @@ import brut.androlib.err.OutDirExistsException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.logging.*; import java.util.logging.*;
/** /**
@ -152,9 +153,16 @@ public class Main {
private static void cmdBuild(String[] args) throws InvalidArgsError, private static void cmdBuild(String[] args) throws InvalidArgsError,
AndrolibException { AndrolibException {
boolean forceBuildAll = false;
boolean debug = false; // hold all the fields
boolean verbose = false; HashMap<String, Boolean> flags = new HashMap<String, Boolean>();
flags.put("forceBuildAll", false);
flags.put("debug", false);
flags.put("verbose", false);
flags.put("injectOriginal", false);
flags.put("framework", false);
flags.put("update", false);
int i; int i;
for (i = 0; i < args.length; i++) { for (i = 0; i < args.length; i++) {
String opt = args[i]; String opt = args[i];
@ -162,11 +170,13 @@ public class Main {
break; break;
} }
if ("-f".equals(opt) || "--force-all".equals(opt)) { if ("-f".equals(opt) || "--force-all".equals(opt)) {
forceBuildAll = true; flags.put("forceBuildA", true);
} else if ("-d".equals(opt) || "--debug".equals(opt)) { } else if ("-d".equals(opt) || "--debug".equals(opt)) {
debug = true; flags.put("debug", true);
} else if ("-v".equals(opt) || "--verbose".equals(opt)) { } else if ("-v".equals(opt) || "--verbose".equals(opt)) {
verbose = true; flags.put("verbose", true);
} else if("-o".equals(opt) || "--original".equals(opt)) {
flags.put("injectOriginal", true);
} else { } else {
throw new InvalidArgsError(); throw new InvalidArgsError();
} }
@ -187,8 +197,7 @@ public class Main {
throw new InvalidArgsError(); throw new InvalidArgsError();
} }
new Androlib().build(new File(appDirName), outFile, forceBuildAll, new Androlib().build(new File(appDirName), outFile, flags);
debug, verbose);
} }
private static void cmdInstallFramework(String[] args) private static void cmdInstallFramework(String[] args)
@ -239,7 +248,7 @@ public class Main {
" -d, --debug\n" + " -d, --debug\n" +
" Decode in debug mode. Check project page for more info.\n" + " Decode in debug mode. Check project page for more info.\n" +
" -b, --no-debug-info\n" + " -b, --no-debug-info\n" +
" Baksmali -- don't write out debug info (.local, .param, .line, etc.).\n" + " Baksmali -- don't write out debug info (.local, .param, .line, etc.)\n" +
" -f, --force\n" + " -f, --force\n" +
" Force delete destination directory.\n" + " Force delete destination directory.\n" +
" -t <tag>, --frame-tag <tag>\n" + " -t <tag>, --frame-tag <tag>\n" +
@ -266,6 +275,8 @@ public class Main {
" Skip changes detection and build all files.\n" + " Skip changes detection and build all files.\n" +
" -d, --debug\n" + " -d, --debug\n" +
" Build in debug mode. Check project page for more info.\n" + " Build in debug mode. Check project page for more info.\n" +
" -o, --original\n" +
" Build resources into original APK. Retains signature." +
"\n" + "\n" +
" if|install-framework <framework.apk> [<tag>]\n" + " if|install-framework <framework.apk> [<tag>]\n" +
" Install framework file to your system.\n" + " Install framework file to your system.\n" +

View File

@ -28,6 +28,7 @@ import brut.directory.*;
import brut.util.BrutIO; import brut.util.BrutIO;
import brut.util.OS; import brut.util.OS;
import java.io.*; import java.io.*;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -169,16 +170,16 @@ public class Androlib {
} }
} }
public void build(File appDir, File outFile, boolean forceBuildAll, public void build(File appDir, File outFile,
boolean debug, boolean verbose) throws AndrolibException { HashMap<String, Boolean> flags) throws AndrolibException {
build(new ExtFile(appDir), outFile, forceBuildAll, debug, verbose); build(new ExtFile(appDir), outFile, flags);
} }
public void build(ExtFile appDir, File outFile, boolean forceBuildAll, public void build(ExtFile appDir, File outFile,
boolean debug, boolean verbose) throws AndrolibException { HashMap<String, Boolean> flags) throws AndrolibException {
Map<String, Object> meta = readMetaFile(appDir); Map<String, Object> meta = readMetaFile(appDir);
Object t1 = meta.get("isFrameworkApk"); Object t1 = meta.get("isFrameworkApk");
boolean framework = t1 == null ? false : (Boolean) t1; flags.put("framework", t1 == null ? false : (Boolean) t1);
mAndRes.setSdkInfo((Map<String, String>) meta.get("sdkInfo")); mAndRes.setSdkInfo((Map<String, String>) meta.get("sdkInfo"));
if (outFile == null) { if (outFile == null) {
@ -188,35 +189,35 @@ public class Androlib {
} }
new File(appDir, APK_DIRNAME).mkdirs(); new File(appDir, APK_DIRNAME).mkdirs();
buildSources(appDir, forceBuildAll, debug); buildSources(appDir, flags);
buildResources(appDir, forceBuildAll, framework, buildResources(appDir, flags,
(Map<String, Object>) meta.get("usesFramework")); (Map<String, Object>) meta.get("usesFramework"));
buildLib(appDir, forceBuildAll); buildLib(appDir, flags);
buildApk(appDir, outFile, framework, verbose); buildApk(appDir, outFile,flags);
} }
public void buildSources(File appDir, boolean forceBuildAll, boolean debug) public void buildSources(File appDir, HashMap<String, Boolean> flags)
throws AndrolibException { throws AndrolibException {
if (! buildSourcesRaw(appDir, forceBuildAll, debug) if (! buildSourcesRaw(appDir, flags)
&& ! buildSourcesSmali(appDir, forceBuildAll, debug) && ! buildSourcesSmali(appDir, flags)
&& ! buildSourcesJava(appDir, forceBuildAll, debug) && ! buildSourcesJava(appDir, flags)
) { ) {
LOGGER.warning("Could not find sources"); LOGGER.warning("Could not find sources");
} }
} }
public boolean buildSourcesRaw(File appDir, boolean forceBuildAll, public boolean buildSourcesRaw(File appDir,
boolean debug) throws AndrolibException { HashMap<String, Boolean> flags) throws AndrolibException {
try { try {
File working = new File(appDir, "classes.dex"); File working = new File(appDir, "classes.dex");
if (! working.exists()) { if (! working.exists()) {
return false; return false;
} }
if (debug) { if (flags.get("debug")) {
LOGGER.warning("Debug mode not available."); LOGGER.warning("Debug mode not available.");
} }
File stored = new File(appDir, APK_DIRNAME + "/classes.dex"); File stored = new File(appDir, APK_DIRNAME + "/classes.dex");
if (forceBuildAll || isModified(working, stored)) { if (flags.get("forceBuildAll") || isModified(working, stored)) {
LOGGER.info("Copying classes.dex file..."); LOGGER.info("Copying classes.dex file...");
BrutIO.copyAndClose(new FileInputStream(working), BrutIO.copyAndClose(new FileInputStream(working),
new FileOutputStream(stored)); new FileOutputStream(stored));
@ -227,35 +228,35 @@ public class Androlib {
} }
} }
public boolean buildSourcesSmali(File appDir, boolean forceBuildAll, public boolean buildSourcesSmali(File appDir,
boolean debug) throws AndrolibException { HashMap<String, Boolean> flags) throws AndrolibException {
ExtFile smaliDir = new ExtFile(appDir, "smali"); ExtFile smaliDir = new ExtFile(appDir, "smali");
if (! smaliDir.exists()) { if (! smaliDir.exists()) {
return false; return false;
} }
File dex = new File(appDir, APK_DIRNAME + "/classes.dex"); File dex = new File(appDir, APK_DIRNAME + "/classes.dex");
if (! forceBuildAll) { if (! flags.get("forceBuildAll")) {
LOGGER.info("Checking whether sources has changed..."); LOGGER.info("Checking whether sources has changed...");
} }
if (forceBuildAll || isModified(smaliDir, dex)) { if (flags.get("forceBuildAll") || isModified(smaliDir, dex)) {
LOGGER.info("Smaling..."); LOGGER.info("Smaling...");
dex.delete(); dex.delete();
SmaliBuilder.build(smaliDir, dex, debug); SmaliBuilder.build(smaliDir, dex, flags);
} }
return true; return true;
} }
public boolean buildSourcesJava(File appDir, boolean forceBuildAll, public boolean buildSourcesJava(File appDir,
boolean debug) throws AndrolibException { HashMap<String, Boolean> flags) throws AndrolibException {
File javaDir = new File(appDir, "src"); File javaDir = new File(appDir, "src");
if (! javaDir.exists()) { if (! javaDir.exists()) {
return false; return false;
} }
File dex = new File(appDir, APK_DIRNAME + "/classes.dex"); File dex = new File(appDir, APK_DIRNAME + "/classes.dex");
if (! forceBuildAll) { if (! flags.get("forceBuildAll")) {
LOGGER.info("Checking whether sources has changed..."); LOGGER.info("Checking whether sources has changed...");
} }
if (forceBuildAll || isModified(javaDir, dex)) { if (flags.get("forceBuildAll") || isModified(javaDir, dex)) {
LOGGER.info("Building java sources..."); LOGGER.info("Building java sources...");
dex.delete(); dex.delete();
new AndrolibJava().build(javaDir, dex); new AndrolibJava().build(javaDir, dex);
@ -263,29 +264,27 @@ public class Androlib {
return true; return true;
} }
public void buildResources(ExtFile appDir, boolean forceBuildAll, public void buildResources(ExtFile appDir, HashMap<String, Boolean> flags,
boolean framework, Map<String, Object> usesFramework) Map<String, Object> usesFramework)
throws AndrolibException { throws AndrolibException {
if (! buildResourcesRaw(appDir, forceBuildAll) if (! buildResourcesRaw(appDir, flags)
&& ! buildResourcesFull(appDir, forceBuildAll, framework, && ! buildResourcesFull(appDir, flags, usesFramework)
usesFramework) && ! buildManifest(appDir, flags, usesFramework)) {
&& ! buildManifest(appDir, forceBuildAll, framework,
usesFramework)) {
LOGGER.warning("Could not find resources"); LOGGER.warning("Could not find resources");
} }
} }
public boolean buildResourcesRaw(ExtFile appDir, boolean forceBuildAll) public boolean buildResourcesRaw(ExtFile appDir, HashMap<String, Boolean> flags)
throws AndrolibException { throws AndrolibException {
try { try {
if (! new File(appDir, "resources.arsc").exists()) { if (! new File(appDir, "resources.arsc").exists()) {
return false; return false;
} }
File apkDir = new File(appDir, APK_DIRNAME); File apkDir = new File(appDir, APK_DIRNAME);
if (! forceBuildAll) { if (! flags.get("forceBuildAll")) {
LOGGER.info("Checking whether resources has changed..."); LOGGER.info("Checking whether resources has changed...");
} }
if (forceBuildAll || isModified( if (flags.get("forceBuildAll") || isModified(
newFiles(APK_RESOURCES_FILENAMES, appDir), newFiles(APK_RESOURCES_FILENAMES, appDir),
newFiles(APK_RESOURCES_FILENAMES, apkDir))) { newFiles(APK_RESOURCES_FILENAMES, apkDir))) {
LOGGER.info("Copying raw resources..."); LOGGER.info("Copying raw resources...");
@ -298,18 +297,18 @@ public class Androlib {
} }
} }
public boolean buildResourcesFull(File appDir, boolean forceBuildAll, public boolean buildResourcesFull(File appDir, HashMap<String, Boolean> flags,
boolean framework, Map<String, Object> usesFramework) Map<String, Object> usesFramework)
throws AndrolibException { throws AndrolibException {
try { try {
if (! new File(appDir, "res").exists()) { if (! new File(appDir, "res").exists()) {
return false; return false;
} }
if (! forceBuildAll) { if (! flags.get("forceBuildAll")) {
LOGGER.info("Checking whether resources has changed..."); LOGGER.info("Checking whether resources has changed...");
} }
File apkDir = new File(appDir, APK_DIRNAME); File apkDir = new File(appDir, APK_DIRNAME);
if (forceBuildAll || isModified( if (flags.get("forceBuildAll") || isModified(
newFiles(APP_RESOURCES_FILENAMES, appDir), newFiles(APP_RESOURCES_FILENAMES, appDir),
newFiles(APK_RESOURCES_FILENAMES, apkDir))) { newFiles(APK_RESOURCES_FILENAMES, apkDir))) {
LOGGER.info("Building resources..."); LOGGER.info("Building resources...");
@ -326,7 +325,7 @@ public class Androlib {
new File(appDir, "AndroidManifest.xml"), new File(appDir, "AndroidManifest.xml"),
new File(appDir, "res"), new File(appDir, "res"),
ninePatch, null, parseUsesFramework(usesFramework), ninePatch, null, parseUsesFramework(usesFramework),
false, framework, false flags
); );
Directory tmpDir = new ExtFile(apkFile).getDirectory(); Directory tmpDir = new ExtFile(apkFile).getDirectory();
@ -342,7 +341,7 @@ public class Androlib {
} }
} }
public boolean buildManifestRaw(ExtFile appDir, boolean forceBuildAll) public boolean buildManifestRaw(ExtFile appDir, HashMap<String, Boolean> flags)
throws AndrolibException { throws AndrolibException {
try { try {
File apkDir = new File(appDir, APK_DIRNAME); File apkDir = new File(appDir, APK_DIRNAME);
@ -355,18 +354,18 @@ public class Androlib {
} }
} }
public boolean buildManifest(ExtFile appDir, boolean forceBuildAll, public boolean buildManifest(ExtFile appDir, HashMap<String, Boolean> flags,
boolean framework, Map<String, Object> usesFramework) Map<String, Object> usesFramework)
throws AndrolibException { throws AndrolibException {
try { try {
if (! new File(appDir, "AndroidManifest.xml").exists()) { if (! new File(appDir, "AndroidManifest.xml").exists()) {
return false; return false;
} }
if (! forceBuildAll) { if (! flags.get("forceBuildAll")) {
LOGGER.info("Checking whether resources has changed..."); LOGGER.info("Checking whether resources has changed...");
} }
File apkDir = new File(appDir, APK_DIRNAME); File apkDir = new File(appDir, APK_DIRNAME);
if (forceBuildAll || isModified( if (flags.get("forceBuildAll") || isModified(
newFiles(APK_MANIFEST_FILENAMES, appDir), newFiles(APK_MANIFEST_FILENAMES, appDir),
newFiles(APK_MANIFEST_FILENAMES, apkDir))) { newFiles(APK_MANIFEST_FILENAMES, apkDir))) {
LOGGER.info("Building AndroidManifest.xml..."); LOGGER.info("Building AndroidManifest.xml...");
@ -384,7 +383,7 @@ public class Androlib {
new File(appDir, "AndroidManifest.xml"), new File(appDir, "AndroidManifest.xml"),
null, null,
ninePatch, null, parseUsesFramework(usesFramework), ninePatch, null, parseUsesFramework(usesFramework),
false, framework, false flags
); );
Directory tmpDir = new ExtFile(apkFile).getDirectory(); Directory tmpDir = new ExtFile(apkFile).getDirectory();
@ -397,18 +396,18 @@ public class Androlib {
throw new AndrolibException(ex); throw new AndrolibException(ex);
} catch (AndrolibException ex) { } catch (AndrolibException ex) {
LOGGER.warning("Parse AndroidManifest.xml failed, treat it as raw file."); LOGGER.warning("Parse AndroidManifest.xml failed, treat it as raw file.");
return buildManifestRaw(appDir, forceBuildAll); return buildManifestRaw(appDir, flags);
} }
} }
public void buildLib(File appDir, boolean forceBuildAll) public void buildLib(File appDir, HashMap<String, Boolean> flags)
throws AndrolibException { throws AndrolibException {
File working = new File(appDir, "lib"); File working = new File(appDir, "lib");
if (! working.exists()) { if (! working.exists()) {
return; return;
} }
File stored = new File(appDir, APK_DIRNAME + "/lib"); File stored = new File(appDir, APK_DIRNAME + "/lib");
if (forceBuildAll || isModified(working, stored)) { if (flags.get("forceBuildAll") || isModified(working, stored)) {
LOGGER.info("Copying libs..."); LOGGER.info("Copying libs...");
try { try {
OS.rmdir(stored); OS.rmdir(stored);
@ -419,7 +418,7 @@ public class Androlib {
} }
} }
public void buildApk(File appDir, File outApk, boolean framework, boolean verbose) public void buildApk(File appDir, File outApk, HashMap<String, Boolean> flags)
throws AndrolibException { throws AndrolibException {
LOGGER.info("Building apk file..."); LOGGER.info("Building apk file...");
if (outApk.exists()) { if (outApk.exists()) {
@ -435,7 +434,7 @@ public class Androlib {
assetDir = null; assetDir = null;
} }
mAndRes.aaptPackage(outApk, null, null, mAndRes.aaptPackage(outApk, null, null,
new File(appDir, APK_DIRNAME), assetDir, null, false, framework, verbose); new File(appDir, APK_DIRNAME), assetDir, null, flags);
} }
public void publicizeResources(File arscFile) throws AndrolibException { public void publicizeResources(File arscFile) throws AndrolibException {

View File

@ -192,18 +192,18 @@ final public class AndrolibResources {
} }
public void aaptPackage(File apkFile, File manifest, File resDir, public void aaptPackage(File apkFile, File manifest, File resDir,
File rawDir, File assetDir, File[] include, File rawDir, File assetDir, File[] include, HashMap<String, Boolean> flags)
boolean update, boolean framework, boolean verbose) throws AndrolibException { throws AndrolibException {
List<String> cmd = new ArrayList<String>(); List<String> cmd = new ArrayList<String>();
cmd.add("aapt"); cmd.add("aapt");
cmd.add("p"); cmd.add("p");
if (verbose) { if (flags.get("verbose")) {
cmd.add("-v"); cmd.add("-v");
} }
if (update) { if (flags.get("update")) {
cmd.add("-u"); cmd.add("-u");
} }
if (mMinSdkVersion != null) { if (mMinSdkVersion != null) {
@ -221,7 +221,7 @@ final public class AndrolibResources {
cmd.add("-F"); cmd.add("-F");
cmd.add(apkFile.getAbsolutePath()); cmd.add(apkFile.getAbsolutePath());
if (framework) { if (flags.get("framework")) {
cmd.add("-x"); cmd.add("-x");
// cmd.add("-0"); // cmd.add("-0");
// cmd.add("arsc"); // cmd.add("arsc");

View File

@ -20,6 +20,7 @@ import brut.androlib.AndrolibException;
import brut.androlib.res.util.ExtFile; import brut.androlib.res.util.ExtFile;
import brut.directory.DirectoryException; import brut.directory.DirectoryException;
import java.io.*; import java.io.*;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -30,15 +31,16 @@ import org.apache.commons.io.IOUtils;
*/ */
public class SmaliBuilder { public class SmaliBuilder {
public static void build(ExtFile smaliDir, File dexFile, boolean debug) public static void build(ExtFile smaliDir, File dexFile,
HashMap<String, Boolean> flags)
throws AndrolibException { throws AndrolibException {
new SmaliBuilder(smaliDir, dexFile, debug).build(); new SmaliBuilder(smaliDir, dexFile, flags).build();
} }
private SmaliBuilder(ExtFile smaliDir, File dexFile, boolean debug) { private SmaliBuilder(ExtFile smaliDir, File dexFile, HashMap<String, Boolean> flags) {
mSmaliDir = smaliDir; mSmaliDir = smaliDir;
mDexFile = dexFile; mDexFile = dexFile;
mDebug = debug; mFlags = flags;
} }
private void build() throws AndrolibException { private void build() throws AndrolibException {
@ -72,7 +74,7 @@ public class SmaliBuilder {
StringBuilder out = new StringBuilder(); StringBuilder out = new StringBuilder();
List<String> lines = IOUtils.readLines(inStream); List<String> lines = IOUtils.readLines(inStream);
if (!mDebug) { if (!mFlags.containsKey("debug")) {
final String[] linesArray = lines.toArray(new String[0]); final String[] linesArray = lines.toArray(new String[0]);
for (int i = 2; i < linesArray.length - 2; i++) { for (int i = 2; i < linesArray.length - 2; i++) {
out.append(linesArray[i]).append('\n'); out.append(linesArray[i]).append('\n');
@ -104,7 +106,7 @@ public class SmaliBuilder {
private final ExtFile mSmaliDir; private final ExtFile mSmaliDir;
private final File mDexFile; private final File mDexFile;
private final boolean mDebug; private final HashMap<String, Boolean> mFlags;
private DexFileBuilder mDexBuilder; private DexFileBuilder mDexBuilder;

View File

@ -20,6 +20,7 @@ import brut.androlib.res.util.ExtFile;
import brut.common.BrutException; import brut.common.BrutException;
import brut.util.OS; import brut.util.OS;
import java.io.*; import java.io.*;
import java.util.HashMap;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.custommonkey.xmlunit.*; import org.custommonkey.xmlunit.*;
import org.junit.*; import org.junit.*;
@ -44,7 +45,7 @@ public class BuildAndDecodeTest {
"brut/apktool/testapp/", sTestOrigDir); "brut/apktool/testapp/", sTestOrigDir);
LOGGER.info("Building testapp.apk..."); LOGGER.info("Building testapp.apk...");
new Androlib().build(sTestOrigDir, testApk, false, false, false); new Androlib().build(sTestOrigDir, testApk, BuildAndDecodeTest.returnStock());
LOGGER.info("Decoding testapp.apk..."); LOGGER.info("Decoding testapp.apk...");
ApkDecoder apkDecoder = new ApkDecoder(testApk); ApkDecoder apkDecoder = new ApkDecoder(testApk);
@ -154,6 +155,18 @@ public class BuildAndDecodeTest {
diff.getAllDifferences().toString(), diff.similar()); diff.getAllDifferences().toString(), diff.similar());
} }
private static HashMap<String, Boolean> returnStock() throws BrutException {
HashMap<String, Boolean> tmp = new HashMap<String, Boolean>();
tmp.put("forceBuildAll", false);
tmp.put("debug", false);
tmp.put("verbose", false);
tmp.put("injectOriginal", false);
tmp.put("framework", false);
tmp.put("update", false);
return tmp;
}
private static ExtFile sTmpDir; private static ExtFile sTmpDir;
private static ExtFile sTestOrigDir; private static ExtFile sTestOrigDir;
private static ExtFile sTestNewDir; private static ExtFile sTestNewDir;