SharedLibraryLoader: separate out extraction

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2019-10-13 11:05:03 +02:00
parent 21af2f2f62
commit 3c8fef2655

View File

@ -25,16 +25,7 @@ public final class SharedLibraryLoader {
private SharedLibraryLoader() { private SharedLibraryLoader() {
} }
public static void loadSharedLibrary(final Context context, final String libName) { public static boolean extractLibrary(final Context context, final String libName, final File destination) throws IOException {
Throwable noAbiException;
try {
System.loadLibrary(libName);
return;
} catch (final UnsatisfiedLinkError e) {
Log.d(TAG, "Failed to load library normally, so attempting to extract from apk", e);
noAbiException = e;
}
final Collection<String> apks = new HashSet<>(); final Collection<String> apks = new HashSet<>();
if (context.getApplicationInfo().sourceDir != null) if (context.getApplicationInfo().sourceDir != null)
apks.add(context.getApplicationInfo().sourceDir); apks.add(context.getApplicationInfo().sourceDir);
@ -56,29 +47,44 @@ public final class SharedLibraryLoader {
final ZipEntry zipEntry = zipFile.getEntry(libZipPath); final ZipEntry zipEntry = zipFile.getEntry(libZipPath);
if (zipEntry == null) if (zipEntry == null)
continue; continue;
File f = null; Log.d(TAG, "Extracting apk:/" + libZipPath + " to " + destination.getAbsolutePath());
try { try (final FileOutputStream out = new FileOutputStream(destination);
f = File.createTempFile("lib", ".so", context.getCacheDir()); final InputStream in = zipFile.getInputStream(zipEntry)) {
Log.d(TAG, "Extracting apk:/" + libZipPath + " to " + f.getAbsolutePath() + " and loading"); int len;
try (final FileOutputStream out = new FileOutputStream(f); while ((len = in.read(buffer)) != -1) {
final InputStream in = zipFile.getInputStream(zipEntry)) { out.write(buffer, 0, len);
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
} }
System.load(f.getAbsolutePath());
return;
} catch (final Exception e) {
Log.d(TAG, "Failed to load library apk:/" + libZipPath, e);
noAbiException = e;
} finally {
if (f != null)
// noinspection ResultOfMethodCallIgnored
f.delete();
} }
return true;
} }
} }
return false;
}
public static void loadSharedLibrary(final Context context, final String libName) {
Throwable noAbiException;
try {
System.loadLibrary(libName);
return;
} catch (final UnsatisfiedLinkError e) {
Log.d(TAG, "Failed to load library normally, so attempting to extract from apk", e);
noAbiException = e;
}
File f = null;
try {
f = File.createTempFile("lib", ".so", context.getCodeCacheDir());
if (extractLibrary(context, libName, f)) {
System.load(f.getAbsolutePath());
return;
}
} catch (final Exception e) {
Log.d(TAG, "Failed to load library apk:/" + libName, e);
noAbiException = e;
} finally {
if (f != null)
// noinspection ResultOfMethodCallIgnored
f.delete();
}
if (noAbiException instanceof RuntimeException) if (noAbiException instanceof RuntimeException)
throw (RuntimeException) noAbiException; throw (RuntimeException) noAbiException;
throw new RuntimeException(noAbiException); throw new RuntimeException(noAbiException);