/*
 * 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 static android.annotation.SystemApi.Client.MODULE_LIBRARIES;

import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;

import java.io.FileDescriptor;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import dalvik.annotation.optimization.FastNative;

/**
 * Provides access to some VM-specific debug features. Though this class and
 * many of its members are public, this class is meant to be wrapped in a more
 * friendly way for use by application developers. On the Android platform, the
 * recommended way to access this functionality is through the class
 * <code>android.os.Debug</code>.
 *
 * @hide
 */
@SystemApi(client = MODULE_LIBRARIES)
public final class VMDebug {
    /**
     * flag for startMethodTracing(), which adds the results from
     * startAllocCounting to the trace key file.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    // Must match android.os.Debug.TRACE_COUNT_ALLOCS.
    public static final int TRACE_COUNT_ALLOCS = 1;

    /* constants for getAllocCount */
    private static final int KIND_ALLOCATED_OBJECTS     = 1<<0;
    private static final int KIND_ALLOCATED_BYTES       = 1<<1;
    private static final int KIND_FREED_OBJECTS         = 1<<2;
    private static final int KIND_FREED_BYTES           = 1<<3;
    private static final int KIND_GC_INVOCATIONS        = 1<<4;
    private static final int KIND_CLASS_INIT_COUNT      = 1<<5;
    private static final int KIND_CLASS_INIT_TIME       = 1<<6;
    private static final int KIND_EXT_ALLOCATED_OBJECTS = 1<<12;
    private static final int KIND_EXT_ALLOCATED_BYTES   = 1<<13;
    private static final int KIND_EXT_FREED_OBJECTS     = 1<<14;
    private static final int KIND_EXT_FREED_BYTES       = 1<<15;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the number of all allocated objects.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_GLOBAL_ALLOCATED_OBJECTS =
        KIND_ALLOCATED_OBJECTS;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the cumulative size of all objects allocated.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_GLOBAL_ALLOCATED_BYTES =
        KIND_ALLOCATED_BYTES;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the number of freed objects.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_GLOBAL_FREED_OBJECTS =
        KIND_FREED_OBJECTS;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the cumulative size of all freed objects.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_GLOBAL_FREED_BYTES =
        KIND_FREED_BYTES;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the number of times an allocation triggered a blocking GC.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_GLOBAL_GC_INVOCATIONS =
        KIND_GC_INVOCATIONS;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the number of initialized classes.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_GLOBAL_CLASS_INIT_COUNT =
        KIND_CLASS_INIT_COUNT;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the cumulative time spent in class initialization.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_GLOBAL_CLASS_INIT_TIME =
        KIND_CLASS_INIT_TIME;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the number of all allocated objects for current thread.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_THREAD_ALLOCATED_OBJECTS =
        KIND_ALLOCATED_OBJECTS << 16;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the cumulative size of all objects allocated for current thread.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_THREAD_ALLOCATED_BYTES =
        KIND_ALLOCATED_BYTES << 16;

    /**
     * Constant for {@link #getAllocCount(int)}
     * to get the number of times an allocation triggered a blocking GC for current thread.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_THREAD_GC_INVOCATIONS =
        KIND_GC_INVOCATIONS << 16;

    /**
     * Constant for {@link #getAllocCount(int)} to get all possible stats.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static final int KIND_ALL_COUNTS = 0xffffffff;

    /* all methods are static */
    private VMDebug() {}

    /**
     * Request JDWP agent to suspend all Java Thread and send VM_START.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native void suspendAllAndSendVmStart();

    /**
     * Returns the time since the last known debugger activity.
     *
     * @return the time in milliseconds, or -1 if the debugger is not connected
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    @FastNative
    public static native long lastDebuggerActivity();

    /**
     * Determines if debugging is enabled in this VM.  If debugging is not
     * enabled, a debugger cannot be attached.
     *
     * @return true if debugging is enabled
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    @FastNative
    public static native boolean isDebuggingEnabled();

    /**
     * Determines if a debugger is currently attached.
     *
     * @return true if (and only if) a debugger is connected
     *
     * @hide
     */
    @UnsupportedAppUsage
    @SystemApi(client = MODULE_LIBRARIES)
    @FastNative
    public static native boolean isDebuggerConnected();

