David Sehr | 139512d | 2018-02-08 15:44:50 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2011 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
David Sehr | 139512d | 2018-02-08 15:44:50 -0800 | [diff] [blame] | 17 | #include <sys/mman.h> |
| 18 | |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 19 | #include <fstream> |
David Sehr | 139512d | 2018-02-08 15:44:50 -0800 | [diff] [blame] | 20 | #include <memory> |
| 21 | |
| 22 | #include "art_dex_file_loader.h" |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 23 | #include "base/file_utils.h" |
David Sehr | 79e2607 | 2018-04-06 17:58:50 -0700 | [diff] [blame] | 24 | #include "base/mem_map.h" |
David Sehr | c431b9d | 2018-03-02 12:01:51 -0800 | [diff] [blame] | 25 | #include "base/os.h" |
David Sehr | 139512d | 2018-02-08 15:44:50 -0800 | [diff] [blame] | 26 | #include "base/stl_util.h" |
| 27 | #include "base/unix_file/fd_file.h" |
David Sehr | 139512d | 2018-02-08 15:44:50 -0800 | [diff] [blame] | 28 | #include "common_runtime_test.h" |
David Sehr | 334b9d7 | 2018-02-12 18:27:56 -0800 | [diff] [blame] | 29 | #include "dex/base64_test_util.h" |
| 30 | #include "dex/code_item_accessors-inl.h" |
| 31 | #include "dex/descriptors_names.h" |
| 32 | #include "dex/dex_file.h" |
| 33 | #include "dex/dex_file-inl.h" |
| 34 | #include "dex/dex_file_loader.h" |
David Sehr | 139512d | 2018-02-08 15:44:50 -0800 | [diff] [blame] | 35 | #include "scoped_thread_state_change-inl.h" |
| 36 | #include "thread-current-inl.h" |
| 37 | |
| 38 | namespace art { |
| 39 | |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 40 | static void Copy(const std::string& src, const std::string& dst) { |
| 41 | std::ifstream src_stream(src, std::ios::binary); |
| 42 | std::ofstream dst_stream(dst, std::ios::binary); |
| 43 | dst_stream << src_stream.rdbuf(); |
| 44 | } |
| 45 | |
| 46 | class ArtDexFileLoaderTest : public CommonRuntimeTest { |
| 47 | public: |
| 48 | virtual void SetUp() { |
| 49 | CommonRuntimeTest::SetUp(); |
| 50 | |
| 51 | std::string dex_location = GetTestDexFileName("Main"); |
Nicolas Geoffray | 0d0f316 | 2018-05-10 12:55:40 +0100 | [diff] [blame] | 52 | std::string multidex_location = GetTestDexFileName("MultiDex"); |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 53 | |
| 54 | data_location_path_ = android_data_ + "/foo.jar"; |
| 55 | system_location_path_ = GetAndroidRoot() + "/foo.jar"; |
| 56 | system_framework_location_path_ = GetAndroidRoot() + "/framework/foo.jar"; |
Nicolas Geoffray | 0d0f316 | 2018-05-10 12:55:40 +0100 | [diff] [blame] | 57 | data_multi_location_path_ = android_data_ + "/multifoo.jar"; |
| 58 | system_multi_location_path_ = GetAndroidRoot() + "/multifoo.jar"; |
| 59 | system_framework_multi_location_path_ = GetAndroidRoot() + "/framework/multifoo.jar"; |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 60 | |
| 61 | Copy(dex_location, data_location_path_); |
| 62 | Copy(dex_location, system_location_path_); |
| 63 | Copy(dex_location, system_framework_location_path_); |
Nicolas Geoffray | 0d0f316 | 2018-05-10 12:55:40 +0100 | [diff] [blame] | 64 | |
| 65 | Copy(multidex_location, data_multi_location_path_); |
| 66 | Copy(multidex_location, system_multi_location_path_); |
| 67 | Copy(multidex_location, system_framework_multi_location_path_); |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | virtual void TearDown() { |
| 71 | remove(data_location_path_.c_str()); |
| 72 | remove(system_location_path_.c_str()); |
| 73 | remove(system_framework_location_path_.c_str()); |
Nicolas Geoffray | 0d0f316 | 2018-05-10 12:55:40 +0100 | [diff] [blame] | 74 | remove(data_multi_location_path_.c_str()); |
| 75 | remove(system_multi_location_path_.c_str()); |
| 76 | remove(system_framework_multi_location_path_.c_str()); |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 77 | CommonRuntimeTest::TearDown(); |
| 78 | } |
| 79 | |
| 80 | protected: |
| 81 | std::string data_location_path_; |
| 82 | std::string system_location_path_; |
| 83 | std::string system_framework_location_path_; |
Nicolas Geoffray | 0d0f316 | 2018-05-10 12:55:40 +0100 | [diff] [blame] | 84 | std::string data_multi_location_path_; |
| 85 | std::string system_multi_location_path_; |
| 86 | std::string system_framework_multi_location_path_; |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 87 | }; |
David Sehr | 139512d | 2018-02-08 15:44:50 -0800 | [diff] [blame] | 88 | |
| 89 | // TODO: Port OpenTestDexFile(s) need to be ported to use non-ART utilities, and |
| 90 | // the tests that depend upon them should be moved to dex_file_loader_test.cc |
| 91 | |
| 92 | TEST_F(ArtDexFileLoaderTest, Open) { |
| 93 | ScopedObjectAccess soa(Thread::Current()); |
| 94 | std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested")); |
| 95 | ASSERT_TRUE(dex.get() != nullptr); |
| 96 | } |
| 97 | |
| 98 | TEST_F(ArtDexFileLoaderTest, GetLocationChecksum) { |
| 99 | ScopedObjectAccess soa(Thread::Current()); |
| 100 | std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main")); |
| 101 | EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum()); |
| 102 | } |
| 103 | |
| 104 | TEST_F(ArtDexFileLoaderTest, GetChecksum) { |
| 105 | std::vector<uint32_t> checksums; |
| 106 | ScopedObjectAccess soa(Thread::Current()); |
| 107 | std::string error_msg; |
| 108 | const ArtDexFileLoader dex_file_loader; |
| 109 | EXPECT_TRUE(dex_file_loader.GetMultiDexChecksums(GetLibCoreDexFileNames()[0].c_str(), |
| 110 | &checksums, |
| 111 | &error_msg)) |
| 112 | << error_msg; |
| 113 | ASSERT_EQ(1U, checksums.size()); |
| 114 | EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksums[0]); |
| 115 | } |
| 116 | |
| 117 | TEST_F(ArtDexFileLoaderTest, GetMultiDexChecksums) { |
| 118 | std::string error_msg; |
| 119 | std::vector<uint32_t> checksums; |
| 120 | std::string multidex_file = GetTestDexFileName("MultiDex"); |
| 121 | const ArtDexFileLoader dex_file_loader; |
| 122 | EXPECT_TRUE(dex_file_loader.GetMultiDexChecksums(multidex_file.c_str(), |
| 123 | &checksums, |
| 124 | &error_msg)) << error_msg; |
| 125 | |
| 126 | std::vector<std::unique_ptr<const DexFile>> dexes = OpenTestDexFiles("MultiDex"); |
| 127 | ASSERT_EQ(2U, dexes.size()); |
| 128 | ASSERT_EQ(2U, checksums.size()); |
| 129 | |
| 130 | EXPECT_EQ(dexes[0]->GetLocation(), DexFileLoader::GetMultiDexLocation(0, multidex_file.c_str())); |
| 131 | EXPECT_EQ(dexes[0]->GetLocationChecksum(), checksums[0]); |
| 132 | |
| 133 | EXPECT_EQ(dexes[1]->GetLocation(), DexFileLoader::GetMultiDexLocation(1, multidex_file.c_str())); |
| 134 | EXPECT_EQ(dexes[1]->GetLocationChecksum(), checksums[1]); |
| 135 | } |
| 136 | |
| 137 | TEST_F(ArtDexFileLoaderTest, ClassDefs) { |
| 138 | ScopedObjectAccess soa(Thread::Current()); |
| 139 | std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested")); |
| 140 | ASSERT_TRUE(raw.get() != nullptr); |
| 141 | EXPECT_EQ(3U, raw->NumClassDefs()); |
| 142 | |
| 143 | const DexFile::ClassDef& c0 = raw->GetClassDef(0); |
| 144 | EXPECT_STREQ("LNested$1;", raw->GetClassDescriptor(c0)); |
| 145 | |
| 146 | const DexFile::ClassDef& c1 = raw->GetClassDef(1); |
| 147 | EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c1)); |
| 148 | |
| 149 | const DexFile::ClassDef& c2 = raw->GetClassDef(2); |
| 150 | EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c2)); |
| 151 | } |
| 152 | |
| 153 | TEST_F(ArtDexFileLoaderTest, GetMethodSignature) { |
| 154 | ScopedObjectAccess soa(Thread::Current()); |
| 155 | std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature")); |
| 156 | ASSERT_TRUE(raw.get() != nullptr); |
| 157 | EXPECT_EQ(1U, raw->NumClassDefs()); |
| 158 | |
| 159 | const DexFile::ClassDef& class_def = raw->GetClassDef(0); |
| 160 | ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def)); |
| 161 | |
| 162 | const uint8_t* class_data = raw->GetClassData(class_def); |
| 163 | ASSERT_TRUE(class_data != nullptr); |
| 164 | ClassDataItemIterator it(*raw, class_data); |
| 165 | |
| 166 | EXPECT_EQ(1u, it.NumDirectMethods()); |
| 167 | |
| 168 | // Check the signature for the static initializer. |
| 169 | { |
| 170 | ASSERT_EQ(1U, it.NumDirectMethods()); |
| 171 | const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex()); |
| 172 | const char* name = raw->StringDataByIdx(method_id.name_idx_); |
| 173 | ASSERT_STREQ("<init>", name); |
| 174 | std::string signature(raw->GetMethodSignature(method_id).ToString()); |
| 175 | ASSERT_EQ("()V", signature); |
| 176 | } |
| 177 | |
| 178 | // Check all virtual methods. |
| 179 | struct Result { |
| 180 | const char* name; |
| 181 | const char* signature; |
| 182 | const char* pretty_method; |
| 183 | }; |
| 184 | static const Result results[] = { |
| 185 | { |
| 186 | "m1", |
| 187 | "(IDJLjava/lang/Object;)Ljava/lang/Float;", |
| 188 | "java.lang.Float GetMethodSignature.m1(int, double, long, java.lang.Object)" |
| 189 | }, |
| 190 | { |
| 191 | "m2", |
| 192 | "(ZSC)LGetMethodSignature;", |
| 193 | "GetMethodSignature GetMethodSignature.m2(boolean, short, char)" |
| 194 | }, |
| 195 | { |
| 196 | "m3", |
| 197 | "()V", |
| 198 | "void GetMethodSignature.m3()" |
| 199 | }, |
| 200 | { |
| 201 | "m4", |
| 202 | "(I)V", |
| 203 | "void GetMethodSignature.m4(int)" |
| 204 | }, |
| 205 | { |
| 206 | "m5", |
| 207 | "(II)V", |
| 208 | "void GetMethodSignature.m5(int, int)" |
| 209 | }, |
| 210 | { |
| 211 | "m6", |
| 212 | "(II[[I)V", |
| 213 | "void GetMethodSignature.m6(int, int, int[][])" |
| 214 | }, |
| 215 | { |
| 216 | "m7", |
| 217 | "(II[[ILjava/lang/Object;)V", |
| 218 | "void GetMethodSignature.m7(int, int, int[][], java.lang.Object)" |
| 219 | }, |
| 220 | { |
| 221 | "m8", |
| 222 | "(II[[ILjava/lang/Object;[[Ljava/lang/Object;)V", |
| 223 | "void GetMethodSignature.m8(int, int, int[][], java.lang.Object, java.lang.Object[][])" |
| 224 | }, |
| 225 | { |
| 226 | "m9", |
| 227 | "()I", |
| 228 | "int GetMethodSignature.m9()" |
| 229 | }, |
| 230 | { |
| 231 | "mA", |
| 232 | "()[[I", |
| 233 | "int[][] GetMethodSignature.mA()" |
| 234 | }, |
| 235 | { |
| 236 | "mB", |
| 237 | "()[[Ljava/lang/Object;", |
| 238 | "java.lang.Object[][] GetMethodSignature.mB()" |
| 239 | }, |
| 240 | }; |
| 241 | ASSERT_EQ(arraysize(results), it.NumVirtualMethods()); |
| 242 | for (const Result& r : results) { |
| 243 | it.Next(); |
| 244 | const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex()); |
| 245 | |
| 246 | const char* name = raw->StringDataByIdx(method_id.name_idx_); |
| 247 | ASSERT_STREQ(r.name, name); |
| 248 | |
| 249 | std::string signature(raw->GetMethodSignature(method_id).ToString()); |
| 250 | ASSERT_EQ(r.signature, signature); |
| 251 | |
| 252 | std::string plain_method = std::string("GetMethodSignature.") + r.name; |
| 253 | ASSERT_EQ(plain_method, raw->PrettyMethod(it.GetMemberIndex(), /* with_signature */ false)); |
| 254 | ASSERT_EQ(r.pretty_method, raw->PrettyMethod(it.GetMemberIndex(), /* with_signature */ true)); |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | TEST_F(ArtDexFileLoaderTest, FindStringId) { |
| 259 | ScopedObjectAccess soa(Thread::Current()); |
| 260 | std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature")); |
| 261 | ASSERT_TRUE(raw.get() != nullptr); |
| 262 | EXPECT_EQ(1U, raw->NumClassDefs()); |
| 263 | |
| 264 | const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;", |
| 265 | "D", "I", "J", nullptr }; |
| 266 | for (size_t i = 0; strings[i] != nullptr; i++) { |
| 267 | const char* str = strings[i]; |
| 268 | const DexFile::StringId* str_id = raw->FindStringId(str); |
| 269 | const char* dex_str = raw->GetStringData(*str_id); |
| 270 | EXPECT_STREQ(dex_str, str); |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | TEST_F(ArtDexFileLoaderTest, FindTypeId) { |
| 275 | for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) { |
| 276 | const char* type_str = java_lang_dex_file_->StringByTypeIdx(dex::TypeIndex(i)); |
| 277 | const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str); |
| 278 | ASSERT_TRUE(type_str_id != nullptr); |
| 279 | dex::StringIndex type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id); |
| 280 | const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx); |
| 281 | ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str)); |
| 282 | ASSERT_TRUE(type_id != nullptr); |
| 283 | EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id).index_, i); |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | TEST_F(ArtDexFileLoaderTest, FindProtoId) { |
| 288 | for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) { |
| 289 | const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i); |
| 290 | const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find); |
| 291 | std::vector<dex::TypeIndex> to_find_types; |
| 292 | if (to_find_tl != nullptr) { |
| 293 | for (size_t j = 0; j < to_find_tl->Size(); j++) { |
| 294 | to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_); |
| 295 | } |
| 296 | } |
| 297 | const DexFile::ProtoId* found = |
| 298 | java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types); |
| 299 | ASSERT_TRUE(found != nullptr); |
| 300 | EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i); |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | TEST_F(ArtDexFileLoaderTest, FindMethodId) { |
| 305 | for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) { |
| 306 | const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i); |
| 307 | const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_); |
| 308 | const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_); |
| 309 | const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_); |
| 310 | const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature); |
| 311 | ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": " |
| 312 | << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "." |
| 313 | << java_lang_dex_file_->GetStringData(name) |
| 314 | << java_lang_dex_file_->GetMethodSignature(to_find); |
| 315 | EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i); |
| 316 | } |
| 317 | } |
| 318 | |
| 319 | TEST_F(ArtDexFileLoaderTest, FindFieldId) { |
| 320 | for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) { |
| 321 | const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i); |
| 322 | const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_); |
| 323 | const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_); |
| 324 | const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_); |
| 325 | const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type); |
| 326 | ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": " |
| 327 | << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " " |
| 328 | << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "." |
| 329 | << java_lang_dex_file_->GetStringData(name); |
| 330 | EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i); |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | TEST_F(ArtDexFileLoaderTest, GetDexCanonicalLocation) { |
| 335 | ScratchFile file; |
| 336 | UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr)); |
| 337 | std::string dex_location(dex_location_real.get()); |
| 338 | |
| 339 | ASSERT_EQ(dex_location, DexFileLoader::GetDexCanonicalLocation(dex_location.c_str())); |
| 340 | std::string multidex_location = DexFileLoader::GetMultiDexLocation(1, dex_location.c_str()); |
| 341 | ASSERT_EQ(multidex_location, DexFileLoader::GetDexCanonicalLocation(multidex_location.c_str())); |
| 342 | |
| 343 | std::string dex_location_sym = dex_location + "symlink"; |
| 344 | ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str())); |
| 345 | |
| 346 | ASSERT_EQ(dex_location, DexFileLoader::GetDexCanonicalLocation(dex_location_sym.c_str())); |
| 347 | |
| 348 | std::string multidex_location_sym = DexFileLoader::GetMultiDexLocation( |
| 349 | 1, dex_location_sym.c_str()); |
| 350 | ASSERT_EQ(multidex_location, |
| 351 | DexFileLoader::GetDexCanonicalLocation(multidex_location_sym.c_str())); |
| 352 | |
| 353 | ASSERT_EQ(0, unlink(dex_location_sym.c_str())); |
| 354 | } |
| 355 | |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 356 | TEST_F(ArtDexFileLoaderTest, IsPlatformDexFile) { |
| 357 | ArtDexFileLoader loader; |
| 358 | bool success; |
| 359 | std::string error_msg; |
| 360 | std::vector<std::unique_ptr<const DexFile>> dex_files; |
| 361 | |
| 362 | // Load file from a non-system directory and check that it is not flagged as framework. |
| 363 | ASSERT_FALSE(LocationIsOnSystemFramework(data_location_path_.c_str())); |
| 364 | success = loader.Open(data_location_path_.c_str(), |
| 365 | data_location_path_, |
| 366 | /* verify */ false, |
| 367 | /* verify_checksum */ false, |
| 368 | &error_msg, |
| 369 | &dex_files); |
David Sehr | d5f8de8 | 2018-04-27 14:12:03 -0700 | [diff] [blame] | 370 | ASSERT_TRUE(success) << error_msg; |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 371 | ASSERT_GE(dex_files.size(), 1u); |
| 372 | for (std::unique_ptr<const DexFile>& dex_file : dex_files) { |
| 373 | ASSERT_FALSE(dex_file->IsPlatformDexFile()); |
| 374 | } |
| 375 | |
| 376 | dex_files.clear(); |
| 377 | |
| 378 | // Load file from a system, non-framework directory and check that it is not flagged as framework. |
| 379 | ASSERT_FALSE(LocationIsOnSystemFramework(system_location_path_.c_str())); |
| 380 | success = loader.Open(system_location_path_.c_str(), |
| 381 | system_location_path_, |
| 382 | /* verify */ false, |
| 383 | /* verify_checksum */ false, |
| 384 | &error_msg, |
| 385 | &dex_files); |
| 386 | ASSERT_TRUE(success); |
| 387 | ASSERT_GE(dex_files.size(), 1u); |
| 388 | for (std::unique_ptr<const DexFile>& dex_file : dex_files) { |
| 389 | ASSERT_FALSE(dex_file->IsPlatformDexFile()); |
| 390 | } |
| 391 | |
| 392 | dex_files.clear(); |
| 393 | |
| 394 | // Load file from a system/framework directory and check that it is flagged as a framework dex. |
| 395 | ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_location_path_.c_str())); |
| 396 | success = loader.Open(system_framework_location_path_.c_str(), |
| 397 | system_framework_location_path_, |
| 398 | /* verify */ false, |
| 399 | /* verify_checksum */ false, |
| 400 | &error_msg, |
| 401 | &dex_files); |
| 402 | ASSERT_TRUE(success); |
| 403 | ASSERT_GE(dex_files.size(), 1u); |
| 404 | for (std::unique_ptr<const DexFile>& dex_file : dex_files) { |
| 405 | ASSERT_TRUE(dex_file->IsPlatformDexFile()); |
| 406 | } |
Nicolas Geoffray | 0d0f316 | 2018-05-10 12:55:40 +0100 | [diff] [blame] | 407 | |
| 408 | dex_files.clear(); |
| 409 | |
| 410 | // Load multidex file from a non-system directory and check that it is not flagged as framework. |
| 411 | success = loader.Open(data_multi_location_path_.c_str(), |
| 412 | data_multi_location_path_, |
| 413 | /* verify */ false, |
| 414 | /* verify_checksum */ false, |
| 415 | &error_msg, |
| 416 | &dex_files); |
| 417 | ASSERT_TRUE(success) << error_msg; |
| 418 | ASSERT_GT(dex_files.size(), 1u); |
| 419 | for (std::unique_ptr<const DexFile>& dex_file : dex_files) { |
| 420 | ASSERT_FALSE(dex_file->IsPlatformDexFile()); |
| 421 | } |
| 422 | |
| 423 | dex_files.clear(); |
| 424 | |
| 425 | // Load multidex file from a system, non-framework directory and check that it is not flagged |
| 426 | // as framework. |
| 427 | success = loader.Open(system_multi_location_path_.c_str(), |
| 428 | system_multi_location_path_, |
| 429 | /* verify */ false, |
| 430 | /* verify_checksum */ false, |
| 431 | &error_msg, |
| 432 | &dex_files); |
| 433 | ASSERT_TRUE(success); |
| 434 | ASSERT_GT(dex_files.size(), 1u); |
| 435 | for (std::unique_ptr<const DexFile>& dex_file : dex_files) { |
| 436 | ASSERT_FALSE(dex_file->IsPlatformDexFile()); |
| 437 | } |
| 438 | |
| 439 | dex_files.clear(); |
| 440 | |
| 441 | // Load multidex file from a system/framework directory and check that it is flagged as a |
| 442 | // framework dex. |
| 443 | success = loader.Open(system_framework_multi_location_path_.c_str(), |
| 444 | system_framework_multi_location_path_, |
| 445 | /* verify */ false, |
| 446 | /* verify_checksum */ false, |
| 447 | &error_msg, |
| 448 | &dex_files); |
| 449 | ASSERT_TRUE(success); |
| 450 | ASSERT_GT(dex_files.size(), 1u); |
| 451 | for (std::unique_ptr<const DexFile>& dex_file : dex_files) { |
| 452 | ASSERT_TRUE(dex_file->IsPlatformDexFile()); |
| 453 | } |
David Brazdil | 8e1a7cb | 2018-03-27 08:14:25 +0000 | [diff] [blame] | 454 | } |
| 455 | |
David Sehr | 139512d | 2018-02-08 15:44:50 -0800 | [diff] [blame] | 456 | } // namespace art |