Methods Summary |
---|
public static int | copyNativeBinaries(com.android.internal.content.NativeLibraryHelper$Handle handle, java.io.File sharedLibraryDir, java.lang.String abi)Copies native binaries to a shared library directory.
for (long apkHandle : handle.apkHandles) {
int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi);
if (res != INSTALL_SUCCEEDED) {
return res;
}
}
return INSTALL_SUCCEEDED;
|
public static int | copyNativeBinariesForSupportedAbi(com.android.internal.content.NativeLibraryHelper$Handle handle, java.io.File libraryRoot, java.lang.String[] abiList, boolean useIsaSubdir)
createNativeLibrarySubdir(libraryRoot);
/*
* If this is an internal application or our nativeLibraryPath points to
* the app-lib directory, unpack the libraries if necessary.
*/
int abi = findSupportedAbi(handle, abiList);
if (abi >= 0) {
/*
* If we have a matching instruction set, construct a subdir under the native
* library root that corresponds to this instruction set.
*/
final String instructionSet = VMRuntime.getInstructionSet(abiList[abi]);
final File subDir;
if (useIsaSubdir) {
final File isaSubdir = new File(libraryRoot, instructionSet);
createNativeLibrarySubdir(isaSubdir);
subDir = isaSubdir;
} else {
subDir = libraryRoot;
}
int copyRet = copyNativeBinaries(handle, subDir, abiList[abi]);
if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
return copyRet;
}
}
return abi;
|
public static int | copyNativeBinariesWithOverride(com.android.internal.content.NativeLibraryHelper$Handle handle, java.io.File libraryRoot, java.lang.String abiOverride)
try {
if (handle.multiArch) {
// Warn if we've set an abiOverride for multi-lib packages..
// By definition, we need to copy both 32 and 64 bit libraries for
// such packages.
if (abiOverride != null && !CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
}
int copyRet = PackageManager.NO_NATIVE_LIBRARIES;
if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
copyRet = copyNativeBinariesForSupportedAbi(handle, libraryRoot,
Build.SUPPORTED_32_BIT_ABIS, true /* use isa specific subdirs */);
if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
Slog.w(TAG, "Failure copying 32 bit native libraries; copyRet=" +copyRet);
return copyRet;
}
}
if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
copyRet = copyNativeBinariesForSupportedAbi(handle, libraryRoot,
Build.SUPPORTED_64_BIT_ABIS, true /* use isa specific subdirs */);
if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
Slog.w(TAG, "Failure copying 64 bit native libraries; copyRet=" +copyRet);
return copyRet;
}
}
} else {
String cpuAbiOverride = null;
if (CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
cpuAbiOverride = null;
} else if (abiOverride != null) {
cpuAbiOverride = abiOverride;
}
String[] abiList = (cpuAbiOverride != null) ?
new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
hasRenderscriptBitcode(handle)) {
abiList = Build.SUPPORTED_32_BIT_ABIS;
}
int copyRet = copyNativeBinariesForSupportedAbi(handle, libraryRoot, abiList,
true /* use isa specific subdirs */);
if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
Slog.w(TAG, "Failure copying native libraries [errorCode=" + copyRet + "]");
return copyRet;
}
}
return PackageManager.INSTALL_SUCCEEDED;
} catch (IOException e) {
Slog.e(TAG, "Copying native libraries failed", e);
return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
}
|
private static void | createNativeLibrarySubdir(java.io.File path)
if (!path.isDirectory()) {
path.delete();
if (!path.mkdir()) {
throw new IOException("Cannot create " + path.getPath());
}
try {
Os.chmod(path.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
} catch (ErrnoException e) {
throw new IOException("Cannot chmod native library directory "
+ path.getPath(), e);
}
} else if (!SELinux.restorecon(path)) {
throw new IOException("Cannot set SELinux context for " + path.getPath());
}
|
public static int | findSupportedAbi(com.android.internal.content.NativeLibraryHelper$Handle handle, java.lang.String[] supportedAbis)Checks if a given APK contains native code for any of the provided
{@code supportedAbis}. Returns an index into {@code supportedAbis} if a matching
ABI is found, {@link PackageManager#NO_NATIVE_LIBRARIES} if the
APK doesn't contain any native code, and
{@link PackageManager#INSTALL_FAILED_NO_MATCHING_ABIS} if none of the ABIs match.
int finalRes = NO_NATIVE_LIBRARIES;
for (long apkHandle : handle.apkHandles) {
final int res = nativeFindSupportedAbi(apkHandle, supportedAbis);
if (res == NO_NATIVE_LIBRARIES) {
// No native code, keep looking through all APKs.
} else if (res == INSTALL_FAILED_NO_MATCHING_ABIS) {
// Found some native code, but no ABI match; update our final
// result if we haven't found other valid code.
if (finalRes < 0) {
finalRes = INSTALL_FAILED_NO_MATCHING_ABIS;
}
} else if (res >= 0) {
// Found valid native code, track the best ABI match
if (finalRes < 0 || res < finalRes) {
finalRes = res;
}
} else {
// Unexpected error; bail
return res;
}
}
return finalRes;
|
private static native int | hasRenderscriptBitcode(long apkHandle)
|
public static boolean | hasRenderscriptBitcode(com.android.internal.content.NativeLibraryHelper$Handle handle)
for (long apkHandle : handle.apkHandles) {
final int res = hasRenderscriptBitcode(apkHandle);
if (res < 0) {
throw new IOException("Error scanning APK, code: " + res);
} else if (res == BITCODE_PRESENT) {
return true;
}
}
return false;
|
private static native void | nativeClose(long handle)
|
private static native int | nativeCopyNativeBinaries(long handle, java.lang.String sharedLibraryPath, java.lang.String abiToCopy)
|
private static native int | nativeFindSupportedAbi(long handle, java.lang.String[] supportedAbis)
|
private static native long | nativeOpenApk(java.lang.String path)
|
private static native long | nativeSumNativeBinaries(long handle, java.lang.String cpuAbi)
|
public static void | removeNativeBinariesFromDirLI(java.io.File nativeLibraryRoot, boolean deleteRootDir)Remove the native binaries of a given package. This deletes the files
if (DEBUG_NATIVE) {
Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryRoot.getPath());
}
/*
* Just remove any file in the directory. Since the directory is owned
* by the 'system' UID, the application is not supposed to have written
* anything there.
*/
if (nativeLibraryRoot.exists()) {
final File[] files = nativeLibraryRoot.listFiles();
if (files != null) {
for (int nn = 0; nn < files.length; nn++) {
if (DEBUG_NATIVE) {
Slog.d(TAG, " Deleting " + files[nn].getName());
}
if (files[nn].isDirectory()) {
removeNativeBinariesFromDirLI(files[nn], true /* delete root dir */);
} else if (!files[nn].delete()) {
Slog.w(TAG, "Could not delete native binary: " + files[nn].getPath());
}
}
}
// Do not delete 'lib' directory itself, unless we're specifically
// asked to or this will prevent installation of future updates.
if (deleteRootDir) {
if (!nativeLibraryRoot.delete()) {
Slog.w(TAG, "Could not delete native binary directory: " + nativeLibraryRoot.getPath());
}
}
}
|
public static void | removeNativeBinariesLI(java.lang.String nativeLibraryPath)
if (nativeLibraryPath == null) return;
removeNativeBinariesFromDirLI(new File(nativeLibraryPath), false /* delete root dir */);
|
private static long | sumNativeBinaries(com.android.internal.content.NativeLibraryHelper$Handle handle, java.lang.String abi)
long sum = 0;
for (long apkHandle : handle.apkHandles) {
sum += nativeSumNativeBinaries(apkHandle, abi);
}
return sum;
|
private static long | sumNativeBinariesForSupportedAbi(com.android.internal.content.NativeLibraryHelper$Handle handle, java.lang.String[] abiList)
int abi = findSupportedAbi(handle, abiList);
if (abi >= 0) {
return sumNativeBinaries(handle, abiList[abi]);
} else {
return 0;
}
|
public static long | sumNativeBinariesWithOverride(com.android.internal.content.NativeLibraryHelper$Handle handle, java.lang.String abiOverride)
long sum = 0;
if (handle.multiArch) {
// Warn if we've set an abiOverride for multi-lib packages..
// By definition, we need to copy both 32 and 64 bit libraries for
// such packages.
if (abiOverride != null && !CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
}
if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
sum += sumNativeBinariesForSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
}
if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
sum += sumNativeBinariesForSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
}
} else {
String cpuAbiOverride = null;
if (CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
cpuAbiOverride = null;
} else if (abiOverride != null) {
cpuAbiOverride = abiOverride;
}
String[] abiList = (cpuAbiOverride != null) ?
new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
hasRenderscriptBitcode(handle)) {
abiList = Build.SUPPORTED_32_BIT_ABIS;
}
sum += sumNativeBinariesForSupportedAbi(handle, abiList);
}
return sum;
|