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 static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
20 
21 import android.annotation.SystemApi;
22 import android.compat.annotation.ChangeId;
23 import android.compat.annotation.EnabledSince;
24 import android.compat.annotation.Disabled;
25 import android.compat.annotation.UnsupportedAppUsage;
26 
27 import dalvik.annotation.compat.VersionCodes;
28 import dalvik.annotation.optimization.FastNative;
29 
30 import libcore.api.CorePlatformApi;
31 
32 import java.lang.ref.FinalizerReference;
33 import java.util.HashMap;
34 import java.util.Map;
35 import java.util.concurrent.atomic.AtomicInteger;
36 import java.util.function.Consumer;
37 
38 /**
39  * Provides an interface to VM-global, Dalvik-specific features.
40  * An application cannot create its own Runtime instance, and must obtain
41  * one from the getRuntime method.
42  *
43  * @hide
44  */
45 @SystemApi(client = MODULE_LIBRARIES)
46 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
47 @libcore.api.IntraCoreApi
48 public final class VMRuntime {
49 
50     /**
51      * Holds the VMRuntime singleton.
52      */
53     private static final VMRuntime THE_ONE = new VMRuntime();
54 
55     // Note: Instruction set names are used to construct the names of some
56     // system properties. To be sure that the properties stay valid the
57     // instruction set name should not exceed 7 characters. See installd
58     // and the package manager for the actual propeties.
59     private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
60             = new HashMap<String, String>(16);
61     static {
62         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
63         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
64         ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
65         ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64");
66         ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
67         ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64");
68         ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64");
69         ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a-hwasan", "arm64");
70     }
71 
72     /**
73      * Remove meta-reflection workaround for hidden api usage for apps targeting R+. This allowed
74      * apps to obtain references to blocklist fields and methods through an extra layer of
75      * reflection.
76      */
77     @ChangeId
78     @EnabledSince(targetSdkVersion = VersionCodes.R)
79     private static final long
80         PREVENT_META_REFLECTION_BLOCKLIST_ACCESS = 142365358; // This is a bug id.
81 
82     /**
83      * Gating access to greylist-max-p APIs.
84      */
85     @ChangeId
86     @EnabledSince(targetSdkVersion = VersionCodes.Q)
87     private static final long HIDE_MAXTARGETSDK_P_HIDDEN_APIS = 149997251; // This is a bug id.
88 
89     /**
90      * Gating access to greylist-max-q APIs.
91      */
92     @ChangeId
93     @EnabledSince(targetSdkVersion = VersionCodes.R)
94     private static final long HIDE_MAXTARGETSDK_Q_HIDDEN_APIS = 149994052; // This is a bug id.
95 
96     /**
97      * Allow apps accessing @TestApi APIs.
98      *
99      * <p>This will always be disabled by default and should only be used by platform test code.
100      */
101     @ChangeId
102     @Disabled
103     private static final long ALLOW_TEST_API_ACCESS = 166236554; // This is a bug id.
104 
105     /**
106      * Interface for logging hidden API usage events.
107      *
108      * @hide
109      */
110     @SystemApi(client = MODULE_LIBRARIES)
111     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
112     public interface HiddenApiUsageLogger {
113 
114         // The following ACCESS_METHOD_ constants must match the values in
115         // art/runtime/hidden_api.h
116         /**
117          * Internal test value that does not correspond to an actual access by the
118          * application. Never logged, added for completeness.
119          *
120          * @hide
121          */
122         @SystemApi(client = MODULE_LIBRARIES)
123         @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
124         public static final int ACCESS_METHOD_NONE = 0;
125 
126         /**
127          *  Used when a method has been accessed via reflection.
128          *
129          * @hide
130          */
131         @SystemApi(client = MODULE_LIBRARIES)
132         @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
133         public static final int ACCESS_METHOD_REFLECTION = 1;
134 
135         /**
136          *  Used when a method has been accessed via JNI.
137          *
138          * @hide
139          */
140         @SystemApi(client = MODULE_LIBRARIES)
141         @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
142         public static final int ACCESS_METHOD_JNI = 2;
143 
144         /**
145          * Used when a method is accessed at link time. Never logged, added only
146          * for completeness.
147          *
148          * @hide
149          */
150         @SystemApi(client = MODULE_LIBRARIES)
151         @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
152         public static final int ACCESS_METHOD_LINKING = 3;
153 
154         /**
155          * Logs hidden API access
156          *
157          * @param sampledValue value that was sampled, to be compared against the
158          *      sampling rate
159          * @param appPackageName package name of the app attempting the access
160          * @param signature signature of the method being called, i.e
161          *      class_name->member_name:type_signature (e.g.
162          *      {@code com.android.app.Activity->mDoReportFullyDrawn:Z}) for fields and
163          *      class_name->method_name_and_signature for methods (e.g
164          *      {@code com.android.app.Activity->finish(I)V})
165          * @param accessType how the accessed was done
166          * @param accessDenied whether the access was allowed or not
167          *
168          * @hide
169          */
170         @SystemApi(client = MODULE_LIBRARIES)
171         @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
hiddenApiUsed(int sampledValue, String appPackageName, String signature, int accessType, boolean accessDenied)172         public void hiddenApiUsed(int sampledValue, String appPackageName,
173             String signature, int accessType, boolean accessDenied);
174     }
175 
176     static HiddenApiUsageLogger hiddenApiUsageLogger;
177 
178     /**
179      * Sets the hidden API usage logger {@link #hiddenApiUsageLogger}.
180      * It should only be called if {@link #setHiddenApiAccessLogSamplingRate(int)}
181      * is called with a value > 0
182      *
183      * @param hiddenApiUsageLogger an object implement {@code HiddenApiUsageLogger} that the runtime
184      *          will call for logging hidden API checks.
185      *
186      * @hide
187      */
188     @SystemApi(client = MODULE_LIBRARIES)
189     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
setHiddenApiUsageLogger(HiddenApiUsageLogger hiddenApiUsageLogger)190     public static void setHiddenApiUsageLogger(HiddenApiUsageLogger hiddenApiUsageLogger) {
191         VMRuntime.hiddenApiUsageLogger = hiddenApiUsageLogger;
192     }
193 
194     /**
195      * Records an attempted hidden API access to
196      * {@link HiddenApiUsageLogger#hiddenApiUsed(int, String, String, int, boolean}
197      * if a logger is registered via {@link #setHiddenApiUsageLogger}.
198      */
hiddenApiUsed(int sampledValue, String appPackageName, String signature, int accessType, boolean accessDenied)199     private static void hiddenApiUsed(int sampledValue, String appPackageName, String signature,
200          int accessType, boolean accessDenied) {
201         if (VMRuntime.hiddenApiUsageLogger != null) {
202             VMRuntime.hiddenApiUsageLogger.hiddenApiUsed(sampledValue, appPackageName,
203                 signature, accessType, accessDenied);
204         }
205     }
206 
207     /**
208      * Magic version number for a current development build, which has not
209      * yet turned into an official release. This number must be larger than
210      * any released version in {@code android.os.Build.VERSION_CODES}.
211      * @hide
212      */
213     @SystemApi(client = MODULE_LIBRARIES)
214     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
215     // Must match android.os.Build.VERSION_CODES.CUR_DEVELOPMENT.
216     public static final int SDK_VERSION_CUR_DEVELOPMENT = 10000;
217 
218     private static Consumer<String> nonSdkApiUsageConsumer = null;
219 
220     private int targetSdkVersion = SDK_VERSION_CUR_DEVELOPMENT;
221 
222     // notifyNativeAllocationsInternal (below) should be called every notifyNativeInterval
223     // allocations. Initialized on demand to allow completely static class initialization.
224     private int notifyNativeInterval;
225 
226     // Allocations since last call to native layer. See notifyNativeAllocation().
227     private final AtomicInteger allocationCount = new AtomicInteger(0);
228 
229     private long[] disabledCompatChanges = new long[0];
230 
231     /**
232      * Prevents this class from being instantiated.
233      */
VMRuntime()234     private VMRuntime() {
235     }
236 
237     /**
238      * Returns the object that represents the current runtime.
239      * @return the runtime object
240      *
241      * @hide
242      */
243     @UnsupportedAppUsage
244     @SystemApi(client = MODULE_LIBRARIES)
245     @libcore.api.CorePlatformApi(status = CorePlatformApi.Status.STABLE)
246     @libcore.api.IntraCoreApi
getRuntime()247     public static VMRuntime getRuntime() {
248         return THE_ONE;
249     }
250 
251     /**
252      * Returns a copy of the VM's command-line property settings.
253      * These are in the form "name=value" rather than "-Dname=value".
254      *
255      * @hide
256      */
properties()257     public native String[] properties();
258 
259     /**
260      * Returns the VM's boot class path.
261      *
262      * @hide
263      */
bootClassPath()264     public native String bootClassPath();
265 
266     /**
267      * Returns the VM's class path.
268      *
269      * @hide
270      */
classPath()271     public native String classPath();
272 
273     /**
274      * Returns the VM's version.
275      *
276      * @hide
277      */
vmVersion()278     public native String vmVersion();
279 
280     /**
281      * Returns the name of the shared library providing the VM implementation.
282      *
283      * @return the name of the shared library providing the VM implementation.
284      *
285      * @hide
286      */
287     @UnsupportedAppUsage
288     @SystemApi(client = MODULE_LIBRARIES)
289     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
vmLibrary()290     public native String vmLibrary();
291 
292     /**
293      * Returns the VM's instruction set.
294      *
295      * @return the VM's instruction set.
296      *
297      * @hide
298      */
299     @UnsupportedAppUsage
300     @SystemApi(client = MODULE_LIBRARIES)
301     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
vmInstructionSet()302     public native String vmInstructionSet();
303 
304     /**
305      * Returns whether the VM is running in 64-bit mode.
306      *
307      * @return true if VM is running in 64-bit mode, false otherwise.
308      *
309      * @hide
310      */
311     @UnsupportedAppUsage
312     @SystemApi(client = MODULE_LIBRARIES)
313     @libcore.api.CorePlatformApi(status = CorePlatformApi.Status.STABLE)
314     @FastNative
is64Bit()315     public native boolean is64Bit();
316 
317     /**
318      * Returns whether the VM is running with JNI checking enabled.
319      *
320      * @return true if the VM is running with JNI checking enabled,
321      *         and false otherwise.
322      *
323      * @hide
324      */
325     @SystemApi(client = MODULE_LIBRARIES)
326     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
327     @FastNative
isCheckJniEnabled()328     public native boolean isCheckJniEnabled();
329 
330     /**
331      * Gets the current ideal heap utilization, represented as a number
332      * between zero and one.  After a GC happens, the Dalvik heap may
333      * be resized so that (size of live objects) / (size of heap) is
334      * equal to this number.
335      *
336      * @return the current ideal heap utilization
337      *
338      * @hide
339      */
getTargetHeapUtilization()340     public native float getTargetHeapUtilization();
341 
342     /**
343      * Retrieves the finalizer timeout in milliseconds.
344      * Finalizers that fail to terminate in this amount of time cause the
345      * runtime to abort.
346      *
347      * @hide
348      */
getFinalizerTimeoutMs()349     public native long getFinalizerTimeoutMs();
350 
351     /**
352      * Sets the current ideal heap utilization, represented as a number
353      * between zero and one.  After a GC happens, the Dalvik heap may
354      * be resized so that (size of live objects) / (size of heap) is
355      * equal to this number.
356      *
357      * <p>This is only a hint to the garbage collector and may be ignored.
358      *
359      * @param newTarget the new suggested ideal heap utilization.
360      *                  This value may be adjusted internally.
361      * @return the previous ideal heap utilization
362      * @throws IllegalArgumentException if newTarget is &lt;= 0.0 or &gt;= 1.0
363      *
364      * @hide
365      */
366     @UnsupportedAppUsage
setTargetHeapUtilization(float newTarget)367     public float setTargetHeapUtilization(float newTarget) {
368         if (newTarget <= 0.0f || newTarget >= 1.0f) {
369             throw new IllegalArgumentException(newTarget + " out of range (0,1)");
370         }
371         /* The native code assumes a value >= 0.1. Clamp it to that. */
372         if (newTarget < 0.1f) {
373             newTarget = 0.1f;
374         }
375         /* Synchronize to make sure that only one thread gets a given "old" value if both
376          * update at the same time.  Allows for reliable save-and-restore semantics.
377          */
378         synchronized (this) {
379             float oldTarget = getTargetHeapUtilization();
380             nativeSetTargetHeapUtilization(newTarget);
381             return oldTarget;
382         }
383     }
384 
385     /**
386      * Sets the target SDK version. Should only be called before the
387      * app starts to run, because it may change the VM's behavior in
388      * dangerous ways. Defaults to {@link #SDK_VERSION_CUR_DEVELOPMENT}.
389      *
390      * @param targetSdkVersion the SDK version the app wants to run with.
391      *
392      * @hide
393      */
394     @UnsupportedAppUsage(maxTargetSdk=0, publicAlternatives="Use the {@code targetSdkVersion}"
395         +" attribute in the {@code uses-sdk} manifest tag instead.")
396     @SystemApi(client = MODULE_LIBRARIES)
397     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
setTargetSdkVersion(int targetSdkVersion)398     public synchronized void setTargetSdkVersion(int targetSdkVersion) {
399         this.targetSdkVersion = targetSdkVersion;
400         setTargetSdkVersionNative(this.targetSdkVersion);
401     }
402 
403 
404     /**
405      * Sets the disabled compat changes. Should only be called before the
406      * app starts to run, because it may change the VM's behavior in
407      * dangerous ways. Defaults to empty.
408      *
409      * @param disabledCompatChanges An array of ChangeIds that we want to disable.
410      *
411      * @hide
412      */
413     @SystemApi(client = MODULE_LIBRARIES)
414     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
setDisabledCompatChanges(long[] disabledCompatChanges)415     public synchronized void setDisabledCompatChanges(long[] disabledCompatChanges) {
416         this.disabledCompatChanges = disabledCompatChanges;
417         setDisabledCompatChangesNative(this.disabledCompatChanges);
418     }
419 
420     /**
421      * Gets the target SDK version. See {@link #setTargetSdkVersion} for
422      * special values.
423      *
424      * @return the target SDK version.
425      *
426      * @hide
427      */
428     @SystemApi(client = MODULE_LIBRARIES)
429     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
getTargetSdkVersion()430     public synchronized int getTargetSdkVersion() {
431         return targetSdkVersion;
432     }
433 
setTargetSdkVersionNative(int targetSdkVersion)434     private native void setTargetSdkVersionNative(int targetSdkVersion);
setDisabledCompatChangesNative(long[] disabledCompatChanges)435     private native void setDisabledCompatChangesNative(long[] disabledCompatChanges);
436 
437     /**
438      * This method exists for binary compatibility.  It was part of a
439      * heap sizing API which was removed in Android 3.0 (Honeycomb).
440      *
441      * @hide
442      */
443     @UnsupportedAppUsage
444     @Deprecated
getMinimumHeapSize()445     public long getMinimumHeapSize() {
446         return 0;
447     }
448 
449     /**
450      * This method exists for binary compatibility.  It was part of a
451      * heap sizing API which was removed in Android 3.0 (Honeycomb).
452      *
453      * @hide
454      */
455     @UnsupportedAppUsage
456     @Deprecated
setMinimumHeapSize(long size)457     public long setMinimumHeapSize(long size) {
458         return 0;
459     }
460 
461     /**
462      * This method exists for binary compatibility.  It used to
463      * perform a garbage collection that cleared SoftReferences.
464      *
465      * @hide
466      */
467     @UnsupportedAppUsage
468     @Deprecated
gcSoftReferences()469     public void gcSoftReferences() {}
470 
471     /**
472      * This method exists for binary compatibility.  It is equivalent
473      * to {@link System#runFinalization}.
474      *
475      * @hide
476      */
477     @UnsupportedAppUsage
478     @Deprecated
runFinalizationSync()479     public void runFinalizationSync() {
480         System.runFinalization();
481     }
482 
483     /**
484      * Implements setTargetHeapUtilization().
485      *
486      * @param newTarget the new suggested ideal heap utilization.
487      *                  This value may be adjusted internally.
488      */
nativeSetTargetHeapUtilization(float newTarget)489     private native void nativeSetTargetHeapUtilization(float newTarget);
490 
491     /**
492      * This method exists for binary compatibility.  It was part of
493      * the external allocation API which was removed in Android 3.0 (Honeycomb).
494      *
495      * @hide
496      */
497     @UnsupportedAppUsage
498     @Deprecated
trackExternalAllocation(long size)499     public boolean trackExternalAllocation(long size) {
500         return true;
501     }
502 
503     /**
504      * This method exists for binary compatibility.  It was part of
505      * the external allocation API which was removed in Android 3.0 (Honeycomb).
506      *
507      * @hide
508      */
509     @UnsupportedAppUsage
510     @Deprecated
trackExternalFree(long size)511     public void trackExternalFree(long size) {}
512 
513     /**
514      * This method exists for binary compatibility.  It was part of
515      * the external allocation API which was removed in Android 3.0 (Honeycomb).
516      *
517      * @hide
518      */
519     @UnsupportedAppUsage
520     @Deprecated
getExternalBytesAllocated()521     public long getExternalBytesAllocated() {
522         return 0;
523     }
524 
525     /**
526      * Sets the list of exemptions from hidden API access enforcement.
527      *
528      * @param signaturePrefixes
529      *         A list of signature prefixes. Each item in the list is a prefix match on the type
530      *         signature of a blacklisted API. All matching APIs are treated as if they were on
531      *         the whitelist: access permitted, and no logging..
532      *
533      * @hide
534      */
535     @SystemApi(client = MODULE_LIBRARIES)
536     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
setHiddenApiExemptions(String[] signaturePrefixes)537     public native void setHiddenApiExemptions(String[] signaturePrefixes);
538 
539     /**
540      * Sets the log sampling rate of hidden API accesses written to the event log.
541      *
542      * @param rate Proportion of hidden API accesses that will be logged; an integer between
543      *                0 and 0x10000 inclusive.
544      *
545      * @hide
546      */
547     @SystemApi(client = MODULE_LIBRARIES)
548     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
setHiddenApiAccessLogSamplingRate(int rate)549     public native void setHiddenApiAccessLogSamplingRate(int rate);
550 
551     /**
552      * Returns an array allocated in an area of the Java heap where it will never be moved.
553      * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
554      * and Bitmaps.
555      *
556      * @param componentType the component type of the returned array.
557      * @param length the length of the returned array.
558      * @return array allocated in an area of the heap where it will never be moved.
559      *
560      * @hide
561      */
562     @UnsupportedAppUsage
563     @SystemApi(client = MODULE_LIBRARIES)
564     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
565     @libcore.api.IntraCoreApi
566     @FastNative
newNonMovableArray(Class<?> componentType, int length)567     public native Object newNonMovableArray(Class<?> componentType, int length);
568 
569     /**
570      * Returns an array of at least {@code minLength}, but potentially larger. The increased size
571      * comes from avoiding any padding after the array. The amount of padding varies depending on
572      * the componentType and the memory allocator implementation.
573      *
574      * @param componentType the component type of the returned array.
575      * @param minLength     the minimum length of the returned array. The actual length could
576      *                      be greater.
577      * @return              array of at least of {@code minLength}
578      *
579      * @hide
580      */
581     @SystemApi(client = MODULE_LIBRARIES)
582     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
583     @FastNative
newUnpaddedArray(Class<?> componentType, int minLength)584     public native Object newUnpaddedArray(Class<?> componentType, int minLength);
585 
586     /**
587      * Returns the address of {@code array[0]}. This differs from using JNI in that JNI
588      * might lie and give you the address of a copy of the array when in forcecopy mode.
589      *
590      * @param array the object we want the native address of.
591      * @return native address of {@code array[0]}.
592      *
593      * @hide
594      */
595     @UnsupportedAppUsage
596     @SystemApi(client = MODULE_LIBRARIES)
597     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
598     @libcore.api.IntraCoreApi
599     @FastNative
addressOf(Object array)600     public native long addressOf(Object array);
601 
602     /**
603      * Removes any growth limits, allowing the application to allocate
604      * up to the maximum heap size.
605      *
606      * @hide
607      */
608     @UnsupportedAppUsage
609     @SystemApi(client = MODULE_LIBRARIES)
610     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
clearGrowthLimit()611     public native void clearGrowthLimit();
612 
613     /**
614      * Make the current growth limit the new non growth limit capacity by releasing pages which
615      * are after the growth limit but before the non growth limit capacity.
616      *
617      * @hide
618      */
619     @SystemApi(client = MODULE_LIBRARIES)
620     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
clampGrowthLimit()621     public native void clampGrowthLimit();
622 
623     /**
624      * Returns true if native debugging is on.
625      *
626      * @return true if native debugging is on, false otherwise.
627      *
628      * @hide
629      */
630     @SystemApi(client = MODULE_LIBRARIES)
631     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
632     @FastNative
isNativeDebuggable()633     public native boolean isNativeDebuggable();
634 
635     /**
636      * Returns true if Java debugging is enabled.
637      *
638      * @hide
639      */
isJavaDebuggable()640     public native boolean isJavaDebuggable();
641 
642     /**
643      * Registers a native allocation so that the heap knows about it and performs GC as required.
644      * If the number of native allocated bytes exceeds the native allocation watermark, the
645      * function requests a concurrent GC. If the native bytes allocated exceeds a second higher
646      * watermark, it is determined that the application is registering native allocations at an
647      * unusually high rate and a GC is performed inside of the function to prevent memory usage
648      * from excessively increasing. Memory allocated via system malloc() should not be included
649      * in this count. The argument must be the same as that later passed to registerNativeFree(),
650      * but may otherwise be approximate.
651      *
652      * @param bytes the number of bytes of the native object.
653      *
654      * @hide
655      */
656     @UnsupportedAppUsage
657     @SystemApi(client = MODULE_LIBRARIES)
658     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
registerNativeAllocation(long bytes)659     public native void registerNativeAllocation(long bytes);
660 
661     /**
662      * Backward compatibility version of {@link #registerNativeAllocation(long)}. We used to pass
663      * an int instead of a long. The RenderScript support library looks it up via reflection.
664      * @deprecated Use {@link #registerNativeAllocation(long)} instead.
665      *
666      * @param bytes the number of bytes of the native object.
667      *
668      * @hide
669      */
670     @UnsupportedAppUsage
671     @Deprecated
672     @SystemApi(client = MODULE_LIBRARIES)
673     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
registerNativeAllocation(int bytes)674     public void registerNativeAllocation(int bytes) {
675         registerNativeAllocation((long) bytes);
676     }
677 
678     /**
679      * Registers a native free by reducing the number of native bytes accounted for.
680      *
681      * @param bytes the number of bytes of the freed object.
682      *
683      * @hide
684      */
685     @UnsupportedAppUsage
686     @SystemApi(client = MODULE_LIBRARIES)
687     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
registerNativeFree(long bytes)688     public native void registerNativeFree(long bytes);
689 
690     /**
691      * Backward compatibility version of {@link #registerNativeFree(long)}.
692      * @deprecated Use {@link #registerNativeFree(long)} instead.
693      *
694      * @param bytes the number of bytes of the freed object.
695      *
696      * @hide
697      */
698     @UnsupportedAppUsage
699     @Deprecated
700     @SystemApi(client = MODULE_LIBRARIES)
701     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
registerNativeFree(int bytes)702     public void registerNativeFree(int bytes) {
703         registerNativeFree((long) bytes);
704     }
705 
706     /**
707      * Return the number of native objects that are reported by a single call to
708      * notifyNativeAllocation().
709      */
getNotifyNativeInterval()710     private static native int getNotifyNativeInterval();
711 
712     /**
713      * Report a native malloc()-only allocation to the GC.
714      *
715      * @hide
716      */
notifyNativeAllocation()717     public void notifyNativeAllocation() {
718         // Minimize JNI calls by notifying once every notifyNativeInterval allocations.
719         // The native code cannot do anything without calling mallinfo(), which is too
720         // expensive to perform on every allocation. To avoid the JNI overhead on every
721         // allocation, we do the sampling here, rather than in native code.
722         // Initialize notifyNativeInterval carefully. Multiple initializations may race.
723         int myNotifyNativeInterval = notifyNativeInterval;
724         if (myNotifyNativeInterval == 0) {
725             // This can race. By Java rules, that's OK.
726             myNotifyNativeInterval = notifyNativeInterval = getNotifyNativeInterval();
727         }
728         // myNotifyNativeInterval is correct here. If another thread won the initial race,
729         // notifyNativeInterval may not be.
730         if (allocationCount.addAndGet(1) % myNotifyNativeInterval == 0) {
731             notifyNativeAllocationsInternal();
732         }
733     }
734 
735     /**
736      * Report to the GC that roughly notifyNativeInterval native malloc()-based
737      * allocations have occurred since the last call to notifyNativeAllocationsInternal().
738      * Hints that we should check whether a GC is required.
739      *
740      * @hide
741      */
notifyNativeAllocationsInternal()742     public native void notifyNativeAllocationsInternal();
743 
744     /**
745      * Wait for objects to be finalized.
746      *
747      * If finalization takes longer than timeout, then the function returns before all objects are
748      * finalized.
749      *
750      * @param timeout
751      *            timeout in nanoseconds of the maximum time to wait until all pending finalizers
752      *            are run. If timeout is 0, then there is no timeout. Note that the timeout does
753      *            not stop the finalization process, it merely stops the wait.
754      *
755      * @see #Runtime.runFinalization()
756      * @see #wait(long,int)
757      *
758      * @hide
759      */
760     @UnsupportedAppUsage
runFinalization(long timeout)761     public static void runFinalization(long timeout) {
762         try {
763             FinalizerReference.finalizeAllEnqueued(timeout);
764         } catch (InterruptedException e) {
765             // Interrupt the current thread without actually throwing the InterruptionException
766             // for the caller.
767             Thread.currentThread().interrupt();
768         }
769     }
770 
771     /**
772      * Request that a garbage collection gets started on a different thread.
773      *
774      * @hide
775      */
776     @SystemApi(client = MODULE_LIBRARIES)
777     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
requestConcurrentGC()778     public native void requestConcurrentGC();
779 
780     /**
781      *
782      * @hide
783      */
requestHeapTrim()784     public native void requestHeapTrim();
785 
786     /**
787      *
788      * @hide
789      */
trimHeap()790     public native void trimHeap();
791 
792     /**
793      *
794      * @hide
795      */
startHeapTaskProcessor()796     public native void startHeapTaskProcessor();
797 
798     /**
799      *
800      * @hide
801      */
stopHeapTaskProcessor()802     public native void stopHeapTaskProcessor();
803 
804     /**
805      *
806      * @hide
807      */
runHeapTasks()808     public native void runHeapTasks();
809 
810     /**
811      * Let the heap know of the new process state. This can change allocation and garbage collection
812      * behavior regarding trimming and compaction.
813      *
814      * @param state The state of the process, as defined in art/runtime/process_state.h.
815      *
816      * @hide
817      */
818     @SystemApi(client = MODULE_LIBRARIES)
819     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
updateProcessState(int state)820     public native void updateProcessState(int state);
821 
822     /**
823      * Let the runtime know that the application startup is completed. This may affect behavior
824      * related to profiling and startup caches.
825      *
826      * @hide
827      */
828     @SystemApi(client = MODULE_LIBRARIES)
829     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
notifyStartupCompleted()830     public native void notifyStartupCompleted();
831 
832     /**
833      * Fill in dex caches with classes, fields, and methods that are
834      * already loaded. Typically used after Zygote preloading.
835      *
836      * @hide
837      */
838     @SystemApi(client = MODULE_LIBRARIES)
839     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
preloadDexCaches()840     public native void preloadDexCaches();
841 
842     /**
843      * Flag denoting that the code paths passed to
844      * {@link #registerAppInfo(String, String, String, String[], int, boolean)}
845      * contains the app primary APK.
846      *
847      * @hide
848      */
849     @SystemApi(client = MODULE_LIBRARIES)
850     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
851     public static final int CODE_PATH_TYPE_PRIMARY_APK = 1 << 0;
852     /**
853      * Flag denoting that the code paths passed to
854      * {@link #registerAppInfo(String, String, String, String[], int, boolean)}
855      * contains the a split APK.
856      *
857      * @hide
858      */
859     @SystemApi(client = MODULE_LIBRARIES)
860     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
861     public static final int CODE_PATH_TYPE_SPLIT_APK = 1 << 1;
862     /**
863      * Flag denoting that the code paths passed to
864      * {@link #registerAppInfo(String, String, String, String[], int, boolean)}
865      * contains a secondary dex file (dynamically loaded by the app).
866      *
867      * @hide
868      */
869     @SystemApi(client = MODULE_LIBRARIES)
870     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
871     public static final int CODE_PATH_TYPE_SECONDARY_DEX = 1 << 2;
872 
873     /**
874      * Register application info to ART.
875      * This enables ART to support certain low level features (such as profiling) and provide
876      * better debug information. The method should be called after the application loads its
877      * apks or dex files.
878      *
879      * @param packageName the name of the package being ran.
880      * @param currentProfileFile the path of the file where the profile information for the current
881      *        execution should be stored.
882      * @param referenceProfileFile the path of the file where the reference profile information
883      *        (for past executions) is stored.
884      * @param appCodePaths the code paths (apk/dex files) of the applications that were loaded.
885      *        These paths will also be profiled.
886      * @param codePathsTypes the type of the code paths.
887      *
888      * @hide
889      */
890     @SystemApi(client = MODULE_LIBRARIES)
891     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
registerAppInfo( String packageName, String currentProfileFile, String referenceProfileFile, String[] appCodePaths, int codePathsType)892     public static native void registerAppInfo(
893             String packageName,
894             String currentProfileFile,
895             String referenceProfileFile,
896             String[] appCodePaths,
897             int codePathsType);
898 
899     /**
900      * Returns the runtime instruction set corresponding to a given ABI. Multiple
901      * compatible ABIs might map to the same instruction set. For example
902      * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}.
903      *
904      * This influences the compilation of the applications classes.
905      *
906      * @param abi The ABI we want the instruction set from.
907      *
908      * @hide
909      */
910     @UnsupportedAppUsage
911     @SystemApi(client = MODULE_LIBRARIES)
912     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
getInstructionSet(String abi)913     public static String getInstructionSet(String abi) {
914         final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
915         if (instructionSet == null) {
916             throw new IllegalArgumentException("Unsupported ABI: " + abi);
917         }
918 
919         return instructionSet;
920     }
921 
922     /**
923      * Returns whether the given {@code instructionSet} is 64 bits.
924      *
925      * @param instructionSet a string representing an instruction set.
926      *
927      * @return true if given {@code instructionSet} is 64 bits, false otherwise.
928      *
929      * @hide
930      */
931     @SystemApi(client = MODULE_LIBRARIES)
932     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
is64BitInstructionSet(String instructionSet)933     public static boolean is64BitInstructionSet(String instructionSet) {
934         return "arm64".equals(instructionSet) ||
935                 "x86_64".equals(instructionSet) ||
936                 "mips64".equals(instructionSet);
937     }
938 
939     /**
940      * Returns whether the given {@code abi} is 64 bits.
941      *
942      * @param abi a string representing an ABI.
943      *
944      * @return true if given {@code abi} is 64 bits, false otherwise.
945      *
946      * @hide
947      */
948     @UnsupportedAppUsage
949     @SystemApi(client = MODULE_LIBRARIES)
950     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
is64BitAbi(String abi)951     public static boolean is64BitAbi(String abi) {
952         return is64BitInstructionSet(getInstructionSet(abi));
953     }
954 
955     /**
956      * Return false if the boot class path for the given instruction
957      * set mapped from disk storage, versus being interpretted from
958      * dirty pages in memory.
959      *
960      * @hide
961      */
isBootClassPathOnDisk(String instructionSet)962     public static native boolean isBootClassPathOnDisk(String instructionSet);
963 
964     /**
965      * Used to notify the runtime that boot completed.
966      *
967      * @hide
968      */
969     @SystemApi(client = MODULE_LIBRARIES)
970     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
bootCompleted()971     public static native void bootCompleted();
972 
973     /**
974      * Used to notify the runtime to reset Jit counters. This is done for the boot image
975      * profiling configuration to avoid samples during class preloading. This helps avoid
976      * the regression from disabling class profiling.
977      *
978      * @hide
979      */
980     @SystemApi(client = MODULE_LIBRARIES)
981     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
resetJitCounters()982     public static native void resetJitCounters();
983 
984     /**
985      * Returns the instruction set of the current runtime.
986      *
987      * @return instruction set of the current runtime.
988      *
989      * @hide
990      */
991     @UnsupportedAppUsage
992     @SystemApi(client = MODULE_LIBRARIES)
993     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
getCurrentInstructionSet()994     public static native String getCurrentInstructionSet();
995 
996     /**
997      * Register the current execution thread to the runtime as sensitive thread.
998      * Should be called just once. Subsequent calls are ignored.
999      *
1000      * @hide
1001      */
1002     @SystemApi(client = MODULE_LIBRARIES)
1003     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
registerSensitiveThread()1004     public static native void registerSensitiveThread();
1005 
1006     /**
1007      * Sets up the priority of the system daemon thread (caller).
1008      *
1009      * @hide
1010      */
setSystemDaemonThreadPriority()1011     public static native void setSystemDaemonThreadPriority();
1012 
1013     /**
1014      * Sets a callback that the runtime can call whenever a usage of a non SDK API is detected.
1015      *
1016      * @param consumer an object implementing the {@code java.util.function.Consumer} interface that
1017      *      the runtime will call whenever a usage of a non SDK API is detected.
1018      *
1019      * @hide
1020      */
1021     @SystemApi(client = MODULE_LIBRARIES)
1022     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
setNonSdkApiUsageConsumer(Consumer<String> consumer)1023     public static void setNonSdkApiUsageConsumer(Consumer<String> consumer) {
1024         nonSdkApiUsageConsumer = consumer;
1025     }
1026 
1027     /**
1028      * Sets whether or not the runtime should dedupe detection and warnings for hidden API usage.
1029      *
1030      * @param dedupe if set, only the first usage of each API will be detected. The default
1031      *      behaviour is to dedupe.
1032      *
1033      * @hide
1034      */
1035     @SystemApi(client = MODULE_LIBRARIES)
1036     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
setDedupeHiddenApiWarnings(boolean dedupe)1037     public static native void setDedupeHiddenApiWarnings(boolean dedupe);
1038 
1039     /**
1040      * Sets the package name of the app running in this process.
1041      *
1042      * @param packageName the value being set
1043      *
1044      * @hide
1045      */
1046     @SystemApi(client = MODULE_LIBRARIES)
1047     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
setProcessPackageName(String packageName)1048     public static native void setProcessPackageName(String packageName);
1049 
1050     /**
1051      * Sets the full path to data directory of the app running in this process.
1052      *
1053      * @param dataDir the value being set
1054      *
1055      * @hide
1056      */
1057     @SystemApi(client = MODULE_LIBRARIES)
1058     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
setProcessDataDirectory(String dataDir)1059     public static native void setProcessDataDirectory(String dataDir);
1060 
1061     /**
1062      * Returns whether {@code encodedClassLoaderContext} is a valid encoded class loader context.
1063      * A class loader context is an internal opaque format used by the runtime to encode the
1064      * class loader hierarchy (including each ClassLoader's classpath) used to load a dex file.
1065      *
1066      * @param encodedClassLoaderContext the class loader context to analyze
1067      * @throws NullPointerException if {@code encodedClassLoaderContext is null.
1068      * @return {@code true} if {@code encodedClassLoaderContext} is a non-null valid encoded class
1069      *         loader context.
1070      *
1071      * @hide
1072      */
1073     @SystemApi(client = MODULE_LIBRARIES)
1074     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
isValidClassLoaderContext(String encodedClassLoaderContext)1075     public static native boolean isValidClassLoaderContext(String encodedClassLoaderContext);
1076 }
1077