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 <= 0.0 or >= 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