Manually add java.io.Buffer private fields to the Core Platform API

This change adds the private fields in java.nio.Buffer to the Core
Platform API programmatically.

These fields are private and there is no way to express them in the
API defintion. Although unfortunate, we are already doing this for
methods and fixing the points of use for these fields is a sizeable
task.

Bug: 124338141
Bug: 144502743
Test: Boots, no warnings from native Core Platform API methods
Change-Id: Icd06cae3f2fe523c71b79430009e76b30caf4b94
(cherry picked from commit 814b9286540d0db5685aedc04c507d95e729d96b)
diff --git a/runtime/hidden_api.cc b/runtime/hidden_api.cc
index b2a1550..c55a134 100644
--- a/runtime/hidden_api.cc
+++ b/runtime/hidden_api.cc
@@ -118,6 +118,26 @@
   }
 }
 
+void InitializeCorePlatformApiPrivateFields() {
+  // The following fields in WellKnownClasses correspond to private fields in the Core Platform
+  // API that cannot be otherwise expressed and propagated through tooling (b/144502743).
+  jfieldID private_core_platform_api_fields[] = {
+    WellKnownClasses::java_nio_Buffer_address,
+    WellKnownClasses::java_nio_Buffer_elementSizeShift,
+    WellKnownClasses::java_nio_Buffer_limit,
+    WellKnownClasses::java_nio_Buffer_position,
+  };
+
+  ScopedObjectAccess soa(Thread::Current());
+  for (const auto private_core_platform_api_field : private_core_platform_api_fields) {
+    ArtField* field = jni::DecodeArtField(private_core_platform_api_field);
+    const uint32_t access_flags = field->GetAccessFlags();
+    uint32_t new_access_flags = access_flags | kAccCorePlatformApi;
+    DCHECK(new_access_flags != access_flags);
+    field->SetAccessFlags(new_access_flags);
+  }
+}
+
 namespace detail {
 
 // Do not change the values of items in this enum, as they are written to the
diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h
index 58844b3..5c0dc6b 100644
--- a/runtime/hidden_api.h
+++ b/runtime/hidden_api.h
@@ -23,9 +23,11 @@
 #include "base/hiddenapi_flags.h"
 #include "base/locks.h"
 #include "intrinsics_enum.h"
+#include "jni/jni_internal.h"
 #include "mirror/class-inl.h"
 #include "reflection.h"
 #include "runtime.h"
+#include "well_known_classes.h"
 
 namespace art {
 namespace hiddenapi {
@@ -156,6 +158,8 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedHiddenApiEnforcementPolicySetting);
 };
 
+void InitializeCorePlatformApiPrivateFields() REQUIRES(!Locks::mutator_lock_);
+
 // Implementation details. DO NOT ACCESS DIRECTLY.
 namespace detail {
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 32ebfa6..df9245e 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -889,6 +889,10 @@
   // needs the SignaturePolymorphic annotation class which is initialized in WellKnownClasses::Init.
   InitializeIntrinsics();
 
+  // InitializeCorePlatformApiPrivateFields() needs to be called after well known class
+  // initializtion in InitNativeMethods().
+  art::hiddenapi::InitializeCorePlatformApiPrivateFields();
+
   // Initialize well known thread group values that may be accessed threads while attaching.
   InitThreadGroups(self);
 
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 486191f..017dd0e 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -150,6 +150,10 @@
 jfieldID WellKnownClasses::java_lang_Throwable_stackTrace;
 jfieldID WellKnownClasses::java_lang_Throwable_stackState;
 jfieldID WellKnownClasses::java_lang_Throwable_suppressedExceptions;
+jfieldID WellKnownClasses::java_nio_Buffer_address;
+jfieldID WellKnownClasses::java_nio_Buffer_elementSizeShift;
+jfieldID WellKnownClasses::java_nio_Buffer_limit;
+jfieldID WellKnownClasses::java_nio_Buffer_position;
 jfieldID WellKnownClasses::java_nio_ByteBuffer_address;
 jfieldID WellKnownClasses::java_nio_ByteBuffer_hb;
 jfieldID WellKnownClasses::java_nio_ByteBuffer_isReadOnly;
@@ -378,6 +382,7 @@
   dalvik_system_BaseDexClassLoader_getLdLibraryPath = CacheMethod(env, dalvik_system_BaseDexClassLoader, false, "getLdLibraryPath", "()Ljava/lang/String;");
   dalvik_system_VMRuntime_runFinalization = CacheMethod(env, dalvik_system_VMRuntime, true, "runFinalization", "(J)V");
   dalvik_system_VMRuntime_hiddenApiUsed = CacheMethod(env, dalvik_system_VMRuntime, true, "hiddenApiUsed", "(ILjava/lang/String;Ljava/lang/String;IZ)V");
+
   java_lang_ClassNotFoundException_init = CacheMethod(env, java_lang_ClassNotFoundException, false, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V");
   java_lang_ClassLoader_loadClass = CacheMethod(env, java_lang_ClassLoader, false, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
 
@@ -412,6 +417,7 @@
   dalvik_system_DexPathList_dexElements = CacheField(env, dalvik_system_DexPathList, false, "dexElements", "[Ldalvik/system/DexPathList$Element;");
   dalvik_system_DexPathList__Element_dexFile = CacheField(env, dalvik_system_DexPathList__Element, false, "dexFile", "Ldalvik/system/DexFile;");
   dalvik_system_VMRuntime_nonSdkApiUsageConsumer = CacheField(env, dalvik_system_VMRuntime, true, "nonSdkApiUsageConsumer", "Ljava/util/function/Consumer;");
+
   java_lang_Thread_parkBlocker = CacheField(env, java_lang_Thread, false, "parkBlocker", "Ljava/lang/Object;");
   java_lang_Thread_daemon = CacheField(env, java_lang_Thread, false, "daemon", "Z");
   java_lang_Thread_group = CacheField(env, java_lang_Thread, false, "group", "Ljava/lang/ThreadGroup;");
@@ -432,6 +438,13 @@
   java_lang_Throwable_stackTrace = CacheField(env, java_lang_Throwable, false, "stackTrace", "[Ljava/lang/StackTraceElement;");
   java_lang_Throwable_stackState = CacheField(env, java_lang_Throwable, false, "backtrace", "Ljava/lang/Object;");
   java_lang_Throwable_suppressedExceptions = CacheField(env, java_lang_Throwable, false, "suppressedExceptions", "Ljava/util/List;");
+
+  ScopedLocalRef<jclass> java_nio_Buffer(env, env->FindClass("java/nio/Buffer"));
+  java_nio_Buffer_address = CacheField(env, java_nio_Buffer.get(), false, "address", "J");
+  java_nio_Buffer_elementSizeShift = CacheField(env, java_nio_Buffer.get(), false, "_elementSizeShift", "I");
+  java_nio_Buffer_limit = CacheField(env, java_nio_Buffer.get(), false, "limit", "I");
+  java_nio_Buffer_position = CacheField(env, java_nio_Buffer.get(), false, "position", "I");
+
   java_nio_ByteBuffer_address = CacheField(env, java_nio_ByteBuffer, false, "address", "J");
   java_nio_ByteBuffer_hb = CacheField(env, java_nio_ByteBuffer, false, "hb", "[B");
   java_nio_ByteBuffer_isReadOnly = CacheField(env, java_nio_ByteBuffer, false, "isReadOnly", "Z");
@@ -457,10 +470,10 @@
 }
 
 void WellKnownClasses::LateInit(JNIEnv* env) {
-  ScopedLocalRef<jclass> java_lang_Runtime(env, env->FindClass("java/lang/Runtime"));
   // CacheField and CacheMethod will initialize their classes. Classes below
   // have clinit sections that call JNI methods. Late init is required
   // to make sure these JNI methods are available.
+  ScopedLocalRef<jclass> java_lang_Runtime(env, env->FindClass("java/lang/Runtime"));
   java_lang_Runtime_nativeLoad =
       CacheMethod(env, java_lang_Runtime.get(), true, "nativeLoad",
                   "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/Class;)"
@@ -587,6 +600,10 @@
   java_lang_Throwable_stackTrace = nullptr;
   java_lang_Throwable_stackState = nullptr;
   java_lang_Throwable_suppressedExceptions = nullptr;
+  java_nio_Buffer_address = nullptr;
+  java_nio_Buffer_elementSizeShift = nullptr;
+  java_nio_Buffer_limit = nullptr;
+  java_nio_Buffer_position = nullptr;
   java_nio_ByteBuffer_address = nullptr;
   java_nio_ByteBuffer_hb = nullptr;
   java_nio_ByteBuffer_isReadOnly = nullptr;
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index 249dfa0..4a35210 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -29,9 +29,7 @@
 class Class;
 }  // namespace mirror
 
-// Various classes used in JNI. We cache them so we don't have to keep looking
-// them up. Similar to libcore's JniConstants (except there's no overlap, so
-// we keep them separate).
+// Various classes used in JNI. We cache them so we don't have to keep looking them up.
 
 struct WellKnownClasses {
  public:
@@ -90,10 +88,10 @@
   static jclass java_lang_Thread;
   static jclass java_lang_ThreadGroup;
   static jclass java_lang_Throwable;
-  static jclass java_util_Collections;
-  static jclass java_util_function_Consumer;
   static jclass java_nio_ByteBuffer;
   static jclass java_nio_DirectByteBuffer;
+  static jclass java_util_Collections;
+  static jclass java_util_function_Consumer;
   static jclass libcore_reflect_AnnotationFactory;
   static jclass libcore_reflect_AnnotationMember;
   static jclass libcore_util_EmptyArray;
@@ -165,6 +163,10 @@
   static jfieldID java_lang_Throwable_stackTrace;
   static jfieldID java_lang_Throwable_stackState;
   static jfieldID java_lang_Throwable_suppressedExceptions;
+  static jfieldID java_nio_Buffer_address;
+  static jfieldID java_nio_Buffer_elementSizeShift;
+  static jfieldID java_nio_Buffer_limit;
+  static jfieldID java_nio_Buffer_position;
   static jfieldID java_nio_ByteBuffer_address;
   static jfieldID java_nio_ByteBuffer_hb;
   static jfieldID java_nio_ByteBuffer_isReadOnly;