Improve checking of multidex dex checksums.

* Fall back to odex file for all multidex entries if the apk is stripped,
  not just for the main multidex entry.
* Verify the number of multidex entries has not changed.
* Improve performance by getting all checksums from the apk in one go
  and cache the results instead of repeatedly opening the apk.
* Stop referring to non-main multidex entries as "secondary" dex files.

Bug: 34604632
Test: added tests to dex_file_test and oat_file_assistant_test
Test: m test-art-host

Change-Id: I58b17ecfbc9165a5bfeffd5281ee21d108f64479
diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc
index 9dca4c0..b6e010c 100644
--- a/runtime/dex_file_test.cc
+++ b/runtime/dex_file_test.cc
@@ -334,6 +334,29 @@
   EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
 }
 
+TEST_F(DexFileTest, GetMultiDexChecksums) {
+  std::string error_msg;
+  std::vector<uint32_t> checksums;
+  std::string multidex_file = GetTestDexFileName("MultiDex");
+  EXPECT_TRUE(DexFile::GetMultiDexChecksums(multidex_file.c_str(),
+                                            &checksums,
+                                            &error_msg)) << error_msg;
+
+  uint32_t checksum0 = 0;
+  EXPECT_TRUE(DexFile::GetChecksum(DexFile::GetMultiDexLocation(0, multidex_file.c_str()).c_str(),
+                                   &checksum0,
+                                   &error_msg)) << error_msg;
+
+  uint32_t checksum1 = 0;
+  EXPECT_TRUE(DexFile::GetChecksum(DexFile::GetMultiDexLocation(1, multidex_file.c_str()).c_str(),
+                                   &checksum1,
+                                   &error_msg)) << error_msg;
+
+  ASSERT_EQ(2u, checksums.size());
+  EXPECT_EQ(checksums[0], checksum0);
+  EXPECT_EQ(checksums[1], checksum1);
+}
+
 TEST_F(DexFileTest, ClassDefs) {
   ScopedObjectAccess soa(Thread::Current());
   std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));