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