Do not check for collision if we only extracted the apk

There is no need to check for collisions or verify the class loader
context if the verification is not enabled for the oat file.

This prevents the collision checks or dex2oat reruns when we only
extracted the dex files from apk and fixes.

Test: test-art-host
Bug: 147208643
Change-Id: I84e77baa89fe36705cc650ff21f95b244e7941d4
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 28984fd..96df61e 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -893,17 +893,23 @@
 
 bool OatFileAssistant::OatFileInfo::ClassLoaderContextIsOkay(ClassLoaderContext* context,
                                                              const std::vector<int>& context_fds) {
-  if (context == nullptr) {
-    VLOG(oat) << "ClassLoaderContext check ignored: null context";
-    return true;
-  }
-
   const OatFile* file = GetFile();
   if (file == nullptr) {
     // No oat file means we have nothing to verify.
     return true;
   }
 
+  if (!CompilerFilter::IsVerificationEnabled(file->GetCompilerFilter())) {
+    // If verification is not enabled we don't need to verify the class loader context and we
+    // assume it's ok.
+    return true;
+  }
+
+  if (context == nullptr) {
+    VLOG(oat) << "ClassLoaderContext check ignored: null context";
+    return true;
+  }
+
   size_t dir_index = oat_file_assistant_->dex_location_.rfind('/');
   std::string classpath_dir = (dir_index != std::string::npos)
       ? oat_file_assistant_->dex_location_.substr(0, dir_index)
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 18448a7..32ae42e 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -1360,29 +1360,52 @@
 
 TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) {
   std::string dex_location = GetScratchDir() + "/TestDex.jar";
+  std::string odex_location = GetOdexDir() + "/TestDex.odex";
+
   std::string context_location = GetScratchDir() + "/ContextDex.jar";
   Copy(GetDexSrc1(), dex_location);
   Copy(GetDexSrc2(), context_location);
 
-  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
-
-  std::string error_msg;
   std::string context_str = "PCL[" + context_location + "]";
+
   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_str);
   ASSERT_TRUE(context != nullptr);
   ASSERT_TRUE(context->OpenDexFiles(kRuntimeISA, ""));
 
+  std::string error_msg;
+  std::vector<std::string> args;
+  args.push_back("--dex-file=" + dex_location);
+  args.push_back("--oat-file=" + odex_location);
+  args.push_back("--class-loader-context=" + context_str);
+  ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
+
   // Update the context by overriding the jar file.
   Copy(GetMultiDexSrc2(), context_location);
   std::unique_ptr<ClassLoaderContext> updated_context = ClassLoaderContext::Create(context_str);
   ASSERT_TRUE(updated_context != nullptr);
-  // DexOptNeeded should advise compilation from scratch.
-  EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
-            oat_file_assistant.GetDexOptNeeded(
-                  CompilerFilter::kDefaultCompilerFilter,
-                  /* profile_changed= */ false,
-                  /* downgrade= */ false,
-                  updated_context.get()));
+
+  {
+    OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+    // DexOptNeeded should advise compilation from scratch when the context changes.
+    EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
+              oat_file_assistant.GetDexOptNeeded(
+                    CompilerFilter::kDefaultCompilerFilter,
+                    /* profile_changed= */ false,
+                    /* downgrade= */ false,
+                    updated_context.get()));
+  }
+  {
+    OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+    // Now check that DexOptNeeded does not advise compilation if we only extracted the file.
+    args.push_back("--compiler-filter=extract");
+    ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
+    EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
+              oat_file_assistant.GetDexOptNeeded(
+                    CompilerFilter::kExtract,
+                    /* profile_changed= */ false,
+                    /* downgrade= */ false,
+                    updated_context.get()));
+  }
 }
 
 // Test that GetLocation of a dex file is the same whether the dex
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index 7c50dbf..23e2ad2 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -393,6 +393,12 @@
     return CheckCollisionResult::kSkippedUnsupportedClassLoader;
   }
 
+  if (!CompilerFilter::IsVerificationEnabled(oat_file->GetCompilerFilter())) {
+    // If verification is not enabled we don't need to check for collisions as the oat file
+    // is either extracted or assumed verified.
+    return CheckCollisionResult::kSkippedVerificationDisabled;
+  }
+
   // If the oat file loading context matches the context used during compilation then we accept
   // the oat file without addition checks
   ClassLoaderContext::VerificationResult result = context->VerifyClassLoaderContextMatch(
diff --git a/runtime/oat_file_manager.h b/runtime/oat_file_manager.h
index d09b6d6..7da4061 100644
--- a/runtime/oat_file_manager.h
+++ b/runtime/oat_file_manager.h
@@ -144,6 +144,7 @@
   enum class CheckCollisionResult {
     kSkippedUnsupportedClassLoader,
     kSkippedClassLoaderContextSharedLibrary,
+    kSkippedVerificationDisabled,
     kNoCollisions,
     kPerformedHasCollisions,
   };