package com.android.internal.content;

import android.content.pm.PackageManager;
import android.os.Build;
import android.os.FileUtils;
import android.os.SystemProperties;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

/**
 * Native libraries helper.
 *
 * @hide
 */
public class NativeLibraryHelper {
    private static final String TAG = "NativeHelper";

    private static final boolean DEBUG_NATIVE = false;

    /*
     * The following constants are returned by listPackageSharedLibsForAbiLI
     * to indicate if native shared libraries were found in the package.
     * Values are:
     *    PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES => native libraries found and installed
     *    PACKAGE_INSTALL_NATIVE_NO_LIBRARIES     => no native libraries in package
     *    PACKAGE_INSTALL_NATIVE_ABI_MISMATCH     => native libraries for another ABI found
     *                                        in package (and not installed)
     *
     */
    private static final int PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES = 0;
    private static final int PACKAGE_INSTALL_NATIVE_NO_LIBRARIES = 1;
    private static final int PACKAGE_INSTALL_NATIVE_ABI_MISMATCH = 2;

    // Directory in the APK that holds all the native shared libraries.
    private static final String APK_LIB = "lib/";
    private static final int APK_LIB_LENGTH = APK_LIB.length();

    // Prefix that native shared libraries must have.
    private static final String LIB_PREFIX = "lib";
    private static final int LIB_PREFIX_LENGTH = LIB_PREFIX.length();

    // Suffix that the native shared libraries must have.
    private static final String LIB_SUFFIX = ".so";
    private static final int LIB_SUFFIX_LENGTH = LIB_SUFFIX.length();

    // Name of the GDB binary.
    private static final String GDBSERVER = "gdbserver";

    // the minimum length of a valid native shared library of the form
    // lib/<something>/lib<name>.so.
    private static final int MIN_ENTRY_LENGTH = APK_LIB_LENGTH + 2 + LIB_PREFIX_LENGTH + 1
            + LIB_SUFFIX_LENGTH;

    /*
     * Find all files of the form lib/<cpuAbi>/lib<name>.so in the .apk
     * and add them to a list to be installed later.
     *
     * NOTE: this method may throw an IOException if the library cannot
     * be copied to its final destination, e.g. if there isn't enough
     * room left on the data partition, or a ZipException if the package
     * file is malformed.
     */
    private static int listPackageSharedLibsForAbiLI(ZipFile zipFile,
            String cpuAbi, List<Pair<ZipEntry, String>> libEntries) throws IOException,
            ZipException {
        final int cpuAbiLen = cpuAbi.length();
        boolean hasNativeLibraries = false;
        boolean installedNativeLibraries = false;

        if (DEBUG_NATIVE) {
            Slog.d(TAG, "Checking " + zipFile.getName() + " for shared libraries of CPU ABI type "
                    + cpuAbi);
        }

        Enumeration<? extends ZipEntry> entries = zipFile.entries();

        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();

            // skip directories
            if (entry.isDirectory()) {
                continue;
            }
            String entryName = entry.getName();

            /*
             * Check that the entry looks like lib/<something>/lib<name>.so
             * here, but don't check the ABI just yet.
             *
             * - must be sufficiently long
             * - must end with LIB_SUFFIX, i.e. ".so"
             * - must start with APK_LIB, i.e. "lib/"
             */
            if (entryName.length() < MIN_ENTRY_LENGTH || !entryName.endsWith(LIB_SUFFIX)
                    || !entryName.startsWith(APK_LIB)) {
                continue;
            }

            // file name must start with LIB_PREFIX, i.e. "lib"
            int lastSlash = entryName.lastIndexOf('/');

            if (lastSlash < 0
                    || !entryName.regionMatches(lastSlash + 1, LIB_PREFIX, 0, LIB_PREFIX_LENGTH)) {
                continue;
            }

            hasNativeLibraries = true;

            // check the cpuAbi now, between lib/ and /lib<name>.so
            if (lastSlash != APK_LIB_LENGTH + cpuAbiLen
                    || !entryName.regionMatches(APK_LIB_LENGTH, cpuAbi, 0, cpuAbiLen))
                continue;

            /*
             * Extract the library file name, ensure it doesn't contain
             * weird characters. we're guaranteed here that it doesn't contain
             * a directory separator though.
             */
            String libFileName = entryName.substring(lastSlash+1);
            if (!FileUtils.isFilenameSafe(new File(libFileName))) {
                continue;
            }

            installedNativeLibraries = true;

            if (DEBUG_NATIVE) {
                Log.d(TAG, "Caching shared lib " + entry.getName());
            }

            libEntries.add(Pair.create(entry, libFileName));
        }
        if (!hasNativeLibraries)
            return PACKAGE_INSTALL_NATIVE_NO_LIBRARIES;

