mirror of
https://github.com/revanced/Apktool.git
synced 2025-05-01 06:34:25 +02:00
Merge branch 'rover12421-yaml-object'
This commit is contained in:
commit
114af9799d
@ -17,6 +17,8 @@
|
|||||||
package brut.androlib;
|
package brut.androlib;
|
||||||
|
|
||||||
import brut.androlib.java.AndrolibJava;
|
import brut.androlib.java.AndrolibJava;
|
||||||
|
import brut.androlib.meta.MetaInfo;
|
||||||
|
import brut.androlib.meta.UsesFramework;
|
||||||
import brut.androlib.res.AndrolibResources;
|
import brut.androlib.res.AndrolibResources;
|
||||||
import brut.androlib.res.data.ResPackage;
|
import brut.androlib.res.data.ResPackage;
|
||||||
import brut.androlib.res.data.ResTable;
|
import brut.androlib.res.data.ResTable;
|
||||||
@ -30,7 +32,6 @@ 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.nio.charset.StandardCharsets;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -40,9 +41,6 @@ import java.util.zip.ZipFile;
|
|||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
@ -239,33 +237,21 @@ public class Androlib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeMetaFile(File mOutDir, Map<String, Object> meta)
|
public void writeMetaFile(File mOutDir, MetaInfo meta)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
DumperOptions options = new DumperOptions();
|
try{
|
||||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
meta.save(new File(mOutDir, "apktool.yml"));
|
||||||
Yaml yaml = new Yaml(options);
|
|
||||||
|
|
||||||
try (
|
|
||||||
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
|
|
||||||
new File(mOutDir, "apktool.yml")), "UTF-8"))
|
|
||||||
) {
|
|
||||||
yaml.dump(meta, writer);
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new AndrolibException(ex);
|
throw new AndrolibException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> readMetaFile(ExtFile appDir)
|
public MetaInfo readMetaFile(ExtFile appDir)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
try(
|
try(
|
||||||
InputStream in = appDir.getDirectory().getFileInput("apktool.yml")
|
InputStream in = appDir.getDirectory().getFileInput("apktool.yml")
|
||||||
) {
|
) {
|
||||||
Yaml yaml = new Yaml();
|
return MetaInfo.load(in);
|
||||||
Map<String, Object> result = (Map<String, Object>) yaml.load(in);
|
|
||||||
if (result.containsKey("unknownFiles")) {
|
|
||||||
result.put("unknownFiles", getUnknownFiles(result));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (DirectoryException | IOException ex) {
|
} catch (DirectoryException | IOException ex) {
|
||||||
throw new AndrolibException(ex);
|
throw new AndrolibException(ex);
|
||||||
}
|
}
|
||||||
@ -279,22 +265,19 @@ public class Androlib {
|
|||||||
throws BrutException {
|
throws BrutException {
|
||||||
LOGGER.info("Using Apktool " + Androlib.getVersion());
|
LOGGER.info("Using Apktool " + Androlib.getVersion());
|
||||||
|
|
||||||
Map<String, Object> meta = readMetaFile(appDir);
|
MetaInfo meta = readMetaFile(appDir);
|
||||||
Object t1 = meta.get("isFrameworkApk");
|
apkOptions.isFramework = meta.isFrameworkApk;
|
||||||
apkOptions.isFramework = (t1 == null ? false : (Boolean) t1);
|
apkOptions.resourcesAreCompressed = meta.compressionType;
|
||||||
apkOptions.resourcesAreCompressed = meta.get("compressionType") == null
|
apkOptions.doNotCompress = meta.doNotCompress;
|
||||||
? false
|
|
||||||
: Boolean.valueOf(meta.get("compressionType").toString());
|
|
||||||
apkOptions.doNotCompress = (Collection<String>) meta.get("doNotCompress");
|
|
||||||
|
|
||||||
mAndRes.setSdkInfo((Map<String, String>) meta.get("sdkInfo"));
|
mAndRes.setSdkInfo(meta.sdkInfo);
|
||||||
mAndRes.setPackageId((Map<String, String>) meta.get("packageInfo"));
|
mAndRes.setPackageId(meta.packageInfo);
|
||||||
mAndRes.setPackageInfo((Map<String, String>) meta.get("packageInfo"));
|
mAndRes.setPackageRenamed(meta.packageInfo);
|
||||||
mAndRes.setVersionInfo((Map<String, String>) meta.get("versionInfo"));
|
mAndRes.setVersionInfo(meta.versionInfo);
|
||||||
mAndRes.setSharedLibrary((boolean) (meta.get("sharedLibrary") == null ? false : meta.get("sharedLibrary")));
|
mAndRes.setSharedLibrary(meta.sharedLibrary);
|
||||||
|
|
||||||
if (outFile == null) {
|
if (outFile == null) {
|
||||||
String outFileName = (String) meta.get("apkFileName");
|
String outFileName = meta.apkFileName;
|
||||||
outFile = new File(appDir, "dist" + File.separator + (outFileName == null ? "out.apk" : outFileName));
|
outFile = new File(appDir, "dist" + File.separator + (outFileName == null ? "out.apk" : outFileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +285,7 @@ public class Androlib {
|
|||||||
buildSources(appDir);
|
buildSources(appDir);
|
||||||
buildNonDefaultSources(appDir);
|
buildNonDefaultSources(appDir);
|
||||||
ResXmlPatcher.fixingPublicAttrsInProviderAttributes(new File(appDir, "AndroidManifest.xml"));
|
ResXmlPatcher.fixingPublicAttrsInProviderAttributes(new File(appDir, "AndroidManifest.xml"));
|
||||||
buildResources(appDir, (Map<String, Object>) meta.get("usesFramework"));
|
buildResources(appDir, meta.usesFramework);
|
||||||
|
|
||||||
buildLib(appDir);
|
buildLib(appDir);
|
||||||
buildLibs(appDir);
|
buildLibs(appDir);
|
||||||
@ -412,7 +395,7 @@ public class Androlib {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void buildResources(ExtFile appDir, Map<String, Object> usesFramework)
|
public void buildResources(ExtFile appDir, UsesFramework usesFramework)
|
||||||
throws BrutException {
|
throws BrutException {
|
||||||
if (!buildResourcesRaw(appDir) && !buildResourcesFull(appDir, usesFramework)
|
if (!buildResourcesRaw(appDir) && !buildResourcesFull(appDir, usesFramework)
|
||||||
&& !buildManifest(appDir, usesFramework)) {
|
&& !buildManifest(appDir, usesFramework)) {
|
||||||
@ -441,7 +424,7 @@ public class Androlib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean buildResourcesFull(File appDir, Map<String, Object> usesFramework)
|
public boolean buildResourcesFull(File appDir, UsesFramework usesFramework)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
try {
|
try {
|
||||||
if (!new File(appDir, "res").exists()) {
|
if (!new File(appDir, "res").exists()) {
|
||||||
@ -492,7 +475,7 @@ public class Androlib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean buildManifest(ExtFile appDir, Map<String, Object> usesFramework)
|
public boolean buildManifest(ExtFile appDir, UsesFramework usesFramework)
|
||||||
throws BrutException {
|
throws BrutException {
|
||||||
try {
|
try {
|
||||||
if (!new File(appDir, "AndroidManifest.xml").exists()) {
|
if (!new File(appDir, "AndroidManifest.xml").exists()) {
|
||||||
@ -587,12 +570,12 @@ public class Androlib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void buildUnknownFiles(File appDir, File outFile, Map<String, Object> meta)
|
public void buildUnknownFiles(File appDir, File outFile, MetaInfo meta)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
if (meta.containsKey("unknownFiles")) {
|
if (meta.unknownFiles != null) {
|
||||||
LOGGER.info("Copying unknown files/dir...");
|
LOGGER.info("Copying unknown files/dir...");
|
||||||
|
|
||||||
Map<String, String> files = (Map<String, String>)meta.get("unknownFiles");
|
Map<String, String> files = meta.unknownFiles;
|
||||||
File tempFile = new File(outFile.getParent(), outFile.getName() + ".apktool_temp");
|
File tempFile = new File(outFile.getParent(), outFile.getName() + ".apktool_temp");
|
||||||
boolean renamed = outFile.renameTo(tempFile);
|
boolean renamed = outFile.renameTo(tempFile);
|
||||||
if(!renamed) {
|
if(!renamed) {
|
||||||
@ -703,18 +686,18 @@ public class Androlib {
|
|||||||
return ApktoolProperties.get("application.version");
|
return ApktoolProperties.get("application.version");
|
||||||
}
|
}
|
||||||
|
|
||||||
private File[] parseUsesFramework(Map<String, Object> usesFramework)
|
private File[] parseUsesFramework(UsesFramework usesFramework)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
if (usesFramework == null) {
|
if (usesFramework == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Integer> ids = (List<Integer>) usesFramework.get("ids");
|
List<Integer> ids = usesFramework.ids;
|
||||||
if (ids == null || ids.isEmpty()) {
|
if (ids == null || ids.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String tag = (String) usesFramework.get("tag");
|
String tag = usesFramework.tag;
|
||||||
File[] files = new File[ids.size()];
|
File[] files = new File[ids.size()];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int id : ids) {
|
for (int id : ids) {
|
||||||
@ -744,15 +727,6 @@ public class Androlib {
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, String> getUnknownFiles(Map<String, Object> meta) {
|
|
||||||
Map<byte[], String> unknownFiles = (Map<byte[], String>) meta.get("unknownFiles");
|
|
||||||
Map<String, String> result = new LinkedHashMap<>();
|
|
||||||
for (Map.Entry<byte[], String> entry : unknownFiles.entrySet()) {
|
|
||||||
result.put(new String(entry.getKey(), StandardCharsets.UTF_8), entry.getValue());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 SMALI_DIRNAME = "smali";
|
||||||
|
@ -19,6 +19,9 @@ package brut.androlib;
|
|||||||
import brut.androlib.err.InFileNotFoundException;
|
import brut.androlib.err.InFileNotFoundException;
|
||||||
import brut.androlib.err.OutDirExistsException;
|
import brut.androlib.err.OutDirExistsException;
|
||||||
import brut.androlib.err.UndefinedResObject;
|
import brut.androlib.err.UndefinedResObject;
|
||||||
|
import brut.androlib.meta.MetaInfo;
|
||||||
|
import brut.androlib.meta.PackageInfo;
|
||||||
|
import brut.androlib.meta.UsesFramework;
|
||||||
import brut.androlib.res.AndrolibResources;
|
import brut.androlib.res.AndrolibResources;
|
||||||
import brut.androlib.res.data.ResPackage;
|
import brut.androlib.res.data.ResPackage;
|
||||||
import brut.androlib.res.data.ResTable;
|
import brut.androlib.res.data.ResTable;
|
||||||
@ -298,12 +301,12 @@ public class ApkDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeMetaFile() throws AndrolibException {
|
private void writeMetaFile() throws AndrolibException {
|
||||||
Map<String, Object> meta = new LinkedHashMap<String, Object>();
|
MetaInfo meta = new MetaInfo();
|
||||||
meta.put("version", Androlib.getVersion());
|
meta.version = Androlib.getVersion();
|
||||||
meta.put("apkFileName", mApkFile.getName());
|
meta.apkFileName = mApkFile.getName();
|
||||||
|
|
||||||
if (mDecodeResources != DECODE_RESOURCES_NONE && (hasManifest() || hasResources())) {
|
if (mDecodeResources != DECODE_RESOURCES_NONE && (hasManifest() || hasResources())) {
|
||||||
meta.put("isFrameworkApk", mAndrolib.isFrameworkApk(getResTable()));
|
meta.isFrameworkApk = mAndrolib.isFrameworkApk(getResTable());
|
||||||
putUsesFramework(meta);
|
putUsesFramework(meta);
|
||||||
putSdkInfo(meta);
|
putSdkInfo(meta);
|
||||||
putPackageInfo(meta);
|
putPackageInfo(meta);
|
||||||
@ -316,7 +319,7 @@ public class ApkDecoder {
|
|||||||
mAndrolib.writeMetaFile(mOutDir, meta);
|
mAndrolib.writeMetaFile(mOutDir, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putUsesFramework(Map<String, Object> meta) throws AndrolibException {
|
private void putUsesFramework(MetaInfo meta) throws AndrolibException {
|
||||||
Set<ResPackage> pkgs = getResTable().listFramePackages();
|
Set<ResPackage> pkgs = getResTable().listFramePackages();
|
||||||
if (pkgs.isEmpty()) {
|
if (pkgs.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@ -329,24 +332,22 @@ public class ApkDecoder {
|
|||||||
}
|
}
|
||||||
Arrays.sort(ids);
|
Arrays.sort(ids);
|
||||||
|
|
||||||
Map<String, Object> uses = new LinkedHashMap<String, Object>();
|
meta.usesFramework = new UsesFramework();
|
||||||
uses.put("ids", ids);
|
meta.usesFramework.ids = Arrays.asList(ids);
|
||||||
|
|
||||||
if (mAndrolib.apkOptions.frameworkTag != null) {
|
if (mAndrolib.apkOptions.frameworkTag != null) {
|
||||||
uses.put("tag", mAndrolib.apkOptions.frameworkTag);
|
meta.usesFramework.tag = mAndrolib.apkOptions.frameworkTag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
meta.put("usesFramework", uses);
|
private void putSdkInfo(MetaInfo meta) throws AndrolibException {
|
||||||
}
|
|
||||||
|
|
||||||
private void putSdkInfo(Map<String, Object> meta) throws AndrolibException {
|
|
||||||
Map<String, String> info = getResTable().getSdkInfo();
|
Map<String, String> info = getResTable().getSdkInfo();
|
||||||
if (info.size() > 0) {
|
if (info.size() > 0) {
|
||||||
meta.put("sdkInfo", info);
|
meta.sdkInfo = info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putPackageInfo(Map<String, Object> meta) throws AndrolibException {
|
private void putPackageInfo(MetaInfo meta) throws AndrolibException {
|
||||||
String renamed = getResTable().getPackageRenamed();
|
String renamed = getResTable().getPackageRenamed();
|
||||||
String original = getResTable().getPackageOriginal();
|
String original = getResTable().getPackageOriginal();
|
||||||
|
|
||||||
@ -355,42 +356,35 @@ public class ApkDecoder {
|
|||||||
id = getResTable().getPackage(renamed).getId();
|
id = getResTable().getPackage(renamed).getId();
|
||||||
} catch (UndefinedResObject ignored) {}
|
} catch (UndefinedResObject ignored) {}
|
||||||
|
|
||||||
HashMap<String, String> packages = new HashMap<String, String>();
|
|
||||||
|
|
||||||
if (Strings.isNullOrEmpty(original)) {
|
if (Strings.isNullOrEmpty(original)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta.packageInfo = new PackageInfo();
|
||||||
|
|
||||||
// only put rename-manifest-package into apktool.yml, if the change will be required
|
// only put rename-manifest-package into apktool.yml, if the change will be required
|
||||||
if (!renamed.equalsIgnoreCase(original)) {
|
if (!renamed.equalsIgnoreCase(original)) {
|
||||||
packages.put("rename-manifest-package", renamed);
|
meta.packageInfo.renameManifestPackage = renamed;
|
||||||
}
|
}
|
||||||
packages.put("forced-package-id", String.valueOf(id));
|
meta.packageInfo.forcedPackageId = String.valueOf(id);
|
||||||
meta.put("packageInfo", packages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putVersionInfo(Map<String, Object> meta) throws AndrolibException {
|
private void putVersionInfo(MetaInfo meta) throws AndrolibException {
|
||||||
Map<String, String> info = getResTable().getVersionInfo();
|
meta.versionInfo = getResTable().getVersionInfo();
|
||||||
if (info.size() > 0) {
|
|
||||||
meta.put("versionInfo", info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putUnknownInfo(Map<String, Object> meta) throws AndrolibException {
|
private void putUnknownInfo(MetaInfo meta) throws AndrolibException {
|
||||||
Map<byte[], String> info = mAndrolib.mResUnknownFiles.getUnknownFiles();
|
meta.unknownFiles = mAndrolib.mResUnknownFiles.getUnknownFiles();
|
||||||
if (info.size() > 0) {
|
|
||||||
meta.put("unknownFiles", info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putFileCompressionInfo(Map<String, Object> meta) throws AndrolibException {
|
private void putFileCompressionInfo(MetaInfo meta) throws AndrolibException {
|
||||||
if (!mUncompressedFiles.isEmpty()) {
|
if (!mUncompressedFiles.isEmpty()) {
|
||||||
meta.put("doNotCompress", mUncompressedFiles);
|
meta.doNotCompress = mUncompressedFiles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putSharedLibraryInfo(Map<String, Object> meta) throws AndrolibException {
|
private void putSharedLibraryInfo(MetaInfo meta) throws AndrolibException {
|
||||||
meta.put("sharedLibrary", mResTable.getSharedLibrary());
|
meta.sharedLibrary = mResTable.getSharedLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Androlib mAndrolib;
|
private final Androlib mAndrolib;
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package brut.androlib.meta;
|
||||||
|
|
||||||
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
import org.yaml.snakeyaml.introspector.PropertyUtils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class MetaInfo {
|
||||||
|
public String version;
|
||||||
|
public String apkFileName;
|
||||||
|
public boolean isFrameworkApk;
|
||||||
|
public UsesFramework usesFramework;
|
||||||
|
public Map<String, String> sdkInfo;
|
||||||
|
public PackageInfo packageInfo;
|
||||||
|
public VersionInfo versionInfo;
|
||||||
|
public boolean compressionType;
|
||||||
|
public boolean sharedLibrary;
|
||||||
|
public Map<String, String> unknownFiles;
|
||||||
|
public Collection<String> doNotCompress;
|
||||||
|
|
||||||
|
private static Yaml getYaml() {
|
||||||
|
DumperOptions options = new DumperOptions();
|
||||||
|
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||||
|
|
||||||
|
StringExRepresent representer = new StringExRepresent();
|
||||||
|
PropertyUtils propertyUtils = representer.getPropertyUtils();
|
||||||
|
propertyUtils.setSkipMissingProperties(true);
|
||||||
|
|
||||||
|
return new Yaml(new StringExConstructor(), representer, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(Writer output) {
|
||||||
|
DumperOptions options = new DumperOptions();
|
||||||
|
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||||
|
getYaml().dump(this, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(File file) throws IOException {
|
||||||
|
try(
|
||||||
|
FileOutputStream fos = new FileOutputStream(file);
|
||||||
|
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
|
||||||
|
Writer writer = new BufferedWriter(outputStreamWriter)
|
||||||
|
){
|
||||||
|
save(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MetaInfo load(InputStream is) {
|
||||||
|
return getYaml().loadAs(is, MetaInfo.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MetaInfo load(File file) throws IOException {
|
||||||
|
try (
|
||||||
|
InputStream fis = new FileInputStream(file)
|
||||||
|
){
|
||||||
|
return load(fis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package brut.androlib.meta;
|
||||||
|
|
||||||
|
public class PackageInfo {
|
||||||
|
public String forcedPackageId;
|
||||||
|
public String renameManifestPackage;
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package brut.androlib.meta;
|
||||||
|
|
||||||
|
import org.yaml.snakeyaml.constructor.AbstractConstruct;
|
||||||
|
import org.yaml.snakeyaml.constructor.Constructor;
|
||||||
|
import org.yaml.snakeyaml.nodes.Node;
|
||||||
|
import org.yaml.snakeyaml.nodes.ScalarNode;
|
||||||
|
import org.yaml.snakeyaml.nodes.Tag;
|
||||||
|
|
||||||
|
public class StringExConstructor extends Constructor {
|
||||||
|
public StringExConstructor() {
|
||||||
|
this.yamlConstructors.put(Tag.STR, new ConstructStringEx());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ConstructStringEx extends AbstractConstruct {
|
||||||
|
public Object construct(Node node) {
|
||||||
|
String val = (String) constructScalar((ScalarNode) node);
|
||||||
|
return YamlStringEscapeUtils.unescapeString(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package brut.androlib.meta;
|
||||||
|
|
||||||
|
import org.yaml.snakeyaml.nodes.Node;
|
||||||
|
import org.yaml.snakeyaml.representer.Representer;
|
||||||
|
|
||||||
|
public class StringExRepresent extends Representer {
|
||||||
|
public StringExRepresent() {
|
||||||
|
RepresentStringEx representStringEx = new RepresentStringEx();
|
||||||
|
multiRepresenters.put(String.class, representStringEx);
|
||||||
|
representers.put(String.class, representStringEx);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RepresentStringEx extends RepresentString {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node representData(Object data) {
|
||||||
|
return super.representData(YamlStringEscapeUtils.escapeString(data.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package brut.androlib.meta;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UsesFramework {
|
||||||
|
public List<Integer> ids;
|
||||||
|
public String tag;
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package brut.androlib.meta;
|
||||||
|
|
||||||
|
public class VersionInfo {
|
||||||
|
public String versionCode;
|
||||||
|
public String versionName;
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package brut.androlib.meta;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringEscapeUtils;
|
||||||
|
import org.apache.commons.lang3.text.translate.CharSequenceTranslator;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
public class YamlStringEscapeUtils {
|
||||||
|
|
||||||
|
public static String escapeString(String str) {
|
||||||
|
return escapeJavaStyleString(str, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param str String to escape values in, may be null
|
||||||
|
* @param escapeSingleQuotes escapes single quotes if <code>true</code>
|
||||||
|
* @param escapeForwardSlash TODO
|
||||||
|
* @return the escaped string
|
||||||
|
*/
|
||||||
|
private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes, boolean escapeForwardSlash) {
|
||||||
|
if (str == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
StringWriter writer = new StringWriter(str.length() * 2);
|
||||||
|
escapeJavaStyleString(writer, str, escapeSingleQuotes, escapeForwardSlash);
|
||||||
|
return writer.toString();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// this should never ever happen while writing to a StringWriter
|
||||||
|
throw new RuntimeException(ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param out write to receieve the escaped string
|
||||||
|
* @param str String to escape values in, may be null
|
||||||
|
* @param escapeSingleQuote escapes single quotes if <code>true</code>
|
||||||
|
* @param escapeForwardSlash TODO
|
||||||
|
* @throws IOException if an IOException occurs
|
||||||
|
*/
|
||||||
|
private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote,
|
||||||
|
boolean escapeForwardSlash) throws IOException {
|
||||||
|
if (out == null) {
|
||||||
|
throw new IllegalArgumentException("The Writer must not be null");
|
||||||
|
}
|
||||||
|
if (str == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int sz;
|
||||||
|
sz = str.length();
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
char ch = str.charAt(i);
|
||||||
|
// "[^\t\n\r\u0020-\u007E\u0085\u00A0-\uD7FF\uE000-\uFFFD]"
|
||||||
|
// handle unicode
|
||||||
|
if (ch > 0xFFFD) {
|
||||||
|
out.write("\\u" + CharSequenceTranslator.hex(ch));
|
||||||
|
} else if (ch > 0xD7FF && ch < 0xE000) {
|
||||||
|
out.write("\\u" + CharSequenceTranslator.hex(ch));
|
||||||
|
} else if (ch > 0x7E && ch != 0x85 && ch < 0xA0) {
|
||||||
|
out.write("\\u00" + CharSequenceTranslator.hex(ch));
|
||||||
|
} else if (ch < 32) {
|
||||||
|
switch (ch) {
|
||||||
|
case '\t' :
|
||||||
|
out.write('\\');
|
||||||
|
out.write('t');
|
||||||
|
break;
|
||||||
|
case '\n' :
|
||||||
|
out.write('\\');
|
||||||
|
out.write('n');
|
||||||
|
break;
|
||||||
|
case '\r' :
|
||||||
|
out.write('\\');
|
||||||
|
out.write('r');
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
if (ch > 0xf) {
|
||||||
|
out.write("\\u00" + CharSequenceTranslator.hex(ch));
|
||||||
|
} else {
|
||||||
|
out.write("\\u000" + CharSequenceTranslator.hex(ch));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (ch) {
|
||||||
|
case '\'' :
|
||||||
|
if (escapeSingleQuote) {
|
||||||
|
out.write('\\');
|
||||||
|
}
|
||||||
|
out.write('\'');
|
||||||
|
break;
|
||||||
|
case '"' :
|
||||||
|
out.write('\\');
|
||||||
|
out.write('"');
|
||||||
|
break;
|
||||||
|
case '\\' :
|
||||||
|
out.write('\\');
|
||||||
|
out.write('\\');
|
||||||
|
break;
|
||||||
|
case '/' :
|
||||||
|
if (escapeForwardSlash) {
|
||||||
|
out.write('\\');
|
||||||
|
}
|
||||||
|
out.write('/');
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
out.write(ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Unescapes any Java literals found in the <code>String</code>.
|
||||||
|
* For example, it will turn a sequence of <code>'\'</code> and
|
||||||
|
* <code>'n'</code> into a newline character, unless the <code>'\'</code>
|
||||||
|
* is preceded by another <code>'\'</code>.</p>
|
||||||
|
*
|
||||||
|
* @param str the <code>String</code> to unescape, may be null
|
||||||
|
* @return a new unescaped <code>String</code>, <code>null</code> if null string input
|
||||||
|
*/
|
||||||
|
public static String unescapeString(String str) {
|
||||||
|
return StringEscapeUtils.unescapeJava(str);
|
||||||
|
}
|
||||||
|
}
|
@ -19,26 +19,35 @@ package brut.androlib.res;
|
|||||||
import brut.androlib.AndrolibException;
|
import brut.androlib.AndrolibException;
|
||||||
import brut.androlib.ApkOptions;
|
import brut.androlib.ApkOptions;
|
||||||
import brut.androlib.err.CantFindFrameworkResException;
|
import brut.androlib.err.CantFindFrameworkResException;
|
||||||
|
import brut.androlib.meta.PackageInfo;
|
||||||
|
import brut.androlib.meta.VersionInfo;
|
||||||
import brut.androlib.res.data.*;
|
import brut.androlib.res.data.*;
|
||||||
import brut.androlib.res.decoder.*;
|
import brut.androlib.res.decoder.*;
|
||||||
import brut.androlib.res.decoder.ARSCDecoder.ARSCData;
|
import brut.androlib.res.decoder.ARSCDecoder.ARSCData;
|
||||||
import brut.androlib.res.decoder.ARSCDecoder.FlagsOffset;
|
import brut.androlib.res.decoder.ARSCDecoder.FlagsOffset;
|
||||||
import brut.androlib.res.util.*;
|
import brut.androlib.res.util.ExtFile;
|
||||||
|
import brut.androlib.res.util.ExtMXSerializer;
|
||||||
|
import brut.androlib.res.util.ExtXmlSerializer;
|
||||||
import brut.androlib.res.xml.ResValuesXmlSerializable;
|
import brut.androlib.res.xml.ResValuesXmlSerializable;
|
||||||
import brut.androlib.res.xml.ResXmlPatcher;
|
import brut.androlib.res.xml.ResXmlPatcher;
|
||||||
import brut.common.BrutException;
|
import brut.common.BrutException;
|
||||||
import brut.directory.*;
|
import brut.directory.Directory;
|
||||||
import brut.util.*;
|
import brut.directory.DirectoryException;
|
||||||
|
import brut.directory.FileDirectory;
|
||||||
|
import brut.util.Duo;
|
||||||
|
import brut.util.Jar;
|
||||||
|
import brut.util.OS;
|
||||||
|
import brut.util.OSDetection;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.zip.*;
|
import java.util.zip.CRC32;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
import java.io.File;
|
import java.util.zip.ZipFile;
|
||||||
import java.io.IOException;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
@ -268,22 +277,22 @@ final public class AndrolibResources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVersionInfo(Map<String, String> map) {
|
public void setVersionInfo(VersionInfo versionInfo) {
|
||||||
if (map != null) {
|
if (versionInfo != null) {
|
||||||
mVersionCode = map.get("versionCode");
|
mVersionCode = versionInfo.versionCode;
|
||||||
mVersionName = map.get("versionName");
|
mVersionName = versionInfo.versionName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPackageInfo(Map<String, String> map) {
|
public void setPackageRenamed(PackageInfo packageInfo) {
|
||||||
if (map != null) {
|
if (packageInfo != null) {
|
||||||
mPackageRenamed = map.get("rename-manifest-package");
|
mPackageRenamed = packageInfo.renameManifestPackage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPackageId(Map<String, String> map) {
|
public void setPackageId(PackageInfo packageInfo) {
|
||||||
if (map != null) {
|
if (packageInfo != null) {
|
||||||
mPackageId = map.get("forced-package-id");
|
mPackageId = packageInfo.forcedPackageId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ package brut.androlib.res.data;
|
|||||||
|
|
||||||
import brut.androlib.AndrolibException;
|
import brut.androlib.AndrolibException;
|
||||||
import brut.androlib.err.UndefinedResObject;
|
import brut.androlib.err.UndefinedResObject;
|
||||||
|
import brut.androlib.meta.VersionInfo;
|
||||||
import brut.androlib.res.AndrolibResources;
|
import brut.androlib.res.AndrolibResources;
|
||||||
import brut.androlib.res.data.value.ResValue;
|
import brut.androlib.res.data.value.ResValue;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -39,8 +40,8 @@ public class ResTable {
|
|||||||
private boolean mAnalysisMode = false;
|
private boolean mAnalysisMode = false;
|
||||||
private boolean mSharedLibrary = false;
|
private boolean mSharedLibrary = false;
|
||||||
|
|
||||||
private Map<String, String> mSdkInfo = new LinkedHashMap<String, String>();
|
private Map<String, String> mSdkInfo = new LinkedHashMap<>();
|
||||||
private Map<String, String> mVersionInfo = new LinkedHashMap<String, String>();
|
private VersionInfo mVersionInfo = new VersionInfo();
|
||||||
|
|
||||||
public ResTable() {
|
public ResTable() {
|
||||||
mAndRes = null;
|
mAndRes = null;
|
||||||
@ -174,11 +175,15 @@ public class ResTable {
|
|||||||
mSdkInfo.put(key, value);
|
mSdkInfo.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addVersionInfo(String key, String value) {
|
public void setVersionName(String versionName) {
|
||||||
mVersionInfo.put(key, value);
|
mVersionInfo.versionName = versionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getVersionInfo() {
|
public void setVersionCode(String versionCode) {
|
||||||
|
mVersionInfo.versionCode = versionCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VersionInfo getVersionInfo() {
|
||||||
return mVersionInfo;
|
return mVersionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package brut.androlib.res.data;
|
package brut.androlib.res.data;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -24,13 +23,13 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class ResUnknownFiles {
|
public class ResUnknownFiles {
|
||||||
|
|
||||||
private final Map<byte[], String> mUnknownFiles = new LinkedHashMap<byte[], String>();
|
private final Map<String, String> mUnknownFiles = new LinkedHashMap<>();
|
||||||
|
|
||||||
public void addUnknownFileInfo(String file, String value) {
|
public void addUnknownFileInfo(String file, String value) {
|
||||||
mUnknownFiles.put(file.getBytes(StandardCharsets.UTF_8), value);
|
mUnknownFiles.put(file, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<byte[], String> getUnknownFiles() {
|
public Map<String, String> getUnknownFiles() {
|
||||||
return mUnknownFiles;
|
return mUnknownFiles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,9 +94,9 @@ public class XmlPullStreamDecoder implements ResStreamDecoder {
|
|||||||
if (attr_name.equalsIgnoreCase(("package"))) {
|
if (attr_name.equalsIgnoreCase(("package"))) {
|
||||||
resTable.setPackageRenamed(pp.getAttributeValue(i));
|
resTable.setPackageRenamed(pp.getAttributeValue(i));
|
||||||
} else if (attr_name.equalsIgnoreCase("versionCode")) {
|
} else if (attr_name.equalsIgnoreCase("versionCode")) {
|
||||||
resTable.addVersionInfo("versionCode", pp.getAttributeValue(i));
|
resTable.setVersionCode(pp.getAttributeValue(i));
|
||||||
} else if (attr_name.equalsIgnoreCase("versionName")) {
|
} else if (attr_name.equalsIgnoreCase("versionName")) {
|
||||||
resTable.addVersionInfo("versionName", pp.getAttributeValue(i));
|
resTable.setVersionName(pp.getAttributeValue(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package brut.androlib;
|
package brut.androlib;
|
||||||
|
|
||||||
|
import brut.androlib.meta.MetaInfo;
|
||||||
import brut.androlib.res.util.ExtFile;
|
import brut.androlib.res.util.ExtFile;
|
||||||
import brut.common.BrutException;
|
import brut.common.BrutException;
|
||||||
import brut.directory.FileDirectory;
|
import brut.directory.FileDirectory;
|
||||||
@ -340,13 +341,13 @@ public class BuildAndDecodeTest {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void compareUnknownFiles() throws BrutException, IOException {
|
private void compareUnknownFiles() throws BrutException, IOException {
|
||||||
Map<String, Object> control = new Androlib().readMetaFile(sTestOrigDir);
|
MetaInfo control = new Androlib().readMetaFile(sTestOrigDir);
|
||||||
Map<String, Object> test = new Androlib().readMetaFile(sTestNewDir);
|
MetaInfo test = new Androlib().readMetaFile(sTestNewDir);
|
||||||
assertTrue(control.containsKey("unknownFiles"));
|
assertNotNull(control.unknownFiles);
|
||||||
assertTrue(test.containsKey("unknownFiles"));
|
assertNotNull(test.unknownFiles);
|
||||||
|
|
||||||
Map<String, String> control_files = (Map<String, String>)control.get("unknownFiles");
|
Map<String, String> control_files = control.unknownFiles;
|
||||||
Map<String, String> test_files = (Map<String, String>)test.get("unknownFiles");
|
Map<String, String> test_files = test.unknownFiles;
|
||||||
assertTrue(control_files.size() == test_files.size());
|
assertTrue(control_files.size() == test_files.size());
|
||||||
|
|
||||||
// Make sure that the compression methods are still the same
|
// Make sure that the compression methods are still the same
|
||||||
|
@ -11,8 +11,8 @@ versionInfo:
|
|||||||
versionName: '1.0'
|
versionName: '1.0'
|
||||||
compressionType: false
|
compressionType: false
|
||||||
unknownFiles:
|
unknownFiles:
|
||||||
!!binary "aGlkZGVuLmZpbGU=": '8'
|
hidden.file: '8'
|
||||||
!!binary "bm9uf3ByaW50YWJsZS5maWxl": '8'
|
non\u007Fprintable.file: '8'
|
||||||
!!binary "c3RvcmVkLmZpbGU=": '0'
|
stored.file: '0'
|
||||||
!!binary "dW5rX2ZvbGRlci91bmtub3duX2ZpbGU=": '8'
|
unk_folder/unknown_file: '8'
|
||||||
!!binary "bGliX2J1ZzYwMy9idWc2MDM=": '8'
|
lib_bug603/bug603: '8'
|
Loading…
x
Reference in New Issue
Block a user