This source file includes following definitions.
- loadNativeLibrariesUsingWorkaroundForTesting
- tryLoadLibraryUsingWorkaround
- getWorkaroundLibDir
- getWorkaroundLibFile
- unpackLibrariesOnce
- deleteWorkaroundLibrariesAsynchronously
- deleteWorkaroundLibrariesSynchronously
- deleteDirectorySync
package org.chromium.base.library_loader;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Build;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class LibraryLoaderHelper {
private static final String TAG = "LibraryLoaderHelper";
private static final String LIB_DIR = "lib";
private static boolean sLibrariesWereUnpacked = false;
public static boolean loadNativeLibrariesUsingWorkaroundForTesting(Context context) {
for (String library : NativeLibraries.LIBRARIES) {
if (!tryLoadLibraryUsingWorkaround(context, library)) {
return false;
}
}
return true;
}
static boolean tryLoadLibraryUsingWorkaround(Context context, String library) {
assert context != null;
File libFile = getWorkaroundLibFile(context, library);
if (!libFile.exists() && !unpackLibrariesOnce(context)) {
return false;
}
try {
System.load(libFile.getAbsolutePath());
return true;
} catch (UnsatisfiedLinkError e) {
return false;
}
}
public static File getWorkaroundLibDir(Context context) {
return context.getDir(LIB_DIR, Context.MODE_PRIVATE);
}
private static File getWorkaroundLibFile(Context context, String library) {
String libName = System.mapLibraryName(library);
return new File(getWorkaroundLibDir(context), libName);
}
private static boolean unpackLibrariesOnce(Context context) {
if (sLibrariesWereUnpacked) {
return false;
}
sLibrariesWereUnpacked = true;
File libDir = getWorkaroundLibDir(context);
deleteDirectorySync(libDir);
try {
ApplicationInfo appInfo = context.getApplicationInfo();
ZipFile file = new ZipFile(new File(appInfo.sourceDir), ZipFile.OPEN_READ);
for (String libName : NativeLibraries.LIBRARIES) {
String jniNameInApk = "lib/" + Build.CPU_ABI + "/" +
System.mapLibraryName(libName);
final ZipEntry entry = file.getEntry(jniNameInApk);
if (entry == null) {
Log.e(TAG, appInfo.sourceDir + " doesn't have file " + jniNameInApk);
file.close();
deleteDirectorySync(libDir);
return false;
}
File outputFile = getWorkaroundLibFile(context, libName);
Log.i(TAG, "Extracting native libraries into " + outputFile.getAbsolutePath());
assert !outputFile.exists();
try {
if (!outputFile.createNewFile()) {
throw new IOException();
}
InputStream is = null;
FileOutputStream os = null;
try {
is = file.getInputStream(entry);
os = new FileOutputStream(outputFile);
int count = 0;
byte[] buffer = new byte[16 * 1024];
while ((count = is.read(buffer)) > 0) {
os.write(buffer, 0, count);
}
} finally {
try {
if (is != null) is.close();
} finally {
if (os != null) os.close();
}
}
outputFile.setReadable(true, false);
outputFile.setExecutable(true, false);
outputFile.setWritable(true);
} catch (IOException e) {
if (outputFile.exists()) {
if (!outputFile.delete()) {
Log.e(TAG, "Failed to delete " + outputFile.getAbsolutePath());
}
}
file.close();
throw e;
}
}
file.close();
return true;
} catch (IOException e) {
Log.e(TAG, "Failed to unpack native libraries", e);
deleteDirectorySync(libDir);
return false;
}
}
static void deleteWorkaroundLibrariesAsynchronously(final Context context) {
new Thread() {
@Override
public void run() {
deleteWorkaroundLibrariesSynchronously(context);
}
}.start();
}
public static void deleteWorkaroundLibrariesSynchronously(Context context) {
File libDir = getWorkaroundLibDir(context);
deleteDirectorySync(libDir);
}
private static void deleteDirectorySync(File dir) {
try {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
String fileName = file.getName();
if (!file.delete()) {
Log.e(TAG, "Failed to remove " + file.getAbsolutePath());
}
}
}
if (!dir.delete()) {
Log.w(TAG, "Failed to remove " + dir.getAbsolutePath());
}
return;
} catch (Exception e) {
Log.e(TAG, "Failed to remove old libs, ", e);
}
}
}