public void buildApk(File appDir, File outApk) throws AndrolibException { LOGGER.info("Building apk file..."); if (outApk.exists()) { outApk.delete(); } else { File outDir = outApk.getParentFile(); if (outDir != null && !outDir.exists()) { outDir.mkdirs(); } } File assetDir = new File(appDir, "assets"); if (!assetDir.exists()) { assetDir = null; } mAndRes.aaptPackage(outApk, null, null, new File(appDir, APK_DIRNAME), assetDir, null); }
public File getFrameworkApk(int id, String frameTag) throws AndrolibException { File dir = getFrameworkDir(); File apk; if (frameTag != null) { apk = new File(dir, String.valueOf(id) + '-' + frameTag + ".apk"); if (apk.exists()) { return apk; } } apk = new File(dir, String.valueOf(id) + ".apk"); if (apk.exists()) { return apk; } if (id == 1) { InputStream in = null; OutputStream out = null; try { in = AndrolibResources.class.getResourceAsStream("/brut/androlib/android-framework.jar"); out = new FileOutputStream(apk); IOUtils.copy(in, out); return apk; } catch (IOException ex) { throw new AndrolibException(ex); } finally { if (in != null) { try { in.close(); } catch (IOException ex) { } } if (out != null) { try { out.close(); } catch (IOException ex) { } } } } throw new CantFindFrameworkResException(id); }
private File getFrameworkDir() throws AndrolibException { File dir = new File( System.getProperty("user.home") + File.separatorChar + "apktool" + File.separatorChar + "framework"); if (!dir.exists()) { if (!dir.mkdirs()) { throw new AndrolibException("Can't create directory: " + dir); } } return dir; }
public boolean buildManifest(ExtFile appDir, Map<String, Object> usesFramework) throws BrutException { try { if (!new File(appDir, "AndroidManifest.xml").exists()) { return false; } if (!apkOptions.forceBuildAll) { LOGGER.info("Checking whether resources has changed..."); } File apkDir = new File(appDir, APK_DIRNAME); if (apkOptions.debugMode) { mAndRes.remove_application_debug(new File(apkDir, "AndroidManifest.xml").getAbsolutePath()); } if (apkOptions.forceBuildAll || isModified( newFiles(APK_MANIFEST_FILENAMES, appDir), newFiles(APK_MANIFEST_FILENAMES, apkDir))) { LOGGER.info("Building AndroidManifest.xml..."); File apkFile = File.createTempFile("APKTOOL", null); apkFile.delete(); File ninePatch = new File(appDir, "9patch"); if (!ninePatch.exists()) { ninePatch = null; } mAndRes.aaptPackage( apkFile, new File(appDir, "AndroidManifest.xml"), null, ninePatch, null, parseUsesFramework(usesFramework)); Directory tmpDir = new ExtFile(apkFile).getDirectory(); tmpDir.copyToDir(apkDir, APK_MANIFEST_FILENAMES); } return true; } catch (IOException | DirectoryException ex) { throw new AndrolibException(ex); } catch (AndrolibException ex) { LOGGER.warning("Parse AndroidManifest.xml failed, treat it as raw file."); return buildManifestRaw(appDir); } }
public boolean detectWhetherAppIsFramework(File appDir) throws AndrolibException { File publicXml = new File(appDir, "res/values/public.xml"); if (!publicXml.exists()) { return false; } Iterator<String> it; try { it = IOUtils.lineIterator(new FileReader(new File(appDir, "res/values/public.xml"))); } catch (FileNotFoundException ex) { throw new AndrolibException("Could not detect whether app is framework one", ex); } it.next(); it.next(); return it.next().contains("0x01"); }
public void buildLib(File appDir) throws AndrolibException { File working = new File(appDir, "lib"); if (!working.exists()) { return; } File stored = new File(appDir, APK_DIRNAME + "/lib"); if (apkOptions.forceBuildAll || isModified(working, stored)) { LOGGER.info("Copying libs..."); try { OS.rmdir(stored); OS.cpdir(working, stored); } catch (BrutException ex) { throw new AndrolibException(ex); } } }
public boolean buildSourcesJava(File appDir) throws AndrolibException { File javaDir = new File(appDir, "src"); if (!javaDir.exists()) { return false; } File dex = new File(appDir, APK_DIRNAME + "/classes.dex"); if (!apkOptions.forceBuildAll) { LOGGER.info("Checking whether sources has changed..."); } if (apkOptions.forceBuildAll || isModified(javaDir, dex)) { LOGGER.info("Building java sources..."); dex.delete(); new AndrolibJava().build(javaDir, dex); } return true; }
public boolean buildResourcesFull(File appDir, Map<String, Object> usesFramework) throws AndrolibException { try { if (!new File(appDir, "res").exists()) { return false; } if (!apkOptions.forceBuildAll) { LOGGER.info("Checking whether resources has changed..."); } File apkDir = new File(appDir, APK_DIRNAME); if (apkOptions.forceBuildAll || isModified( newFiles(APP_RESOURCES_FILENAMES, appDir), newFiles(APK_RESOURCES_FILENAMES, apkDir))) { LOGGER.info("Building resources..."); File apkFile = File.createTempFile("APKTOOL", null); apkFile.delete(); File ninePatch = new File(appDir, "9patch"); if (!ninePatch.exists()) { ninePatch = null; } mAndRes.aaptPackage( apkFile, new File(appDir, "AndroidManifest.xml"), new File(appDir, "res"), ninePatch, null, parseUsesFramework(usesFramework)); Directory tmpDir = new ExtFile(apkFile).getDirectory(); tmpDir.copyToDir( apkDir, tmpDir.containsDir("res") ? APK_RESOURCES_FILENAMES : APK_RESOURCES_WITHOUT_RES_FILENAMES); // delete tmpDir apkFile.delete(); } return true; } catch (IOException | BrutException ex) { throw new AndrolibException(ex); } }
public boolean buildSourcesRaw(File appDir, String filename) throws AndrolibException { File working = new File(appDir, filename); if (!working.exists()) { return false; } File stored = new File(appDir, APK_DIRNAME + "/" + filename); if (apkOptions.forceBuildAll || isModified(working, stored)) { LOGGER.info("Copying " + appDir.toString() + " " + filename + " file..."); try { BrutIO.copyAndClose(new FileInputStream(working), new FileOutputStream(stored)); return true; } catch (IOException ex) { throw new AndrolibException(ex); } } return true; }
public void writeOriginalFiles(ExtFile apkFile, File outDir) throws AndrolibException { LOGGER.info("Copying original files..."); File originalDir = new File(outDir, "original"); if (!originalDir.exists()) { originalDir.mkdirs(); } try { Directory in = apkFile.getDirectory(); if (in.containsFile("AndroidManifest.xml")) { in.copyToDir(originalDir, "AndroidManifest.xml"); } if (in.containsDir("META-INF")) { in.copyToDir(originalDir, "META-INF"); } } catch (DirectoryException ex) { throw new AndrolibException(ex); } }
public void buildCopyOriginalFiles(File appDir) throws AndrolibException { if (apkOptions.copyOriginalFiles) { File originalDir = new File(appDir, "original"); if (originalDir.exists()) { try { LOGGER.info("Copy original files..."); Directory in = (new ExtFile(originalDir)).getDirectory(); if (in.containsFile("AndroidManifest.xml")) { LOGGER.info("Copy AndroidManifest.xml..."); in.copyToDir(new File(appDir, APK_DIRNAME), "AndroidManifest.xml"); } if (in.containsDir("META-INF")) { LOGGER.info("Copy META-INF..."); in.copyToDir(new File(appDir, APK_DIRNAME), "META-INF"); } } catch (DirectoryException ex) { throw new AndrolibException(ex); } } } }
public void buildUnknownFiles(File appDir, File outFile, Map<String, Object> meta) throws AndrolibException { File file; Path globalPath = Paths.get(appDir.getPath() + File.separatorChar + UNK_DIRNAME); if (meta.containsKey("unknownFiles")) { LOGGER.info("Copying unknown files/dir..."); Map<String, String> files = (Map<String, String>) meta.get("unknownFiles"); try { // set our filesystem options Map<String, String> zip_properties = new HashMap<>(); zip_properties.put("create", "false"); zip_properties.put("encoding", "UTF-8"); // create filesystem Path path = Paths.get(outFile.getAbsolutePath()); // loop through files inside for (Map.Entry<String, String> entry : files.entrySet()) { file = new File(globalPath.toFile(), entry.getKey()); if (file.isFile() && file.exists()) { insertFolder( path, zip_properties, file.getParentFile(), entry.getValue(), globalPath.toAbsolutePath()); insertFile(path, zip_properties, file, entry.getValue(), globalPath.toAbsolutePath()); } } } catch (IOException ex) { throw new AndrolibException(ex); } } }
private boolean isModified(File working, File stored) { return !stored.exists() || BrutIO.recursiveModifiedTime(working) > BrutIO.recursiveModifiedTime(stored); }