Home | History | Annotate | Download | only in system
      1 /*
      2  * Copyright (C) 2007 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 
     17 package dalvik.system;
     18 
     19 import dalvik.annotation.optimization.FastNative;
     20 import java.lang.ref.FinalizerReference;
     21 import java.util.HashMap;
     22 import java.util.Map;
     23 import java.util.function.Consumer;
     24 
     25 /**
     26  * Provides an interface to VM-global, Dalvik-specific features.
     27  * An application cannot create its own Runtime instance, and must obtain
     28  * one from the getRuntime method.
     29  *
     30  * @hide
     31  */
     32 public final class VMRuntime {
     33 
     34     /**
     35      * Holds the VMRuntime singleton.
     36      */
     37     private static final VMRuntime THE_ONE = new VMRuntime();
     38 
     39     // Note: Instruction set names are used to construct the names of some
     40     // system properties. To be sure that the properties stay valid the
     41     // instruction set name should not exceed 7 characters. See installd
     42     // and the package manager for the actual propeties.
     43     private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
     44             = new HashMap<String, String>(16);
     45     static {
     46         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
     47         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
     48         ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
     49         ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64");
     50         ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
     51         ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64");
     52         ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64");
     53     }
     54 
     55     /**
     56      * Magic version number for a current development build, which has not
     57      * yet turned into an official release. This number must be larger than
     58      * any released version in {@code android.os.Build.VERSION_CODES}.
     59      * @hide
     60      */
     61     public static final int SDK_VERSION_CUR_DEVELOPMENT = 10000;
     62 
     63     private static Consumer<String> nonSdkApiUsageConsumer = null;
     64 
     65     private int targetSdkVersion = SDK_VERSION_CUR_DEVELOPMENT;
     66 
     67     /**
     68      * Prevents this class from being instantiated.
     69      */
     70     private VMRuntime() {
     71     }
     72 
     73     /**
     74      * Returns the object that represents the VM instance's Dalvik-specific
     75      * runtime environment.
     76      *
     77      * @return the runtime object
     78      */
     79     public static VMRuntime getRuntime() {
     80         return THE_ONE;
     81     }
     82 
     83     /**
     84      * Returns a copy of the VM's command-line property settings.
     85      * These are in the form "name=value" rather than "-Dname=value".
     86      */
     87     public native String[] properties();
     88 
     89     /**
     90      * Returns the VM's boot class path.
     91      */
     92     public native String bootClassPath();
     93 
     94     /**
     95      * Returns the VM's class path.
     96      */
     97     public native String classPath();
     98 
     99     /**
    100      * Returns the VM's version.
    101      */
    102     public native String vmVersion();
    103 
    104     /**
    105      * Returns the name of the shared library providing the VM implementation.
    106      */
    107     public native String vmLibrary();
    108 
    109     /**
    110      * Returns the VM's instruction set.
    111      */
    112     public native String vmInstructionSet();
    113 
    114     /**
    115      * Returns whether the VM is running in 64-bit mode.
    116      */
    117     @FastNative
    118     public native boolean is64Bit();
    119 
    120     /**
    121      * Returns whether the VM is running with JNI checking enabled.
    122      */
    123     @FastNative
    124     public native boolean isCheckJniEnabled();
    125 
    126     /**
    127      * Gets the current ideal heap utilization, represented as a number
    128      * between zero and one.  After a GC happens, the Dalvik heap may
    129      * be resized so that (size of live objects) / (size of heap) is
    130      * equal to this number.
    131      *
    132      * @return the current ideal heap utilization
    133      */
    134     public native float getTargetHeapUtilization();
    135 
    136     /**
    137      * Sets the current ideal heap utilization, represented as a number
    138      * between zero and one.  After a GC happens, the Dalvik heap may
    139      * be resized so that (size of live objects) / (size of heap) is
    140      * equal to this number.
    141      *
    142      * <p>This is only a hint to the garbage collector and may be ignored.
    143      *
    144      * @param newTarget the new suggested ideal heap utilization.
    145      *                  This value may be adjusted internally.
    146      * @return the previous ideal heap utilization
    147      * @throws IllegalArgumentException if newTarget is &lt;= 0.0 or &gt;= 1.0
    148      */
    149     public float setTargetHeapUtilization(float newTarget) {
    150         if (newTarget <= 0.0f || newTarget >= 1.0f) {
    151             throw new IllegalArgumentException(newTarget +
    152                     " out of range (0,1)");
    153         }
    154         /* Synchronize to make sure that only one thread gets
    155          * a given "old" value if both update at the same time.
    156          * Allows for reliable save-and-restore semantics.
    157          */
    158         synchronized (this) {
    159             float oldTarget = getTargetHeapUtilization();
    160             nativeSetTargetHeapUtilization(newTarget);
    161             return oldTarget;
    162         }
    163     }
    164 
    165     /**
    166      * Sets the target SDK version. Should only be called before the
    167      * app starts to run, because it may change the VM's behavior in
    168      * dangerous ways. Defaults to {@link #SDK_VERSION_CUR_DEVELOPMENT}.
    169      */
    170     public synchronized void setTargetSdkVersion(int targetSdkVersion) {
    171         this.targetSdkVersion = targetSdkVersion;
    172         setTargetSdkVersionNative(this.targetSdkVersion);
    173     }
    174 
    175     /**
    176      * Gets the target SDK version. See {@link #setTargetSdkVersion} for
    177      * special values.
    178      */
    179     public synchronized int getTargetSdkVersion() {
    180         return targetSdkVersion;
    181     }
    182 
    183     private native void setTargetSdkVersionNative(int targetSdkVersion);
    184 
    185     /**
    186      * This method exists for binary compatibility.  It was part of a
    187      * heap sizing API which was removed in Android 3.0 (Honeycomb).
    188      */
    189     @Deprecated
    190     public long getMinimumHeapSize() {
    191         return 0;
    192     }
    193 
    194     /**
    195      * This method exists for binary compatibility.  It was part of a
    196      * heap sizing API which was removed in Android 3.0 (Honeycomb).
    197      */
    198     @Deprecated
    199     public long setMinimumHeapSize(long size) {
    200         return 0;
    201     }
    202 
    203     /**
    204      * This method exists for binary compatibility.  It used to
    205      * perform a garbage collection that cleared SoftReferences.
    206      */
    207     @Deprecated
    208     public void gcSoftReferences() {}
    209 
    210     /**
    211      * This method exists for binary compatibility.  It is equivalent
    212      * to {@link System#runFinalization}.
    213      */
    214     @Deprecated
    215     public void runFinalizationSync() {
    216         System.runFinalization();
    217     }
    218 
    219     /**
    220      * Implements setTargetHeapUtilization().
    221      *
    222      * @param newTarget the new suggested ideal heap utilization.
    223      *                  This value may be adjusted internally.
    224      */
    225     private native void nativeSetTargetHeapUtilization(float newTarget);
    226 
    227     /**
    228      * This method exists for binary compatibility.  It was part of
    229      * the external allocation API which was removed in Android 3.0 (Honeycomb).
    230      */
    231     @Deprecated
    232     public boolean trackExternalAllocation(long size) {
    233         return true;
    234     }
    235 
    236     /**
    237      * This method exists for binary compatibility.  It was part of
    238      * the external allocation API which was removed in Android 3.0 (Honeycomb).
    239      */
    240     @Deprecated
    241     public void trackExternalFree(long size) {}
    242 
    243     /**
    244      * This method exists for binary compatibility.  It was part of
    245      * the external allocation API which was removed in Android 3.0 (Honeycomb).
    246      */
    247     @Deprecated
    248     public long getExternalBytesAllocated() {
    249         return 0;
    250     }
    251 
    252     /**
    253      * Tells the VM to enable the JIT compiler. If the VM does not have a JIT
    254      * implementation, calling this method should have no effect.
    255      */
    256     public native void startJitCompilation();
    257 
    258     /**
    259      * Tells the VM to disable the JIT compiler. If the VM does not have a JIT
    260      * implementation, calling this method should have no effect.
    261      */
    262     public native void disableJitCompilation();
    263 
    264     /**
    265      * Returns true if the app has accessed a hidden API. This does not include
    266      * attempts which have been blocked.
    267      */
    268     public native boolean hasUsedHiddenApi();
    269 
    270     /**
    271      * Sets the list of exemptions from hidden API access enforcement.
    272      *
    273      * @param signaturePrefixes
    274      *         A list of signature prefixes. Each item in the list is a prefix match on the type
    275      *         signature of a blacklisted API. All matching APIs are treated as if they were on
    276      *         the whitelist: access permitted, and no logging..
    277      */
    278     public native void setHiddenApiExemptions(String[] signaturePrefixes);
    279 
    280     /**
    281      * Sets the log sampling rate of hidden API accesses written to the event log.
    282      *
    283      * @param rate Proportion of hidden API accesses that will be logged; an integer between
    284      *                0 and 0x10000 inclusive.
    285      */
    286     public native void setHiddenApiAccessLogSamplingRate(int rate);
    287 
    288     /**
    289      * Returns an array allocated in an area of the Java heap where it will never be moved.
    290      * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
    291      * and Bitmaps.
    292      */
    293     @FastNative
    294     public native Object newNonMovableArray(Class<?> componentType, int length);
    295 
    296     /**
    297      * Returns an array of at least minLength, but potentially larger. The increased size comes from
    298      * avoiding any padding after the array. The amount of padding varies depending on the
    299      * componentType and the memory allocator implementation.
    300      */
    301     @FastNative
    302     public native Object newUnpaddedArray(Class<?> componentType, int minLength);
    303 
    304     /**
    305      * Returns the address of array[0]. This differs from using JNI in that JNI might lie and
    306      * give you the address of a copy of the array when in forcecopy mode.
    307      */
    308     @FastNative
    309     public native long addressOf(Object array);
    310 
    311     /**
    312      * Removes any growth limits, allowing the application to allocate
    313      * up to the maximum heap size.
    314      */
    315     public native void clearGrowthLimit();
    316 
    317     /**
    318      * Make the current growth limit the new non growth limit capacity by releasing pages which
    319      * are after the growth limit but before the non growth limit capacity.
    320      */
    321     public native void clampGrowthLimit();
    322 
    323     /**
    324      * Returns true if either a Java debugger or native debugger is active.
    325      */
    326     @FastNative
    327     public native boolean isDebuggerActive();
    328 
    329     /**
    330      * Returns true if native debugging is on.
    331      */
    332     @FastNative
    333     public native boolean isNativeDebuggable();
    334 
    335     /**
    336      * Returns true if Java debugging is enabled.
    337      */
    338     public native boolean isJavaDebuggable();
    339 
    340     /**
    341      * Registers a native allocation so that the heap knows about it and performs GC as required.
    342      * If the number of native allocated bytes exceeds the native allocation watermark, the
    343      * function requests a concurrent GC. If the native bytes allocated exceeds a second higher
    344      * watermark, it is determined that the application is registering native allocations at an
    345      * unusually high rate and a GC is performed inside of the function to prevent memory usage
    346      * from excessively increasing.
    347      */
    348     public native void registerNativeAllocation(int bytes);
    349 
    350     /**
    351      * Registers a native free by reducing the number of native bytes accounted for.
    352      */
    353     public native void registerNativeFree(int bytes);
    354 
    355     /**
    356      * Wait for objects to be finalized.
    357      *
    358      * If finalization takes longer than timeout, then the function returns before all objects are
    359      * finalized.
    360      *
    361      * @param timeout
    362      *            timeout in nanoseconds of the maximum time to wait until all pending finalizers
    363      *            are run. If timeout is 0, then there is no timeout. Note that the timeout does
    364      *            not stop the finalization process, it merely stops the wait.
    365      *
    366      * @see #Runtime.runFinalization()
    367      * @see #wait(long,int)
    368      */
    369     public static void runFinalization(long timeout) {
    370         try {
    371             FinalizerReference.finalizeAllEnqueued(timeout);
    372         } catch (InterruptedException e) {
    373             // Interrupt the current thread without actually throwing the InterruptionException
    374             // for the caller.
    375             Thread.currentThread().interrupt();
    376         }
    377     }
    378 
    379     public native void requestConcurrentGC();
    380     public native void concurrentGC();
    381     public native void requestHeapTrim();
    382     public native void trimHeap();
    383     public native void startHeapTaskProcessor();
    384     public native void stopHeapTaskProcessor();
    385     public native void runHeapTasks();
    386 
    387     /**
    388      * Let the heap know of the new process state. This can change allocation and garbage collection
    389      * behavior regarding trimming and compaction.
    390      */
    391     public native void updateProcessState(int state);
    392 
    393     /**
    394      * Fill in dex caches with classes, fields, and methods that are
    395      * already loaded. Typically used after Zygote preloading.
    396      */
    397     public native void preloadDexCaches();
    398 
    399     /**
    400      * Register application info.
    401      * @param profileFile the path of the file where the profile information should be stored.
    402      * @param codePaths the code paths that should be profiled.
    403      */
    404     public static native void registerAppInfo(String profileFile, String[] codePaths);
    405 
    406     /**
    407      * Returns the runtime instruction set corresponding to a given ABI. Multiple
    408      * compatible ABIs might map to the same instruction set. For example
    409      * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}.
    410      *
    411      * This influences the compilation of the applications classes.
    412      */
    413     public static String getInstructionSet(String abi) {
    414         final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
    415         if (instructionSet == null) {
    416             throw new IllegalArgumentException("Unsupported ABI: " + abi);
    417         }
    418 
    419         return instructionSet;
    420     }
    421 
    422     public static boolean is64BitInstructionSet(String instructionSet) {
    423         return "arm64".equals(instructionSet) ||
    424                 "x86_64".equals(instructionSet) ||
    425                 "mips64".equals(instructionSet);
    426     }
    427 
    428     public static boolean is64BitAbi(String abi) {
    429         return is64BitInstructionSet(getInstructionSet(abi));
    430     }
    431 
    432     /**
    433      * Return false if the boot class path for the given instruction
    434      * set mapped from disk storage, versus being interpretted from
    435      * dirty pages in memory.
    436      */
    437     public static native boolean isBootClassPathOnDisk(String instructionSet);
    438 
    439     /**
    440      * Returns the instruction set of the current runtime.
    441      */
    442     public static native String getCurrentInstructionSet();
    443 
    444     /**
    445      * Return true if the dalvik cache was pruned when booting. This may have happened for
    446      * various reasons, e.g., after an OTA. The return value is for the current instruction
    447      * set.
    448      */
    449     public static native boolean didPruneDalvikCache();
    450 
    451     /**
    452      * Register the current execution thread to the runtime as sensitive thread.
    453      * Should be called just once. Subsequent calls are ignored.
    454      */
    455     public static native void registerSensitiveThread();
    456 
    457     /**
    458      * Sets up the priority of the system daemon thread (caller).
    459      */
    460     public static native void setSystemDaemonThreadPriority();
    461 
    462     /**
    463      * Sets a callback that the runtime can call whenever a usage of a non SDK API is detected.
    464      */
    465     public static void setNonSdkApiUsageConsumer(Consumer<String> consumer) {
    466         nonSdkApiUsageConsumer = consumer;
    467     }
    468 
    469     /**
    470      * Sets whether or not the runtime should dedupe detection and warnings for hidden API usage.
    471      * If deduping is enabled, only the first usage of each API will be detected. The default
    472      * behaviour is to dedupe.
    473      */
    474     public static native void setDedupeHiddenApiWarnings(boolean dedupe);
    475 
    476     /**
    477      * Sets the package name of the app running in this process.
    478      */
    479     public static native void setProcessPackageName(String packageName);
    480 }
    481