/** * Adds all non-class files from folder, so that we can add META-INF/services resources. */ private void addResourcesFromFolder( ApkBuilder builder, File folder ) throws SealedApkException, DuplicateFileException, ApkCreationException, IOException { final int folderPathLength = folder.getCanonicalPath().length(); final List<File> resourceFiles = new ArrayList<>( ); collectFiles( folder, resourceFiles ); for ( final File resourceFile : resourceFiles ) { final String resourceName = resourceFile .getCanonicalPath() .substring( folderPathLength + 1 ) .replaceAll( "\\\\", "/" ); getLog().info( "Adding resource " + resourceFile + " : " + resourceName ); builder.addFile( resourceFile, resourceName ); } }
final String debugKeyStore = signWithDebugKeyStore ? ApkBuilder.getDebugKeystore() : null; final ApkBuilder apkBuilder = new ApkBuilder( outputFile, zipArchive, dexFile, debugKeyStore, null ); if ( apkDebug ) apkBuilder.setDebugMode( true ); apkBuilder.addResourcesFromJar( innerJar ); apkBuilder.addResourcesFromJar( jarFile ); apkBuilder.addNativeLibraries( nativeFolder ); apkBuilder.sealApk(); e.getArchivePath(), e.getFile1(), e.getFile2() ); throw new MojoExecutionException( msg, e );
/** * Returns the file's sha1, computing it if necessary. * @return the sha1 * @throws Sha1Exception */ private String getSha1() throws Sha1Exception { if (mSha1 == null) { mSha1 = JarListSanitizer.getSha1(mFile); } return mSha1; }
public void addNativeLibraries(List<FileEntry> entries) throws SealedApkException, DuplicateFileException, ApkCreationException { if (mIsSealed) { throw new SealedApkException("APK is already sealed"); } for (FileEntry entry : entries) { try { doAddFile(entry.mFile, entry.mPath); } catch (IOException e) { mBuilder.cleanUp(); throw new ApkCreationException(e, "Failed to add %s", entry.mFile); } } }
public void addNativeLibraries(List<FileEntry> entries) throws SealedApkException, DuplicateFileException, ApkCreationException { if (mIsSealed) { throw new SealedApkException("APK is already sealed"); } for (FileEntry entry : entries) { try { doAddFile(entry.mFile, entry.mPath); } catch (IOException e) { mBuilder.cleanUp(); throw new ApkCreationException(e, "Failed to add %s", entry.mFile); } } }
/** * Adds the resources from a source folder. * @param sourceFolder the source folder. * @throws ApkCreationException if an error occurred * @throws SealedApkException if the APK is already sealed. * @throws DuplicateFileException if a file conflicts with another already added to the APK * at the same location inside the APK archive. */ public void addSourceFolder(File sourceFolder) throws ApkCreationException, SealedApkException, DuplicateFileException { if (mIsSealed) { throw new SealedApkException("APK is already sealed"); } addSourceFolder(this, sourceFolder); }
@NonNull public List<File> findInputFiles() throws IOException { // gather source files. SourceSearcher searcher = new SourceSearcher(mSourceFolders, EXT_RS, EXT_FS); FileGatherer fileGatherer = new FileGatherer(); searcher.search(fileGatherer); return fileGatherer.getFiles(); }
private void doAddFile(File file, String archivePath) throws DuplicateFileException, IOException { verbosePrintln("%1$s => %2$s", file, archivePath); File duplicate = checkFileForDuplicate(archivePath); if (duplicate != null) { throw new DuplicateFileException(archivePath, duplicate, file); } mAddedFiles.put(archivePath, file); mBuilder.writeFile(file, archivePath); }
private void processFile(@NonNull final File file, @NonNull final SourceFileProcessor processor) throws IOException { if (file.isFile()) { // get the extension of the file. String ext = checkExtension(file); if (ext != null) { processor.processFile(file, ext); } } else if (file.isDirectory()) { File[] children = file.listFiles(); if (children != null) { for (File child : children) { processFile(child, processor); } } } }
@Override public boolean checkEntry(String archivePath) throws ZipAbortException { verbosePrintln("=> %s", archivePath); File duplicate = checkFileForDuplicate(archivePath); if (duplicate != null) { throw new DuplicateFileException(archivePath, duplicate, mInputFile); } else { mAddedFiles.put(archivePath, mInputFile); } return true; } }
/** * Creates a new instance. * * This creates a new builder that will create the specified output file, using the two * mandatory given input files. * * Optional {@link PrivateKey} and {@link X509Certificate} can be provided to sign the APK. * * An optional {@link PrintStream} can also be provided for verbose output. If null, there will * be no output. * * @param apkFile the file to create * @param resFile the file representing the packaged resource file. * @param dexFile the file representing the dex file. This can be null for apk with no code. * @param key the private key used to sign the package. Can be null. * @param certificate the certificate used to sign the package. Can be null. * @param verboseStream the stream to which verbose output should go. If null, verbose mode * is not enabled. * @throws ApkCreationException */ public ApkBuilder(File apkFile, File resFile, File dexFile, PrivateKey key, X509Certificate certificate, PrintStream verboseStream) throws ApkCreationException { init(apkFile, resFile, dexFile, key, certificate, verboseStream); }
public void cleanDependencies() { if (mDependencyFiles != null) { for (DependencyFile depFile : mDependencyFiles) { depFile.getFile().delete(); } } }
/** * Checks a file to make sure it should be packaged as standard resources. * @param fileName the name of the file (including extension) * @return true if the file should be packaged as standard java resources. */ public static boolean checkFileForPackaging(String fileName) { String[] fileSegments = fileName.split("\\."); String fileExt = ""; if (fileSegments.length > 1) { fileExt = fileSegments[fileSegments.length-1]; } return checkFileForPackaging(fileName, fileExt); }
protected static void deleteFolder(File folder) { File[] files = folder.listFiles(); if (files != null && files.length > 0) { for (File file : files) { if (file.isDirectory()) { deleteFolder(file); } else { file.delete(); } } } folder.delete(); } }
public void search(@NonNull SourceFileProcessor processor) throws IOException { for (File file : mSourceFolders) { processFile(file, processor); } }
/** * Adds a file to the APK at a given path * @param file the file to add * @param archivePath the path of the file inside the APK archive. * @throws ApkCreationException if an error occurred * @throws SealedApkException if the APK is already sealed. * @throws DuplicateFileException if a file conflicts with another already added to the APK * at the same location inside the APK archive. */ @Override public void addFile(File file, String archivePath) throws ApkCreationException, SealedApkException, DuplicateFileException { if (mIsSealed) { throw new SealedApkException("APK is already sealed"); } try { doAddFile(file, archivePath); } catch (DuplicateFileException e) { mBuilder.cleanUp(); throw e; } catch (Exception e) { mBuilder.cleanUp(); throw new ApkCreationException(e, "Failed to add %s", file); } }
/** * Seals the APK, and signs it if necessary. * @throws ApkCreationException * @throws ApkCreationException if an error occurred * @throws SealedApkException if the APK is already sealed. */ public void sealApk() throws ApkCreationException, SealedApkException { if (mIsSealed) { throw new SealedApkException("APK is already sealed"); } // close and sign the application package. try { mBuilder.close(); mIsSealed = true; } catch (Exception e) { throw new ApkCreationException(e, "Failed to seal APK"); } finally { mBuilder.cleanUp(); } }
private void addSecondaryDexes( File dexFile, ApkBuilder apkBuilder ) throws ApkCreationException, SealedApkException, DuplicateFileException { int dexNumber = 2; String dexFileName = getNextDexFileName( dexNumber ); File secondDexFile = createNextDexFile( dexFile, dexFileName ); while ( secondDexFile.exists() ) { apkBuilder.addFile( secondDexFile, dexFileName ); dexNumber++; dexFileName = getNextDexFileName( dexNumber ); secondDexFile = createNextDexFile( dexFile, dexFileName ); } }
@Override public boolean checkEntry(String archivePath) throws ZipAbortException { verbosePrintln("=> %s", archivePath); File duplicate = checkFileForDuplicate(archivePath); if (duplicate != null) { throw new DuplicateFileException(archivePath, duplicate, mInputFile); } else { mAddedFiles.put(archivePath, mInputFile); } return true; } }
/** * Seals the APK, and signs it if necessary. * @throws ApkCreationException * @throws ApkCreationException if an error occurred * @throws SealedApkException if the APK is already sealed. */ public void sealApk() throws ApkCreationException, SealedApkException { if (mIsSealed) { throw new SealedApkException("APK is already sealed"); } // close and sign the application package. try { mBuilder.close(); mIsSealed = true; } catch (Exception e) { throw new ApkCreationException(e, "Failed to seal APK"); } finally { mBuilder.cleanUp(); } }