    /**
     * Returns an array of strings that identify VM features.  This is
     * used by DDMS to determine what sorts of operations the VM can
     * perform.
     *
     * @return array of strings identifying VM features
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native String[] getVmFeatureList();

    /**
     * Start method tracing, specifying a file name as well as a default
     * buffer size. See <a
     * href="{@docRoot}guide/developing/tools/traceview.html"> Running the
     * Traceview Debugging Program</a> for information about reading
     * trace files.
     *
     * <p>You can use either a fully qualified path and
     * name, or just a name. If only a name is specified, the file will
     * be created under the /sdcard/ directory. If a name is not given,
     * the default is /sdcard/dmtrace.trace.</p>
     *
     * @param traceFileName   name to give the trace file
     * @param bufferSize      the maximum size of both files combined. If passed
     *                        as {@code 0}, it defaults to 8MB.
     * @param flags           flags to control method tracing. The only one that
     *                        is currently defined is {@link #TRACE_COUNT_ALLOCS}.
     * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
     *                        method instrumentation is used.
     * @param intervalUs      the time between samples in microseconds when
     *                        sampling is enabled.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static void startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
        startMethodTracingFilename(traceFileName, checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
    }

    /**
     * Like {@link #startMethodTracing(String, int, int)}, but taking an already-opened
     * {@code FileDescriptor} in which the trace is written.  The file name is also
     * supplied simply for logging.  Makes a dup of the file descriptor.
     * Streams tracing data to the file if streamingOutput is true.
     *
     * @param traceFileName   name to give the trace file
     * @param fd              already opened {@code FileDescriptor} in which trace is written
     * @param bufferSize      the maximum size of both files combined. If passed
     *                        as {@code 0}, it defaults to 8MB.
     * @param flags           flags to control method tracing. The only one that
     *                        is currently defined is {@link #TRACE_COUNT_ALLOCS}.
     * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
     *                        method instrumentation is used.
     * @param intervalUs      the time between samples in microseconds when
     *                        sampling is enabled.
     * @param streamingOutput streams tracing data to the duped {@code fd} file descriptor
     *                        if {@code streamingOutput} is {@code true}.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize,
                                          int flags, boolean samplingEnabled, int intervalUs,
                                          boolean streamingOutput) {
        if (fd == null) {
            throw new NullPointerException("fd == null");
        }
        startMethodTracingFd(traceFileName, fd.getInt$(), checkBufferSize(bufferSize), flags,
                             samplingEnabled, intervalUs, streamingOutput);
    }

    /**
     * Starts method tracing without a backing file.  When {@link #stopMethodTracing()}
     * is called, the result is sent directly to DDMS.  (If DDMS is not
     * attached when tracing ends, the profiling data will be discarded.)
     *
     * @param bufferSize      the maximum size of both files combined. If passed
     *                        as {@code 0}, it defaults to 8MB.
     * @param flags           flags to control method tracing. The only one that
     *                        is currently defined is {@link #TRACE_COUNT_ALLOCS}.
     * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
     *                        method instrumentation is used.
     * @param intervalUs      the time between samples in microseconds when
     *                        sampling is enabled.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static void startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
        startMethodTracingDdmsImpl(checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
    }

    private static int checkBufferSize(int bufferSize) {
        if (bufferSize == 0) {
            // Default to 8MB per the documentation.
            bufferSize = 8 * 1024 * 1024;
        }
        if (bufferSize < 1024) {
            throw new IllegalArgumentException("buffer size < 1024: " + bufferSize);
        }
        return bufferSize;
    }

    private static native void startMethodTracingDdmsImpl(int bufferSize, int flags, boolean samplingEnabled, int intervalUs);
    private static native void startMethodTracingFd(String traceFileName, int fd, int bufferSize,
            int flags, boolean samplingEnabled, int intervalUs, boolean streamingOutput);
    private static native void startMethodTracingFilename(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs);

    /**
     * Determine whether method tracing is currently active and what type is
     * active.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native int getMethodTracingMode();

    /**
     * Stops method tracing.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native void stopMethodTracing();

    /**
     * Get an indication of thread CPU usage. The value returned indicates the
     * amount of time that the current thread has spent executing code or
     * waiting for certain types of I/O.
     * <p>
     * The time is expressed in nanoseconds, and is only meaningful when
     * compared to the result from an earlier call. Note that nanosecond
     * resolution does not imply nanosecond accuracy.
     *
     * @return the CPU usage. A value of -1 means the system does not support
     *         this feature.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    @FastNative
    public static native long threadCpuTimeNanos();

    /**
     * Starts counting the number and aggregate size of memory allocations.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native void startAllocCounting();

    /**
     * Stops counting the number and aggregate size of memory allocations.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native void stopAllocCounting();

    /**
     * Returns information on the number of objects allocated by the runtime between a
     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
     *
     * @param kind either {@code KIND_GLOBAL_*} or {@code KIND_THREAD_*}.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native int getAllocCount(int kind);

    /**
     * Resets counting the number and aggregate size of memory allocations for the given kinds.
     *
     * @param kinds a union of {@code KIND_GLOBAL_*} and {@code KIND_THREAD_*}.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native void resetAllocCount(int kinds);

    /**
     * This method exists for binary compatibility.  It was part of
     * the allocation limits API which was removed in Android 3.0 (Honeycomb).
     *
     * @hide
     */
    @Deprecated
    public static int setAllocationLimit(int limit) {
        return -1;
    }

