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