/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.os;

import android.os.Trace;

import dalvik.system.DelegateLastClassLoader;
import dalvik.system.DexClassLoader;
import dalvik.system.PathClassLoader;

/**
 * Creates class loaders.
 *
 * @hide
 */
public class ClassLoaderFactory {
    // Unconstructable
    private ClassLoaderFactory() {}

    private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
    private static final String DEX_CLASS_LOADER_NAME = DexClassLoader.class.getName();
    private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
            DelegateLastClassLoader.class.getName();

    /**
     * Returns true if {@code name} is a supported classloader. {@code name} must be a
     * binary name of a class, as defined by {@code Class.getName}.
     */
    public static boolean isValidClassLoaderName(String name) {
        // This method is used to parse package data and does not accept null names.
        return name != null && (isPathClassLoaderName(name) || isDelegateLastClassLoaderName(name));
    }

    /**
     * Returns true if {@code name} is the encoding for either PathClassLoader or DexClassLoader.
     * The two class loaders are grouped together because they have the same behaviour.
     */
    public static boolean isPathClassLoaderName(String name) {
        // For null values we default to PathClassLoader. This cover the case when packages
        // don't specify any value for their class loaders.
        return name == null || PATH_CLASS_LOADER_NAME.equals(name) ||
                DEX_CLASS_LOADER_NAME.equals(name);
    }

    /**
     * Returns true if {@code name} is the encoding for the DelegateLastClassLoader.
     */
    public static boolean isDelegateLastClassLoaderName(String name) {
        return DELEGATE_LAST_CLASS_LOADER_NAME.equals(name);
    }

    /**
     * Same as {@code createClassLoader} below, except that no associated namespace
     * is created.
     */
    public static ClassLoader createClassLoader(String dexPath,
            String librarySearchPath, ClassLoader parent, String classloaderName) {
        if (isPathClassLoaderName(classloaderName)) {
            return new PathClassLoader(dexPath, librarySearchPath, parent);
        } else if (isDelegateLastClassLoaderName(classloaderName)) {
            return new DelegateLastClassLoader(dexPath, librarySearchPath, parent);
        }

        throw new AssertionError("Invalid classLoaderName: " + classloaderName);
    }

    /**
     * Create a ClassLoader and initialize a linker-namespace for it.
     */
    public static ClassLoader createClassLoader(String dexPath,
            String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
            int targetSdkVersion, boolean isNamespaceShared, String classloaderName) {

        final ClassLoader classLoader = createClassLoader(dexPath, librarySearchPath, parent,
                classloaderName);

        boolean isForVendor = false;
        for (String path : dexPath.split(":")) {
            if (path.startsWith("/vendor/")) {
                isForVendor = true;
                break;
            }
        }
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "createClassloaderNamespace");
        String errorMessage = createClassloaderNamespace(classLoader,
                                                         targetSdkVersion,
                                                         librarySearchPath,
                                                         libraryPermittedPath,
                                                         isNamespaceShared,
                                                         isForVendor);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        if (errorMessage != null) {
            throw new UnsatisfiedLinkError("Unable to create namespace for the classloader " +
                                           classLoader + ": " + errorMessage);
        }

        return classLoader;
    }

    private static native String createClassloaderNamespace(ClassLoader classLoader,
                                                            int targetSdkVersion,
                                                            String librarySearchPath,
                                                            String libraryPermittedPath,
                                                            boolean isNamespaceShared,
                                                            boolean isForVendor);
}
