1 /*
2  * Copyright (C) 2017 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 
17 #include "class_loader_context.h"
18 
19 #include <gtest/gtest.h>
20 
21 #include "android-base/strings.h"
22 #include "art_field-inl.h"
23 #include "base/dchecked_vector.h"
24 #include "base/stl_util.h"
25 #include "class_linker.h"
26 #include "class_root-inl.h"
27 #include "common_runtime_test.h"
28 #include "dex/dex_file.h"
29 #include "handle_scope-inl.h"
30 #include "jni/jni_internal.h"
31 #include "mirror/class.h"
32 #include "mirror/class_loader-inl.h"
33 #include "mirror/object-inl.h"
34 #include "mirror/object_array-alloc-inl.h"
35 #include "oat_file_assistant.h"
36 #include "runtime.h"
37 #include "scoped_thread_state_change-inl.h"
38 #include "thread.h"
39 #include "well_known_classes.h"
40 
41 namespace art {
42 
43 class ClassLoaderContextTest : public CommonRuntimeTest {
44  public:
VerifyContextSize(ClassLoaderContext * context,size_t expected_size)45   void VerifyContextSize(ClassLoaderContext* context, size_t expected_size) {
46     ASSERT_TRUE(context != nullptr);
47     ASSERT_EQ(expected_size, context->GetParentChainSize());
48   }
49 
VerifyClassLoaderPCL(ClassLoaderContext * context,size_t index,const std::string & classpath)50   void VerifyClassLoaderPCL(ClassLoaderContext* context,
51                             size_t index,
52                             const std::string& classpath) {
53     VerifyClassLoaderInfo(
54         context, index, ClassLoaderContext::kPathClassLoader, classpath);
55   }
56 
VerifyClassLoaderDLC(ClassLoaderContext * context,size_t index,const std::string & classpath)57   void VerifyClassLoaderDLC(ClassLoaderContext* context,
58                             size_t index,
59                             const std::string& classpath) {
60     VerifyClassLoaderInfo(
61         context, index, ClassLoaderContext::kDelegateLastClassLoader, classpath);
62   }
63 
VerifyClassLoaderIMC(ClassLoaderContext * context,size_t index,const std::string & classpath)64   void VerifyClassLoaderIMC(ClassLoaderContext* context,
65                             size_t index,
66                             const std::string& classpath) {
67     VerifyClassLoaderInfo(
68         context, index, ClassLoaderContext::kInMemoryDexClassLoader, classpath);
69   }
70 
VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,const std::string & classpath)71   void VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext* context,
72                                          size_t loader_index,
73                                          size_t shared_library_index,
74                                          const std::string& classpath) {
75     VerifyClassLoaderInfoSL(
76         context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
77         classpath);
78   }
79 
VerifyClassLoaderSharedLibraryIMC(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,const std::string & classpath)80   void VerifyClassLoaderSharedLibraryIMC(ClassLoaderContext* context,
81                                          size_t loader_index,
82                                          size_t shared_library_index,
83                                          const std::string& classpath) {
84     VerifyClassLoaderInfoSL(
85         context, loader_index, shared_library_index, ClassLoaderContext::kInMemoryDexClassLoader,
86         classpath);
87   }
88 
VerifySharedLibrariesSize(ClassLoaderContext * context,size_t loader_index,size_t expected_size)89   void VerifySharedLibrariesSize(ClassLoaderContext* context,
90                                  size_t loader_index,
91                                  size_t expected_size) {
92     ASSERT_TRUE(context != nullptr);
93     ASSERT_GT(context->GetParentChainSize(), loader_index);
94     const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
95     ASSERT_EQ(info.shared_libraries.size(), expected_size);
96   }
97 
VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,const std::string & classpath)98   void VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext* context,
99                                          size_t loader_index,
100                                          size_t shared_library_index,
101                                          const std::string& classpath) {
102     VerifyClassLoaderInfoSL(
103         context, loader_index, shared_library_index, ClassLoaderContext::kDelegateLastClassLoader,
104         classpath);
105   }
106 
VerifyClassLoaderPCLFromTestDex(ClassLoaderContext * context,size_t index,const std::string & test_name)107   void VerifyClassLoaderPCLFromTestDex(ClassLoaderContext* context,
108                                        size_t index,
109                                        const std::string& test_name) {
110     VerifyClassLoaderFromTestDex(
111         context, index, ClassLoaderContext::kPathClassLoader, test_name);
112   }
113 
VerifyClassLoaderDLCFromTestDex(ClassLoaderContext * context,size_t index,const std::string & test_name)114   void VerifyClassLoaderDLCFromTestDex(ClassLoaderContext* context,
115                                        size_t index,
116                                        const std::string& test_name) {
117     VerifyClassLoaderFromTestDex(
118         context, index, ClassLoaderContext::kDelegateLastClassLoader, test_name);
119   }
120 
VerifyClassLoaderIMCFromTestDex(ClassLoaderContext * context,size_t index,const std::string & test_name)121   void VerifyClassLoaderIMCFromTestDex(ClassLoaderContext* context,
122                                        size_t index,
123                                        const std::string& test_name) {
124     VerifyClassLoaderFromTestDex(
125         context, index, ClassLoaderContext::kInMemoryDexClassLoader, test_name, "<unknown>");
126   }
127 
128   enum class LocationCheck {
129     kEquals,
130     kEndsWith
131   };
132   enum class BaseLocationCheck {
133     kEquals,
134     kEndsWith
135   };
136 
IsAbsoluteLocation(const std::string & location)137   static bool IsAbsoluteLocation(const std::string& location) {
138     return !location.empty() && location[0] == '/';
139   }
140 
VerifyOpenDexFiles(ClassLoaderContext * context,size_t index,std::vector<std::unique_ptr<const DexFile>> * all_dex_files,bool classpath_matches_dex_location=true,bool only_read_checksums=false)141   void VerifyOpenDexFiles(
142       ClassLoaderContext* context,
143       size_t index,
144       std::vector<std::unique_ptr<const DexFile>>* all_dex_files,
145       bool classpath_matches_dex_location = true,
146       bool only_read_checksums = false) {
147     ASSERT_TRUE(context != nullptr);
148     if (only_read_checksums) {
149       ASSERT_EQ(context->dex_files_state_,
150                 ClassLoaderContext::ContextDexFilesState::kDexFilesChecksumsRead);
151     } else {
152       ASSERT_EQ(context->dex_files_state_,
153                 ClassLoaderContext::ContextDexFilesState::kDexFilesOpened);
154     }
155     ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
156     ASSERT_EQ(all_dex_files->size(), info.classpath.size());
157     ASSERT_EQ(all_dex_files->size(), info.checksums.size());
158     if (only_read_checksums) {
159       ASSERT_EQ(0u, info.opened_dex_files.size());
160     } else {
161       ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());
162     }
163 
164     for (size_t k = 0, cur_open_dex_index = 0;
165          k < all_dex_files->size();
166          k++, cur_open_dex_index++) {
167       const std::string& opened_location = only_read_checksums
168           ? info.classpath[cur_open_dex_index]
169           : info.opened_dex_files[cur_open_dex_index]->GetLocation();
170       uint32_t opened_checksum = only_read_checksums
171           ? info.checksums[cur_open_dex_index]
172           : info.opened_dex_files[cur_open_dex_index]->GetLocationChecksum();
173 
174       std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k];
175       std::string expected_location = expected_dex_file->GetLocation();
176 
177       if (!IsAbsoluteLocation(opened_location)) {
178         // If the opened location is relative (it was open from a relative path without a
179         // classpath_dir) it might not match the expected location which is absolute in tests).
180         // So we compare the endings (the checksum will validate it's actually the same file).
181         ASSERT_EQ(0, expected_location.compare(
182             expected_location.length() - opened_location.length(),
183             opened_location.length(),
184             opened_location));
185       } else {
186         ASSERT_EQ(expected_location, opened_location);
187       }
188       ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_checksum);
189       if (classpath_matches_dex_location) {
190         ASSERT_EQ(info.classpath[k], opened_location);
191       }
192     }
193   }
194 
CreateContextForClassLoader(jobject class_loader)195   std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
196     return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
197   }
198 
ParseContextWithChecksums(const std::string & context_spec)199   std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
200     std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
201     if (!context->Parse(context_spec, /*parse_checksums=*/ true)) {
202       return nullptr;
203     }
204     return context;
205   }
206 
VerifyContextForClassLoader(ClassLoaderContext * context)207   void VerifyContextForClassLoader(ClassLoaderContext* context) {
208     ASSERT_TRUE(context != nullptr);
209     ASSERT_EQ(context->dex_files_state_, ClassLoaderContext::ContextDexFilesState::kDexFilesOpened);
210     ASSERT_FALSE(context->owns_the_dex_files_);
211   }
212 
VerifyClassLoaderDexFiles(ScopedObjectAccess & soa,Handle<mirror::ClassLoader> class_loader,jclass type,std::vector<const DexFile * > & expected_dex_files)213   void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa,
214                                  Handle<mirror::ClassLoader> class_loader,
215                                  jclass type,
216                                  std::vector<const DexFile*>& expected_dex_files)
217       REQUIRES_SHARED(Locks::mutator_lock_) {
218     ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));
219 
220     std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, class_loader);
221     ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
222 
223     for (size_t i = 0; i < expected_dex_files.size(); i++) {
224       ASSERT_EQ(expected_dex_files[i]->GetLocation(),
225                 class_loader_dex_files[i]->GetLocation());
226       ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
227                 class_loader_dex_files[i]->GetLocationChecksum());
228     }
229   }
230 
PretendContextOpenedDexFiles(ClassLoaderContext * context)231   void PretendContextOpenedDexFiles(ClassLoaderContext* context) {
232     context->dex_files_state_ = ClassLoaderContext::ContextDexFilesState::kDexFilesOpened;
233   }
234 
PretendContextOpenedDexFilesForChecksums(ClassLoaderContext * context)235   void PretendContextOpenedDexFilesForChecksums(ClassLoaderContext* context) {
236     context->dex_files_state_ = ClassLoaderContext::ContextDexFilesState::kDexFilesChecksumsRead;
237   }
238 
TestOpenDexFiles(bool only_read_checksums)239   void TestOpenDexFiles(bool only_read_checksums) {
240     std::string multidex_name = GetTestDexFileName("MultiDex");
241     std::string myclass_dex_name = GetTestDexFileName("MyClass");
242     std::string dex_name = GetTestDexFileName("Main");
243 
244     std::unique_ptr<ClassLoaderContext> context =
245         ClassLoaderContext::Create(
246             "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
247             "DLC[" + dex_name + "]");
248 
249     ASSERT_TRUE(context->OpenDexFiles(
250         /*classpath_dir=*/ "",
251         /*context_fds=*/ std::vector<int>(),
252         only_read_checksums));
253 
254     VerifyContextSize(context.get(), 2);
255 
256     std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
257     std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
258     for (size_t i = 0; i < myclass_dex_files.size(); i++) {
259       all_dex_files0.emplace_back(myclass_dex_files[i].release());
260     }
261     VerifyOpenDexFiles(context.get(),
262                        /*index=*/ 0,
263                        &all_dex_files0,
264                        /*classpath_matches_dex_location=*/ false,
265                        only_read_checksums);
266     std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
267     VerifyOpenDexFiles(context.get(),
268                        /*index=*/ 1,
269                        &all_dex_files1,
270                        /*classpath_matches_dex_location=*/ false,
271                        only_read_checksums);
272   }
273 
TestOpenValidDexFilesRelative(bool use_classpath_dir,bool only_read_checksums)274   void TestOpenValidDexFilesRelative(bool use_classpath_dir, bool only_read_checksums) {
275     char cwd_buf[4096];
276     if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
277       PLOG(FATAL) << "Could not get working directory";
278     }
279     std::string multidex_name;
280     std::string myclass_dex_name;
281     std::string dex_name;
282     if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
283         !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
284         !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
285       LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
286                 << "relative path.";
287       SUCCEED();
288       return;
289     }
290 
291     std::unique_ptr<ClassLoaderContext> context =
292         ClassLoaderContext::Create(
293             "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
294             "DLC[" + dex_name + "]");
295 
296     ASSERT_TRUE(context->OpenDexFiles(
297         /*classpath_dir=*/ use_classpath_dir ? cwd_buf : "",
298         /*context_fds=*/ std::vector<int>(),
299         only_read_checksums));
300     VerifyContextSize(context.get(), 2);
301 
302     std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
303     std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
304     for (size_t i = 0; i < myclass_dex_files.size(); i++) {
305       all_dex_files0.emplace_back(myclass_dex_files[i].release());
306     }
307     VerifyOpenDexFiles(context.get(),
308                        /*index=*/ 0,
309                        &all_dex_files0,
310                        /*classpath_matches_dex_location=*/ false,
311                        only_read_checksums);
312 
313     std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
314     VerifyOpenDexFiles(context.get(),
315                        /*index=*/ 1,
316                        &all_dex_files1,
317                        /*classpath_matches_dex_location=*/ false,
318                        only_read_checksums);
319   }
320 
321   // Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
322   // TODO We should somehow support this in all situations. b/72042237.
CreateRelativeString(const std::string & in,const char * cwd,std::string * out)323   bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
324     int cwd_len = strlen(cwd);
325     if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
326       return false;
327     }
328     bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
329     int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
330     *out = in.substr(start_position);
331     return true;
332   }
333 
334  private:
VerifyClassLoaderInfo(ClassLoaderContext * context,size_t index,ClassLoaderContext::ClassLoaderType type,const std::string & classpath)335   void VerifyClassLoaderInfo(ClassLoaderContext* context,
336                              size_t index,
337                              ClassLoaderContext::ClassLoaderType type,
338                              const std::string& classpath) {
339     ASSERT_TRUE(context != nullptr);
340     ASSERT_GT(context->GetParentChainSize(), index);
341     ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
342     ASSERT_EQ(type, info.type);
343     std::vector<std::string> expected_classpath;
344     Split(classpath, ':', &expected_classpath);
345     ASSERT_EQ(expected_classpath, info.classpath);
346   }
347 
VerifyClassLoaderInfoSL(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,ClassLoaderContext::ClassLoaderType type,const std::string & classpath)348   void VerifyClassLoaderInfoSL(ClassLoaderContext* context,
349                                size_t loader_index,
350                                size_t shared_library_index,
351                                ClassLoaderContext::ClassLoaderType type,
352                                const std::string& classpath) {
353     ASSERT_TRUE(context != nullptr);
354     ASSERT_GT(context->GetParentChainSize(), loader_index);
355     const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
356     ASSERT_GT(info.shared_libraries.size(), shared_library_index);
357     const ClassLoaderContext::ClassLoaderInfo& sl =
358         *info.shared_libraries[shared_library_index].get();
359     ASSERT_EQ(type, info.type);
360     std::vector<std::string> expected_classpath;
361     Split(classpath, ':', &expected_classpath);
362     ASSERT_EQ(expected_classpath, sl.classpath);
363   }
364 
VerifyClassLoaderFromTestDex(ClassLoaderContext * context,size_t index,ClassLoaderContext::ClassLoaderType type,const std::string & test_name,const std::string & classpath="")365   void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
366                                     size_t index,
367                                     ClassLoaderContext::ClassLoaderType type,
368                                     const std::string& test_name,
369                                     const std::string& classpath = "") {
370     std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());
371 
372     // If `classpath` is set, override the expected value of ClassLoaderInfo::classpath.
373     // Otherwise assume it is equal to dex location (here test dex file name).
374     VerifyClassLoaderInfo(context,
375                           index,
376                           type,
377                           classpath.empty() ? GetTestDexFileName(test_name.c_str()) : classpath);
378     VerifyOpenDexFiles(context,
379                        index,
380                        &dex_files,
381                        /* classpath_matches_dex_location= */ classpath.empty());
382   }
383 };
384 
TEST_F(ClassLoaderContextTest,ParseValidEmptyContext)385 TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) {
386   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("");
387   // An empty context should create a single empty PathClassLoader.
388   VerifyContextSize(context.get(), 1);
389   VerifyClassLoaderPCL(context.get(), 0, "");
390 }
391 
TEST_F(ClassLoaderContextTest,ParseInvalidSharedLibraryContext)392 TEST_F(ClassLoaderContextTest, ParseInvalidSharedLibraryContext) {
393   // '&' used to be a special context.
394   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
395   ASSERT_TRUE(context == nullptr);
396 }
397 
TEST_F(ClassLoaderContextTest,ParseValidContextPCL)398 TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
399   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("PCL[a.dex]");
400   VerifyContextSize(context.get(), 1);
401   VerifyClassLoaderPCL(context.get(), 0, "a.dex");
402 }
403 
TEST_F(ClassLoaderContextTest,ParseValidContextDLC)404 TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
405   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("DLC[a.dex]");
406   VerifyContextSize(context.get(), 1);
407   VerifyClassLoaderDLC(context.get(), 0, "a.dex");
408 }
409 
TEST_F(ClassLoaderContextTest,ParseValidContextIMC)410 TEST_F(ClassLoaderContextTest, ParseValidContextIMC) {
411   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums("IMC[<unknown>*111]");
412   ASSERT_FALSE(context == nullptr);
413 }
414 
TEST_F(ClassLoaderContextTest,ParseInvalidContextIMCNoChecksum)415 TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCNoChecksum) {
416   // IMC is treated as an unknown class loader unless a checksum is provided.
417   // This is because the dex location is always bogus.
418   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[<unknown>]");
419   ASSERT_TRUE(context == nullptr);
420 }
421 
TEST_F(ClassLoaderContextTest,ParseInvalidContextIMCWrongClasspathMagic)422 TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCWrongClasspathMagic) {
423   // IMC does not support arbitrary dex location. A magic marker must be used
424   // otherwise the spec should be rejected.
425   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[a.dex*111]");
426   ASSERT_TRUE(context == nullptr);
427 }
428 
TEST_F(ClassLoaderContextTest,ParseValidContextChain)429 TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
430   std::unique_ptr<ClassLoaderContext> context =
431       ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
432   VerifyContextSize(context.get(), 3);
433   VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
434   VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
435   VerifyClassLoaderPCL(context.get(), 2, "e.dex");
436 }
437 
TEST_F(ClassLoaderContextTest,ParseSharedLibraries)438 TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
439   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
440       "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]};DLC[c.dex:d.dex]{DLC[s4.dex]}");
441   VerifyContextSize(context.get(), 2);
442   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
443   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
444   VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
445   VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
446 }
447 
TEST_F(ClassLoaderContextTest,ParseEnclosingSharedLibraries)448 TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
449   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
450       "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
451   VerifyContextSize(context.get(), 1);
452   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
453 }
454 
TEST_F(ClassLoaderContextTest,ParseComplexSharedLibraries1)455 TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
456   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
457       "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
458   VerifyContextSize(context.get(), 1);
459   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
460 }
461 
TEST_F(ClassLoaderContextTest,ParseComplexSharedLibraries2)462 TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
463   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
464       "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
465       "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
466   VerifyContextSize(context.get(), 1);
467   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
468   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
469   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
470   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
471   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
472 }
473 
TEST_F(ClassLoaderContextTest,ParseValidEmptyContextDLC)474 TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
475   std::unique_ptr<ClassLoaderContext> context =
476       ClassLoaderContext::Create("DLC[]");
477   VerifyContextSize(context.get(), 1);
478   VerifyClassLoaderDLC(context.get(), 0, "");
479 }
480 
TEST_F(ClassLoaderContextTest,ParseValidEmptyContextSharedLibrary)481 TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
482   std::unique_ptr<ClassLoaderContext> context =
483       ClassLoaderContext::Create("DLC[]{}");
484   VerifyContextSize(context.get(), 1);
485   VerifySharedLibrariesSize(context.get(), 0, 0);
486 }
487 
TEST_F(ClassLoaderContextTest,ParseInvalidValidContexts)488 TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
489   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
490   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
491   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
492   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
493   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
494   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
495   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
496   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
497   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
498   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
499   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
500   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
501   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
502   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
503   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
504 }
505 
TEST_F(ClassLoaderContextTest,OpenInvalidDexFiles)506 TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
507   std::unique_ptr<ClassLoaderContext> context =
508       ClassLoaderContext::Create("PCL[does_not_exist.dex]");
509   VerifyContextSize(context.get(), 1);
510   ASSERT_FALSE(context->OpenDexFiles("."));
511 }
512 
TEST_F(ClassLoaderContextTest,ReadChecksumsInvalidDexFiles)513 TEST_F(ClassLoaderContextTest, ReadChecksumsInvalidDexFiles) {
514   std::unique_ptr<ClassLoaderContext> context =
515       ClassLoaderContext::Create("PCL[does_not_exist.dex]");
516   VerifyContextSize(context.get(), 1);
517   ASSERT_FALSE(context->OpenDexFiles(
518         /*classpath_dir=*/ ".",
519         /*context_fds=*/ std::vector<int>(),
520         /*only_read_checksums=*/ true));
521 }
522 
TEST_F(ClassLoaderContextTest,OpenValidDexFiles)523 TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
524   TestOpenDexFiles(/*only_read_checksums=*/ false);
525 }
526 
TEST_F(ClassLoaderContextTest,ReadDexFileChecksums)527 TEST_F(ClassLoaderContextTest, ReadDexFileChecksums) {
528   TestOpenDexFiles(/*only_read_checksums=*/ true);
529 }
530 
TEST_F(ClassLoaderContextTest,OpenValidDexFilesRelative)531 TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
532   TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ false, /*only_read_checksums=*/ false);
533 }
534 
TEST_F(ClassLoaderContextTest,ReadChecksumsValidDexFilesRelative)535 TEST_F(ClassLoaderContextTest, ReadChecksumsValidDexFilesRelative) {
536   TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ false, /*only_read_checksums=*/ true);
537 }
538 
TEST_F(ClassLoaderContextTest,OpenValidDexFilesClasspathDir)539 TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
540   TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ true, /*only_read_checksums=*/ false);
541 }
542 
TEST_F(ClassLoaderContextTest,ReadChecksumsValidDexFilesClasspathDir)543 TEST_F(ClassLoaderContextTest, ReadChecksumsValidDexFilesClasspathDir) {
544   TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ true, /*only_read_checksums=*/ true);
545 }
546 
TEST_F(ClassLoaderContextTest,OpenInvalidDexFilesMix)547 TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
548   std::string dex_name = GetTestDexFileName("Main");
549   std::unique_ptr<ClassLoaderContext> context =
550       ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
551   ASSERT_FALSE(context->OpenDexFiles());
552 }
553 
TEST_F(ClassLoaderContextTest,ReadChecksumsInvalidDexFilesMix)554 TEST_F(ClassLoaderContextTest, ReadChecksumsInvalidDexFilesMix) {
555   std::string dex_name = GetTestDexFileName("Main");
556   std::unique_ptr<ClassLoaderContext> context =
557       ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
558   ASSERT_FALSE(context->OpenDexFiles(
559       /*classpath_dir=*/ "",
560       /*context_fds=*/ std::vector<int>(),
561       /*only_read_checksums=*/ true));
562 }
563 
TEST_F(ClassLoaderContextTest,OpenDexFilesForIMCFails)564 TEST_F(ClassLoaderContextTest, OpenDexFilesForIMCFails) {
565   std::unique_ptr<ClassLoaderContext> context;
566   std::string dex_name = GetTestDexFileName("Main");
567 
568   context = ParseContextWithChecksums("IMC[<unknown>*111]");
569   VerifyContextSize(context.get(), 1);
570   ASSERT_FALSE(context->OpenDexFiles("."));
571 }
572 
573 // Verify that we can fully open the dex files after only reading their checksums.
TEST_F(ClassLoaderContextTest,SubsequentOpenDexFilesOperations)574 TEST_F(ClassLoaderContextTest, SubsequentOpenDexFilesOperations) {
575   std::string dex_name = GetTestDexFileName("Main");
576   std::unique_ptr<ClassLoaderContext> context =
577       ClassLoaderContext::Create("PCL[" + dex_name + "]");
578 
579   std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("Main");
580 
581   ASSERT_TRUE(context->OpenDexFiles(
582       /*classpath_dir=*/ "",
583       /*context_fds=*/ std::vector<int>(),
584       /*only_read_checksums=*/ true));
585 
586   VerifyOpenDexFiles(
587       context.get(),
588       /*index=*/ 0,
589       &all_dex_files0,
590       /*classpath_matches_dex_location=*/ false,
591       /*only_read_checksums=*/ true);
592 
593   ASSERT_TRUE(context->OpenDexFiles(
594       /*classpath_dir=*/ "",
595       /*context_fds=*/ std::vector<int>(),
596       /*only_read_checksums=*/ false));
597 
598   VerifyOpenDexFiles(
599       context.get(),
600       /*index=*/ 0,
601       &all_dex_files0,
602       /*classpath_matches_dex_location=*/ false,
603       /*only_read_checksums=*/ false);
604 }
605 
TEST_F(ClassLoaderContextTest,CreateClassLoader)606 TEST_F(ClassLoaderContextTest, CreateClassLoader) {
607   std::string dex_name = GetTestDexFileName("Main");
608   std::unique_ptr<ClassLoaderContext> context =
609       ClassLoaderContext::Create("PCL[" + dex_name + "]");
610   ASSERT_TRUE(context->OpenDexFiles());
611 
612   std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
613   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
614 
615   std::vector<const DexFile*> compilation_sources_raw =
616       MakeNonOwningPointerVector(compilation_sources);
617   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
618   ASSERT_TRUE(jclass_loader != nullptr);
619 
620   ScopedObjectAccess soa(Thread::Current());
621 
622   StackHandleScope<1> hs(soa.Self());
623   Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
624       soa.Decode<mirror::ClassLoader>(jclass_loader));
625 
626   ASSERT_TRUE(class_loader->GetClass() ==
627       soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
628   ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
629       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
630 
631   // For the first class loader the class path dex files must come first and then the
632   // compilation sources.
633   std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
634   for (auto& dex : compilation_sources_raw) {
635     expected_classpath.push_back(dex);
636   }
637 
638   VerifyClassLoaderDexFiles(soa,
639                             class_loader,
640                             WellKnownClasses::dalvik_system_PathClassLoader,
641                             expected_classpath);
642 }
643 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithEmptyContext)644 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
645   std::unique_ptr<ClassLoaderContext> context =
646       ClassLoaderContext::Create("");
647   ASSERT_TRUE(context->OpenDexFiles());
648 
649   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
650 
651   std::vector<const DexFile*> compilation_sources_raw =
652       MakeNonOwningPointerVector(compilation_sources);
653   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
654   ASSERT_TRUE(jclass_loader != nullptr);
655 
656   ScopedObjectAccess soa(Thread::Current());
657 
658   StackHandleScope<1> hs(soa.Self());
659   Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
660       soa.Decode<mirror::ClassLoader>(jclass_loader));
661 
662   // An empty context should create a single PathClassLoader with only the compilation sources.
663   VerifyClassLoaderDexFiles(soa,
664                             class_loader,
665                             WellKnownClasses::dalvik_system_PathClassLoader,
666                             compilation_sources_raw);
667   ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
668       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
669 }
670 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithComplexChain)671 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
672   // Setup the context.
673   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
674   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
675   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
676   std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
677 
678   std::string context_spec =
679       "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
680       "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
681       "PCL[" + CreateClassPath(classpath_dex_d) + "]";
682 
683   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
684   ASSERT_TRUE(context->OpenDexFiles());
685 
686   // Setup the compilation sources.
687   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
688   std::vector<const DexFile*> compilation_sources_raw =
689       MakeNonOwningPointerVector(compilation_sources);
690 
691   // Create the class loader.
692   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
693   ASSERT_TRUE(jclass_loader != nullptr);
694 
695   // Verify the class loader.
696   ScopedObjectAccess soa(Thread::Current());
697 
698   StackHandleScope<3> hs(soa.Self());
699   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
700       soa.Decode<mirror::ClassLoader>(jclass_loader));
701 
702   // Verify the first class loader
703 
704   // For the first class loader the class path dex files must come first and then the
705   // compilation sources.
706   std::vector<const DexFile*> class_loader_1_dex_files =
707       MakeNonOwningPointerVector(classpath_dex_a);
708   for (auto& dex : classpath_dex_b) {
709     class_loader_1_dex_files.push_back(dex.get());
710   }
711   for (auto& dex : compilation_sources_raw) {
712     class_loader_1_dex_files.push_back(dex);
713   }
714   VerifyClassLoaderDexFiles(soa,
715                             class_loader_1,
716                             WellKnownClasses::dalvik_system_PathClassLoader,
717                             class_loader_1_dex_files);
718 
719   // Verify the second class loader
720   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
721   std::vector<const DexFile*> class_loader_2_dex_files =
722       MakeNonOwningPointerVector(classpath_dex_c);
723   VerifyClassLoaderDexFiles(soa,
724                             class_loader_2,
725                             WellKnownClasses::dalvik_system_DelegateLastClassLoader,
726                             class_loader_2_dex_files);
727 
728   // Verify the third class loader
729   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
730   std::vector<const DexFile*> class_loader_3_dex_files =
731       MakeNonOwningPointerVector(classpath_dex_d);
732   VerifyClassLoaderDexFiles(soa,
733                             class_loader_3,
734                             WellKnownClasses::dalvik_system_PathClassLoader,
735                             class_loader_3_dex_files);
736   // The last class loader should have the BootClassLoader as a parent.
737   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
738       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
739 }
740 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithSharedLibraries)741 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
742   // Setup the context.
743   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
744   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
745   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
746   std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
747 
748   std::string context_spec =
749       "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
750       "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
751       "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
752 
753   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
754   ASSERT_TRUE(context->OpenDexFiles());
755 
756   // Setup the compilation sources.
757   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
758   std::vector<const DexFile*> compilation_sources_raw =
759       MakeNonOwningPointerVector(compilation_sources);
760 
761   // Create the class loader.
762   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
763   ASSERT_TRUE(jclass_loader != nullptr);
764 
765   // Verify the class loader.
766   ScopedObjectAccess soa(Thread::Current());
767 
768   StackHandleScope<4> hs(soa.Self());
769   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
770       soa.Decode<mirror::ClassLoader>(jclass_loader));
771 
772   // For the first class loader the class path dex files must come first and then the
773   // compilation sources.
774   std::vector<const DexFile*> class_loader_1_dex_files =
775       MakeNonOwningPointerVector(classpath_dex_a);
776   for (auto& dex : classpath_dex_b) {
777     class_loader_1_dex_files.push_back(dex.get());
778   }
779   for (auto& dex : compilation_sources_raw) {
780     class_loader_1_dex_files.push_back(dex);
781   }
782   VerifyClassLoaderDexFiles(soa,
783                             class_loader_1,
784                             WellKnownClasses::dalvik_system_PathClassLoader,
785                             class_loader_1_dex_files);
786 
787   // Verify the shared libraries.
788   ArtField* field =
789       jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
790   ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
791   ASSERT_TRUE(raw_shared_libraries != nullptr);
792 
793   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
794       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
795   ASSERT_EQ(shared_libraries->GetLength(), 2);
796 
797   // Verify the first shared library.
798   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
799   std::vector<const DexFile*> class_loader_2_dex_files =
800       MakeNonOwningPointerVector(classpath_dex_c);
801   VerifyClassLoaderDexFiles(soa,
802                             class_loader_2,
803                             WellKnownClasses::dalvik_system_DelegateLastClassLoader,
804                             class_loader_2_dex_files);
805   raw_shared_libraries = field->GetObject(class_loader_2.Get());
806   ASSERT_TRUE(raw_shared_libraries == nullptr);
807 
808   // Verify the second shared library.
809   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
810   std::vector<const DexFile*> class_loader_3_dex_files =
811       MakeNonOwningPointerVector(classpath_dex_d);
812   VerifyClassLoaderDexFiles(soa,
813                             class_loader_3,
814                             WellKnownClasses::dalvik_system_PathClassLoader,
815                             class_loader_3_dex_files);
816   raw_shared_libraries = field->GetObject(class_loader_3.Get());
817   ASSERT_TRUE(raw_shared_libraries == nullptr);
818 
819   // All class loaders should have the BootClassLoader as a parent.
820   ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
821       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
822   ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
823       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
824   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
825       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
826 }
827 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithSharedLibrariesInParentToo)828 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
829   // Setup the context.
830   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
831   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
832   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
833   std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
834 
835   std::string context_spec =
836       "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
837       "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
838       "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
839       "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
840 
841   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
842   ASSERT_TRUE(context->OpenDexFiles());
843 
844   // Setup the compilation sources.
845   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
846   std::vector<const DexFile*> compilation_sources_raw =
847       MakeNonOwningPointerVector(compilation_sources);
848 
849   // Create the class loader.
850   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
851   ASSERT_TRUE(jclass_loader != nullptr);
852 
853   // Verify the class loader.
854   ScopedObjectAccess soa(Thread::Current());
855 
856   StackHandleScope<6> hs(soa.Self());
857   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
858       soa.Decode<mirror::ClassLoader>(jclass_loader));
859 
860   // For the first class loader the class path dex files must come first and then the
861   // compilation sources.
862   std::vector<const DexFile*> class_loader_1_dex_files =
863       MakeNonOwningPointerVector(classpath_dex_a);
864   for (auto& dex : compilation_sources_raw) {
865     class_loader_1_dex_files.push_back(dex);
866   }
867   VerifyClassLoaderDexFiles(soa,
868                             class_loader_1,
869                             WellKnownClasses::dalvik_system_PathClassLoader,
870                             class_loader_1_dex_files);
871 
872   // Verify its shared library.
873   ArtField* field =
874       jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
875   ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
876   ASSERT_TRUE(raw_shared_libraries != nullptr);
877 
878   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
879       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
880   ASSERT_EQ(shared_libraries->GetLength(), 1);
881 
882   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
883   std::vector<const DexFile*> class_loader_2_dex_files =
884       MakeNonOwningPointerVector(classpath_dex_b);
885   VerifyClassLoaderDexFiles(soa,
886                             class_loader_2,
887                             WellKnownClasses::dalvik_system_PathClassLoader,
888                             class_loader_2_dex_files);
889   raw_shared_libraries = field->GetObject(class_loader_2.Get());
890   ASSERT_TRUE(raw_shared_libraries == nullptr);
891 
892   // Verify the parent.
893   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
894   std::vector<const DexFile*> class_loader_3_dex_files =
895       MakeNonOwningPointerVector(classpath_dex_c);
896   VerifyClassLoaderDexFiles(soa,
897                             class_loader_3,
898                             WellKnownClasses::dalvik_system_PathClassLoader,
899                             class_loader_3_dex_files);
900 
901   // Verify its shared library.
902   raw_shared_libraries = field->GetObject(class_loader_3.Get());
903   ASSERT_TRUE(raw_shared_libraries != nullptr);
904 
905   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
906       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
907   ASSERT_EQ(shared_libraries->GetLength(), 1);
908 
909   Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
910   std::vector<const DexFile*> class_loader_4_dex_files =
911       MakeNonOwningPointerVector(classpath_dex_d);
912   VerifyClassLoaderDexFiles(soa,
913                             class_loader_4,
914                             WellKnownClasses::dalvik_system_PathClassLoader,
915                             class_loader_4_dex_files);
916   raw_shared_libraries = field->GetObject(class_loader_4.Get());
917   ASSERT_TRUE(raw_shared_libraries == nullptr);
918 
919   // Class loaders should have the BootClassLoader as a parent.
920   ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
921       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
922   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
923       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
924   ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
925       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
926 }
927 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithSharedLibrariesDependencies)928 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
929   // Setup the context.
930   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
931   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
932   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
933   std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
934 
935   std::string context_spec =
936       "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
937       "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
938       "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
939       "PCL[" + CreateClassPath(classpath_dex_d) + "]";
940 
941   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
942   ASSERT_TRUE(context->OpenDexFiles());
943 
944   // Setup the compilation sources.
945   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
946   std::vector<const DexFile*> compilation_sources_raw =
947       MakeNonOwningPointerVector(compilation_sources);
948 
949   // Create the class loader.
950   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
951   ASSERT_TRUE(jclass_loader != nullptr);
952 
953   // Verify the class loader.
954   ScopedObjectAccess soa(Thread::Current());
955 
956   StackHandleScope<6> hs(soa.Self());
957   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
958       soa.Decode<mirror::ClassLoader>(jclass_loader));
959 
960   // For the first class loader the class path dex files must come first and then the
961   // compilation sources.
962   std::vector<const DexFile*> class_loader_1_dex_files =
963       MakeNonOwningPointerVector(classpath_dex_a);
964   for (auto& dex : compilation_sources_raw) {
965     class_loader_1_dex_files.push_back(dex);
966   }
967   VerifyClassLoaderDexFiles(soa,
968                             class_loader_1,
969                             WellKnownClasses::dalvik_system_PathClassLoader,
970                             class_loader_1_dex_files);
971 
972   // Verify its shared library.
973   ArtField* field =
974       jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
975   ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
976   ASSERT_TRUE(raw_shared_libraries != nullptr);
977 
978   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
979       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
980   ASSERT_EQ(shared_libraries->GetLength(), 1);
981 
982   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
983   std::vector<const DexFile*> class_loader_2_dex_files =
984       MakeNonOwningPointerVector(classpath_dex_b);
985   VerifyClassLoaderDexFiles(soa,
986                             class_loader_2,
987                             WellKnownClasses::dalvik_system_PathClassLoader,
988                             class_loader_2_dex_files);
989 
990   // Verify the shared library dependency of the shared library.
991   raw_shared_libraries = field->GetObject(class_loader_2.Get());
992   ASSERT_TRUE(raw_shared_libraries != nullptr);
993 
994   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
995       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
996   ASSERT_EQ(shared_libraries_2->GetLength(), 1);
997 
998   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
999   std::vector<const DexFile*> class_loader_3_dex_files =
1000       MakeNonOwningPointerVector(classpath_dex_c);
1001   VerifyClassLoaderDexFiles(soa,
1002                             class_loader_3,
1003                             WellKnownClasses::dalvik_system_PathClassLoader,
1004                             class_loader_3_dex_files);
1005   raw_shared_libraries = field->GetObject(class_loader_3.Get());
1006   ASSERT_TRUE(raw_shared_libraries == nullptr);
1007 
1008   // Verify the parent.
1009   Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
1010   std::vector<const DexFile*> class_loader_4_dex_files =
1011       MakeNonOwningPointerVector(classpath_dex_d);
1012   VerifyClassLoaderDexFiles(soa,
1013                             class_loader_4,
1014                             WellKnownClasses::dalvik_system_PathClassLoader,
1015                             class_loader_4_dex_files);
1016   raw_shared_libraries = field->GetObject(class_loader_4.Get());
1017   ASSERT_TRUE(raw_shared_libraries == nullptr);
1018 
1019   // Class loaders should have the BootClassLoader as a parent.
1020   ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1021       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1022   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1023       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1024   ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
1025       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1026 }
1027 
TEST_F(ClassLoaderContextTest,RemoveSourceLocations)1028 TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
1029   std::unique_ptr<ClassLoaderContext> context =
1030       ClassLoaderContext::Create("PCL[a.dex]");
1031   dchecked_vector<std::string> classpath_dex;
1032   classpath_dex.push_back("a.dex");
1033   dchecked_vector<std::string> compilation_sources;
1034   compilation_sources.push_back("src.dex");
1035 
1036   // Nothing should be removed.
1037   ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
1038   VerifyClassLoaderPCL(context.get(), 0, "a.dex");
1039   // Classes should be removed.
1040   ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
1041   VerifyClassLoaderPCL(context.get(), 0, "");
1042 }
1043 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithSameSharedLibraries)1044 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
1045   // Setup the context.
1046   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
1047   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
1048   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
1049 
1050   std::string context_spec =
1051       "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
1052       "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
1053       "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
1054       "PCL[" + CreateClassPath(classpath_dex_b) + "]}";
1055 
1056   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
1057   ASSERT_TRUE(context->OpenDexFiles());
1058 
1059   // Setup the compilation sources.
1060   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
1061   std::vector<const DexFile*> compilation_sources_raw =
1062       MakeNonOwningPointerVector(compilation_sources);
1063 
1064   // Create the class loader.
1065   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
1066   ASSERT_TRUE(jclass_loader != nullptr);
1067 
1068   // Verify the class loader.
1069   ScopedObjectAccess soa(Thread::Current());
1070 
1071   StackHandleScope<6> hs(soa.Self());
1072   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
1073       soa.Decode<mirror::ClassLoader>(jclass_loader));
1074 
1075   // For the first class loader the class path dex files must come first and then the
1076   // compilation sources.
1077   std::vector<const DexFile*> class_loader_1_dex_files =
1078       MakeNonOwningPointerVector(classpath_dex_a);
1079   for (auto& dex : compilation_sources_raw) {
1080     class_loader_1_dex_files.push_back(dex);
1081   }
1082   VerifyClassLoaderDexFiles(soa,
1083                             class_loader_1,
1084                             WellKnownClasses::dalvik_system_PathClassLoader,
1085                             class_loader_1_dex_files);
1086 
1087   // Verify its shared library.
1088   ArtField* field =
1089       jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
1090   ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
1091   ASSERT_TRUE(raw_shared_libraries != nullptr);
1092 
1093   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
1094       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1095   ASSERT_EQ(shared_libraries->GetLength(), 1);
1096 
1097   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
1098   std::vector<const DexFile*> class_loader_2_dex_files =
1099       MakeNonOwningPointerVector(classpath_dex_b);
1100   VerifyClassLoaderDexFiles(soa,
1101                             class_loader_2,
1102                             WellKnownClasses::dalvik_system_PathClassLoader,
1103                             class_loader_2_dex_files);
1104 
1105   // Verify the parent.
1106   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
1107   std::vector<const DexFile*> class_loader_3_dex_files =
1108       MakeNonOwningPointerVector(classpath_dex_c);
1109   VerifyClassLoaderDexFiles(soa,
1110                             class_loader_3,
1111                             WellKnownClasses::dalvik_system_PathClassLoader,
1112                             class_loader_3_dex_files);
1113 
1114   // Verify its shared library is the same as the child.
1115   raw_shared_libraries = field->GetObject(class_loader_3.Get());
1116   ASSERT_TRUE(raw_shared_libraries != nullptr);
1117   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1118       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1119   ASSERT_EQ(shared_libraries_2->GetLength(), 1);
1120   ASSERT_OBJ_PTR_EQ(shared_libraries_2->Get(0), class_loader_2.Get());
1121 
1122   // Class loaders should have the BootClassLoader as a parent.
1123   ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1124       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1125   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1126       soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1127 }
1128 
TEST_F(ClassLoaderContextTest,EncodeInOatFile)1129 TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
1130   std::string dex1_name = GetTestDexFileName("Main");
1131   std::string dex2_name = GetTestDexFileName("MyClass");
1132   std::unique_ptr<ClassLoaderContext> context =
1133       ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1134   ASSERT_TRUE(context->OpenDexFiles());
1135 
1136   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1137   std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1138   std::string encoding = context->EncodeContextForOatFile("");
1139   std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
1140       CreateClassPathWithChecksums(dex2) + "]";
1141   ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1142 }
1143 
TEST_F(ClassLoaderContextTest,EncodeInOatFileIMC)1144 TEST_F(ClassLoaderContextTest, EncodeInOatFileIMC) {
1145   jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1146   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1147 
1148   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1149   ASSERT_TRUE(context->OpenDexFiles());
1150 
1151   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1152   std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1153   ASSERT_EQ(dex2.size(), 1u);
1154 
1155   std::string encoding = context->EncodeContextForOatFile("");
1156   std::string expected_encoding = "IMC[<unknown>*" + std::to_string(dex2[0]->GetLocationChecksum())
1157       + "];PCL[" + CreateClassPathWithChecksums(dex1) + "]";
1158   ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1159 }
1160 
TEST_F(ClassLoaderContextTest,EncodeForDex2oat)1161 TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
1162   std::string dex1_name = GetTestDexFileName("Main");
1163   std::string dex2_name = GetTestDexFileName("MultiDex");
1164   std::unique_ptr<ClassLoaderContext> context =
1165       ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1166   ASSERT_TRUE(context->OpenDexFiles());
1167 
1168   std::string encoding = context->EncodeContextForDex2oat("");
1169   std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
1170   ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1171 }
1172 
TEST_F(ClassLoaderContextTest,EncodeForDex2oatIMC)1173 TEST_F(ClassLoaderContextTest, EncodeForDex2oatIMC) {
1174   jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1175   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1176 
1177   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1178   ASSERT_TRUE(context->OpenDexFiles());
1179 
1180   std::string encoding = context->EncodeContextForDex2oat("");
1181   std::string expected_encoding = "IMC[<unknown>];PCL[" + GetTestDexFileName("Main") + "]";
1182   ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1183 }
1184 
TEST_F(ClassLoaderContextTest,EncodeContextsSinglePath)1185 TEST_F(ClassLoaderContextTest, EncodeContextsSinglePath) {
1186   jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1187   std::unique_ptr<ClassLoaderContext> context =
1188       CreateContextForClassLoader(class_loader);
1189 
1190   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1191   ASSERT_EQ(1u, encodings.size());
1192   ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1193 }
1194 
TEST_F(ClassLoaderContextTest,EncodeContextsMultiDex)1195 TEST_F(ClassLoaderContextTest, EncodeContextsMultiDex) {
1196   jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1197   std::unique_ptr<ClassLoaderContext> context =
1198       CreateContextForClassLoader(class_loader);
1199 
1200   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1201   ASSERT_EQ(1u, encodings.size());
1202   ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("MultiDex")));
1203 }
1204 
TEST_F(ClassLoaderContextTest,EncodeContextsRepeatedMultiDex)1205 TEST_F(ClassLoaderContextTest, EncodeContextsRepeatedMultiDex) {
1206   jobject top_class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1207   jobject middle_class_loader =
1208       LoadDexInPathClassLoader("Main", top_class_loader);
1209   jobject bottom_class_loader =
1210       LoadDexInPathClassLoader("MultiDex", middle_class_loader);
1211   std::unique_ptr<ClassLoaderContext> context =
1212       CreateContextForClassLoader(bottom_class_loader);
1213 
1214   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1215   ASSERT_EQ(1u, encodings.size());
1216 
1217   std::string main_dex_name = GetTestDexFileName("Main");
1218   std::string multidex_dex_name = GetTestDexFileName("MultiDex");
1219   ASSERT_EQ(
1220       "PCL[];PCL[" + main_dex_name + "];PCL[" + multidex_dex_name + "]",
1221       encodings.at(multidex_dex_name));
1222 }
1223 
TEST_F(ClassLoaderContextTest,EncodeContextsSinglePathWithShared)1224 TEST_F(ClassLoaderContextTest, EncodeContextsSinglePathWithShared) {
1225   jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);
1226 
1227   ScopedObjectAccess soa(Thread::Current());
1228   StackHandleScope<1> hs(soa.Self());
1229   Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1230     mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1231         soa.Self(),
1232         GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1233         1));
1234   libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1235 
1236   jobject class_loader_b = LoadDexInPathClassLoader(
1237       "Main", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1238 
1239   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1240 
1241   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1242   ASSERT_EQ(1u, encodings.size());
1243   ASSERT_EQ(
1244       "PCL[]{PCL[" + GetTestDexFileName("MyClass") + "]}",
1245       encodings.at(GetTestDexFileName("Main")));
1246 }
1247 
TEST_F(ClassLoaderContextTest,EncodeContextsMultiplePaths)1248 TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePaths) {
1249   jobject class_loader = LoadDexInPathClassLoader(
1250       std::vector<std::string>{ "Main", "MultiDex"}, nullptr);
1251 
1252   std::unique_ptr<ClassLoaderContext> context =
1253       CreateContextForClassLoader(class_loader);
1254 
1255   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1256   ASSERT_EQ(2u, encodings.size());
1257   ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1258   ASSERT_EQ(
1259       "PCL[" + GetTestDexFileName("Main") + "]", encodings.at(GetTestDexFileName("MultiDex")));
1260 }
1261 
TEST_F(ClassLoaderContextTest,EncodeContextsMultiplePathsWithShared)1262 TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePathsWithShared) {
1263   jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);
1264 
1265   ScopedObjectAccess soa(Thread::Current());
1266   StackHandleScope<1> hs(soa.Self());
1267   Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1268     mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1269         soa.Self(),
1270         GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1271         1));
1272   libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1273 
1274   jobject class_loader_b = LoadDexInPathClassLoader(
1275       std::vector<std::string> { "Main", "MultiDex" },
1276       nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1277 
1278   std::unique_ptr<ClassLoaderContext> context =
1279       CreateContextForClassLoader(class_loader_b);
1280 
1281   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1282   ASSERT_EQ(2u, encodings.size());
1283   const std::string context_suffix =
1284       "{PCL[" + GetTestDexFileName("MyClass") + "]}";
1285   ASSERT_EQ("PCL[]" + context_suffix, encodings.at(GetTestDexFileName("Main")));
1286   ASSERT_EQ(
1287       "PCL[" + GetTestDexFileName("Main") + "]" + context_suffix,
1288       encodings.at(GetTestDexFileName("MultiDex")));
1289 }
1290 
TEST_F(ClassLoaderContextTest,EncodeContextsIMC)1291 TEST_F(ClassLoaderContextTest, EncodeContextsIMC) {
1292   jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1293   jobject class_loader_b =
1294       LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1295 
1296   std::unique_ptr<ClassLoaderContext> context =
1297       CreateContextForClassLoader(class_loader_b);
1298 
1299   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1300   ASSERT_EQ(1u, encodings.size());
1301   ASSERT_EQ(
1302       "IMC[];PCL[" + GetTestDexFileName("Main") + "]",
1303       encodings.at("<unknown>"));
1304 }
1305 
TEST_F(ClassLoaderContextTest,EncodeContextsForSingleDex)1306 TEST_F(ClassLoaderContextTest, EncodeContextsForSingleDex) {
1307   jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1308   std::map<std::string, std::string> encodings =
1309       ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1310   ASSERT_EQ(1u, encodings.size());
1311   ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1312 }
1313 
CreateForeignClassLoader()1314 static jobject CreateForeignClassLoader() {
1315   ScopedObjectAccess soa(Thread::Current());
1316   JNIEnv* env = soa.Env();
1317 
1318   // We cannot instantiate a ClassLoader directly, so instead we allocate an Object to represent
1319   // our foreign ClassLoader (this works because the runtime does proper instanceof checks before
1320   // operating on this object.
1321   jmethodID ctor = env->GetMethodID(WellKnownClasses::java_lang_Object, "<init>", "()V");
1322   return env->NewObject(WellKnownClasses::java_lang_Object, ctor);
1323 }
1324 
TEST_F(ClassLoaderContextTest,EncodeContextsForUnsupportedBase)1325 TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedBase) {
1326   std::map<std::string, std::string> empty;
1327   ASSERT_EQ(
1328       empty, ClassLoaderContext::EncodeClassPathContextsForClassLoader(CreateForeignClassLoader()));
1329 }
1330 
TEST_F(ClassLoaderContextTest,EncodeContextsForUnsupportedChain)1331 TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChain) {
1332   jobject class_loader = LoadDexInPathClassLoader("Main", CreateForeignClassLoader());
1333   std::map<std::string, std::string> encodings =
1334       ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1335   ASSERT_EQ(1u, encodings.size());
1336   ASSERT_EQ(
1337       ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1338       encodings.at(GetTestDexFileName("Main")));
1339 }
1340 
TEST_F(ClassLoaderContextTest,EncodeContextsForUnsupportedChainMultiPath)1341 TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiPath) {
1342   jobject class_loader = LoadDexInPathClassLoader(std::vector<std::string> { "Main", "MyClass" },
1343                                                   CreateForeignClassLoader());
1344   std::map<std::string, std::string> encodings =
1345       ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1346   ASSERT_EQ(2u, encodings.size());
1347   ASSERT_EQ(
1348       ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1349       encodings.at(GetTestDexFileName("Main")));
1350   ASSERT_EQ(
1351       ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1352       encodings.at(GetTestDexFileName("MyClass")));
1353 }
1354 
TEST_F(ClassLoaderContextTest,EncodeContextsForUnsupportedChainMultiDex)1355 TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiDex) {
1356   jobject class_loader = LoadDexInPathClassLoader("MultiDex", CreateForeignClassLoader());
1357   std::map<std::string, std::string> encodings =
1358       ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1359   ASSERT_EQ(1u, encodings.size());
1360   ASSERT_EQ(
1361       ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1362       encodings.at(GetTestDexFileName("MultiDex")));
1363 }
1364 
TEST_F(ClassLoaderContextTest,IsValidEncoding)1365 TEST_F(ClassLoaderContextTest, IsValidEncoding) {
1366   ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[]"));
1367   ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex]"));
1368   ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex];PCL[bar.dex]"));
1369   ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("DLC[];PCL[bar.dex]"));
1370   ASSERT_TRUE(
1371       ClassLoaderContext::IsValidEncoding(
1372         ClassLoaderContext::kUnsupportedClassLoaderContextEncoding));
1373   ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("not_valid"));
1374   ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("[]"));
1375   ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("FCL[]"));
1376   ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("foo.dex:bar.dex"));
1377 }
1378 
1379 // TODO(calin) add a test which creates the context for a class loader together with dex_elements.
TEST_F(ClassLoaderContextTest,CreateContextForClassLoader)1380 TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
1381   // The chain is
1382   //    ClassLoaderA (PathClassLoader)
1383   //       ^
1384   //       |
1385   //    ClassLoaderB (DelegateLastClassLoader)
1386   //       ^
1387   //       |
1388   //    ClassLoaderC (PathClassLoader)
1389   //       ^
1390   //       |
1391   //    ClassLoaderD (DelegateLastClassLoader)
1392 
1393   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1394   jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1395   jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1396   jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1397 
1398   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1399 
1400   VerifyContextForClassLoader(context.get());
1401   VerifyContextSize(context.get(), 4);
1402 
1403   VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1404   VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
1405   VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
1406   VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1407 }
1408 
TEST_F(ClassLoaderContextTest,CreateContextForClassLoaderIMC)1409 TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) {
1410   // The chain is
1411   //    ClassLoaderA (PathClassLoader)
1412   //       ^
1413   //       |
1414   //    ClassLoaderB (InMemoryDexClassLoader)
1415   //       ^
1416   //       |
1417   //    ClassLoaderC (InMemoryDexClassLoader)
1418   //       ^
1419   //       |
1420   //    ClassLoaderD (DelegateLastClassLoader)
1421 
1422   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1423   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1424   jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1425   jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1426 
1427   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1428 
1429   VerifyContextForClassLoader(context.get());
1430   VerifyContextSize(context.get(), 4);
1431 
1432   VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1433   VerifyClassLoaderIMCFromTestDex(context.get(), 1, "ForClassLoaderC");
1434   VerifyClassLoaderIMCFromTestDex(context.get(), 2, "ForClassLoaderB");
1435   VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1436 }
1437 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatch)1438 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
1439   std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
1440   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1441   // Pretend that we successfully open the dex files to pass the DCHECKS.
1442   // (as it's much easier to test all the corner cases without relying on actual dex files).
1443   PretendContextOpenedDexFilesForChecksums(context.get());
1444 
1445   VerifyContextSize(context.get(), 2);
1446   VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1447   VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1448 
1449   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1450             ClassLoaderContext::VerificationResult::kVerifies);
1451 
1452   std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
1453   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1454             ClassLoaderContext::VerificationResult::kMismatch);
1455 
1456   std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
1457   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1458             ClassLoaderContext::VerificationResult::kMismatch);
1459 
1460   std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
1461   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1462             ClassLoaderContext::VerificationResult::kMismatch);
1463 
1464   std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
1465   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1466             ClassLoaderContext::VerificationResult::kMismatch);
1467 
1468   std::string wrong_extra_class_loader = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];PCL[d.dex*321]";
1469   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1470             ClassLoaderContext::VerificationResult::kMismatch);
1471 
1472   std::string wrong_extra_classpath = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890:d.dex*321]";
1473   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1474             ClassLoaderContext::VerificationResult::kMismatch);
1475 
1476   std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
1477   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1478             ClassLoaderContext::VerificationResult::kMismatch);
1479 }
1480 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextWithIMCMatch)1481 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) {
1482   std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];IMC[<unknown>*111]";
1483   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1484   // Pretend that we successfully open the dex files to pass the DCHECKS.
1485   // (as it's much easier to test all the corner cases without relying on actual dex files).
1486   PretendContextOpenedDexFiles(context.get());
1487 
1488   VerifyContextSize(context.get(), 3);
1489   VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1490   VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1491   VerifyClassLoaderIMC(context.get(), 2, "<unknown>");
1492 
1493   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1494             ClassLoaderContext::VerificationResult::kVerifies);
1495 }
1496 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchWithSL)1497 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1498   std::string context_spec =
1499       "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1500       ";DLC[c.dex*890]";
1501   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1502   // Pretend that we successfully open the dex files to pass the DCHECKS.
1503   // (as it's much easier to test all the corner cases without relying on actual dex files).
1504   PretendContextOpenedDexFiles(context.get());
1505 
1506   VerifyContextSize(context.get(), 2);
1507   VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1508   VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1509   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1510   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1511 
1512   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1513             ClassLoaderContext::VerificationResult::kVerifies);
1514 
1515   std::string wrong_class_loader_type =
1516       "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1517       ";DLC[c.dex*890]";
1518   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1519             ClassLoaderContext::VerificationResult::kMismatch);
1520 
1521   std::string wrong_class_loader_order =
1522       "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1523       ";DLC[c.dex*890]";
1524   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1525             ClassLoaderContext::VerificationResult::kMismatch);
1526 
1527   std::string wrong_classpath_order =
1528       "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1529       ";DLC[c.dex*890]";
1530   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1531             ClassLoaderContext::VerificationResult::kMismatch);
1532 
1533   std::string wrong_checksum =
1534       "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1535       ";DLC[c.dex*890]";
1536   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1537             ClassLoaderContext::VerificationResult::kMismatch);
1538 
1539   std::string wrong_extra_class_loader =
1540       "PCL[a.dex*123:b.dex*456]"
1541       "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1542       ";DLC[c.dex*890]";
1543   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1544             ClassLoaderContext::VerificationResult::kMismatch);
1545 
1546   std::string wrong_extra_classpath =
1547       "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321:i.dex#444];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1548       ";DLC[c.dex*890]";
1549   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1550             ClassLoaderContext::VerificationResult::kMismatch);
1551 }
1552 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchWithIMCSL)1553 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) {
1554   std::string context_spec =
1555       "IMC[<unknown>*123:<unknown>*456]"
1556       "{IMC[<unknown>*321];IMC[<unknown>*654]#IMC[<unknown>*098:<unknown>*999]};"
1557       "DLC[c.dex*890]";
1558   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1559   // Pretend that we successfully open the dex files to pass the DCHECKS.
1560   // (as it's much easier to test all the corner cases without relying on actual dex files).
1561   PretendContextOpenedDexFiles(context.get());
1562 
1563   VerifyContextSize(context.get(), 2);
1564   VerifyClassLoaderIMC(context.get(), 0, "<unknown>:<unknown>");
1565   VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1566   VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "<unknown>");
1567   VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "<unknown>:<unknown>");
1568 
1569   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1570             ClassLoaderContext::VerificationResult::kVerifies);
1571 }
1572 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchAfterEncoding)1573 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1574   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1575   jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1576   jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1577   jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1578 
1579   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1580 
1581   std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1582   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1583             ClassLoaderContext::VerificationResult::kVerifies);
1584 
1585   std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1586   size_t pos = dex_location.rfind('/');
1587   ASSERT_NE(std::string::npos, pos);
1588   std::string parent = dex_location.substr(0, pos);
1589 
1590   std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1591   ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1592   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1593             ClassLoaderContext::VerificationResult::kVerifies);
1594 }
1595 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchAfterEncodingIMC)1596 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingIMC) {
1597   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1598   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1599   jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1600   jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1601 
1602   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1603 
1604   std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1605   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1606             ClassLoaderContext::VerificationResult::kVerifies);
1607 
1608   std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1609   size_t pos = dex_location.rfind('/');
1610   ASSERT_NE(std::string::npos, pos);
1611   std::string parent = dex_location.substr(0, pos);
1612 
1613   std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1614   ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1615   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1616             ClassLoaderContext::VerificationResult::kVerifies);
1617 }
1618 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchAfterEncodingMultidex)1619 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1620   jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1621 
1622   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1623 
1624   std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1625   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1626             ClassLoaderContext::VerificationResult::kVerifies);
1627 
1628   std::string dex_location = GetTestDexFileName("MultiDex");
1629   size_t pos = dex_location.rfind('/');
1630   ASSERT_NE(std::string::npos, pos);
1631   std::string parent = dex_location.substr(0, pos);
1632 
1633   std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1634   ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1635   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1636             ClassLoaderContext::VerificationResult::kVerifies);
1637 }
1638 
TEST_F(ClassLoaderContextTest,CreateContextForClassLoaderWithSharedLibraries)1639 TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) {
1640   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1641 
1642   ScopedObjectAccess soa(Thread::Current());
1643   StackHandleScope<1> hs(soa.Self());
1644   Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1645     mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1646         soa.Self(),
1647         GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1648         1));
1649   libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1650 
1651   jobject class_loader_b = LoadDexInPathClassLoader(
1652       "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1653 
1654   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1655   ASSERT_TRUE(context != nullptr);
1656   std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB");
1657   VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation());
1658   dex_files = OpenTestDexFiles("ForClassLoaderA");
1659   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation());
1660 
1661   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1662             ClassLoaderContext::VerificationResult::kVerifies);
1663 }
1664 
TEST_F(ClassLoaderContextTest,CheckForDuplicateDexFilesNotFoundSingleCL)1665 TEST_F(ClassLoaderContextTest, CheckForDuplicateDexFilesNotFoundSingleCL) {
1666   jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1667 
1668   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1669 
1670   std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(
1671       std::vector<const DexFile*>());
1672   ASSERT_EQ(0u, result.size());
1673 
1674   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("ForClassLoaderA");
1675   std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1676   result = context->CheckForDuplicateDexFiles(dex1_raw);
1677   ASSERT_EQ(0u, result.size());
1678 }
1679 
TEST_F(ClassLoaderContextTest,CheckForDuplicateDexFilesFound)1680 TEST_F(ClassLoaderContextTest, CheckForDuplicateDexFilesFound) {
1681   jobject class_loader = LoadDexInPathClassLoader(std::vector<std::string> { "Main", "Main" }, nullptr);
1682 
1683   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1684 
1685   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1686   std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1687   std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(dex1_raw);
1688   ASSERT_EQ(1u, result.size()) << context->EncodeContextForOatFile("");
1689   ASSERT_EQ(dex1_raw[0], *(result.begin()));
1690 }
1691 
1692 
TEST_F(ClassLoaderContextTest,CheckForDuplicateCrossCLNotFound)1693 TEST_F(ClassLoaderContextTest, CheckForDuplicateCrossCLNotFound) {
1694   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1695   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1696 
1697   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1698 
1699   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("ForClassLoaderA");
1700   std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1701   std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(dex1_raw);
1702   ASSERT_EQ(0u, result.size());
1703 }
1704 
1705 }  // namespace art
1706