mirror of
https://github.com/revanced/Apktool.git
synced 2025-01-07 10:35:52 +01:00
Extract class Framework from AndrolibResources (#3105)
This commit is contained in:
parent
9c495cae29
commit
40d427e5bd
@ -22,6 +22,7 @@ import brut.androlib.exceptions.CantFindFrameworkResException;
|
|||||||
import brut.androlib.exceptions.InFileNotFoundException;
|
import brut.androlib.exceptions.InFileNotFoundException;
|
||||||
import brut.androlib.exceptions.OutDirExistsException;
|
import brut.androlib.exceptions.OutDirExistsException;
|
||||||
import brut.androlib.res.AndrolibResources;
|
import brut.androlib.res.AndrolibResources;
|
||||||
|
import brut.androlib.res.Framework;
|
||||||
import brut.common.BrutException;
|
import brut.common.BrutException;
|
||||||
import brut.directory.DirectoryException;
|
import brut.directory.DirectoryException;
|
||||||
import brut.directory.ExtFile;
|
import brut.directory.ExtFile;
|
||||||
@ -271,23 +272,23 @@ public class Main {
|
|||||||
|
|
||||||
private static void cmdInstallFramework(CommandLine cli, Config config) throws AndrolibException {
|
private static void cmdInstallFramework(CommandLine cli, Config config) throws AndrolibException {
|
||||||
String apkName = getLastArg(cli);
|
String apkName = getLastArg(cli);
|
||||||
new AndrolibResources(config).installFramework(new File(apkName));
|
new Framework(config).installFramework(new File(apkName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cmdListFrameworks(CommandLine cli, Config config) throws AndrolibException {
|
private static void cmdListFrameworks(CommandLine cli, Config config) throws AndrolibException {
|
||||||
new AndrolibResources(config).listFrameworkDirectory();
|
new Framework(config).listFrameworkDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cmdPublicizeResources(CommandLine cli, Config config) throws AndrolibException {
|
private static void cmdPublicizeResources(CommandLine cli, Config config) throws AndrolibException {
|
||||||
String apkName = getLastArg(cli);
|
String apkName = getLastArg(cli);
|
||||||
new AndrolibResources(config).publicizeResources(new File(apkName));
|
new Framework(config).publicizeResources(new File(apkName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cmdEmptyFrameworkDirectory(CommandLine cli, Config config) throws AndrolibException {
|
private static void cmdEmptyFrameworkDirectory(CommandLine cli, Config config) throws AndrolibException {
|
||||||
if (cli.hasOption("f") || cli.hasOption("force")) {
|
if (cli.hasOption("f") || cli.hasOption("force")) {
|
||||||
config.forceDeleteFramework = true;
|
config.forceDeleteFramework = true;
|
||||||
}
|
}
|
||||||
new AndrolibResources(config).emptyFrameworkDirectory();
|
new Framework(config).emptyFrameworkDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getLastArg(CommandLine cli) {
|
private static String getLastArg(CommandLine cli) {
|
||||||
|
@ -20,6 +20,7 @@ import brut.androlib.exceptions.AndrolibException;
|
|||||||
import brut.androlib.meta.MetaInfo;
|
import brut.androlib.meta.MetaInfo;
|
||||||
import brut.androlib.meta.UsesFramework;
|
import brut.androlib.meta.UsesFramework;
|
||||||
import brut.androlib.res.AndrolibResources;
|
import brut.androlib.res.AndrolibResources;
|
||||||
|
import brut.androlib.res.Framework;
|
||||||
import brut.androlib.res.data.ResConfigFlags;
|
import brut.androlib.res.data.ResConfigFlags;
|
||||||
import brut.androlib.res.xml.ResXmlPatcher;
|
import brut.androlib.res.xml.ResXmlPatcher;
|
||||||
import brut.androlib.src.SmaliBuilder;
|
import brut.androlib.src.SmaliBuilder;
|
||||||
@ -570,11 +571,12 @@ public class ApkBuilder {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Framework framework = new Framework(config);
|
||||||
String tag = usesFramework.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) {
|
||||||
files[i++] = mAndRes.getFrameworkApk(id, tag);
|
files[i++] = framework.getFrameworkApk(id, tag);
|
||||||
}
|
}
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,8 @@ final public class AndrolibResources {
|
|||||||
|
|
||||||
public ResPackage loadFrameworkPkg(ResTable resTable, int id)
|
public ResPackage loadFrameworkPkg(ResTable resTable, int id)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
File apk = getFrameworkApk(id, config.frameworkTag);
|
Framework framework = new Framework(config);
|
||||||
|
File apk = framework.getFrameworkApk(id, config.frameworkTag);
|
||||||
|
|
||||||
LOGGER.info("Loading resource table from file: " + apk);
|
LOGGER.info("Loading resource table from file: " + apk);
|
||||||
mFramework = new ExtFile(apk);
|
mFramework = new ExtFile(apk);
|
||||||
@ -819,215 +820,6 @@ final public class AndrolibResources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFrameworkApk(int id, String frameTag)
|
|
||||||
throws AndrolibException {
|
|
||||||
File dir = getFrameworkDirectory();
|
|
||||||
File apk;
|
|
||||||
|
|
||||||
if (frameTag != null) {
|
|
||||||
apk = new File(dir, String.valueOf(id) + '-' + frameTag + ".apk");
|
|
||||||
if (apk.exists()) {
|
|
||||||
return apk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apk = new File(dir, id + ".apk");
|
|
||||||
if (apk.exists()) {
|
|
||||||
return apk;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id == 1) {
|
|
||||||
try (InputStream in = getAndroidFrameworkResourcesAsStream();
|
|
||||||
OutputStream out = Files.newOutputStream(apk.toPath())) {
|
|
||||||
IOUtils.copy(in, out);
|
|
||||||
return apk;
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new AndrolibException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new CantFindFrameworkResException(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void emptyFrameworkDirectory() throws AndrolibException {
|
|
||||||
File dir = getFrameworkDirectory();
|
|
||||||
File apk;
|
|
||||||
|
|
||||||
apk = new File(dir, "1.apk");
|
|
||||||
|
|
||||||
if (! apk.exists()) {
|
|
||||||
LOGGER.warning("Can't empty framework directory, no file found at: " + apk.getAbsolutePath());
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
if (apk.exists() && Objects.requireNonNull(dir.listFiles()).length > 1 && ! config.forceDeleteFramework) {
|
|
||||||
LOGGER.warning("More than default framework detected. Please run command with `--force` parameter to wipe framework directory.");
|
|
||||||
} else {
|
|
||||||
for (File file : Objects.requireNonNull(dir.listFiles())) {
|
|
||||||
if (file.isFile() && file.getName().endsWith(".apk")) {
|
|
||||||
LOGGER.info("Removing " + file.getName() + " framework file...");
|
|
||||||
//noinspection ResultOfMethodCallIgnored
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
throw new AndrolibException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void listFrameworkDirectory() throws AndrolibException {
|
|
||||||
File dir = getFrameworkDirectory();
|
|
||||||
if (dir == null) {
|
|
||||||
LOGGER.severe("No framework directory found. Nothing to list.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File file : Objects.requireNonNull(dir.listFiles())) {
|
|
||||||
if (file.isFile() && file.getName().endsWith(".apk")) {
|
|
||||||
LOGGER.info(file.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void installFramework(File frameFile) throws AndrolibException {
|
|
||||||
installFramework(frameFile, config.frameworkTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void installFramework(File frameFile, String tag)
|
|
||||||
throws AndrolibException {
|
|
||||||
InputStream in = null;
|
|
||||||
ZipOutputStream out = null;
|
|
||||||
try {
|
|
||||||
ZipFile zip = new ZipFile(frameFile);
|
|
||||||
ZipEntry entry = zip.getEntry("resources.arsc");
|
|
||||||
|
|
||||||
if (entry == null) {
|
|
||||||
throw new AndrolibException("Can't find resources.arsc file");
|
|
||||||
}
|
|
||||||
|
|
||||||
in = zip.getInputStream(entry);
|
|
||||||
byte[] data = IOUtils.toByteArray(in);
|
|
||||||
|
|
||||||
ARSCData arsc = ARSCDecoder.decode(new ByteArrayInputStream(data), true, true);
|
|
||||||
publicizeResources(data, arsc.getFlagsOffsets());
|
|
||||||
|
|
||||||
File outFile = new File(getFrameworkDirectory(), arsc
|
|
||||||
.getOnePackage().getId()
|
|
||||||
+ (tag == null ? "" : '-' + tag)
|
|
||||||
+ ".apk");
|
|
||||||
|
|
||||||
out = new ZipOutputStream(Files.newOutputStream(outFile.toPath()));
|
|
||||||
out.setMethod(ZipOutputStream.STORED);
|
|
||||||
CRC32 crc = new CRC32();
|
|
||||||
crc.update(data);
|
|
||||||
entry = new ZipEntry("resources.arsc");
|
|
||||||
entry.setSize(data.length);
|
|
||||||
entry.setMethod(ZipOutputStream.STORED);
|
|
||||||
entry.setCrc(crc.getValue());
|
|
||||||
out.putNextEntry(entry);
|
|
||||||
out.write(data);
|
|
||||||
out.closeEntry();
|
|
||||||
|
|
||||||
//Write fake AndroidManifest.xml file to support original aapt
|
|
||||||
entry = zip.getEntry("AndroidManifest.xml");
|
|
||||||
if (entry != null) {
|
|
||||||
in = zip.getInputStream(entry);
|
|
||||||
byte[] manifest = IOUtils.toByteArray(in);
|
|
||||||
CRC32 manifestCrc = new CRC32();
|
|
||||||
manifestCrc.update(manifest);
|
|
||||||
entry.setSize(manifest.length);
|
|
||||||
entry.setCompressedSize(-1);
|
|
||||||
entry.setCrc(manifestCrc.getValue());
|
|
||||||
out.putNextEntry(entry);
|
|
||||||
out.write(manifest);
|
|
||||||
out.closeEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
zip.close();
|
|
||||||
LOGGER.info("Framework installed to: " + outFile);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new AndrolibException(ex);
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(in);
|
|
||||||
IOUtils.closeQuietly(out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publicizeResources(File arscFile) throws AndrolibException {
|
|
||||||
byte[] data = new byte[(int) arscFile.length()];
|
|
||||||
|
|
||||||
try(InputStream in = Files.newInputStream(arscFile.toPath());
|
|
||||||
OutputStream out = Files.newOutputStream(arscFile.toPath())) {
|
|
||||||
//noinspection ResultOfMethodCallIgnored
|
|
||||||
in.read(data);
|
|
||||||
publicizeResources(data);
|
|
||||||
out.write(data);
|
|
||||||
} catch (IOException ex){
|
|
||||||
throw new AndrolibException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publicizeResources(byte[] arsc) throws AndrolibException {
|
|
||||||
publicizeResources(arsc, ARSCDecoder.decode(new ByteArrayInputStream(arsc), true, true).getFlagsOffsets());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publicizeResources(byte[] arsc, FlagsOffset[] flagsOffsets) {
|
|
||||||
for (FlagsOffset flags : flagsOffsets) {
|
|
||||||
int offset = flags.offset + 3;
|
|
||||||
int end = offset + 4 * flags.count;
|
|
||||||
while (offset < end) {
|
|
||||||
arsc[offset] |= (byte) 0x40;
|
|
||||||
offset += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getFrameworkDirectory() throws AndrolibException {
|
|
||||||
if (mFrameworkDirectory != null) {
|
|
||||||
return mFrameworkDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
String path;
|
|
||||||
|
|
||||||
// use default framework path or specified on the command line
|
|
||||||
path = config.frameworkDirectory;
|
|
||||||
|
|
||||||
File dir = new File(path);
|
|
||||||
|
|
||||||
if (!dir.isDirectory() && dir.isFile()) {
|
|
||||||
throw new AndrolibException("--frame-path is set to a file, not a directory.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir.getParentFile() != null && dir.getParentFile().isFile()) {
|
|
||||||
throw new AndrolibException("Please remove file at " + dir.getParentFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! dir.exists()) {
|
|
||||||
if (! dir.mkdirs()) {
|
|
||||||
if (config.frameworkDirectory != null) {
|
|
||||||
LOGGER.severe("Can't create Framework directory: " + dir);
|
|
||||||
}
|
|
||||||
throw new AndrolibException(String.format(
|
|
||||||
"Can't create directory: (%s). Pass a writable path with --frame-path {DIR}. ", dir
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.frameworkDirectory == null) {
|
|
||||||
if (! dir.canWrite()) {
|
|
||||||
LOGGER.severe(String.format("WARNING: Could not write to (%1$s), using %2$s instead...",
|
|
||||||
dir.getAbsolutePath(), System.getProperty("java.io.tmpdir")));
|
|
||||||
LOGGER.severe("Please be aware this is a volatile directory and frameworks could go missing, " +
|
|
||||||
"please utilize --frame-path if the default storage directory is unavailable");
|
|
||||||
|
|
||||||
dir = new File(System.getProperty("java.io.tmpdir"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mFrameworkDirectory = dir;
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
private File getAaptBinaryFile() throws AndrolibException {
|
private File getAaptBinaryFile() throws AndrolibException {
|
||||||
try {
|
try {
|
||||||
@ -1044,10 +836,6 @@ final public class AndrolibResources {
|
|||||||
return config.isAapt2() ? 2 : 1;
|
return config.isAapt2() ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getAndroidFrameworkResourcesAsStream() {
|
|
||||||
return Jar.class.getResourceAsStream("/brut/androlib/android-framework.jar");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (mFramework != null) {
|
if (mFramework != null) {
|
||||||
mFramework.close();
|
mFramework.close();
|
||||||
|
@ -0,0 +1,244 @@
|
|||||||
|
package brut.androlib.res;
|
||||||
|
|
||||||
|
import brut.androlib.Config;
|
||||||
|
import brut.androlib.exceptions.AndrolibException;
|
||||||
|
import brut.androlib.exceptions.CantFindFrameworkResException;
|
||||||
|
import brut.androlib.res.decoder.ARSCDecoder;
|
||||||
|
import brut.util.Jar;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
public class Framework {
|
||||||
|
|
||||||
|
private final Config config;
|
||||||
|
|
||||||
|
private File mFrameworkDirectory = null;
|
||||||
|
|
||||||
|
private final static Logger LOGGER = Logger.getLogger(Framework.class.getName());
|
||||||
|
|
||||||
|
public Framework(Config config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void installFramework(File frameFile) throws AndrolibException {
|
||||||
|
installFramework(frameFile, config.frameworkTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void installFramework(File frameFile, String tag)
|
||||||
|
throws AndrolibException {
|
||||||
|
InputStream in = null;
|
||||||
|
ZipOutputStream out = null;
|
||||||
|
try {
|
||||||
|
ZipFile zip = new ZipFile(frameFile);
|
||||||
|
ZipEntry entry = zip.getEntry("resources.arsc");
|
||||||
|
|
||||||
|
if (entry == null) {
|
||||||
|
throw new AndrolibException("Can't find resources.arsc file");
|
||||||
|
}
|
||||||
|
|
||||||
|
in = zip.getInputStream(entry);
|
||||||
|
byte[] data = IOUtils.toByteArray(in);
|
||||||
|
|
||||||
|
ARSCDecoder.ARSCData arsc = ARSCDecoder.decode(new ByteArrayInputStream(data), true, true);
|
||||||
|
publicizeResources(data, arsc.getFlagsOffsets());
|
||||||
|
|
||||||
|
File outFile = new File(getFrameworkDirectory(), arsc
|
||||||
|
.getOnePackage().getId()
|
||||||
|
+ (tag == null ? "" : '-' + tag)
|
||||||
|
+ ".apk");
|
||||||
|
|
||||||
|
out = new ZipOutputStream(Files.newOutputStream(outFile.toPath()));
|
||||||
|
out.setMethod(ZipOutputStream.STORED);
|
||||||
|
CRC32 crc = new CRC32();
|
||||||
|
crc.update(data);
|
||||||
|
entry = new ZipEntry("resources.arsc");
|
||||||
|
entry.setSize(data.length);
|
||||||
|
entry.setMethod(ZipOutputStream.STORED);
|
||||||
|
entry.setCrc(crc.getValue());
|
||||||
|
out.putNextEntry(entry);
|
||||||
|
out.write(data);
|
||||||
|
out.closeEntry();
|
||||||
|
|
||||||
|
//Write fake AndroidManifest.xml file to support original aapt
|
||||||
|
entry = zip.getEntry("AndroidManifest.xml");
|
||||||
|
if (entry != null) {
|
||||||
|
in = zip.getInputStream(entry);
|
||||||
|
byte[] manifest = IOUtils.toByteArray(in);
|
||||||
|
CRC32 manifestCrc = new CRC32();
|
||||||
|
manifestCrc.update(manifest);
|
||||||
|
entry.setSize(manifest.length);
|
||||||
|
entry.setCompressedSize(-1);
|
||||||
|
entry.setCrc(manifestCrc.getValue());
|
||||||
|
out.putNextEntry(entry);
|
||||||
|
out.write(manifest);
|
||||||
|
out.closeEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
zip.close();
|
||||||
|
LOGGER.info("Framework installed to: " + outFile);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new AndrolibException(ex);
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(in);
|
||||||
|
IOUtils.closeQuietly(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void listFrameworkDirectory() throws AndrolibException {
|
||||||
|
File dir = getFrameworkDirectory();
|
||||||
|
if (dir == null) {
|
||||||
|
LOGGER.severe("No framework directory found. Nothing to list.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (File file : Objects.requireNonNull(dir.listFiles())) {
|
||||||
|
if (file.isFile() && file.getName().endsWith(".apk")) {
|
||||||
|
LOGGER.info(file.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void publicizeResources(File arscFile) throws AndrolibException {
|
||||||
|
byte[] data = new byte[(int) arscFile.length()];
|
||||||
|
|
||||||
|
try(InputStream in = Files.newInputStream(arscFile.toPath());
|
||||||
|
OutputStream out = Files.newOutputStream(arscFile.toPath())) {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
in.read(data);
|
||||||
|
publicizeResources(data);
|
||||||
|
out.write(data);
|
||||||
|
} catch (IOException ex){
|
||||||
|
throw new AndrolibException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void publicizeResources(byte[] arsc) throws AndrolibException {
|
||||||
|
publicizeResources(arsc, ARSCDecoder.decode(new ByteArrayInputStream(arsc), true, true).getFlagsOffsets());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void publicizeResources(byte[] arsc, ARSCDecoder.FlagsOffset[] flagsOffsets) {
|
||||||
|
for (ARSCDecoder.FlagsOffset flags : flagsOffsets) {
|
||||||
|
int offset = flags.offset + 3;
|
||||||
|
int end = offset + 4 * flags.count;
|
||||||
|
while (offset < end) {
|
||||||
|
arsc[offset] |= (byte) 0x40;
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFrameworkDirectory() throws AndrolibException {
|
||||||
|
if (mFrameworkDirectory != null) {
|
||||||
|
return mFrameworkDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
String path;
|
||||||
|
|
||||||
|
// use default framework path or specified on the command line
|
||||||
|
path = config.frameworkDirectory;
|
||||||
|
|
||||||
|
File dir = new File(path);
|
||||||
|
|
||||||
|
if (!dir.isDirectory() && dir.isFile()) {
|
||||||
|
throw new AndrolibException("--frame-path is set to a file, not a directory.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir.getParentFile() != null && dir.getParentFile().isFile()) {
|
||||||
|
throw new AndrolibException("Please remove file at " + dir.getParentFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! dir.exists()) {
|
||||||
|
if (! dir.mkdirs()) {
|
||||||
|
if (config.frameworkDirectory != null) {
|
||||||
|
LOGGER.severe("Can't create Framework directory: " + dir);
|
||||||
|
}
|
||||||
|
throw new AndrolibException(String.format(
|
||||||
|
"Can't create directory: (%s). Pass a writable path with --frame-path {DIR}. ", dir
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.frameworkDirectory == null) {
|
||||||
|
if (! dir.canWrite()) {
|
||||||
|
LOGGER.severe(String.format("WARNING: Could not write to (%1$s), using %2$s instead...",
|
||||||
|
dir.getAbsolutePath(), System.getProperty("java.io.tmpdir")));
|
||||||
|
LOGGER.severe("Please be aware this is a volatile directory and frameworks could go missing, " +
|
||||||
|
"please utilize --frame-path if the default storage directory is unavailable");
|
||||||
|
|
||||||
|
dir = new File(System.getProperty("java.io.tmpdir"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mFrameworkDirectory = dir;
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFrameworkApk(int id, String frameTag)
|
||||||
|
throws AndrolibException {
|
||||||
|
File dir = getFrameworkDirectory();
|
||||||
|
File apk;
|
||||||
|
|
||||||
|
if (frameTag != null) {
|
||||||
|
apk = new File(dir, String.valueOf(id) + '-' + frameTag + ".apk");
|
||||||
|
if (apk.exists()) {
|
||||||
|
return apk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apk = new File(dir, id + ".apk");
|
||||||
|
if (apk.exists()) {
|
||||||
|
return apk;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 1) {
|
||||||
|
try (InputStream in = getAndroidFrameworkResourcesAsStream();
|
||||||
|
OutputStream out = Files.newOutputStream(apk.toPath())) {
|
||||||
|
IOUtils.copy(in, out);
|
||||||
|
return apk;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new AndrolibException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new CantFindFrameworkResException(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void emptyFrameworkDirectory() throws AndrolibException {
|
||||||
|
File dir = getFrameworkDirectory();
|
||||||
|
File apk;
|
||||||
|
|
||||||
|
apk = new File(dir, "1.apk");
|
||||||
|
|
||||||
|
if (! apk.exists()) {
|
||||||
|
LOGGER.warning("Can't empty framework directory, no file found at: " + apk.getAbsolutePath());
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (apk.exists() && Objects.requireNonNull(dir.listFiles()).length > 1 && ! config.forceDeleteFramework) {
|
||||||
|
LOGGER.warning("More than default framework detected. Please run command with `--force` parameter to wipe framework directory.");
|
||||||
|
} else {
|
||||||
|
for (File file : Objects.requireNonNull(dir.listFiles())) {
|
||||||
|
if (file.isFile() && file.getName().endsWith(".apk")) {
|
||||||
|
LOGGER.info("Removing " + file.getName() + " framework file...");
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
throw new AndrolibException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream getAndroidFrameworkResourcesAsStream() {
|
||||||
|
return Jar.class.getResourceAsStream("/brut/androlib/android-framework.jar");
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ package brut.androlib;
|
|||||||
|
|
||||||
import brut.androlib.exceptions.AndrolibException;
|
import brut.androlib.exceptions.AndrolibException;
|
||||||
import brut.androlib.res.AndrolibResources;
|
import brut.androlib.res.AndrolibResources;
|
||||||
|
import brut.androlib.res.Framework;
|
||||||
import brut.common.BrutException;
|
import brut.common.BrutException;
|
||||||
import brut.directory.DirUtil;
|
import brut.directory.DirUtil;
|
||||||
import brut.directory.Directory;
|
import brut.directory.Directory;
|
||||||
@ -138,8 +139,8 @@ public abstract class TestUtils {
|
|||||||
|
|
||||||
static File getFrameworkDirectory() throws AndrolibException {
|
static File getFrameworkDirectory() throws AndrolibException {
|
||||||
Config config = Config.getDefaultConfig();
|
Config config = Config.getDefaultConfig();
|
||||||
AndrolibResources androlibResources = new AndrolibResources(config);
|
Framework framework = new Framework(config);
|
||||||
return androlibResources.getFrameworkDirectory();
|
return framework.getFrameworkDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ResValueElementQualifier implements ElementQualifier {
|
public static class ResValueElementQualifier implements ElementQualifier {
|
||||||
|
@ -19,6 +19,7 @@ package brut.androlib.aapt1;
|
|||||||
import brut.androlib.*;
|
import brut.androlib.*;
|
||||||
import brut.androlib.exceptions.AndrolibException;
|
import brut.androlib.exceptions.AndrolibException;
|
||||||
import brut.androlib.res.AndrolibResources;
|
import brut.androlib.res.AndrolibResources;
|
||||||
|
import brut.androlib.res.Framework;
|
||||||
import brut.directory.ExtFile;
|
import brut.directory.ExtFile;
|
||||||
import brut.common.BrutException;
|
import brut.common.BrutException;
|
||||||
import brut.util.OS;
|
import brut.util.OS;
|
||||||
@ -55,7 +56,7 @@ public class SharedLibraryTest extends BaseTest {
|
|||||||
config.frameworkDirectory = sTmpDir.getAbsolutePath();
|
config.frameworkDirectory = sTmpDir.getAbsolutePath();
|
||||||
config.frameworkTag = "building";
|
config.frameworkTag = "building";
|
||||||
|
|
||||||
new AndrolibResources(config).installFramework(new File(sTmpDir + File.separator + apkName));
|
new Framework(config).installFramework(new File(sTmpDir + File.separator + apkName));
|
||||||
|
|
||||||
assertTrue(fileExists("2-building.apk"));
|
assertTrue(fileExists("2-building.apk"));
|
||||||
}
|
}
|
||||||
@ -67,7 +68,7 @@ public class SharedLibraryTest extends BaseTest {
|
|||||||
Config config = Config.getDefaultConfig();
|
Config config = Config.getDefaultConfig();
|
||||||
config.frameworkDirectory = sTmpDir.getAbsolutePath();
|
config.frameworkDirectory = sTmpDir.getAbsolutePath();
|
||||||
|
|
||||||
new AndrolibResources(config).installFramework(new File(sTmpDir + File.separator + apkName));
|
new Framework(config).installFramework(new File(sTmpDir + File.separator + apkName));
|
||||||
|
|
||||||
assertTrue(fileExists("2.apk"));
|
assertTrue(fileExists("2.apk"));
|
||||||
}
|
}
|
||||||
@ -83,7 +84,7 @@ public class SharedLibraryTest extends BaseTest {
|
|||||||
config.frameworkTag = "shared";
|
config.frameworkTag = "shared";
|
||||||
|
|
||||||
// install library/framework
|
// install library/framework
|
||||||
new AndrolibResources(config).installFramework(new File(sTmpDir + File.separator + library));
|
new Framework(config).installFramework(new File(sTmpDir + File.separator + library));
|
||||||
assertTrue(fileExists("2-shared.apk"));
|
assertTrue(fileExists("2-shared.apk"));
|
||||||
|
|
||||||
// decode client.apk
|
// decode client.apk
|
||||||
|
Loading…
Reference in New Issue
Block a user