Skip to content

Commit

Permalink
Merge pull request #1020 from agrieve/stored-entries
Browse files Browse the repository at this point in the history
Adds doNotCompress list to apktool.yml
  • Loading branch information
iBotPeaches committed Aug 15, 2015
2 parents 2033e30 + 392420c commit 5c6f325
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 47 deletions.
43 changes: 27 additions & 16 deletions brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.io.*;
import java.util.*;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
Expand Down Expand Up @@ -158,6 +159,22 @@ public void decodeRawFiles(ExtFile apkFile, File outDir)
}
}

public void recordUncompressedFiles(ExtFile apkFile, Collection<String> uncompressedFiles) throws AndrolibException {
try {
Directory unk = apkFile.getDirectory();
Set<String> files = unk.getFiles(true);
for (String file : files) {
if (isAPKFileNames(file) && !NO_COMPRESS_PATTERN.matcher(file).find()) {
if (unk.getCompressionLevel(file) == 0) {
uncompressedFiles.add(file);
}
}
}
} catch (DirectoryException ex) {
throw new AndrolibException(ex);
}
}

private boolean isAPKFileNames(String file) {
for (String apkFile : APK_STANDARD_ALL_FILENAMES) {
if (apkFile.equals(file) || file.startsWith(apkFile + "/")) {
Expand All @@ -171,13 +188,8 @@ public void decodeUnknownFiles(ExtFile apkFile, File outDir, ResTable resTable)
throws AndrolibException {
LOGGER.info("Copying unknown files...");
File unknownOut = new File(outDir, UNK_DIRNAME);
ZipEntry invZipFile;

// have to use container of ZipFile to help identify compression type
// with regular looping of apkFile for easy copy
try {
Directory unk = apkFile.getDirectory();
ZipFile apkZipFile = new ZipFile(apkFile.getAbsolutePath());

// loop all items in container recursively, ignoring any that are pre-defined by aapt
Set<String> files = unk.getFiles(true);
Expand All @@ -186,19 +198,12 @@ public void decodeUnknownFiles(ExtFile apkFile, File outDir, ResTable resTable)

// copy file out of archive into special "unknown" folder
unk.copyToDir(unknownOut, file);
try {
invZipFile = apkZipFile.getEntry(file);

// lets record the name of the file, and its compression type
// so that we may re-include it the same way
if (invZipFile != null) {
mResUnknownFiles.addUnknownFileInfo(invZipFile.getName(), String.valueOf(invZipFile.getMethod()));
}
} catch (NullPointerException ignored) { }
// lets record the name of the file, and its compression type
// so that we may re-include it the same way
mResUnknownFiles.addUnknownFileInfo(file, String.valueOf(unk.getCompressionLevel(file)));
}
}
apkZipFile.close();
} catch (DirectoryException | IOException ex) {
} catch (DirectoryException ex) {
throw new AndrolibException(ex);
}
}
Expand Down Expand Up @@ -266,6 +271,7 @@ public void build(ExtFile appDir, File outFile)
apkOptions.resourcesAreCompressed = meta.get("compressionType") == null
? false
: Boolean.valueOf(meta.get("compressionType").toString());
apkOptions.doNotCompress = (Collection<String>) meta.get("doNotCompress");

mAndRes.setSdkInfo((Map<String, String>) meta.get("sdkInfo"));
mAndRes.setPackageId((Map<String, String>) meta.get("packageInfo"));
Expand Down Expand Up @@ -739,4 +745,9 @@ private File[] newFiles(String[] names, File dir) {
"AndroidManifest.xml" };
private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] {
"classes.dex", "AndroidManifest.xml", "resources.arsc", "res", "lib", "libs", "assets", "META-INF" };
// Taken from AOSP's frameworks/base/tools/aapt/Package.cpp
private final static Pattern NO_COMPRESS_PATTERN = Pattern.compile("\\.(" +
"jpg|jpeg|png|gif|wav|mp2|mp3|ogg|aac|mpg|mpeg|mid|midi|smf|jet|rtttl|imy|xmf|mp4|" +
"m4a|m4v|3gp|3gpp|3g2|3gpp2|amr|awb|wma|wmv)$");

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import java.io.IOException;
import java.util.*;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
Expand Down Expand Up @@ -89,8 +87,6 @@ public void decode() throws AndrolibException, IOException, DirectoryException {
LOGGER.info("Using Apktool " + Androlib.getVersion() + " on " + mApkFile.getName());

if (hasResources()) {
setCompressionMode();

switch (mDecodeResources) {
case DECODE_RESOURCES_NONE:
mAndrolib.decodeResourcesRaw(mApkFile, outDir);
Expand Down Expand Up @@ -159,6 +155,8 @@ public void decode() throws AndrolibException, IOException, DirectoryException {

mAndrolib.decodeRawFiles(mApkFile, outDir);
mAndrolib.decodeUnknownFiles(mApkFile, outDir, mResTable);
mUncompressedFiles = new ArrayList<String>();
mAndrolib.recordUncompressedFiles(mApkFile, mUncompressedFiles);
mAndrolib.writeOriginalFiles(mApkFile, outDir);
writeMetaFile();
}
Expand Down Expand Up @@ -193,18 +191,6 @@ public void setAnalysisMode(boolean mode, boolean pass) throws AndrolibException
}
}

public void setCompressionMode() throws AndrolibException, IOException {
// read the resources.arsc checking for STORED vs DEFLATE
// this will determine whether we compress on rebuild or not.
ZipFile zf = new ZipFile(mApkFile.getAbsolutePath());
ZipEntry ze = zf.getEntry("resources.arsc");
if (ze != null) {
int compression = ze.getMethod();
mCompressResources = (compression == ZipEntry.DEFLATED);
}
zf.close();
}

public void setTargetSdkVersion() throws AndrolibException, IOException {
if (mResTable == null) {
mResTable = mAndrolib.getResTable(mApkFile);
Expand Down Expand Up @@ -320,10 +306,10 @@ private void writeMetaFile() throws AndrolibException {
putSdkInfo(meta);
putPackageInfo(meta);
putVersionInfo(meta);
putCompressionInfo(meta);
putSharedLibraryInfo(meta);
}
putUnknownInfo(meta);
putFileCompressionInfo(meta);

mAndrolib.writeMetaFile(mOutDir, meta);
}
Expand Down Expand Up @@ -391,18 +377,16 @@ private void putUnknownInfo(Map<String, Object> meta) throws AndrolibException {
}
}

private void putCompressionInfo(Map<String, Object> meta) throws AndrolibException {
meta.put("compressionType", getCompressionType());
private void putFileCompressionInfo(Map<String, Object> meta) throws AndrolibException {
if (!mUncompressedFiles.isEmpty()) {
meta.put("doNotCompress", mUncompressedFiles);
}
}

private void putSharedLibraryInfo(Map<String, Object> meta) throws AndrolibException {
meta.put("sharedLibrary", mResTable.getSharedLibrary());
}

private boolean getCompressionType() {
return mCompressResources;
}

private final Androlib mAndrolib;

private final static Logger LOGGER = Logger.getLogger(Androlib.class.getName());
Expand All @@ -417,7 +401,7 @@ private boolean getCompressionType() {
private boolean mForceDelete = false;
private boolean mKeepBrokenResources = false;
private boolean mBakDeb = true;
private boolean mCompressResources = false;
private Collection<String> mUncompressedFiles;
private boolean mAnalysisMode = false;
private int mApi = 15;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package brut.androlib;

import java.util.Collection;

public class ApkOptions {
public boolean forceBuildAll = false;
public boolean debugMode = false;
Expand All @@ -23,6 +25,7 @@ public class ApkOptions {
public boolean updateFiles = false;
public boolean isFramework = false;
public boolean resourcesAreCompressed = false;
public Collection<String> doNotCompress;

public String frameworkFolderLocation = null;
public String frameworkTag = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,13 @@ public void aaptPackage(File apkFile, File manifest, File resDir, File rawDir, F
cmd.add("-x");
}

if (! apkOptions.resourcesAreCompressed) {
if (apkOptions.doNotCompress != null) {
for (String file : apkOptions.doNotCompress) {
cmd.add("-0");
cmd.add(file);
}
}
if (!apkOptions.resourcesAreCompressed) {
cmd.add("-0");
cmd.add("arsc");
}
Expand Down
19 changes: 13 additions & 6 deletions brut.j.dir/src/main/java/brut/directory/AbstractDirectory.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

public abstract class AbstractDirectory implements Directory {
protected Set<String> mFiles;
protected Set<String> mFilesRecursive;
protected Map<String, AbstractDirectory> mDirs;

@Override
Expand All @@ -41,14 +42,15 @@ public Set<String> getFiles(boolean recursive) {
if (!recursive) {
return mFiles;
}

Set<String> files = new LinkedHashSet<String>(mFiles);
for (Map.Entry<String, ? extends Directory> dir : getAbstractDirs().entrySet()) {
for (String path : dir.getValue().getFiles(true)) {
files.add(dir.getKey() + separator + path);
if (mFilesRecursive == null) {
mFilesRecursive = new LinkedHashSet<String>(mFiles);
for (Map.Entry<String, ? extends Directory> dir : getAbstractDirs().entrySet()) {
for (String path : dir.getValue().getFiles(true)) {
mFilesRecursive.add(dir.getKey() + separator + path);
}
}
}
return files;
return mFilesRecursive;
}

@Override
Expand Down Expand Up @@ -205,6 +207,11 @@ public void copyToDir(File out, String fileName)
DirUtil.copyToDir(this, out, fileName);
}

public int getCompressionLevel(String fileName)
throws DirectoryException {
return -1; // Unknown
}

protected Map<String, AbstractDirectory> getAbstractDirs() {
return getAbstractDirs(false);
}
Expand Down
3 changes: 3 additions & 0 deletions brut.j.dir/src/main/java/brut/directory/Directory.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,8 @@ public void copyToDir(File out, String[] fileNames)
public void copyToDir(File out, String fileName)
throws DirectoryException;

public int getCompressionLevel(String fileName)
throws DirectoryException;

public final char separator = '/';
}
10 changes: 10 additions & 0 deletions brut.j.dir/src/main/java/brut/directory/ZipRODirectory.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ protected void removeFileLocal(String name) {
throw new UnsupportedOperationException();
}

@Override
public int getCompressionLevel(String fileName)
throws DirectoryException {
ZipEntry entry = mZipFile.getEntry(fileName);
if (entry == null) {
throw new PathNotExist("Entry not found: " + fileName);
}
return entry.getMethod();
}

private void loadAll() {
mFiles = new LinkedHashSet<String>();
mDirs = new LinkedHashMap<String, AbstractDirectory>();
Expand Down

0 comments on commit 5c6f325

Please sign in to comment.