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