Don't let the oat file close BCP FD passed from outside

Bug: 186132447
Test: odrefresh --use-compilation-os=10 --force-compile
      # complete successfully with other changes
Test: TH
Change-Id: I3393ccd8fdc8ece71dbed8d16ef3c62ba935ea75
diff --git a/libdexfile/dex/art_dex_file_loader.cc b/libdexfile/dex/art_dex_file_loader.cc
index 62014aa..a7dd13e 100644
--- a/libdexfile/dex/art_dex_file_loader.cc
+++ b/libdexfile/dex/art_dex_file_loader.cc
@@ -311,8 +311,39 @@
                                std::string* error_msg,
                                std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
   ScopedTrace trace("Dex file open Zip " + std::string(location));
+  return OpenZipInternal(ZipArchive::OpenFromFd(fd, location.c_str(), error_msg),
+                         location,
+                         verify,
+                         verify_checksum,
+                         error_msg,
+                         dex_files);
+}
+
+bool ArtDexFileLoader::OpenZipFromOwnedFd(
+    int fd,
+    const std::string& location,
+    bool verify,
+    bool verify_checksum,
+    std::string* error_msg,
+    std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
+  ScopedTrace trace("Dex file open Zip " + std::string(location) + " (owned fd)");
+  return OpenZipInternal(ZipArchive::OpenFromOwnedFd(fd, location.c_str(), error_msg),
+                         location,
+                         verify,
+                         verify_checksum,
+                         error_msg,
+                         dex_files);
+}
+
+bool ArtDexFileLoader::OpenZipInternal(
+    ZipArchive* raw_zip_archive,
+    const std::string& location,
+    bool verify,
+    bool verify_checksum,
+    std::string* error_msg,
+    std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
   DCHECK(dex_files != nullptr) << "DexFile::OpenZip: out-param is nullptr";
-  std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd, location.c_str(), error_msg));
+  std::unique_ptr<ZipArchive> zip_archive(raw_zip_archive);
   if (zip_archive.get() == nullptr) {
     DCHECK(!error_msg->empty());
     return false;
diff --git a/libdexfile/dex/art_dex_file_loader.h b/libdexfile/dex/art_dex_file_loader.h
index 786142a..49c81f4 100644
--- a/libdexfile/dex/art_dex_file_loader.h
+++ b/libdexfile/dex/art_dex_file_loader.h
@@ -110,7 +110,8 @@
                                          bool mmap_shared,
                                          std::string* error_msg) const;
 
-  // Opens dex files from within a .jar, .zip, or .apk file
+  // Opens dex files from within a .jar, .zip, or .apk file using its file descriptor. The file
+  // descriptor ownership is taken over, i.e. will be closed by this class.
   bool OpenZip(int fd,
                const std::string& location,
                bool verify,
@@ -118,6 +119,15 @@
                std::string* error_msg,
                std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
 
+  // Opens dex files from within a .jar, .zip, or .apk file using its file descriptor. The file
+  // descriptor is assumed owned by the caller.
+  bool OpenZipFromOwnedFd(int fd,
+                          const std::string& location,
+                          bool verify,
+                          bool verify_checksum,
+                          std::string* error_msg,
+                          std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
+
  private:
   bool OpenWithMagic(uint32_t magic,
                      int fd,
@@ -152,6 +162,13 @@
                                                        std::string* error_msg,
                                                        DexFileLoaderErrorCode* error_code) const;
 
+  bool OpenZipInternal(ZipArchive* raw_zip_archive,
+                       const std::string& location,
+                       bool verify,
+                       bool verify_checksum,
+                       std::string* error_msg,
+                       std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
+
   static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
                                              size_t size,
                                              const uint8_t* data_base,
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index a6a1a01..0d6339b 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -734,15 +734,21 @@
         const ArtDexFileLoader dex_file_loader;
         bool loaded = false;
         CHECK(zip_fd == -1 || dex_fds.empty());  // Allow only the supported combinations.
-        int fd = zip_fd >= 0 ?: dex_fd;
-        if (fd != -1) {
-          // Note that we assume dex_fds are backing by jars.
-          loaded = dex_file_loader.OpenZip(fd,
+        if (zip_fd != -1) {
+          loaded = dex_file_loader.OpenZip(zip_fd,
                                            dex_file_location,
                                            /*verify=*/ false,
                                            /*verify_checksum=*/ false,
                                            error_msg,
                                            &new_dex_files);
+        } else if (dex_fd != -1) {
+          // Note that we assume dex_fds are backing by jars.
+          loaded = dex_file_loader.OpenZipFromOwnedFd(dex_fd,
+                                                      dex_file_location,
+                                                      /*verify=*/ false,
+                                                      /*verify_checksum=*/ false,
+                                                      error_msg,
+                                                      &new_dex_files);
         } else {
           loaded = dex_file_loader.Open(dex_file_name.c_str(),
                                         dex_file_location,