        if (!installedNativeLibraries)
            return PACKAGE_INSTALL_NATIVE_ABI_MISMATCH;

        return PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES;
    }

    /*
     * Find the gdbserver executable program in a package at
     * lib/<cpuAbi>/gdbserver and add it to the list of binaries
     * to be copied out later.
     *
     * Returns PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES on success,
     * or PACKAGE_INSTALL_NATIVE_NO_LIBRARIES otherwise.
     */
    private static int listPackageGdbServerLI(ZipFile zipFile, String cpuAbi,
            List<Pair<ZipEntry, String>> nativeFiles) throws IOException, ZipException {
        final String apkGdbServerPath = "lib/" + cpuAbi + "/" + GDBSERVER;

        Enumeration<? extends ZipEntry> entries = zipFile.entries();

        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            // skip directories
            if (entry.isDirectory()) {
                continue;
            }
            String entryName = entry.getName();

            if (!entryName.equals(apkGdbServerPath)) {
                continue;
            }

            if (false) {
                Log.d(TAG, "Found gdbserver: " + entry.getName());
            }

            final String installGdbServerPath = GDBSERVER;
            nativeFiles.add(Pair.create(entry, installGdbServerPath));

            return PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES;
        }
        return PACKAGE_INSTALL_NATIVE_NO_LIBRARIES;
    }

    /*
     * Examine shared libraries stored in the APK as
     * lib/<cpuAbi>/lib<name>.so and add them to a list to be copied
     * later.
     *
     * This function will first try the main CPU ABI defined by Build.CPU_ABI
     * (which corresponds to ro.product.cpu.abi), and also try an alternate
     * one if ro.product.cpu.abi2 is defined.
     */
    public static int listPackageNativeBinariesLI(ZipFile zipFile,
            List<Pair<ZipEntry, String>> nativeFiles) throws ZipException, IOException {
        String cpuAbi = Build.CPU_ABI;

        int result = listPackageSharedLibsForAbiLI(zipFile, cpuAbi, nativeFiles);

        /*
         * Some architectures are capable of supporting several CPU ABIs
         * for example, 'armeabi-v7a' also supports 'armeabi' native code
         * this is indicated by the definition of the ro.product.cpu.abi2
         * system property.
         *
         * only scan the package twice in case of ABI mismatch
         */
        if (result == PACKAGE_INSTALL_NATIVE_ABI_MISMATCH) {
            final String cpuAbi2 = SystemProperties.get("ro.product.cpu.abi2", null);
            if (cpuAbi2 != null) {
                result = listPackageSharedLibsForAbiLI(zipFile, cpuAbi2, nativeFiles);
            }

            if (result == PACKAGE_INSTALL_NATIVE_ABI_MISMATCH) {
                Slog.w(TAG, "Native ABI mismatch from package file");
                return PackageManager.INSTALL_FAILED_INVALID_APK;
            }

            if (result == PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES) {
                cpuAbi = cpuAbi2;
            }
        }

        /*
         * Debuggable packages may have gdbserver embedded, so add it to
         * the list to the list of items to be extracted (as lib/gdbserver)
         * into the application's native library directory later.
         */
        if (result == PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES) {
            listPackageGdbServerLI(zipFile, cpuAbi, nativeFiles);
        }
        return PackageManager.INSTALL_SUCCEEDED;
    }

    public static int copyNativeBinariesLI(File scanFile, File sharedLibraryDir) {
        /*
         * Check all the native files that need to be copied and add
         * that to the container size.
         */
        ZipFile zipFile;
        try {
            zipFile = new ZipFile(scanFile);

            List<Pair<ZipEntry, String>> nativeFiles = new LinkedList<Pair<ZipEntry, String>>();

            NativeLibraryHelper.listPackageNativeBinariesLI(zipFile, nativeFiles);

            final int N = nativeFiles.size();

            for (int i = 0; i < N; i++) {
                final Pair<ZipEntry, String> entry = nativeFiles.get(i);

                File destFile = new File(sharedLibraryDir, entry.second);
                copyNativeBinaryLI(zipFile, entry.first, sharedLibraryDir, destFile);
            }
            zipFile.close();
        } catch (ZipException e) {
            Slog.w(TAG, "Failed to extract data from package file", e);
            return PackageManager.INSTALL_FAILED_INVALID_APK;
        } catch (IOException e) {
            Slog.w(TAG, "Failed to cache package shared libs", e);
            return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
        }

        return PackageManager.INSTALL_SUCCEEDED;
    }

    private static void copyNativeBinaryLI(ZipFile zipFile, ZipEntry entry,
            File binaryDir, File binaryFile) throws IOException {
        InputStream inputStream = zipFile.getInputStream(entry);
        try {
            File tempFile = File.createTempFile("tmp", "tmp", binaryDir);
            String tempFilePath = tempFile.getPath();
            // XXX package manager can't change owner, so the executable files for
            // now need to be left as world readable and owned by the system.
            if (!FileUtils.copyToFile(inputStream, tempFile)
                    || !tempFile.setLastModified(entry.getTime())
                    || FileUtils.setPermissions(tempFilePath, FileUtils.S_IRUSR | FileUtils.S_IWUSR
                            | FileUtils.S_IRGRP | FileUtils.S_IXUSR | FileUtils.S_IXGRP
                            | FileUtils.S_IXOTH | FileUtils.S_IROTH, -1, -1) != 0
                    || !tempFile.renameTo(binaryFile)) {
                // Failed to properly write file.
                tempFile.delete();
                throw new IOException("Couldn't create cached binary " + binaryFile + " in "
                        + binaryDir);
            }
        } finally {
            inputStream.close();
        }
    }

    // Convenience method to call removeNativeBinariesFromDirLI(File)
    public static boolean removeNativeBinariesLI(String nativeLibraryPath) {
        return removeNativeBinariesFromDirLI(new File(nativeLibraryPath));
    }

    // Remove the native binaries of a given package. This simply
    // gets rid of the files in the 'lib' sub-directory.
    public static boolean removeNativeBinariesFromDirLI(File nativeLibraryDir) {
        if (DEBUG_NATIVE) {
            Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryDir.getPath());
        }

        boolean deletedFiles = false;

        /*
         * 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 (nativeLibraryDir.exists()) {
            final File[] binaries = nativeLibraryDir.listFiles();
            if (binaries != null) {
                for (int nn = 0; nn < binaries.length; nn++) {
                    if (DEBUG_NATIVE) {
                        Slog.d(TAG, "    Deleting " + binaries[nn].getName());
                    }

                    if (!binaries[nn].delete()) {
                        Slog.w(TAG, "Could not delete native binary: " + binaries[nn].getPath());
                    } else {
                        deletedFiles = true;
                    }
                }
            }
            // Do not delete 'lib' directory itself, or this will prevent
            // installation of future updates.
        }

        return deletedFiles;
    }
}