    /**
     * This method exists for binary compatibility.  It was part of
     * the allocation limits API which was removed in Android 3.0 (Honeycomb).
     *
     * @hide
     */
    @Deprecated
    public static int setGlobalAllocationLimit(int limit) {
        return -1;
    }

    /**
     * Count the number of instructions executed between two points.
     *
     * @hide
     */
    @Deprecated
    public static void startInstructionCounting() {}

    /**
     *
     * @hide
     */
    @Deprecated
    public static void stopInstructionCounting() {}

    /**
     *
     * @hide
     */
    @Deprecated
    public static void getInstructionCount(int[] counts) {}

    /**
     *
     * @hide
     */
    @Deprecated
    public static void resetInstructionCount() {}

    /**
     * Dumps a list of loaded class to the log file.
     *
     * @param flags a union of {@link android.os.Debug.SHOW_FULL_DETAIL},
     *    {@link android.os.Debug.SHOW_CLASSLOADER}, and {@link android.os.Debug.SHOW_INITIALIZED}.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    @FastNative
    public static native void printLoadedClasses(int flags);

    /**
     * Gets the number of loaded classes.
     *
     * @return the number of loaded classes
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    @FastNative
    public static native int getLoadedClassCount();

    /**
     * Dumps "hprof" data to the specified file.  This may cause a GC.
     *
     * The VM may create a temporary file in the same directory.
     *
     * @param filename Full pathname of output file (e.g. "/sdcard/dump.hprof").
     * @throws UnsupportedOperationException if the VM was built without
     *         HPROF support.
     * @throws IOException if an error occurs while opening or writing files.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static void dumpHprofData(String filename) throws IOException {
        if (filename == null) {
            throw new NullPointerException("filename == null");
        }
        dumpHprofData(filename, null);
    }

    /**
     * Collects "hprof" heap data and sends it to DDMS.  This may cause a GC.
     *
     * @throws UnsupportedOperationException if the VM was built without
     *         HPROF support.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native void dumpHprofDataDdms();

    /**
     * Dumps "hprof" heap data to a file, by name or descriptor.
     *
     * @param fileName Name of output file.  If fd is non-null, the
     *        file name is only used in log messages (and may be null).
     * @param fd Descriptor of open file that will receive the output.
     *        If this is null, the fileName is used instead.
     * @throws {@link IOException} if an error occurs while opening or writing files.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static void dumpHprofData(String fileName, FileDescriptor fd)
            throws IOException {
       dumpHprofData(fileName, fd != null ? fd.getInt$() : -1);
    }

    private static native void dumpHprofData(String fileName, int fd)
            throws IOException;

    /**
     * Dumps the contents of the VM reference tables (e.g. JNI locals and
     * globals) to the log file.
     *
     * @hide
     */
    @UnsupportedAppUsage
    @SystemApi(client = MODULE_LIBRARIES)
    public static native void dumpReferenceTables();

