/*
 * Copyright (C) 2007 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 dalvik.system;

import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;

import dalvik.annotation.compat.VersionCodes;

import java.lang.ref.FinalizerReference;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;

/**
 * Provides an interface to VM-global, Dalvik-specific features.
 * An application cannot create its own Runtime instance, and must obtain
 * one from the getRuntime method.
 *
 * @hide
 */
@libcore.api.CorePlatformApi
public final class VMRuntime {

    /**
     * Holds the VMRuntime singleton.
     */
    private static final VMRuntime THE_ONE = new VMRuntime();

    // Note: Instruction set names are used to construct the names of some
    // system properties. To be sure that the properties stay valid the
    // instruction set name should not exceed 7 characters. See installd
    // and the package manager for the actual propeties.
    private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
            = new HashMap<String, String>(16);
    static {
        ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
        ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
        ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
        ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64");
        ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
        ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64");
        ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64");
        ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a-hwasan", "arm64");
    }

    /**
     * Remove meta-reflection workaround for hidden api usage for apps targeting R+. This allowed
     * apps to obtain references to blacklisted fields and methods through an extra layer of
     * reflection.
     */
    @ChangeId
    @EnabledAfter(targetSdkVersion = VersionCodes.Q)
    private static final long
        PREVENT_META_REFLECTION_BLACKLIST_ACCESS = 142365358; // This is a bug id.

    /**
     * Gating access to greylist-max-p APIs.
     */
    @ChangeId
    @EnabledAfter(targetSdkVersion = VersionCodes.P)
    private static final long HIDE_MAXTARGETSDK_P_HIDDEN_APIS = 149997251; // This is a bug id.

    /**
     * Gating access to greylist-max-q APIs.
     */
    @ChangeId
    @EnabledAfter(targetSdkVersion = VersionCodes.Q)
    private static final long HIDE_MAXTARGETSDK_Q_HIDDEN_APIS = 149994052; // This is a bug id.

    /**
     * Interface for logging hidden API usage events.
     */
    @libcore.api.CorePlatformApi
    public interface HiddenApiUsageLogger {

        // The following ACCESS_METHOD_ constants must match the values in
        // art/runtime/hidden_api.h
        /**
         * Internal test value that does not correspond to an actual access by the
         * application. Never logged, added for completeness.
         */
        public static final int ACCESS_METHOD_NONE = 0;

        /**
         *  Used when a method has been accessed via reflection.
         */
        public static final int ACCESS_METHOD_REFLECTION = 1;

        /**
         *  Used when a method has been accessed via JNI.
         */
        public static final int ACCESS_METHOD_JNI = 2;

        /**
         * Used when a method is accessed at link time. Never logged, added only
         * for completeness.
         */
        public static final int ACCESS_METHOD_LINKING = 3;

        /**
         * Logs hidden API access
         *
         * @param sampledValue value that was sampled, to be compared against the
         *      sampling rate
         * @param appPackageName package name of the app attempting the access
         * @param signature signature of the method being called, i.e
         *      class_name->member_name:type_signature (e.g.
         *      {@code com.android.app.Activity->mDoReportFullyDrawn:Z}) for fields and
         *      class_name->method_name_and_signature for methods (e.g
         *      {@code com.android.app.Activity->finish(I)V})
         * @param accessType how the accessed was done
         * @param accessDenied whether the access was allowed or not
         */
        public void hiddenApiUsed(int sampledValue, String appPackageName,
            String signature, int accessType, boolean accessDenied);
    }

    static HiddenApiUsageLogger hiddenApiUsageLogger;

    /**
     * Sets the hidden API usage logger {@link #hiddenApiUsageLogger}.
     * It should only be called if {@link #setHiddenApiAccessLogSamplingRate(int)}
     * is called with a value > 0
     */
    @libcore.api.CorePlatformApi
    public static void setHiddenApiUsageLogger(HiddenApiUsageLogger hiddenApiUsageLogger) {
        VMRuntime.hiddenApiUsageLogger = hiddenApiUsageLogger;
    }

