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.compat.UnsupportedAppUsage;
20 import dalvik.annotation.optimization.FastNative;
21 import java.lang.ref.FinalizerReference;
22 import java.util.concurrent.atomic.AtomicInteger;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.function.Consumer;
26 
27 /**
28  * Provides an interface to VM-global, Dalvik-specific features.
29  * An application cannot create its own Runtime instance, and must obtain
30  * one from the getRuntime method.
31  *
32  * @hide
33  */
34 @libcore.api.CorePlatformApi
35 public final class VMRuntime {
36 
37     /**
38      * Holds the VMRuntime singleton.
39      */
40     private static final VMRuntime THE_ONE = new VMRuntime();
41 
42     // Note: Instruction set names are used to construct the names of some
43     // system properties. To be sure that the properties stay valid the
44     // instruction set name should not exceed 7 characters. See installd
45     // and the package manager for the actual propeties.
46     private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
47             = new HashMap<String, String>(16);
48     static {
49         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
50         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
51         ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
52         ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64");
53         ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
54         ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64");
55         ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64");
56     }
57 
58     /**
59      * Interface for logging hidden API usage events.
60      */
61     @libcore.api.CorePlatformApi
62     public interface HiddenApiUsageLogger {
63 
64         // The following ACCESS_METHOD_ constants must match the values in
65         // art/runtime/hidden_api.h
66         /**
67          * Internal test value that does not correspond to an actual access by the
68          * application. Never logged, added for completeness.
69          */
70         public static final int ACCESS_METHOD_NONE = 0;
71 
72         /**
73          *  Used when a method has been accessed via reflection.
74          */
75         public static final int ACCESS_METHOD_REFLECTION = 1;
76 
77         /**
78          *  Used when a method has been accessed via JNI.
79          */
80         public static final int ACCESS_METHOD_JNI = 2;
81 
82         /**
83          * Used when a method is accessed at link time. Never logged, added only
84          * for completeness.
85          */
86         public static final int ACCESS_METHOD_LINKING = 3;
87 
88         /**
89          * Logs hidden API access
90          *
91          * @param sampledValue value that was sampled, to be compared against the
92          *      sampling rate
93          * @param appPackageName package name of the app attempting the access
94          * @param signature signature of the method being called, i.e
95          *      class_name->member_name:type_signature (e.g.
96          *      {@code com.android.app.Activity->mDoReportFullyDrawn:Z}) for fields and
97          *      class_name->method_name_and_signature for methods (e.g
98          *      {@code com.android.app.Activity->finish(I)V})
99          * @param accessType how the accessed was done
100          * @param accessDenied whether the access was allowed or not
101          */
hiddenApiUsed(int sampledValue, String appPackageName, String signature, int accessType, boolean accessDenied)102         public void hiddenApiUsed(int sampledValue, String appPackageName,
103             String signature, int accessType, boolean accessDenied);
104     }
105 
106     static HiddenApiUsageLogger hiddenApiUsageLogger;
107 
108     /**
109      * Sets the hidden API usage logger {@link #hiddenApiUsageLogger}.
110      * It should only be called if {@link #setHiddenApiAccessLogSamplingRate(int)}
111      * is called with a value > 0
112      */
113     @libcore.api.CorePlatformApi
setHiddenApiUsageLogger(HiddenApiUsageLogger hiddenApiUsageLogger)114     public static void setHiddenApiUsageLogger(HiddenApiUsageLogger hiddenApiUsageLogger) {
115         VMRuntime.hiddenApiUsageLogger = hiddenApiUsageLogger;
116     }
117 
118     /**
119      * Records an attempted hidden API access to
120      * {@link HiddenApiUsageLogger#hiddenApiUsed(int, String, String, int, boolean}
121      * if a logger is registered via {@link #setHiddenApiUsageLogger}.
122      */
hiddenApiUsed(int sampledValue, String appPackageName, String signature, int accessType, boolean accessDenied)123     private static void hiddenApiUsed(int sampledValue, String appPackageName, String signature,
124          int accessType, boolean accessDenied) {
125         if (VMRuntime.hiddenApiUsageLogger != null) {
126             VMRuntime.hiddenApiUsageLogger.hiddenApiUsed(sampledValue, appPackageName,
127                 signature, accessType, accessDenied);
128         }
129     }
130 
131     /**
132      * Magic version number for a current development build, which has not
133      * yet turned into an official release. This number must be larger than
134      * any released version in {@code android.os.Build.VERSION_CODES}.
135      * @hide
136      */
137     @libcore.api.CorePlatformApi
138     public static final int SDK_VERSION_CUR_DEVELOPMENT = 10000;
139 
140     private static Consumer<String> nonSdkApiUsageConsumer = null;
141 
142     private int targetSdkVersion = SDK_VERSION_CUR_DEVELOPMENT;
143 
144     // notifyNativeAllocationsInternal (below) should be called every notifyNativeInterval
145     // allocations. Initialized on demand to allow completely static class initialization.
146     private int notifyNativeInterval;
147 
148     // Allocations since last call to native layer. See notifyNativeAllocation().
149     private final AtomicInteger allocationCount = new AtomicInteger(0);
150 
151     /**
152      * Prevents this class from being instantiated.
153      */
VMRuntime()154     private VMRuntime() {
155     }
156 
157     /**
158      * Returns the object that represents the VM instance's Dalvik-specific
159      * runtime environment.
160      *
161      * @return the runtime object
162      */
163     @UnsupportedAppUsage
164     @libcore.api.CorePlatformApi
getRuntime()165     public static VMRuntime getRuntime() {
166         return THE_ONE;
167     }
168 
169     /**
170      * Returns a copy of the VM's command-line property settings.
171      * These are in the form "name=value" rather than "-Dname=value".
172      */
properties()173     public native String[] properties();
174 
175     /**
176      * Returns the VM's boot class path.
177      */
bootClassPath()178     public native String bootClassPath();
179 
180     /**
181      * Returns the VM's class path.
182      */
classPath()183     public native String classPath();
184 
185     /**
186      * Returns the VM's version.
187      */
vmVersion()188     public native String vmVersion();
189 
190     /**
191      * Returns the name of the shared library providing the VM implementation.
192      */
193     @UnsupportedAppUsage
194     @libcore.api.CorePlatformApi
vmLibrary()195     public native String vmLibrary();
196 
197     /**
198      * Returns the VM's instruction set.
199      */
200     @UnsupportedAppUsage
201     @libcore.api.CorePlatformApi
vmInstructionSet()202     public native String vmInstructionSet();
203 
204     /**
205      * Returns whether the VM is running in 64-bit mode.
206      */
207     @UnsupportedAppUsage
208     @libcore.api.CorePlatformApi
209     @FastNative
is64Bit()210     public native boolean is64Bit();
211 
212     /**
213      * Returns whether the VM is running with JNI checking enabled.
214      */
215     @libcore.api.CorePlatformApi
216     @FastNative
isCheckJniEnabled()217     public native boolean isCheckJniEnabled();
218 
219     /**
220      * Gets the current ideal heap utilization, represented as a number
221      * between zero and one.  After a GC happens, the Dalvik heap may
222      * be resized so that (size of live objects) / (size of heap) is
223      * equal to this number.
224      *
225      * @return the current ideal heap utilization
226      */
227     @libcore.api.CorePlatformApi
getTargetHeapUtilization()228     public native float getTargetHeapUtilization();
229 
230     /**
231      * Retrieves the finalizer timeout in milliseconds.
232      * Finalizers that fail to terminate in this amount of time cause the
233      * runtime to abort.
234      */
getFinalizerTimeoutMs()235     public native long getFinalizerTimeoutMs();
236 
237     /**
238      * Sets the current ideal heap utilization, represented as a number
239      * between zero and one.  After a GC happens, the Dalvik heap may
240      * be resized so that (size of live objects) / (size of heap) is
241      * equal to this number.
242      *
243      * <p>This is only a hint to the garbage collector and may be ignored.
244      *
245      * @param newTarget the new suggested ideal heap utilization.
246      *                  This value may be adjusted internally.
247      * @return the previous ideal heap utilization
248      * @throws IllegalArgumentException if newTarget is &lt;= 0.0 or &gt;= 1.0
249      */
250     @UnsupportedAppUsage
251     @libcore.api.CorePlatformApi
setTargetHeapUtilization(float newTarget)252     public float setTargetHeapUtilization(float newTarget) {
253         if (newTarget <= 0.0f || newTarget >= 1.0f) {
254             throw new IllegalArgumentException(newTarget + " out of range (0,1)");
255         }
256         /* The native code assumes a value >= 0.1. Clamp it to that. */
257         if (newTarget < 0.1f) {
258             newTarget = 0.1f;
259         }
260         /* Synchronize to make sure that only one thread gets a given "old" value if both
261          * update at the same time.  Allows for reliable save-and-restore semantics.
262          */
263         synchronized (this) {
264             float oldTarget = getTargetHeapUtilization();
265             nativeSetTargetHeapUtilization(newTarget);
266             return oldTarget;
267         }
268     }
269 
270     /**
271      * Sets the target SDK version. Should only be called before the
272      * app starts to run, because it may change the VM's behavior in
273      * dangerous ways. Defaults to {@link #SDK_VERSION_CUR_DEVELOPMENT}.
274      */
275     @libcore.api.CorePlatformApi
setTargetSdkVersion(int targetSdkVersion)276     public synchronized void setTargetSdkVersion(int targetSdkVersion) {
277         this.targetSdkVersion = targetSdkVersion;
278         setTargetSdkVersionNative(this.targetSdkVersion);
279     }
280 
281     /**
282      * Gets the target SDK version. See {@link #setTargetSdkVersion} for
283      * special values.
284      */
285     @libcore.api.CorePlatformApi
getTargetSdkVersion()286     public synchronized int getTargetSdkVersion() {
287         return targetSdkVersion;
288     }
289 
setTargetSdkVersionNative(int targetSdkVersion)290     private native void setTargetSdkVersionNative(int targetSdkVersion);
291 
292     /**
293      * This method exists for binary compatibility.  It was part of a
294      * heap sizing API which was removed in Android 3.0 (Honeycomb).
295      */
296     @UnsupportedAppUsage
297     @Deprecated
getMinimumHeapSize()298     public long getMinimumHeapSize() {
299         return 0;
300     }
301 
302     /**
303      * This method exists for binary compatibility.  It was part of a
304      * heap sizing API which was removed in Android 3.0 (Honeycomb).
305      */
306     @UnsupportedAppUsage
307     @Deprecated
setMinimumHeapSize(long size)308     public long setMinimumHeapSize(long size) {
309         return 0;
310     }
311 
312     /**
313      * This method exists for binary compatibility.  It used to
314      * perform a garbage collection that cleared SoftReferences.
315      */
316     @UnsupportedAppUsage
317     @Deprecated
gcSoftReferences()318     public void gcSoftReferences() {}
319 
320     /**
321      * This method exists for binary compatibility.  It is equivalent
322      * to {@link System#runFinalization}.
323      */
324     @UnsupportedAppUsage
325     @Deprecated
runFinalizationSync()326     public void runFinalizationSync() {
327         System.runFinalization();
328     }
329 
330     /**
331      * Implements setTargetHeapUtilization().
332      *
333      * @param newTarget the new suggested ideal heap utilization.
334      *                  This value may be adjusted internally.
335      */
nativeSetTargetHeapUtilization(float newTarget)336     private native void nativeSetTargetHeapUtilization(float newTarget);
337 
338     /**
339      * This method exists for binary compatibility.  It was part of
340      * the external allocation API which was removed in Android 3.0 (Honeycomb).
341      */
342     @UnsupportedAppUsage
343     @Deprecated
trackExternalAllocation(long size)344     public boolean trackExternalAllocation(long size) {
345         return true;
346     }
347 
348     /**
349      * This method exists for binary compatibility.  It was part of
350      * the external allocation API which was removed in Android 3.0 (Honeycomb).
351      */
352     @UnsupportedAppUsage
353     @Deprecated
trackExternalFree(long size)354     public void trackExternalFree(long size) {}
355 
356     /**
357      * This method exists for binary compatibility.  It was part of
358      * the external allocation API which was removed in Android 3.0 (Honeycomb).
359      */
360     @UnsupportedAppUsage
361     @Deprecated
getExternalBytesAllocated()362     public long getExternalBytesAllocated() {
363         return 0;
364     }
365 
366     /**
367      * Tells the VM to enable the JIT compiler. If the VM does not have a JIT
368      * implementation, calling this method should have no effect.
369      */
370     @libcore.api.CorePlatformApi
startJitCompilation()371     public native void startJitCompilation();
372 
373     /**
374      * Tells the VM to disable the JIT compiler. If the VM does not have a JIT
375      * implementation, calling this method should have no effect.
376      */
377     @libcore.api.CorePlatformApi
disableJitCompilation()378     public native void disableJitCompilation();
379 
380     /**
381      * Sets the list of exemptions from hidden API access enforcement.
382      *
383      * @param signaturePrefixes
384      *         A list of signature prefixes. Each item in the list is a prefix match on the type
385      *         signature of a blacklisted API. All matching APIs are treated as if they were on
386      *         the whitelist: access permitted, and no logging..
387      */
388     @libcore.api.CorePlatformApi
setHiddenApiExemptions(String[] signaturePrefixes)389     public native void setHiddenApiExemptions(String[] signaturePrefixes);
390 
391     /**
392      * Sets the log sampling rate of hidden API accesses written to the event log.
393      *
394      * @param rate Proportion of hidden API accesses that will be logged; an integer between
395      *                0 and 0x10000 inclusive.
396      */
397     @libcore.api.CorePlatformApi
setHiddenApiAccessLogSamplingRate(int rate)398     public native void setHiddenApiAccessLogSamplingRate(int rate);
399 
400     /**
401      * Returns an array allocated in an area of the Java heap where it will never be moved.
402      * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
403      * and Bitmaps.
404      */
405     @UnsupportedAppUsage
406     @libcore.api.CorePlatformApi
407     @FastNative
newNonMovableArray(Class<?> componentType, int length)408     public native Object newNonMovableArray(Class<?> componentType, int length);
409 
410     /**
411      * Returns an array of at least minLength, but potentially larger. The increased size comes from
412      * avoiding any padding after the array. The amount of padding varies depending on the
413      * componentType and the memory allocator implementation.
414      */
415     @libcore.api.CorePlatformApi
416     @FastNative
newUnpaddedArray(Class<?> componentType, int minLength)417     public native Object newUnpaddedArray(Class<?> componentType, int minLength);
418 
419     /**
420      * Returns the address of array[0]. This differs from using JNI in that JNI might lie and
421      * give you the address of a copy of the array when in forcecopy mode.
422      */
423     @UnsupportedAppUsage
424     @libcore.api.CorePlatformApi
425     @FastNative
addressOf(Object array)426     public native long addressOf(Object array);
427 
428     /**
429      * Removes any growth limits, allowing the application to allocate
430      * up to the maximum heap size.
431      */
432     @UnsupportedAppUsage
433     @libcore.api.CorePlatformApi
clearGrowthLimit()434     public native void clearGrowthLimit();
435 
436     /**
437      * Make the current growth limit the new non growth limit capacity by releasing pages which
438      * are after the growth limit but before the non growth limit capacity.
439      */
440     @libcore.api.CorePlatformApi
clampGrowthLimit()441     public native void clampGrowthLimit();
442 
443     /**
444      * Returns true if either a Java debugger or native debugger is active.
445      */
446     @FastNative
isDebuggerActive()447     public native boolean isDebuggerActive();
448 
449     /**
450      * Returns true if native debugging is on.
451      */
452     @libcore.api.CorePlatformApi
453     @FastNative
isNativeDebuggable()454     public native boolean isNativeDebuggable();
455 
456     /**
457      * Returns true if Java debugging is enabled.
458      */
isJavaDebuggable()459     public native boolean isJavaDebuggable();
460 
461     /**
462      * Registers a native allocation so that the heap knows about it and performs GC as required.
463      * If the number of native allocated bytes exceeds the native allocation watermark, the
464      * function requests a concurrent GC. If the native bytes allocated exceeds a second higher
465      * watermark, it is determined that the application is registering native allocations at an
466      * unusually high rate and a GC is performed inside of the function to prevent memory usage
467      * from excessively increasing. Memory allocated via system malloc() should not be included
468      * in this count. The argument must be the same as that later passed to registerNativeFree(),
469      * but may otherwise be approximate.
470      */
471     @UnsupportedAppUsage
472     @libcore.api.CorePlatformApi
registerNativeAllocation(long bytes)473     public native void registerNativeAllocation(long bytes);
474 
475     /**
476      * Backward compatibility version of registerNativeAllocation. We used to pass an int instead
477      * of a long. The RenderScript support library looks it up via reflection.
478      * @deprecated Use long argument instead.
479      */
480     @UnsupportedAppUsage
481     @Deprecated
482     @libcore.api.CorePlatformApi
registerNativeAllocation(int bytes)483     public void registerNativeAllocation(int bytes) {
484         registerNativeAllocation((long) bytes);
485     }
486 
487     /**
488      * Registers a native free by reducing the number of native bytes accounted for.
489      */
490     @UnsupportedAppUsage
491     @libcore.api.CorePlatformApi
registerNativeFree(long bytes)492     public native void registerNativeFree(long bytes);
493 
494     /**
495      * Backward compatibility version of registerNativeFree.
496      * @deprecated Use long argument instead.
497      */
498     @UnsupportedAppUsage
499     @Deprecated
500     @libcore.api.CorePlatformApi
registerNativeFree(int bytes)501     public void registerNativeFree(int bytes) {
502         registerNativeFree((long) bytes);
503     }
504 
505     /**
506      * Return the number of native objects that are reported by a single call to
507      * notifyNativeAllocation().
508      */
getNotifyNativeInterval()509     private static native int getNotifyNativeInterval();
510 
511     /**
512      * Report a native malloc()-only allocation to the GC.
513      */
notifyNativeAllocation()514     public void notifyNativeAllocation() {
515         // Minimize JNI calls by notifying once every notifyNativeInterval allocations.
516         // The native code cannot do anything without calling mallinfo(), which is too
517         // expensive to perform on every allocation. To avoid the JNI overhead on every
518         // allocation, we do the sampling here, rather than in native code.
519         // Initialize notifyNativeInterval carefully. Multiple initializations may race.
520         int myNotifyNativeInterval = notifyNativeInterval;
521         if (myNotifyNativeInterval == 0) {
522             // This can race. By Java rules, that's OK.
523             myNotifyNativeInterval = notifyNativeInterval = getNotifyNativeInterval();
524         }
525         // myNotifyNativeInterval is correct here. If another thread won the initial race,
526         // notifyNativeInterval may not be.
527         if (allocationCount.addAndGet(1) % myNotifyNativeInterval == 0) {
528             notifyNativeAllocationsInternal();
529         }
530     }
531 
532     /**
533      * Report to the GC that roughly notifyNativeInterval native malloc()-based
534      * allocations have occurred since the last call to notifyNativeAllocationsInternal().
535      * Hints that we should check whether a GC is required.
536      */
notifyNativeAllocationsInternal()537     public native void notifyNativeAllocationsInternal();
538 
539     /**
540      * Wait for objects to be finalized.
541      *
542      * If finalization takes longer than timeout, then the function returns before all objects are
543      * finalized.
544      *
545      * @param timeout
546      *            timeout in nanoseconds of the maximum time to wait until all pending finalizers
547      *            are run. If timeout is 0, then there is no timeout. Note that the timeout does
548      *            not stop the finalization process, it merely stops the wait.
549      *
550      * @see #Runtime.runFinalization()
551      * @see #wait(long,int)
552      */
553     @UnsupportedAppUsage
runFinalization(long timeout)554     public static void runFinalization(long timeout) {
555         try {
556             FinalizerReference.finalizeAllEnqueued(timeout);
557         } catch (InterruptedException e) {
558             // Interrupt the current thread without actually throwing the InterruptionException
559             // for the caller.
560             Thread.currentThread().interrupt();
561         }
562     }
563 
564     @libcore.api.CorePlatformApi
requestConcurrentGC()565     public native void requestConcurrentGC();
concurrentGC()566     public native void concurrentGC();
requestHeapTrim()567     public native void requestHeapTrim();
trimHeap()568     public native void trimHeap();
startHeapTaskProcessor()569     public native void startHeapTaskProcessor();
stopHeapTaskProcessor()570     public native void stopHeapTaskProcessor();
runHeapTasks()571     public native void runHeapTasks();
572 
573     /**
574      * Let the heap know of the new process state. This can change allocation and garbage collection
575      * behavior regarding trimming and compaction.
576      */
577     @libcore.api.CorePlatformApi
updateProcessState(int state)578     public native void updateProcessState(int state);
579 
580     /**
581      * Let the runtime know that the application startup is completed. This may affect behavior
582      * related to profiling and startup caches.
583      */
584     @libcore.api.CorePlatformApi
notifyStartupCompleted()585     public native void notifyStartupCompleted();
586 
587     /**
588      * Fill in dex caches with classes, fields, and methods that are
589      * already loaded. Typically used after Zygote preloading.
590      */
591     @libcore.api.CorePlatformApi
preloadDexCaches()592     public native void preloadDexCaches();
593 
594     /**
595      * Register application info.
596      * @param profileFile the path of the file where the profile information should be stored.
597      * @param codePaths the code paths that should be profiled.
598      */
599     @libcore.api.CorePlatformApi
registerAppInfo(String profileFile, String[] codePaths)600     public static native void registerAppInfo(String profileFile, String[] codePaths);
601 
602     /**
603      * Returns the runtime instruction set corresponding to a given ABI. Multiple
604      * compatible ABIs might map to the same instruction set. For example
605      * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}.
606      *
607      * This influences the compilation of the applications classes.
608      */
609     @UnsupportedAppUsage
610     @libcore.api.CorePlatformApi
getInstructionSet(String abi)611     public static String getInstructionSet(String abi) {
612         final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
613         if (instructionSet == null) {
614             throw new IllegalArgumentException("Unsupported ABI: " + abi);
615         }
616 
617         return instructionSet;
618     }
619 
620     @libcore.api.CorePlatformApi
is64BitInstructionSet(String instructionSet)621     public static boolean is64BitInstructionSet(String instructionSet) {
622         return "arm64".equals(instructionSet) ||
623                 "x86_64".equals(instructionSet) ||
624                 "mips64".equals(instructionSet);
625     }
626 
627     @UnsupportedAppUsage
628     @libcore.api.CorePlatformApi
is64BitAbi(String abi)629     public static boolean is64BitAbi(String abi) {
630         return is64BitInstructionSet(getInstructionSet(abi));
631     }
632 
633     /**
634      * Return false if the boot class path for the given instruction
635      * set mapped from disk storage, versus being interpretted from
636      * dirty pages in memory.
637      */
638     @libcore.api.CorePlatformApi
isBootClassPathOnDisk(String instructionSet)639     public static native boolean isBootClassPathOnDisk(String instructionSet);
640 
641     /**
642      * Returns whether the runtime is using a boot image.
643      *
644      * <p>While isBootClassPathOnDisk checks for the existence of an image file on disk,
645      * this method queries the runtime whether it is <em>using</em> an image.
646      */
647     @libcore.api.CorePlatformApi
648     @FastNative
hasBootImageSpaces()649     public static native boolean hasBootImageSpaces();
650 
651     /**
652      * Returns the instruction set of the current runtime.
653      */
654     @UnsupportedAppUsage
655     @libcore.api.CorePlatformApi
getCurrentInstructionSet()656     public static native String getCurrentInstructionSet();
657 
658     /**
659      * Return true if the dalvik cache was pruned when booting. This may have happened for
660      * various reasons, e.g., after an OTA. The return value is for the current instruction
661      * set.
662      */
663     @libcore.api.CorePlatformApi
didPruneDalvikCache()664     public static native boolean didPruneDalvikCache();
665 
666     /**
667      * Register the current execution thread to the runtime as sensitive thread.
668      * Should be called just once. Subsequent calls are ignored.
669      */
670     @libcore.api.CorePlatformApi
registerSensitiveThread()671     public static native void registerSensitiveThread();
672 
673     /**
674      * Sets up the priority of the system daemon thread (caller).
675      */
setSystemDaemonThreadPriority()676     public static native void setSystemDaemonThreadPriority();
677 
678     /**
679      * Sets a callback that the runtime can call whenever a usage of a non SDK API is detected.
680      */
681     @libcore.api.CorePlatformApi
setNonSdkApiUsageConsumer(Consumer<String> consumer)682     public static void setNonSdkApiUsageConsumer(Consumer<String> consumer) {
683         nonSdkApiUsageConsumer = consumer;
684     }
685 
686     /**
687      * Sets whether or not the runtime should dedupe detection and warnings for hidden API usage.
688      * If deduping is enabled, only the first usage of each API will be detected. The default
689      * behaviour is to dedupe.
690      */
691     @libcore.api.CorePlatformApi
setDedupeHiddenApiWarnings(boolean dedupe)692     public static native void setDedupeHiddenApiWarnings(boolean dedupe);
693 
694     /**
695      * Sets the package name of the app running in this process.
696      */
697     @libcore.api.CorePlatformApi
setProcessPackageName(String packageName)698     public static native void setProcessPackageName(String packageName);
699 
700     /**
701      * Sets the full path to data directory of the app running in this process.
702      */
703     @libcore.api.CorePlatformApi
setProcessDataDirectory(String dataDir)704     public static native void setProcessDataDirectory(String dataDir);
705 }
706