    /**
     * Counts the instances of a class.
     * It is the caller's responsibility to do GC if they don't want unreachable
     * objects to get counted.
     *
     * @param klass the class to be counted.
     * @param assignable if true, any instance whose class is assignable to
     *                   {@code klass}, as defined by {@link Class#isAssignableFrom},
     *                   is counted. If false, only instances whose class is
     *                   equal to {@code klass} are counted.
     * @return the number of matching instances.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native long countInstancesOfClass(Class klass, boolean assignable);

    /**
     * Counts the instances of classes.
     * It is the caller's responsibility to do GC if they don't want unreachable
     * objects to get counted.
     *
     * @param classes the classes to be counted.
     * @param assignable if true, any instance whose class is assignable to
     *                   {@code classes[i]}, as defined by {@link Class#isAssignableFrom},
     *                   is counted. If false, only instances whose class is
     *                   equal to {@code classes[i]} are counted.
     * @return an array containing the number of matching instances. The value
     *         for index {@code i} is the number of instances of
     *         the class {@code classes[i]}
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native long[] countInstancesOfClasses(Class[] classes, boolean assignable);

    /* Map from the names of the runtime stats supported by getRuntimeStat() to their IDs */
    private static final HashMap<String, Integer> runtimeStatsMap = new HashMap<>();

    static {
        runtimeStatsMap.put("art.gc.gc-count", 0);
        runtimeStatsMap.put("art.gc.gc-time", 1);
        runtimeStatsMap.put("art.gc.bytes-allocated", 2);
        runtimeStatsMap.put("art.gc.bytes-freed", 3);
        runtimeStatsMap.put("art.gc.blocking-gc-count", 4);
        runtimeStatsMap.put("art.gc.blocking-gc-time", 5);
        runtimeStatsMap.put("art.gc.gc-count-rate-histogram", 6);
        runtimeStatsMap.put("art.gc.blocking-gc-count-rate-histogram", 7);
        runtimeStatsMap.put("art.gc.objects-allocated", 8);
        runtimeStatsMap.put("art.gc.total-time-waiting-for-gc", 9);
        runtimeStatsMap.put("art.gc.pre-oome-gc-count", 10);
    }

    /**
     * Returns the value of a particular runtime statistic or {@code null} if no
     * such runtime statistic exists.
     *
     * @param statName the name of the runtime statistic to look up.
     *
     * @return the value of the runtime statistic.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static String getRuntimeStat(String statName) {
        if (statName == null) {
            throw new NullPointerException("statName == null");
        }
        Integer statId = runtimeStatsMap.get(statName);
        if (statId != null) {
            return getRuntimeStatInternal(statId);
        }
        return null;
    }

    /**
     * Returns a map of the names/values of the runtime statistics
     * that {@link #getRuntimeStat()} supports.
     *
     * @return a map of the names/values of the supported runtime statistics.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static Map<String, String> getRuntimeStats() {
        HashMap<String, String> map = new HashMap<>();
        String[] values = getRuntimeStatsInternal();
        for (String name : runtimeStatsMap.keySet()) {
            int id = runtimeStatsMap.get(name);
            String value = values[id];
            map.put(name, value);
        }
        return map;
    }

    private static native String getRuntimeStatInternal(int statId);
    private static native String[] getRuntimeStatsInternal();

    /**
     * Attaches an agent to the VM.
     *
     * @param agent       The path to the agent .so file plus optional agent arguments.
     * @param classLoader The classloader to use as a loading context.
     *
     * @throws IOException if an error occurs while opening {@code agent} file.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static void attachAgent(String agent, ClassLoader classLoader) throws IOException {
        nativeAttachAgent(agent, classLoader);
    }

    private static native void nativeAttachAgent(String agent, ClassLoader classLoader)
            throws IOException;

    /**
     * Exempts a class from any future non-SDK API access checks.
     * Methods declared in the class will be allowed to perform
     * reflection/JNI against the framework completely unrestricted.
     * Note that this does not affect uses of non-SDK APIs that the class links against.
     * Note that this does not affect methods declared outside this class, e.g.
     * inherited from a superclass or an implemented interface.
     *
     * @param klass The class whose methods should be exempted.
     *
     * @hide
     */
    @UnsupportedAppUsage
    public static native void allowHiddenApiReflectionFrom(Class<?> klass);

    /**
     * Sets the number of frames recorded for allocation tracking.
     *
     * @param stackDepth The number of frames captured for each stack trace.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static native void setAllocTrackerStackDepth(int stackDepth);
}