    /**
     * Records an attempted hidden API access to
     * {@link HiddenApiUsageLogger#hiddenApiUsed(int, String, String, int, boolean}
     * if a logger is registered via {@link #setHiddenApiUsageLogger}.
     */
    private static void hiddenApiUsed(int sampledValue, String appPackageName, String signature,
         int accessType, boolean accessDenied) {
        if (VMRuntime.hiddenApiUsageLogger != null) {
            VMRuntime.hiddenApiUsageLogger.hiddenApiUsed(sampledValue, appPackageName,
                signature, accessType, accessDenied);
        }
    }

    /**
     * Magic version number for a current development build, which has not
     * yet turned into an official release. This number must be larger than
     * any released version in {@code android.os.Build.VERSION_CODES}.
     * @hide
     */
    @libcore.api.CorePlatformApi
    public static final int SDK_VERSION_CUR_DEVELOPMENT = 10000;

    private static Consumer<String> nonSdkApiUsageConsumer = null;

    private int targetSdkVersion = SDK_VERSION_CUR_DEVELOPMENT;

    // notifyNativeAllocationsInternal (below) should be called every notifyNativeInterval
    // allocations. Initialized on demand to allow completely static class initialization.
    private int notifyNativeInterval;

    // Allocations since last call to native layer. See notifyNativeAllocation().
    private final AtomicInteger allocationCount = new AtomicInteger(0);

    private long[] disabledCompatChanges = new long[0];

    /**
     * Prevents this class from being instantiated.
     */
    private VMRuntime() {
    }

    /**
     * Returns the object that represents the VM instance's Dalvik-specific
     * runtime environment.
     *
     * @return the runtime object
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public static VMRuntime getRuntime() {
        return THE_ONE;
    }

    /**
     * Returns a copy of the VM's command-line property settings.
     * These are in the form "name=value" rather than "-Dname=value".
     */
    public native String[] properties();

    /**
     * Returns the VM's boot class path.
     */
    public native String bootClassPath();

    /**
     * Returns the VM's class path.
     */
    public native String classPath();

    /**
     * Returns the VM's version.
     */
    public native String vmVersion();

    /**
     * Returns the name of the shared library providing the VM implementation.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public native String vmLibrary();

    /**
     * Returns the VM's instruction set.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public native String vmInstructionSet();

    /**
     * Returns whether the VM is running in 64-bit mode.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    @FastNative
    public native boolean is64Bit();

    /**
     * Returns whether the VM is running with JNI checking enabled.
     */
    @libcore.api.CorePlatformApi
    @FastNative
    public native boolean isCheckJniEnabled();

    /**
     * Gets the current ideal heap utilization, represented as a number
     * between zero and one.  After a GC happens, the Dalvik heap may
     * be resized so that (size of live objects) / (size of heap) is
     * equal to this number.
     *
     * @return the current ideal heap utilization
     */
    @libcore.api.CorePlatformApi
    public native float getTargetHeapUtilization();

    /**
     * Retrieves the finalizer timeout in milliseconds.
     * Finalizers that fail to terminate in this amount of time cause the
     * runtime to abort.
     */
    public native long getFinalizerTimeoutMs();

