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