Do not require classes.dex to support stripped zip files

Change-Id: Ief34c1b559dbebda85d181ae49da7d35446c9b37
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 500cb59..99145b8 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -673,18 +673,19 @@
 }
 
 const OatFile* ClassLinker::FindOpenedOatFileForDexFile(const DexFile& dex_file) {
-  return FindOpenedOatFileFromDexLocation(dex_file.GetLocation().c_str(),
-                                          dex_file.GetLocationChecksum());
+  const char* dex_location = dex_file.GetLocation().c_str();
+  uint32_t dex_location_checksum = dex_file.GetLocationChecksum();
+  return FindOpenedOatFileFromDexLocation(dex_location, &dex_location_checksum);
 }
 
 const OatFile* ClassLinker::FindOpenedOatFileFromDexLocation(const char* dex_location,
-                                                             uint32_t dex_location_checksum) {
+                                                             const uint32_t* const dex_location_checksum) {
   ReaderMutexLock mu(Thread::Current(), dex_lock_);
   for (size_t i = 0; i < oat_files_.size(); i++) {
     const OatFile* oat_file = oat_files_[i];
     DCHECK(oat_file != NULL);
     const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location,
-                                                                      &dex_location_checksum,
+                                                                      dex_location_checksum,
                                                                       false);
     if (oat_dex_file != NULL) {
       return oat_file;
@@ -943,13 +944,13 @@
 }
 
 const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const char* dex_location,
-                                                                uint32_t dex_location_checksum,
+                                                                const uint32_t* const dex_location_checksum,
                                                                 std::string* error_msg) {
   const OatFile* open_oat_file = FindOpenedOatFileFromDexLocation(dex_location,
                                                                   dex_location_checksum);
   if (open_oat_file != nullptr) {
     const OatFile::OatDexFile* oat_dex_file = open_oat_file->GetOatDexFile(dex_location,
-                                                                           &dex_location_checksum);
+                                                                           dex_location_checksum);
     return oat_dex_file->OpenDexFile(error_msg);
   }
 
@@ -962,6 +963,12 @@
   if (dex_file != nullptr) {
     return dex_file;
   }
+  if (dex_location_checksum == nullptr) {
+    *error_msg = StringPrintf("Failed to open oat file from %s and no classes.dex found in %s: %s",
+                              odex_filename.c_str(), dex_location, error_msg->c_str());
+    return nullptr;
+  }
+
   std::string cache_error_msg;
   std::string cache_location(GetDalvikCacheFilenameOrDie(dex_location));
   dex_file = VerifyAndOpenDexFileFromOatFile(cache_location, dex_location, &cache_error_msg,
@@ -978,7 +985,7 @@
 
   // Try to generate oat file if it wasn't found or was obsolete.
   error_msg->clear();
-  return FindOrCreateOatFileForDexLocation(dex_location, dex_location_checksum,
+  return FindOrCreateOatFileForDexLocation(dex_location, *dex_location_checksum,
                                            cache_location.c_str(), error_msg);
 }
 
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 4e2cc06..edec9cb 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -268,7 +268,7 @@
   // that this returns null if the location checksum of the DexFile
   // does not match the OatFile.
   const DexFile* FindDexFileInOatFileFromDexLocation(const char* location,
-                                                     uint32_t location_checksum,
+                                                     const uint32_t* const location_checksum,
                                                      std::string* error_msg)
       LOCKS_EXCLUDED(dex_lock_, Locks::mutator_lock_);
 
@@ -495,7 +495,7 @@
       LOCKS_EXCLUDED(dex_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const OatFile* FindOpenedOatFileFromDexLocation(const char* dex_location,
-                                                  uint32_t dex_location_checksum)
+                                                  const uint32_t* const dex_location_checksum)
       LOCKS_EXCLUDED(dex_lock);
   const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location)
       LOCKS_EXCLUDED(dex_lock_);
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index c9e0e83..600045f 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -95,20 +95,27 @@
   }
 
   uint32_t dex_location_checksum;
+  uint32_t* dex_location_checksum_pointer = &dex_location_checksum;
   std::string error_msg;
-  if (!DexFile::GetChecksum(sourceName.c_str(), &dex_location_checksum, &error_msg)) {
-    ScopedObjectAccess soa(env);
-    DCHECK(!error_msg.empty());
-    ThrowIOException("%s", error_msg.c_str());
-    return 0;
+  if (!DexFile::GetChecksum(sourceName.c_str(), dex_location_checksum_pointer, &error_msg)) {
+    dex_location_checksum_pointer = NULL;
   }
 
   ClassLinker* linker = Runtime::Current()->GetClassLinker();
   const DexFile* dex_file;
   if (outputName.c_str() == nullptr) {
+    // FindOrCreateOatFileForDexLocation can tolerate a missing dex_location_checksum
+    error_msg.clear();
     dex_file = linker->FindDexFileInOatFileFromDexLocation(sourceName.c_str(),
-                                                           dex_location_checksum, &error_msg);
+                                                           dex_location_checksum_pointer, &error_msg);
   } else {
+    // FindOrCreateOatFileForDexLocation requires the dex_location_checksum
+    if (dex_location_checksum_pointer == NULL) {
+      ScopedObjectAccess soa(env);
+      DCHECK(!error_msg.empty());
+      ThrowIOException("%s", error_msg.c_str());
+      return 0;
+    }
     dex_file = linker->FindOrCreateOatFileForDexLocation(sourceName.c_str(), dex_location_checksum,
                                                          outputName.c_str(), &error_msg);
   }