Enable InMemoryDexClassLoader vdex only for Q+ targets

Some legacy apps depend on InMemoryDexClassLoader not loading classes
immediately. Disable verification result caching for them.

Bug: 2131483
Test: art/test.py -b -r -t 692 -t 693
Change-Id: Ie230b837c2fdd5cda13e06faba501fe07e1f65bc
diff --git a/libartbase/base/sdk_version.h b/libartbase/base/sdk_version.h
index e2dbc50..219ac86 100644
--- a/libartbase/base/sdk_version.h
+++ b/libartbase/base/sdk_version.h
@@ -33,6 +33,7 @@
   kO     = 26u,
   kO_MR1 = 27u,
   kP     = 28u,
+  kQ     = 29u,
   kMax   = std::numeric_limits<uint32_t>::max(),
 };
 
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index 92acdd0..0543644 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -29,6 +29,7 @@
 #include "base/file_utils.h"
 #include "base/logging.h"  // For VLOG.
 #include "base/mutex-inl.h"
+#include "base/sdk_version.h"
 #include "base/stl_util.h"
 #include "base/systrace.h"
 #include "class_linker.h"
@@ -965,15 +966,22 @@
 void OatFileManager::RunBackgroundVerification(const std::vector<const DexFile*>& dex_files,
                                                jobject class_loader,
                                                const char* class_loader_context) {
-  if (Runtime::Current()->IsJavaDebuggable()) {
+  Runtime* const runtime = Runtime::Current();
+  Thread* const self = Thread::Current();
+
+  if (runtime->IsJavaDebuggable()) {
     // Threads created by ThreadPool ("runtime threads") are not allowed to load
     // classes when debuggable to match class-initialization semantics
     // expectations. Do not verify in the background.
     return;
   }
 
-  Thread* const self = Thread::Current();
-  if (Runtime::Current()->IsShuttingDown(self)) {
+  if (!IsSdkVersionSetAndAtLeast(runtime->GetTargetSdkVersion(), SdkVersion::kQ)) {
+    // Do not run for legacy apps as they may depend on the previous class loader behaviour.
+    return;
+  }
+
+  if (runtime->IsShuttingDown(self)) {
     // Not allowed to create new threads during runtime shutdown.
     return;
   }
diff --git a/test/692-vdex-inmem-loader/src/Main.java b/test/692-vdex-inmem-loader/src/Main.java
index 6beef5c..53f4c36 100644
--- a/test/692-vdex-inmem-loader/src/Main.java
+++ b/test/692-vdex-inmem-loader/src/Main.java
@@ -64,6 +64,9 @@
     System.loadLibrary(args[0]);
     ClassLoader[] loaders = null;
 
+    // Feature only enabled for target SDK version Q and later.
+    setTargetSdkVersion(/* Q */ 29);
+
     // Feature is disabled in debuggable mode because runtime threads are not
     // allowed to load classes.
     boolean featureEnabled = !isDebuggable();
@@ -108,6 +111,7 @@
   }
 
   private static native boolean isDebuggable();
+  private static native int setTargetSdkVersion(int version);
   private static native void setProcessDataDir(String path);
   private static native void waitForVerifier();
   private static native boolean areClassesVerified(ClassLoader loader);
diff --git a/test/693-vdex-inmem-loader-evict/src/Main.java b/test/693-vdex-inmem-loader-evict/src/Main.java
index 7d9da1b..e06f232 100644
--- a/test/693-vdex-inmem-loader-evict/src/Main.java
+++ b/test/693-vdex-inmem-loader-evict/src/Main.java
@@ -24,6 +24,9 @@
   public static void main(String[] args) throws Exception {
     System.loadLibrary(args[0]);
 
+    // Feature only enabled for target SDK version Q and later.
+    setTargetSdkVersion(/* Q */ 29);
+
     if (isDebuggable()) {
       // Background verification is disabled in debuggable mode. This test makes
       // no sense then.
@@ -60,6 +63,7 @@
   }
 
   private static native boolean isDebuggable();
+  private static native int setTargetSdkVersion(int version);
   private static native void setProcessDataDir(String path);
   private static native void waitForVerifier();
   private static native boolean hasVdexFile(ClassLoader loader);
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index 0ee3bcf..db70eec 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -375,4 +375,8 @@
   return Runtime::Current()->IsJavaDebuggable() ? JNI_TRUE : JNI_FALSE;
 }
 
+extern "C" JNIEXPORT void JNICALL Java_Main_setTargetSdkVersion(JNIEnv*, jclass, jint version) {
+  Runtime::Current()->SetTargetSdkVersion(static_cast<uint32_t>(version));
+}
+
 }  // namespace art