NativeLibraryHelper.java revision 1378aba7aeeb7f6dd6cc2503968ba7b0e58d9333
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.content; 18 19import android.content.pm.PackageManager; 20import android.util.Slog; 21 22import java.io.File; 23 24/** 25 * Native libraries helper. 26 * 27 * @hide 28 */ 29public class NativeLibraryHelper { 30 private static final String TAG = "NativeHelper"; 31 32 private static final boolean DEBUG_NATIVE = false; 33 34 /** 35 * A handle to an opened APK. Used as input to the various NativeLibraryHelper 36 * methods. Allows us to scan and parse the APK exactly once instead of doing 37 * it multiple times. 38 * 39 * @hide 40 */ 41 public static class ApkHandle { 42 final String apkPath; 43 final long apkHandle; 44 45 public ApkHandle(String path) { 46 apkPath = path; 47 apkHandle = nativeOpenApk(apkPath); 48 } 49 50 public ApkHandle(File apkFile) { 51 apkPath = apkFile.getPath(); 52 apkHandle = nativeOpenApk(apkPath); 53 } 54 55 public void close() { 56 nativeClose(apkHandle); 57 } 58 } 59 60 61 private static native long nativeOpenApk(String path); 62 private static native void nativeClose(long handle); 63 64 private static native long nativeSumNativeBinaries(long handle, String cpuAbi); 65 66 /** 67 * Sums the size of native binaries in an APK for a given ABI. 68 * 69 * @return size of all native binary files in bytes 70 */ 71 public static long sumNativeBinariesLI(ApkHandle handle, String abi) { 72 return nativeSumNativeBinaries(handle.apkHandle, abi); 73 } 74 75 private native static int nativeCopyNativeBinaries(long handle, 76 String sharedLibraryPath, String abiToCopy); 77 78 /** 79 * Copies native binaries to a shared library directory. 80 * 81 * @param handle APK file to scan for native libraries 82 * @param sharedLibraryDir directory for libraries to be copied to 83 * @return {@link PackageManager#INSTALL_SUCCEEDED} if successful or another 84 * error code from that class if not 85 */ 86 public static int copyNativeBinariesIfNeededLI(ApkHandle handle, File sharedLibraryDir, 87 String abi) { 88 return nativeCopyNativeBinaries(handle.apkHandle, sharedLibraryDir.getPath(), abi); 89 } 90 91 /** 92 * Checks if a given APK contains native code for any of the provided 93 * {@code supportedAbis}. Returns an index into {@code supportedAbis} if a matching 94 * ABI is found, {@link PackageManager#NO_NATIVE_LIBRARIES} if the 95 * APK doesn't contain any native code, and 96 * {@link PackageManager#INSTALL_FAILED_NO_MATCHING_ABIS} if none of the ABIs match. 97 */ 98 public static int findSupportedAbi(ApkHandle handle, String[] supportedAbis) { 99 return nativeFindSupportedAbi(handle.apkHandle, supportedAbis); 100 } 101 102 private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis); 103 104 // Convenience method to call removeNativeBinariesFromDirLI(File) 105 public static boolean removeNativeBinariesLI(String nativeLibraryPath) { 106 return removeNativeBinariesFromDirLI(new File(nativeLibraryPath)); 107 } 108 109 // Remove the native binaries of a given package. This simply 110 // gets rid of the files in the 'lib' sub-directory. 111 public static boolean removeNativeBinariesFromDirLI(File nativeLibraryDir) { 112 if (DEBUG_NATIVE) { 113 Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryDir.getPath()); 114 } 115 116 boolean deletedFiles = false; 117 118 /* 119 * Just remove any file in the directory. Since the directory is owned 120 * by the 'system' UID, the application is not supposed to have written 121 * anything there. 122 */ 123 if (nativeLibraryDir.exists()) { 124 final File[] binaries = nativeLibraryDir.listFiles(); 125 if (binaries != null) { 126 for (int nn = 0; nn < binaries.length; nn++) { 127 if (DEBUG_NATIVE) { 128 Slog.d(TAG, " Deleting " + binaries[nn].getName()); 129 } 130 131 if (!binaries[nn].delete()) { 132 Slog.w(TAG, "Could not delete native binary: " + binaries[nn].getPath()); 133 } else { 134 deletedFiles = true; 135 } 136 } 137 } 138 // Do not delete 'lib' directory itself, or this will prevent 139 // installation of future updates. 140 } 141 142 return deletedFiles; 143 } 144} 145