Pipe disabled compat changes to runtime through zygote.

Test: device boots
Test: Logging results of isChangeEnabled are matching state and respect adb overrides.
Bug: 145743810
Change-Id: I03da331d3d36876fb646c2962e200aeecb5af84b
Merged-In: I03da331d3d36876fb646c2962e200aeecb5af84b
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 2102713..b34d5f4 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -275,6 +275,22 @@
 #endif
 }
 
+static void VMRuntime_setDisabledCompatChangesNative(JNIEnv* env, jobject,
+    jlongArray disabled_compat_changes) {
+  if (disabled_compat_changes == nullptr) {
+    return;
+  }
+  std::set<uint64_t> disabled_compat_changes_vec;
+  int length = env->GetArrayLength(disabled_compat_changes);
+  jlong* elements = env->GetLongArrayElements(disabled_compat_changes, /*isCopy*/nullptr);
+  for (int i = 0; i < length; i++) {
+    disabled_compat_changes_vec.insert(static_cast<uint64_t>(elements[i]));
+  }
+  Runtime::Current()->SetDisabledCompatChanges(disabled_compat_changes_vec);
+
+  // TODO(145743810): pipe into libc as well.
+}
+
 static inline size_t clamp_to_size_t(jlong n) {
   if (sizeof(jlong) > sizeof(size_t)
       && UNLIKELY(n > static_cast<jlong>(std::numeric_limits<size_t>::max()))) {
@@ -781,6 +797,7 @@
   FAST_NATIVE_METHOD(VMRuntime, newUnpaddedArray, "(Ljava/lang/Class;I)Ljava/lang/Object;"),
   NATIVE_METHOD(VMRuntime, properties, "()[Ljava/lang/String;"),
   NATIVE_METHOD(VMRuntime, setTargetSdkVersionNative, "(I)V"),
+  NATIVE_METHOD(VMRuntime, setDisabledCompatChangesNative, "([J)V"),
   NATIVE_METHOD(VMRuntime, registerNativeAllocation, "(J)V"),
   NATIVE_METHOD(VMRuntime, registerNativeFree, "(J)V"),
   NATIVE_METHOD(VMRuntime, getNotifyNativeInterval, "()I"),
diff --git a/runtime/runtime.h b/runtime/runtime.h
index be6c262..fd09dfb 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -677,6 +677,19 @@
     return target_sdk_version_;
   }
 
+  void SetDisabledCompatChanges(const std::set<uint64_t>& disabled_changes) {
+    disabled_compat_changes_ = disabled_changes;
+  }
+
+  std::set<uint64_t> GetDisabledCompatChanges() const {
+    return disabled_compat_changes_;
+  }
+
+  bool isChangeEnabled(uint64_t change_id) const {
+    // TODO(145743810): add an up call to java to log to statsd
+    return disabled_compat_changes_.count(change_id) == 0;
+  }
+
   uint32_t GetZygoteMaxFailedBoots() const {
     return zygote_max_failed_boots_;
   }
@@ -1167,6 +1180,9 @@
   // Specifies target SDK version to allow workarounds for certain API levels.
   uint32_t target_sdk_version_;
 
+  // A set of disabled compat changes for the running app, all other changes are enabled.
+  std::set<uint64_t> disabled_compat_changes_;
+
   // Implicit checks flags.
   bool implicit_null_checks_;       // NullPointer checks are implicit.
   bool implicit_so_checks_;         // StackOverflow checks are implicit.