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.os.Build;
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    private static native long nativeSumNativeBinaries(String file, String cpuAbi, String cpuAbi2);
35
36    /**
37     * Sums the size of native binaries in an APK.
38     *
39     * @param apkFile APK file to scan for native libraries
40     * @return size of all native binary files in bytes
41     */
42    public static long sumNativeBinariesLI(File apkFile) {
43        final String cpuAbi = Build.CPU_ABI;
44        final String cpuAbi2 = Build.CPU_ABI2;
45        return nativeSumNativeBinaries(apkFile.getPath(), cpuAbi, cpuAbi2);
46    }
47
48    private native static int nativeCopyNativeBinaries(String filePath, String sharedLibraryPath,
49            String cpuAbi, String cpuAbi2);
50
51    /**
52     * Copies native binaries to a shared library directory.
53     *
54     * @param apkFile APK file to scan for native libraries
55     * @param sharedLibraryDir directory for libraries to be copied to
56     * @return {@link PackageManager#INSTALL_SUCCEEDED} if successful or another
57     *         error code from that class if not
58     */
59    public static int copyNativeBinariesIfNeededLI(File apkFile, File sharedLibraryDir) {
60        final String cpuAbi = Build.CPU_ABI;
61        final String cpuAbi2 = Build.CPU_ABI2;
62        return nativeCopyNativeBinaries(apkFile.getPath(), sharedLibraryDir.getPath(), cpuAbi,
63                cpuAbi2);
64    }
65
66    // Convenience method to call removeNativeBinariesFromDirLI(File)
67    public static boolean removeNativeBinariesLI(String nativeLibraryPath) {
68        return removeNativeBinariesFromDirLI(new File(nativeLibraryPath));
69    }
70
71    // Remove the native binaries of a given package. This simply
72    // gets rid of the files in the 'lib' sub-directory.
73    public static boolean removeNativeBinariesFromDirLI(File nativeLibraryDir) {
74        if (DEBUG_NATIVE) {
75            Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryDir.getPath());
76        }
77
78        boolean deletedFiles = false;
79
80        /*
81         * Just remove any file in the directory. Since the directory is owned
82         * by the 'system' UID, the application is not supposed to have written
83         * anything there.
84         */
85        if (nativeLibraryDir.exists()) {
86            final File[] binaries = nativeLibraryDir.listFiles();
87            if (binaries != null) {
88                for (int nn = 0; nn < binaries.length; nn++) {
89                    if (DEBUG_NATIVE) {
90                        Slog.d(TAG, "    Deleting " + binaries[nn].getName());
91                    }
92
93                    if (!binaries[nn].delete()) {
94                        Slog.w(TAG, "Could not delete native binary: " + binaries[nn].getPath());
95                    } else {
96                        deletedFiles = true;
97                    }
98                }
99            }
100            // Do not delete 'lib' directory itself, or this will prevent
101            // installation of future updates.
102        }
103
104        return deletedFiles;
105    }
106}
107