    /**
     * Sets the current ideal heap utilization, represented as a number
     * between zero and one.  After a GC happens, the Dalvik heap may
     * be resized so that (size of live objects) / (size of heap) is
     * equal to this number.
     *
     * <p>This is only a hint to the garbage collector and may be ignored.
     *
     * @param newTarget the new suggested ideal heap utilization.
     *                  This value may be adjusted internally.
     * @return the previous ideal heap utilization
     * @throws IllegalArgumentException if newTarget is &lt;= 0.0 or &gt;= 1.0
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public float setTargetHeapUtilization(float newTarget) {
        if (newTarget <= 0.0f || newTarget >= 1.0f) {
            throw new IllegalArgumentException(newTarget + " out of range (0,1)");
        }
        /* The native code assumes a value >= 0.1. Clamp it to that. */
        if (newTarget < 0.1f) {
            newTarget = 0.1f;
        }
        /* Synchronize to make sure that only one thread gets a given "old" value if both
         * update at the same time.  Allows for reliable save-and-restore semantics.
         */
        synchronized (this) {
            float oldTarget = getTargetHeapUtilization();
            nativeSetTargetHeapUtilization(newTarget);
            return oldTarget;
        }
    }

    /**
     * Sets the target SDK version. Should only be called before the
     * app starts to run, because it may change the VM's behavior in
     * dangerous ways. Defaults to {@link #SDK_VERSION_CUR_DEVELOPMENT}.
     */
    @UnsupportedAppUsage(maxTargetSdk=0, publicAlternatives="Use the {@code targetSdkVersion}"
        +" attribute in the {@code uses-sdk} manifest tag instead.")
    @libcore.api.CorePlatformApi
    public synchronized void setTargetSdkVersion(int targetSdkVersion) {
        this.targetSdkVersion = targetSdkVersion;
        setTargetSdkVersionNative(this.targetSdkVersion);
    }


    /**
     * Sets the disabled compat changes. Should only be called before the
     * app starts to run, because it may change the VM's behavior in
     * dangerous ways. Defaults to empty.
     */
    @libcore.api.CorePlatformApi
    public synchronized void setDisabledCompatChanges(long[] disabledCompatChanges) {
        this.disabledCompatChanges = disabledCompatChanges;
        setDisabledCompatChangesNative(this.disabledCompatChanges);
    }

    /**
     * Gets the target SDK version. See {@link #setTargetSdkVersion} for
     * special values.
     */
    @libcore.api.CorePlatformApi
    public synchronized int getTargetSdkVersion() {
        return targetSdkVersion;
    }

    private native void setTargetSdkVersionNative(int targetSdkVersion);
    private native void setDisabledCompatChangesNative(long[] disabledCompatChanges);

    /**
     * This method exists for binary compatibility.  It was part of a
     * heap sizing API which was removed in Android 3.0 (Honeycomb).
     */
    @UnsupportedAppUsage
    @Deprecated
    public long getMinimumHeapSize() {
        return 0;
    }

    /**
     * This method exists for binary compatibility.  It was part of a
     * heap sizing API which was removed in Android 3.0 (Honeycomb).
     */
    @UnsupportedAppUsage
    @Deprecated
    public long setMinimumHeapSize(long size) {
        return 0;
    }

    /**
     * This method exists for binary compatibility.  It used to
     * perform a garbage collection that cleared SoftReferences.
     */
    @UnsupportedAppUsage
    @Deprecated
    public void gcSoftReferences() {}

    /**
     * This method exists for binary compatibility.  It is equivalent
     * to {@link System#runFinalization}.
     */
    @UnsupportedAppUsage
    @Deprecated
    public void runFinalizationSync() {
        System.runFinalization();
    }

    /**
     * Implements setTargetHeapUtilization().
     *
     * @param newTarget the new suggested ideal heap utilization.
     *                  This value may be adjusted internally.
     */
    private native void nativeSetTargetHeapUtilization(float newTarget);

    /**
     * This method exists for binary compatibility.  It was part of
     * the external allocation API which was removed in Android 3.0 (Honeycomb).
     */
    @UnsupportedAppUsage
    @Deprecated
    public boolean trackExternalAllocation(long size) {
        return true;
    }

    /**
     * This method exists for binary compatibility.  It was part of
     * the external allocation API which was removed in Android 3.0 (Honeycomb).
     */
    @UnsupportedAppUsage
    @Deprecated
    public void trackExternalFree(long size) {}

    /**
     * This method exists for binary compatibility.  It was part of
     * the external allocation API which was removed in Android 3.0 (Honeycomb).
     */
    @UnsupportedAppUsage
    @Deprecated
    public long getExternalBytesAllocated() {
        return 0;
    }

    /**
     * Tells the VM to enable the JIT compiler. If the VM does not have a JIT
     * implementation, calling this method should have no effect.
     */
    @libcore.api.CorePlatformApi
    public native void startJitCompilation();

    /**
     * Tells the VM to disable the JIT compiler. If the VM does not have a JIT
     * implementation, calling this method should have no effect.
     */
    @libcore.api.CorePlatformApi
    public native void disableJitCompilation();

    /**
     * Sets the list of exemptions from hidden API access enforcement.
     *
     * @param signaturePrefixes
     *         A list of signature prefixes. Each item in the list is a prefix match on the type
     *         signature of a blacklisted API. All matching APIs are treated as if they were on
     *         the whitelist: access permitted, and no logging..
     */
    @libcore.api.CorePlatformApi
    public native void setHiddenApiExemptions(String[] signaturePrefixes);

    /**
     * Sets the log sampling rate of hidden API accesses written to the event log.
     *
     * @param rate Proportion of hidden API accesses that will be logged; an integer between
     *                0 and 0x10000 inclusive.
     */
    @libcore.api.CorePlatformApi
    public native void setHiddenApiAccessLogSamplingRate(int rate);

    /**
     * Returns an array allocated in an area of the Java heap where it will never be moved.
     * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
     * and Bitmaps.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    @FastNative
    public native Object newNonMovableArray(Class<?> componentType, int length);

    /**
     * Returns an array of at least minLength, but potentially larger. The increased size comes from
     * avoiding any padding after the array. The amount of padding varies depending on the
     * componentType and the memory allocator implementation.
     */
    @libcore.api.CorePlatformApi
    @FastNative
    public native Object newUnpaddedArray(Class<?> componentType, int minLength);

    /**
     * Returns the address of array[0]. This differs from using JNI in that JNI might lie and
     * give you the address of a copy of the array when in forcecopy mode.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    @FastNative
    public native long addressOf(Object array);

    /**
     * Removes any growth limits, allowing the application to allocate
     * up to the maximum heap size.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public native void clearGrowthLimit();

    /**
     * Make the current growth limit the new non growth limit capacity by releasing pages which
     * are after the growth limit but before the non growth limit capacity.
     */
    @libcore.api.CorePlatformApi
    public native void clampGrowthLimit();

    /**
     * Returns true if native debugging is on.
     */
    @libcore.api.CorePlatformApi
    @FastNative
    public native boolean isNativeDebuggable();

    /**
     * Returns true if Java debugging is enabled.
     */
    public native boolean isJavaDebuggable();

    /**
     * Registers a native allocation so that the heap knows about it and performs GC as required.
     * If the number of native allocated bytes exceeds the native allocation watermark, the
     * function requests a concurrent GC. If the native bytes allocated exceeds a second higher
     * watermark, it is determined that the application is registering native allocations at an
     * unusually high rate and a GC is performed inside of the function to prevent memory usage
     * from excessively increasing. Memory allocated via system malloc() should not be included
     * in this count. The argument must be the same as that later passed to registerNativeFree(),
     * but may otherwise be approximate.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public native void registerNativeAllocation(long bytes);

    /**
     * Backward compatibility version of registerNativeAllocation. We used to pass an int instead
     * of a long. The RenderScript support library looks it up via reflection.
     * @deprecated Use long argument instead.
     */
    @UnsupportedAppUsage
    @Deprecated
    @libcore.api.CorePlatformApi
    public void registerNativeAllocation(int bytes) {
        registerNativeAllocation((long) bytes);
    }

    /**
     * Registers a native free by reducing the number of native bytes accounted for.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public native void registerNativeFree(long bytes);

    /**
     * Backward compatibility version of registerNativeFree.
     * @deprecated Use long argument instead.
     */
    @UnsupportedAppUsage
    @Deprecated
    @libcore.api.CorePlatformApi
    public void registerNativeFree(int bytes) {
        registerNativeFree((long) bytes);
    }

    /**
     * Return the number of native objects that are reported by a single call to
     * notifyNativeAllocation().
     */
    private static native int getNotifyNativeInterval();

    /**
     * Report a native malloc()-only allocation to the GC.
     */
    public void notifyNativeAllocation() {
        // Minimize JNI calls by notifying once every notifyNativeInterval allocations.
        // The native code cannot do anything without calling mallinfo(), which is too
        // expensive to perform on every allocation. To avoid the JNI overhead on every
        // allocation, we do the sampling here, rather than in native code.
        // Initialize notifyNativeInterval carefully. Multiple initializations may race.
        int myNotifyNativeInterval = notifyNativeInterval;
        if (myNotifyNativeInterval == 0) {
            // This can race. By Java rules, that's OK.
            myNotifyNativeInterval = notifyNativeInterval = getNotifyNativeInterval();
        }
        // myNotifyNativeInterval is correct here. If another thread won the initial race,
        // notifyNativeInterval may not be.
        if (allocationCount.addAndGet(1) % myNotifyNativeInterval == 0) {
            notifyNativeAllocationsInternal();
        }
    }

    /**
     * Report to the GC that roughly notifyNativeInterval native malloc()-based
     * allocations have occurred since the last call to notifyNativeAllocationsInternal().
     * Hints that we should check whether a GC is required.
     */
    public native void notifyNativeAllocationsInternal();

    /**
     * Wait for objects to be finalized.
     *
     * If finalization takes longer than timeout, then the function returns before all objects are
     * finalized.
     *
     * @param timeout
     *            timeout in nanoseconds of the maximum time to wait until all pending finalizers
     *            are run. If timeout is 0, then there is no timeout. Note that the timeout does
     *            not stop the finalization process, it merely stops the wait.
     *
     * @see #Runtime.runFinalization()
     * @see #wait(long,int)
     */
    @UnsupportedAppUsage
    public static void runFinalization(long timeout) {
        try {
            FinalizerReference.finalizeAllEnqueued(timeout);
        } catch (InterruptedException e) {
            // Interrupt the current thread without actually throwing the InterruptionException
            // for the caller.
            Thread.currentThread().interrupt();
        }
    }

    @libcore.api.CorePlatformApi
    public native void requestConcurrentGC();
    public native void concurrentGC();
    public native void requestHeapTrim();
    public native void trimHeap();
    public native void startHeapTaskProcessor();
    public native void stopHeapTaskProcessor();
    public native void runHeapTasks();

    /**
     * Let the heap know of the new process state. This can change allocation and garbage collection
     * behavior regarding trimming and compaction.
     */
    @libcore.api.CorePlatformApi
    public native void updateProcessState(int state);

    /**
     * Let the runtime know that the application startup is completed. This may affect behavior
     * related to profiling and startup caches.
     */
    @libcore.api.CorePlatformApi
    public native void notifyStartupCompleted();

    /**
     * Fill in dex caches with classes, fields, and methods that are
     * already loaded. Typically used after Zygote preloading.
     */
    @libcore.api.CorePlatformApi
    public native void preloadDexCaches();

    /**
     * Register application info.
     * @param profileFile the path of the file where the profile information should be stored.
     * @param codePaths the code paths that should be profiled.
     */
    @libcore.api.CorePlatformApi
    public static native void registerAppInfo(String profileFile, String[] codePaths);

    /**
     * Returns the runtime instruction set corresponding to a given ABI. Multiple
     * compatible ABIs might map to the same instruction set. For example
     * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}.
     *
     * This influences the compilation of the applications classes.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public static String getInstructionSet(String abi) {
        final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
        if (instructionSet == null) {
            throw new IllegalArgumentException("Unsupported ABI: " + abi);
        }

        return instructionSet;
    }

    @libcore.api.CorePlatformApi
    public static boolean is64BitInstructionSet(String instructionSet) {
        return "arm64".equals(instructionSet) ||
                "x86_64".equals(instructionSet) ||
                "mips64".equals(instructionSet);
    }

    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public static boolean is64BitAbi(String abi) {
        return is64BitInstructionSet(getInstructionSet(abi));
    }

    /**
     * Prevent initialization of the caller's class if they are calling
     * from their clinit method. This works because calling a JNI method
     * from clinit causes the transactional runtime to abort the current
     * transaction.
     * @hide
     */
    @CriticalNative
    public static native void doNotInitializeInAot();

    /**
     * Return false if the boot class path for the given instruction
     * set mapped from disk storage, versus being interpretted from
     * dirty pages in memory.
     */
    @libcore.api.CorePlatformApi
    public static native boolean isBootClassPathOnDisk(String instructionSet);

    /**
     * Returns whether the runtime is using a boot image.
     *
     * <p>While isBootClassPathOnDisk checks for the existence of an image file on disk,
     * this method queries the runtime whether it is <em>using</em> an image.
     */
    @libcore.api.CorePlatformApi
    @FastNative
    public static native boolean hasBootImageSpaces();

    /**
     * Used to notify the runtime that boot completed.
     */
    @libcore.api.CorePlatformApi
    public static native void bootCompleted();

    /**
     * Used to notify the runtime to reset Jit counters. This is done for the boot image
     * profiling configuration to avoid samples during class preloading. This helps avoid
     * the regression from disabling class profiling.
     */
    @libcore.api.CorePlatformApi
    public static native void resetJitCounters();

    /**
     * Returns the instruction set of the current runtime.
     */
    @UnsupportedAppUsage
    @libcore.api.CorePlatformApi
    public static native String getCurrentInstructionSet();

    /**
     * Return true if the dalvik cache was pruned when booting. This may have happened for
     * various reasons, e.g., after an OTA. The return value is for the current instruction
     * set.
     */
    @libcore.api.CorePlatformApi
    public static native boolean didPruneDalvikCache();

    /**
     * Register the current execution thread to the runtime as sensitive thread.
     * Should be called just once. Subsequent calls are ignored.
     */
    @libcore.api.CorePlatformApi
    public static native void registerSensitiveThread();

    /**
     * Sets up the priority of the system daemon thread (caller).
     */
    public static native void setSystemDaemonThreadPriority();

    /**
     * Sets a callback that the runtime can call whenever a usage of a non SDK API is detected.
     */
    @libcore.api.CorePlatformApi
    public static void setNonSdkApiUsageConsumer(Consumer<String> consumer) {
        nonSdkApiUsageConsumer = consumer;
    }

    /**
     * Sets whether or not the runtime should dedupe detection and warnings for hidden API usage.
     * If deduping is enabled, only the first usage of each API will be detected. The default
     * behaviour is to dedupe.
     */
    @libcore.api.CorePlatformApi
    public static native void setDedupeHiddenApiWarnings(boolean dedupe);

    /**
     * Sets the package name of the app running in this process.
     */
    @libcore.api.CorePlatformApi
    public static native void setProcessPackageName(String packageName);

    /**
     * Sets the full path to data directory of the app running in this process.
     */
    @libcore.api.CorePlatformApi
    public static native void setProcessDataDirectory(String dataDir);

    /**
     * Returns whether {@code encodedClassLoaderContext} is a valid encoded class loader context.
     * A class loader context is an internal opaque format used by the runtime to encode the
     * class loader hierarchy (including each ClassLoader's classpath) used to load a dex file.
     *
     * @return True if encodedClassLoaderContext is a non-null valid encoded class loader context.
     *   Throws NullPointerException if encodedClassLoaderContext is null.
     */
    @libcore.api.CorePlatformApi
    public static native boolean isValidClassLoaderContext(String encodedClassLoaderContext);
}
