Only allow skipping dex madvise on T+

Skipping the madvise call requires working knowledge of the process
state. However, pre T, the framework may delay certain process state
updates when the process is launching. As such, only allow the
short-circuit on T+.

Bug: 235390330
Test: m + validate madvise calls on T+
Change-Id: I515ac0dde116a99f7b82b71a4d6b468842943194
Merged-In: I515ac0dde116a99f7b82b71a4d6b468842943194
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 149c8a9..2de3eb5 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -178,6 +178,7 @@
 #include "well_known_classes.h"
 
 #ifdef ART_TARGET_ANDROID
+#include <android/api-level.h>
 #include <android/set_abort_message.h>
 #include "com_android_apex.h"
 namespace apex = com::android::apex;
@@ -3358,13 +3359,21 @@
                                   const uint8_t* map_begin,
                                   const uint8_t* map_end,
                                   const std::string& file_name) {
+#ifdef ART_TARGET_ANDROID
   // Short-circuit the madvise optimization for background processes. This
   // avoids IO and memory contention with foreground processes, particularly
   // those involving app startup.
-  const Runtime* runtime = Runtime::Current();
-  if (runtime != nullptr && !runtime->InJankPerceptibleProcessState()) {
-    return;
+  // Note: We can only safely short-circuit the madvise on T+, as it requires
+  // the framework to always immediately notify ART of process states.
+  static const int kApiLevel = android_get_device_api_level();
+  const bool accurate_process_state_at_startup = kApiLevel >= __ANDROID_API_T__;
+  if (accurate_process_state_at_startup) {
+    const Runtime* runtime = Runtime::Current();
+    if (runtime != nullptr && !runtime->InJankPerceptibleProcessState()) {
+      return;
+    }
   }
+#endif  // ART_TARGET_ANDROID
 
   // Ideal blockTransferSize for madvising files (128KiB)
   static constexpr size_t kIdealIoTransferSizeBytes = 128*1024;