Return the same dex location for dex file whether backed by dex file or not.

Bug: 126901248
Test: oat_file_assistant_test
Change-Id: Idae49fb00bfad7007cc55e53a83e4a3e42f53e07
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index a99bd51..92b61e0 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -1176,7 +1176,6 @@
   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
 }
 
-
 // A task to generate a dex location. Used by the RaceToGenerate test.
 class RaceGenerateTask : public Task {
  public:
@@ -1381,6 +1380,128 @@
                   updated_context.get()));
 }
 
+// Test that GetLocation of a dex file is the same whether the dex
+// filed is backed by an oat file or not.
+TEST_F(OatFileAssistantTest, GetDexLocation) {
+  std::string dex_location = GetScratchDir() + "/TestDex.jar";
+  std::string oat_location = GetOdexDir() + "/TestDex.odex";
+
+  // Start the runtime to initialize the system's class loader.
+  Thread::Current()->TransitionFromSuspendedToRunnable();
+  runtime_->Start();
+
+  Copy(GetDexSrc1(), dex_location);
+
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  std::vector<std::string> error_msgs;
+  const OatFile* oat_file = nullptr;
+
+  dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
+      dex_location.c_str(),
+      Runtime::Current()->GetSystemClassLoader(),
+      /*dex_elements=*/nullptr,
+      &oat_file,
+      &error_msgs);
+  EXPECT_EQ(dex_files.size(), 1u);
+  EXPECT_EQ(oat_file, nullptr);
+  std::string stored_dex_location = dex_files[0]->GetLocation();
+  {
+    // Create the oat file.
+    std::vector<std::string> args;
+    args.push_back("--dex-file=" + dex_location);
+    args.push_back("--dex-location=TestDex.jar");
+    args.push_back("--oat-file=" + oat_location);
+    std::string error_msg;
+    ASSERT_TRUE(DexoptTest::Dex2Oat(args, &error_msg)) << error_msg;
+  }
+  dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
+      dex_location.c_str(),
+      Runtime::Current()->GetSystemClassLoader(),
+      /*dex_elements=*/nullptr,
+      &oat_file,
+      &error_msgs);
+  EXPECT_EQ(dex_files.size(), 1u);
+  EXPECT_NE(oat_file, nullptr);
+  std::string oat_stored_dex_location = dex_files[0]->GetLocation();
+  EXPECT_EQ(oat_stored_dex_location, stored_dex_location);
+}
+
+// Test that a dex file on the platform location gets the right hiddenapi domain,
+// regardless of whether it has a backing oat file.
+TEST_F(OatFileAssistantTest, SystemFrameworkDir) {
+  std::string filebase = "OatFileAssistantTestSystemFrameworkDir";
+  std::string dex_location = GetAndroidRoot() + "/framework/" + filebase + ".jar";
+  Copy(GetDexSrc1(), dex_location);
+
+  std::string odex_dir = GetAndroidRoot() + "/framework/oat/";
+  mkdir(odex_dir.c_str(), 0700);
+  odex_dir = odex_dir + std::string(GetInstructionSetString(kRuntimeISA));
+  mkdir(odex_dir.c_str(), 0700);
+  std::string oat_location = odex_dir + "/" + filebase + ".odex";
+  // Clean up in case previous run crashed.
+  remove(oat_location.c_str());
+
+  // Start the runtime to initialize the system's class loader.
+  Thread::Current()->TransitionFromSuspendedToRunnable();
+  runtime_->Start();
+
+  std::vector<std::unique_ptr<const DexFile>> dex_files_first;
+  std::vector<std::unique_ptr<const DexFile>> dex_files_second;
+  std::vector<std::string> error_msgs;
+  const OatFile* oat_file = nullptr;
+
+  dex_files_first = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
+      dex_location.c_str(),
+      Runtime::Current()->GetSystemClassLoader(),
+      /*dex_elements=*/nullptr,
+      &oat_file,
+      &error_msgs);
+  EXPECT_EQ(dex_files_first.size(), 1u);
+  EXPECT_EQ(oat_file, nullptr) << dex_location;
+  EXPECT_EQ(dex_files_first[0]->GetOatDexFile(), nullptr);
+
+  // Register the dex file to get a domain.
+  {
+    ScopedObjectAccess soa(Thread::Current());
+    Runtime::Current()->GetClassLinker()->RegisterDexFile(
+        *dex_files_first[0],
+        soa.Decode<mirror::ClassLoader>(Runtime::Current()->GetSystemClassLoader()));
+  }
+  std::string stored_dex_location = dex_files_first[0]->GetLocation();
+  EXPECT_EQ(dex_files_first[0]->GetHiddenapiDomain(), hiddenapi::Domain::kPlatform);
+  {
+    // Create the oat file.
+    std::vector<std::string> args;
+    args.push_back("--dex-file=" + dex_location);
+    args.push_back("--dex-location=" + filebase + ".jar");
+    args.push_back("--oat-file=" + oat_location);
+    std::string error_msg;
+    ASSERT_TRUE(DexoptTest::Dex2Oat(args, &error_msg)) << error_msg;
+  }
+  dex_files_second = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
+      dex_location.c_str(),
+      Runtime::Current()->GetSystemClassLoader(),
+      /*dex_elements=*/nullptr,
+      &oat_file,
+      &error_msgs);
+  EXPECT_EQ(dex_files_second.size(), 1u);
+  EXPECT_NE(oat_file, nullptr);
+  EXPECT_NE(dex_files_second[0]->GetOatDexFile(), nullptr);
+  EXPECT_NE(dex_files_second[0]->GetOatDexFile()->GetOatFile(), nullptr);
+
+  // Register the dex file to get a domain.
+  {
+    ScopedObjectAccess soa(Thread::Current());
+    Runtime::Current()->GetClassLinker()->RegisterDexFile(
+        *dex_files_second[0],
+        soa.Decode<mirror::ClassLoader>(Runtime::Current()->GetSystemClassLoader()));
+  }
+  std::string oat_stored_dex_location = dex_files_second[0]->GetLocation();
+  EXPECT_EQ(oat_stored_dex_location, stored_dex_location);
+  EXPECT_EQ(dex_files_second[0]->GetHiddenapiDomain(), hiddenapi::Domain::kPlatform);
+  EXPECT_EQ(0, remove(oat_location.c_str()));
+}
+
 // TODO: More Tests:
 //  * Test class linker falls back to unquickened dex for DexNoOat
 //  * Test class linker falls back to unquickened dex for MultiDexNoOat