• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 "hidden_api.h"
18 
19 #include <fstream>
20 #include <sstream>
21 
22 #include "android-base/stringprintf.h"
23 #include "base/file_utils.h"
24 #include "base/sdk_version.h"
25 #include "base/stl_util.h"
26 #include "common_runtime_test.h"
27 #include "jni/jni_internal.h"
28 #include "proxy_test.h"
29 #include "well_known_classes-inl.h"
30 
31 namespace art HIDDEN {
32 
33 using android::base::StringPrintf;
34 using hiddenapi::detail::MemberSignature;
35 using hiddenapi::detail::ShouldDenyAccessToMemberImpl;
36 
37 // Should be the same as dalvik.system.VMRuntime.HIDE_MAXTARGETSDK_P_HIDDEN_APIS,
38 // dalvik.system.VMRuntime.HIDE_MAXTARGETSDK_Q_HIDDEN_APIS, and
39 // dalvik.system.VMRuntime.EXEMPT_TEST_API_ACCESS_VERIFICATION.
40 static constexpr uint64_t kHideMaxtargetsdkPHiddenApis = 149997251;
41 static constexpr uint64_t kHideMaxtargetsdkQHiddenApis = 149994052;
42 static constexpr uint64_t kAllowTestApiAccess = 166236554;
43 
44 
Copy(const char * src_filename,File * dst,std::string * error_msg)45 static bool Copy(const char* src_filename, File* dst, /*out*/ std::string* error_msg) {
46   std::unique_ptr<File> src(OS::OpenFileForReading(src_filename));
47   if (src == nullptr) {
48     *error_msg = StringPrintf("Failed to open for reading: %s", src_filename);
49     return false;
50   }
51   int64_t length = src->GetLength();
52   if (length < 0) {
53     *error_msg = "Failed to get file length.";
54     return false;
55   }
56   if (!dst->Copy(src.get(), /*offset=*/ 0, length)) {
57     *error_msg = "Failed to copy file contents.";
58     return false;
59   }
60   if (dst->Flush() != 0) {
61     *error_msg = "Failed to flush.";
62     return false;
63   }
64   return true;
65 }
66 
LoadDexFiles(const std::string & path,Thread * self,std::vector<std::unique_ptr<const DexFile>> * dex_files,ObjPtr<mirror::ClassLoader> * class_loader,std::string * error_msg)67 static bool LoadDexFiles(const std::string& path,
68                          Thread* self,
69                          /* out */ std::vector<std::unique_ptr<const DexFile>>* dex_files,
70                          /* out */ ObjPtr<mirror::ClassLoader>* class_loader,
71                          /* out */ std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
72   ArtDexFileLoader dex_file_loader(path);
73   if (!dex_file_loader.Open(/* verify= */ true,
74                             /* verify_checksum= */ true,
75                             error_msg,
76                             dex_files)) {
77     return false;
78   }
79 
80   ClassLinker* const linker = Runtime::Current()->GetClassLinker();
81 
82   StackHandleScope<2> hs(self);
83   Handle<mirror::Class> h_class =
84       hs.NewHandle(WellKnownClasses::dalvik_system_PathClassLoader.Get());
85   Handle<mirror::ClassLoader> h_loader = hs.NewHandle(linker->CreateWellKnownClassLoader(
86       self,
87       MakeNonOwningPointerVector(*dex_files),
88       h_class,
89       /* parent_loader= */ ScopedNullHandle<mirror::ClassLoader>(),
90       /* shared_libraries= */ ScopedNullHandle<mirror::ObjectArray<mirror::ClassLoader>>(),
91       /* shared_libraries_after= */ ScopedNullHandle<mirror::ObjectArray<mirror::ClassLoader>>()));
92   for (const auto& dex_file : *dex_files) {
93     linker->RegisterDexFile(*dex_file.get(), h_loader.Get());
94   }
95 
96   *class_loader = h_loader.Get();
97   return true;
98 }
99 
Remove(const char * path,std::string * error_msg)100 static bool Remove(const char* path, /*out*/ std::string* error_msg) {
101   if (TEMP_FAILURE_RETRY(remove(path)) == 0) {
102     return true;
103   }
104   *error_msg = StringPrintf("Unable to remove(\"%s\"): %s", path, strerror(errno));
105   return false;
106 }
107 
CheckAllDexFilesInDomain(ObjPtr<mirror::ClassLoader> loader,const std::vector<std::unique_ptr<const DexFile>> & dex_files,hiddenapi::Domain expected_domain,std::string * error_msg)108 static bool CheckAllDexFilesInDomain(ObjPtr<mirror::ClassLoader> loader,
109                                      const std::vector<std::unique_ptr<const DexFile>>& dex_files,
110                                      hiddenapi::Domain expected_domain,
111                                      /* out */ std::string* error_msg)
112     REQUIRES_SHARED(Locks::mutator_lock_) {
113   for (const auto& dex_file : dex_files) {
114     hiddenapi::AccessContext context(loader, dex_file.get());
115     if (context.GetDomain() != expected_domain) {
116       std::stringstream ss;
117       ss << dex_file->GetLocation() << ": access context domain does not match "
118           << "(expected=" << static_cast<uint32_t>(expected_domain)
119           << ", actual=" << static_cast<uint32_t>(context.GetDomain()) << ")";
120       *error_msg = ss.str();
121       return false;
122     }
123     if (dex_file->GetHiddenapiDomain() != expected_domain) {
124       std::stringstream ss;
125       ss << dex_file->GetLocation() << ": dex file domain does not match "
126           << "(expected=" << static_cast<uint32_t>(expected_domain)
127           << ", actual=" << static_cast<uint32_t>(dex_file->GetHiddenapiDomain()) << ")";
128       *error_msg = ss.str();
129       return false;
130     }
131   }
132 
133   return true;
134 }
135 
136 class HiddenApiTest : public CommonRuntimeTest {
137  protected:
SetUp()138   void SetUp() override {
139     // Do the normal setup.
140     CommonRuntimeTest::SetUp();
141     self_ = Thread::Current();
142     self_->TransitionFromSuspendedToRunnable();
143     jclass_loader_ = LoadDex("HiddenApiSignatures");
144     bool started = runtime_->Start();
145     CHECK(started);
146 
147     class1_field1_ = GetArtField("mypackage/packagea/Class1", "field1", "I");
148     class1_field12_ = GetArtField("mypackage/packagea/Class1", "field12", "I");
149     class1_init_ = GetArtMethod("mypackage/packagea/Class1", "<init>", "()V");
150     class1_method1_ = GetArtMethod("mypackage/packagea/Class1", "method1", "()V");
151     class1_method1_i_ = GetArtMethod("mypackage/packagea/Class1", "method1", "(I)V");
152     class1_method12_ = GetArtMethod("mypackage/packagea/Class1", "method12", "()V");
153     class12_field1_ = GetArtField("mypackage/packagea/Class12", "field1", "I");
154     class12_method1_ = GetArtMethod("mypackage/packagea/Class12", "method1", "()V");
155     class2_field1_ = GetArtField("mypackage/packagea/Class2", "field1", "I");
156     class2_method1_ = GetArtMethod("mypackage/packagea/Class2", "method1", "()V");
157     class2_method1_i_ = GetArtMethod("mypackage/packagea/Class2", "method1", "(I)V");
158     class3_field1_ = GetArtField("mypackage/packageb/Class3", "field1", "I");
159     class3_method1_ = GetArtMethod("mypackage/packageb/Class3", "method1", "()V");
160     class3_method1_i_ = GetArtMethod("mypackage/packageb/Class3", "method1", "(I)V");
161   }
162 
GetArtMethod(const char * class_name,const char * name,const char * signature)163   ArtMethod* GetArtMethod(const char* class_name, const char* name, const char* signature) {
164     JNIEnv* env = Thread::Current()->GetJniEnv();
165     jclass klass = env->FindClass(class_name);
166     jmethodID method_id = env->GetMethodID(klass, name, signature);
167     ArtMethod* art_method = jni::DecodeArtMethod(method_id);
168     return art_method;
169   }
170 
GetArtField(const char * class_name,const char * name,const char * signature)171   ArtField* GetArtField(const char* class_name, const char* name, const char* signature) {
172     JNIEnv* env = Thread::Current()->GetJniEnv();
173     jclass klass = env->FindClass(class_name);
174     jfieldID field_id = env->GetFieldID(klass, name, signature);
175     ArtField* art_field = jni::DecodeArtField(field_id);
176     return art_field;
177   }
178 
SetChangeIdState(uint64_t change,bool enabled)179   void SetChangeIdState(uint64_t change, bool enabled) {
180     CompatFramework& compat_framework = runtime_->GetCompatFramework();
181     std::set<uint64_t> disabled_changes = compat_framework.GetDisabledCompatChanges();
182     if (enabled) {
183       disabled_changes.erase(change);
184     } else {
185       disabled_changes.insert(change);
186     }
187     compat_framework.SetDisabledCompatChanges(disabled_changes);
188   }
189 
ShouldDenyAccess(hiddenapi::ApiList list)190   bool ShouldDenyAccess(hiddenapi::ApiList list) REQUIRES_SHARED(Locks::mutator_lock_) {
191     // Choose parameters such that there are no side effects (AccessMethod::kNone)
192     // and that the member is not on the exemptions list (here we choose one which
193     // is not even in boot class path).
194     return ShouldDenyAccessToMemberImpl(/* member= */ class1_field1_,
195                                         list,
196                                         /* access_method= */ hiddenapi::AccessMethod::kNone);
197   }
198 
TestLocation(const std::string & location,hiddenapi::Domain expected_domain)199   void TestLocation(const std::string& location, hiddenapi::Domain expected_domain) {
200     // Create a temp file with a unique name based on `location` to isolate tests
201     // that may run in parallel. b/238730923
202     const std::string_view suffix = ".jar";
203     const std::string_view placeholder = "XXXXXX";  // See `mkstemps()`.
204     ASSERT_TRUE(location.ends_with(suffix));
205     std::unique_ptr<char[]> unique_location(new char[location.length() + placeholder.length() + 1]);
206     ASSERT_TRUE(unique_location != nullptr);
207     size_t stem_length = location.length() - suffix.length();
208     memcpy(unique_location.get(), location.data(), stem_length);
209     memcpy(unique_location.get() + stem_length, placeholder.data(), placeholder.length());
210     memcpy(unique_location.get() + stem_length + placeholder.length(),
211            location.data() + stem_length,
212            suffix.length());
213     unique_location[location.length() + placeholder.length()] = 0;
214     int fd = mkstemps(unique_location.get(), suffix.length());
215     ASSERT_TRUE(fd != -1) << strerror(errno);
216 
217     // Copy "Main" to the temp file.
218     std::string error_msg;
219     {
220       File file(fd, /*check_usage=*/ true);
221       bool copied = Copy(GetTestDexFileName("Main").c_str(), &file, &error_msg);
222       int flush_close_result = file.FlushCloseOrErase();
223       if (!copied && flush_close_result == 0) {
224         // Silently remove the temp file before reporting the `Copy()` failure.
225         std::string ignored_error_msg;
226         Remove(unique_location.get(), &ignored_error_msg);
227       }
228       ASSERT_TRUE(copied) << error_msg;
229       ASSERT_EQ(flush_close_result, 0);
230     }
231 
232     ScopedObjectAccess soa(Thread::Current());
233     std::vector<std::unique_ptr<const DexFile>> dex_files;
234     ObjPtr<mirror::ClassLoader> class_loader;
235     ASSERT_TRUE(
236         LoadDexFiles(unique_location.get(), soa.Self(), &dex_files, &class_loader, &error_msg))
237         << error_msg;
238     ASSERT_GE(dex_files.size(), 1u);
239     ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
240                                          dex_files,
241                                          expected_domain,
242                                          &error_msg)) << error_msg;
243 
244     dex_files.clear();
245     ASSERT_TRUE(Remove(unique_location.get(), &error_msg)) << error_msg;
246   }
247 
248  protected:
249   Thread* self_;
250   jobject jclass_loader_;
251   ArtField* class1_field1_;
252   ArtField* class1_field12_;
253   ArtMethod* class1_init_;
254   ArtMethod* class1_method1_;
255   ArtMethod* class1_method1_i_;
256   ArtMethod* class1_method12_;
257   ArtField* class12_field1_;
258   ArtMethod* class12_method1_;
259   ArtField* class2_field1_;
260   ArtMethod* class2_method1_;
261   ArtMethod* class2_method1_i_;
262   ArtField* class3_field1_;
263   ArtMethod* class3_method1_;
264   ArtMethod* class3_method1_i_;
265 };
266 
TEST_F(HiddenApiTest,CheckGetActionFromRuntimeFlags)267 TEST_F(HiddenApiTest, CheckGetActionFromRuntimeFlags) {
268   ScopedObjectAccess soa(self_);
269 
270   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kJustWarn);
271   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
272   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
273   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
274   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
275   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
276   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
277   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), false);
278   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), false);
279 
280   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
281   runtime_->SetTargetSdkVersion(
282       static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetO().GetMaxAllowedSdkVersion()));
283   SetChangeIdState(kHideMaxtargetsdkPHiddenApis, false);
284   SetChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
285   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
286   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
287   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
288   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
289   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
290   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
291   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), false);
292   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
293 
294   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
295   runtime_->SetTargetSdkVersion(
296       static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetO().GetMaxAllowedSdkVersion()) + 1);
297   SetChangeIdState(kHideMaxtargetsdkPHiddenApis, false);
298   SetChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
299   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
300   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
301   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
302   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
303   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
304   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
305   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
306   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
307   SetChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
308   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
309   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
310   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
311   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
312   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
313   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
314   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
315   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
316 
317   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
318   runtime_->SetTargetSdkVersion(
319       static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetP().GetMaxAllowedSdkVersion()) + 1);
320   SetChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
321   SetChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
322   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
323   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
324   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
325   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
326   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
327   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
328   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
329   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
330 
331   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
332   runtime_->SetTargetSdkVersion(
333       static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetQ().GetMaxAllowedSdkVersion()) + 1);
334   SetChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
335   SetChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
336   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
337   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
338   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
339   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
340   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
341   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
342   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
343   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
344 
345   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
346   runtime_->SetTargetSdkVersion(
347       static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetR().GetMaxAllowedSdkVersion()) + 1);
348   SetChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
349   SetChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
350   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
351   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
352   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
353   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), true);
354   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
355   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
356   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
357   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
358 
359   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
360   runtime_->SetTargetSdkVersion(
361       static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetS().GetMaxAllowedSdkVersion()) + 1);
362   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
363   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
364   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), true);
365   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), true);
366   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
367   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
368   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
369   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
370 }
371 
TEST_F(HiddenApiTest,CheckTestApiEnforcement)372 TEST_F(HiddenApiTest, CheckTestApiEnforcement) {
373   ScopedObjectAccess soa(self_);
374 
375   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
376   runtime_->SetTargetSdkVersion(
377       static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetR().GetMaxAllowedSdkVersion()) + 1);
378 
379   // Default case where all TestApis are treated like non-TestApi.
380   runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
381   SetChangeIdState(kAllowTestApiAccess, false);
382   ASSERT_EQ(
383       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Sdk()), false);
384   ASSERT_EQ(
385       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Unsupported()), false);
386   ASSERT_EQ(
387       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetR()), true);
388   ASSERT_EQ(
389       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetQ()), true);
390   ASSERT_EQ(
391       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetP()), true);
392   ASSERT_EQ(
393       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetO()), true);
394   ASSERT_EQ(
395       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Blocked()), true);
396 
397   // A case where we want to allow access to TestApis.
398   runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kDisabled);
399   SetChangeIdState(kAllowTestApiAccess, false);
400   ASSERT_EQ(
401       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Sdk()), false);
402   ASSERT_EQ(
403       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Unsupported()), false);
404   ASSERT_EQ(
405       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetR()), false);
406   ASSERT_EQ(
407       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetQ()), false);
408   ASSERT_EQ(
409       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetP()), false);
410   ASSERT_EQ(
411       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetO()), false);
412   ASSERT_EQ(
413       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Blocked()), false);
414 
415   // A second case where we want to allow access to TestApis.
416   runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
417   SetChangeIdState(kAllowTestApiAccess, true);
418   ASSERT_EQ(
419       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Sdk()), false);
420   ASSERT_EQ(
421       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Unsupported()), false);
422   ASSERT_EQ(
423       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetR()), false);
424   ASSERT_EQ(
425       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetQ()), false);
426   ASSERT_EQ(
427       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetP()), false);
428   ASSERT_EQ(
429       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::MaxTargetO()), false);
430   ASSERT_EQ(
431       ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Blocked()), false);
432 }
433 
TEST_F(HiddenApiTest,CheckMembersRead)434 TEST_F(HiddenApiTest, CheckMembersRead) {
435   ASSERT_NE(nullptr, class1_field1_);
436   ASSERT_NE(nullptr, class1_field12_);
437   ASSERT_NE(nullptr, class1_init_);
438   ASSERT_NE(nullptr, class1_method1_);
439   ASSERT_NE(nullptr, class1_method1_i_);
440   ASSERT_NE(nullptr, class1_method12_);
441   ASSERT_NE(nullptr, class12_field1_);
442   ASSERT_NE(nullptr, class12_method1_);
443   ASSERT_NE(nullptr, class2_field1_);
444   ASSERT_NE(nullptr, class2_method1_);
445   ASSERT_NE(nullptr, class2_method1_i_);
446   ASSERT_NE(nullptr, class3_field1_);
447   ASSERT_NE(nullptr, class3_method1_);
448   ASSERT_NE(nullptr, class3_method1_i_);
449 }
450 
TEST_F(HiddenApiTest,CheckEverythingMatchesL)451 TEST_F(HiddenApiTest, CheckEverythingMatchesL) {
452   ScopedObjectAccess soa(self_);
453   std::string prefix("L");
454   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
455   ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
456   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
457   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
458   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
459   ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
460   ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
461   ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
462   ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
463   ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
464   ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
465   ASSERT_TRUE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
466   ASSERT_TRUE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
467   ASSERT_TRUE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
468 }
469 
TEST_F(HiddenApiTest,CheckPackageMatch)470 TEST_F(HiddenApiTest, CheckPackageMatch) {
471   ScopedObjectAccess soa(self_);
472   std::string prefix("Lmypackage/packagea/");
473   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
474   ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
475   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
476   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
477   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
478   ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
479   ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
480   ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
481   ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
482   ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
483   ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
484   ASSERT_FALSE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
485   ASSERT_FALSE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
486   ASSERT_FALSE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
487 }
488 
TEST_F(HiddenApiTest,CheckClassMatch)489 TEST_F(HiddenApiTest, CheckClassMatch) {
490   ScopedObjectAccess soa(self_);
491   std::string prefix("Lmypackage/packagea/Class1");
492   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
493   ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
494   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
495   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
496   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
497   ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
498   ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
499   ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
500   ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
501   ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
502   ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
503 }
504 
TEST_F(HiddenApiTest,CheckClassExactMatch)505 TEST_F(HiddenApiTest, CheckClassExactMatch) {
506   ScopedObjectAccess soa(self_);
507   std::string prefix("Lmypackage/packagea/Class1;");
508   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
509   ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
510   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
511   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
512   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
513   ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
514   ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
515   ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
516   ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
517   ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
518 }
519 
TEST_F(HiddenApiTest,CheckMethodMatch)520 TEST_F(HiddenApiTest, CheckMethodMatch) {
521   ScopedObjectAccess soa(self_);
522   std::string prefix("Lmypackage/packagea/Class1;->method1");
523   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
524   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
525   ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
526   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
527   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
528   ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
529   ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
530   ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
531 }
532 
TEST_F(HiddenApiTest,CheckMethodExactMatch)533 TEST_F(HiddenApiTest, CheckMethodExactMatch) {
534   ScopedObjectAccess soa(self_);
535   std::string prefix("Lmypackage/packagea/Class1;->method1(");
536   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
537   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
538   ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
539   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
540   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
541   ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
542 }
543 
TEST_F(HiddenApiTest,CheckMethodSignatureMatch)544 TEST_F(HiddenApiTest, CheckMethodSignatureMatch) {
545   ScopedObjectAccess soa(self_);
546   std::string prefix("Lmypackage/packagea/Class1;->method1(I)");
547   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
548   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
549   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
550   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
551   ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
552 }
553 
TEST_F(HiddenApiTest,CheckMethodSignatureAndReturnMatch)554 TEST_F(HiddenApiTest, CheckMethodSignatureAndReturnMatch) {
555   ScopedObjectAccess soa(self_);
556   std::string prefix("Lmypackage/packagea/Class1;->method1()V");
557   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
558   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
559   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
560   ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
561   ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
562 }
563 
TEST_F(HiddenApiTest,CheckFieldMatch)564 TEST_F(HiddenApiTest, CheckFieldMatch) {
565   ScopedObjectAccess soa(self_);
566   std::string prefix("Lmypackage/packagea/Class1;->field1");
567   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
568   ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
569   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
570   ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
571   ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
572 }
573 
TEST_F(HiddenApiTest,CheckFieldExactMatch)574 TEST_F(HiddenApiTest, CheckFieldExactMatch) {
575   ScopedObjectAccess soa(self_);
576   std::string prefix("Lmypackage/packagea/Class1;->field1:");
577   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
578   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
579   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
580 }
581 
TEST_F(HiddenApiTest,CheckFieldTypeMatch)582 TEST_F(HiddenApiTest, CheckFieldTypeMatch) {
583   ScopedObjectAccess soa(self_);
584   std::string prefix("Lmypackage/packagea/Class1;->field1:I");
585   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
586   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
587   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
588 }
589 
TEST_F(HiddenApiTest,CheckConstructorMatch)590 TEST_F(HiddenApiTest, CheckConstructorMatch) {
591   ScopedObjectAccess soa(self_);
592   std::string prefix("Lmypackage/packagea/Class1;-><init>");
593   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
594   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
595 }
596 
TEST_F(HiddenApiTest,CheckConstructorExactMatch)597 TEST_F(HiddenApiTest, CheckConstructorExactMatch) {
598   ScopedObjectAccess soa(self_);
599   std::string prefix("Lmypackage/packagea/Class1;-><init>()V");
600   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
601   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
602 }
603 
TEST_F(HiddenApiTest,CheckMethodSignatureTrailingCharsNoMatch)604 TEST_F(HiddenApiTest, CheckMethodSignatureTrailingCharsNoMatch) {
605   ScopedObjectAccess soa(self_);
606   std::string prefix("Lmypackage/packagea/Class1;->method1()Vfoo");
607   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
608 }
609 
TEST_F(HiddenApiTest,CheckConstructorTrailingCharsNoMatch)610 TEST_F(HiddenApiTest, CheckConstructorTrailingCharsNoMatch) {
611   ScopedObjectAccess soa(self_);
612   std::string prefix("Lmypackage/packagea/Class1;-><init>()Vfoo");
613   ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
614 }
615 
TEST_F(HiddenApiTest,CheckFieldTrailingCharsNoMatch)616 TEST_F(HiddenApiTest, CheckFieldTrailingCharsNoMatch) {
617   ScopedObjectAccess soa(self_);
618   std::string prefix("Lmypackage/packagea/Class1;->field1:Ifoo");
619   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
620 }
621 
TEST_F(HiddenApiTest,CheckMemberSignatureForProxyClass)622 TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) {
623   ScopedObjectAccess soa(self_);
624   StackHandleScope<4> hs(soa.Self());
625   Handle<mirror::ClassLoader> class_loader(
626       hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader_)));
627 
628   // Find interface we will create a proxy for.
629   Handle<mirror::Class> h_iface(hs.NewHandle(
630       class_linker_->FindClass(soa.Self(), "Lmypackage/packagea/Interface;", class_loader)));
631   ASSERT_TRUE(h_iface != nullptr);
632 
633   // Create the proxy class.
634   std::vector<Handle<mirror::Class>> interfaces;
635   interfaces.push_back(h_iface);
636   Handle<mirror::Class> proxyClass = hs.NewHandle(proxy_test::GenerateProxyClass(
637       soa, jclass_loader_, runtime_->GetClassLinker(), "$Proxy1234", interfaces));
638   ASSERT_TRUE(proxyClass != nullptr);
639   ASSERT_TRUE(proxyClass->IsProxyClass());
640   ASSERT_TRUE(proxyClass->IsInitialized());
641 
642   // Find the "method" virtual method.
643   ArtMethod* method = nullptr;
644   for (auto& m : proxyClass->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
645     if (strcmp("method", m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetName()) == 0) {
646       method = &m;
647       break;
648     }
649   }
650   ASSERT_TRUE(method != nullptr);
651 
652   // Find the "interfaces" static field. This is generated for all proxies.
653   ArtField* field = nullptr;
654   for (size_t i = 0; i < proxyClass->NumStaticFields(); ++i) {
655     ArtField* f = proxyClass->GetStaticField(i);
656     if (strcmp("interfaces", f->GetName()) == 0) {
657       field = f;
658       break;
659     }
660   }
661   ASSERT_TRUE(field != nullptr);
662 
663   // Test the signature. We expect the signature from the interface class.
664   std::ostringstream ss_method;
665   MemberSignature(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)).Dump(ss_method);
666   ASSERT_EQ("Lmypackage/packagea/Interface;->method()V", ss_method.str());
667 
668   // Test the signature. We expect the signature of the proxy class.
669   std::ostringstream ss_field;
670   MemberSignature(field).Dump(ss_field);
671   ASSERT_EQ("L$Proxy1234;->interfaces:[Ljava/lang/Class;", ss_field.str());
672 }
673 
TEST_F(HiddenApiTest,DexDomain_DataDir)674 TEST_F(HiddenApiTest, DexDomain_DataDir) {
675   // Load file from a non-system directory and check that it is not flagged as framework.
676   std::string data_location_path = android_data_ + "/foo.jar";
677   ASSERT_FALSE(LocationIsOnSystemFramework(data_location_path));
678   TestLocation(data_location_path, hiddenapi::Domain::kApplication);
679 }
680 
TEST_F(HiddenApiTest,DexDomain_SystemDir)681 TEST_F(HiddenApiTest, DexDomain_SystemDir) {
682   // Load file from a system, non-framework directory and check that it is not flagged as framework.
683   std::string system_location_path = GetAndroidRoot() + "/foo.jar";
684   ASSERT_FALSE(LocationIsOnSystemFramework(system_location_path));
685   TestLocation(system_location_path, hiddenapi::Domain::kApplication);
686 }
687 
TEST_F(HiddenApiTest,DexDomain_SystemExtDir)688 TEST_F(HiddenApiTest, DexDomain_SystemExtDir) {
689   // Load file from a system_ext, non-framework directory and check that it is not flagged as
690   // framework.
691   std::string system_ext_location_path = android_system_ext_ + "/foo.jar";
692   ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_location_path));
693   TestLocation(system_ext_location_path, hiddenapi::Domain::kApplication);
694 }
695 
TEST_F(HiddenApiTest,DexDomain_SystemSystemExtDir)696 TEST_F(HiddenApiTest, DexDomain_SystemSystemExtDir) {
697   // Load file from a system/system_ext, non-framework directory and check that it is not flagged as
698   // framework.
699   std::filesystem::create_directory(GetAndroidRoot() + "/system_ext");
700   std::string system_ext_location_path =  GetAndroidRoot() + "/system_ext/foo.jar";
701   ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_location_path));
702   TestLocation(system_ext_location_path, hiddenapi::Domain::kApplication);
703 }
704 
TEST_F(HiddenApiTest,DexDomain_SystemFrameworkDir)705 TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir) {
706   // Load file from a system/framework directory and check that it is flagged as a framework dex.
707   std::filesystem::create_directory(GetAndroidRoot() + "/framework");
708   std::string system_framework_location_path = GetAndroidRoot() + "/framework/foo.jar";
709   ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_location_path));
710   TestLocation(system_framework_location_path, hiddenapi::Domain::kPlatform);
711 }
712 
TEST_F(HiddenApiTest,DexDomain_SystemExtFrameworkDir)713 TEST_F(HiddenApiTest, DexDomain_SystemExtFrameworkDir) {
714   // Load file from a system_ext/framework directory and check that it is flagged as a framework dex.
715   std::filesystem::create_directory(android_system_ext_ + "/framework");
716   std::string system_ext_framework_location_path = android_system_ext_ + "/framework/foo.jar";
717   ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_location_path));
718   TestLocation(system_ext_framework_location_path, hiddenapi::Domain::kPlatform);
719 }
720 
TEST_F(HiddenApiTest,DexDomain_SystemSystemExtFrameworkDir)721 TEST_F(HiddenApiTest, DexDomain_SystemSystemExtFrameworkDir) {
722   // Load file from a system/system_ext/framework directory and check that it is flagged as a
723   // framework dex.
724   std::filesystem::create_directory(GetAndroidRoot() + "/system_ext");
725   std::filesystem::create_directory(GetAndroidRoot() + "/system_ext/framework");
726   std::string system_ext_framework_location_path =
727        GetAndroidRoot() + "/system_ext/framework/foo.jar";
728   ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_location_path));
729   TestLocation(system_ext_framework_location_path, hiddenapi::Domain::kPlatform);
730 }
731 
TEST_F(HiddenApiTest,DexDomain_DataDir_MultiDex)732 TEST_F(HiddenApiTest, DexDomain_DataDir_MultiDex) {
733   // Load multidex file from a non-system directory and check that it is not flagged as framework.
734   std::string data_multi_location_path = android_data_ + "/multifoo.jar";
735   ASSERT_FALSE(LocationIsOnSystemFramework(data_multi_location_path));
736   TestLocation(data_multi_location_path, hiddenapi::Domain::kApplication);
737 }
738 
TEST_F(HiddenApiTest,DexDomain_SystemDir_MultiDex)739 TEST_F(HiddenApiTest, DexDomain_SystemDir_MultiDex) {
740   // Load multidex file from a system, non-framework directory and check that it is not flagged
741   // as framework.
742   std::string system_multi_location_path = GetAndroidRoot() + "/multifoo.jar";
743   ASSERT_FALSE(LocationIsOnSystemFramework(system_multi_location_path));
744   TestLocation(system_multi_location_path, hiddenapi::Domain::kApplication);
745 }
746 
TEST_F(HiddenApiTest,DexDomain_SystemExtDir_MultiDex)747 TEST_F(HiddenApiTest, DexDomain_SystemExtDir_MultiDex) {
748   // Load multidex file from a system_ext, non-framework directory and check that it is not flagged
749   // as framework.
750   std::string system_ext_multi_location_path = android_system_ext_ + "/multifoo.jar";
751   ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_multi_location_path));
752   TestLocation(system_ext_multi_location_path, hiddenapi::Domain::kApplication);
753 }
754 
TEST_F(HiddenApiTest,DexDomain_SystemSystemExtDir_MultiDex)755 TEST_F(HiddenApiTest, DexDomain_SystemSystemExtDir_MultiDex) {
756   // Load multidex file from a system/system_ext, non-framework directory and check that it is not
757   // flagged as framework.
758   std::filesystem::create_directory(GetAndroidRoot() + "/system_ext");
759   std::string system_ext_multi_location_path =
760       GetAndroidRoot() + "/system_ext/multifoo.jar";
761   ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_multi_location_path));
762   TestLocation(system_ext_multi_location_path, hiddenapi::Domain::kApplication);
763 }
764 
TEST_F(HiddenApiTest,DexDomain_SystemFrameworkDir_MultiDex)765 TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir_MultiDex) {
766   // Load multidex file from a system/framework directory and check that it is flagged as a
767   // framework dex.
768   std::filesystem::create_directory(GetAndroidRoot() + "/framework");
769   std::string system_framework_multi_location_path = GetAndroidRoot() + "/framework/multifoo.jar";
770   ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_multi_location_path));
771   TestLocation(system_framework_multi_location_path, hiddenapi::Domain::kPlatform);
772 }
773 
TEST_F(HiddenApiTest,DexDomain_SystemExtFrameworkDir_MultiDex)774 TEST_F(HiddenApiTest, DexDomain_SystemExtFrameworkDir_MultiDex) {
775   // Load multidex file from a system_ext/framework directory and check that it is flagged as a
776   // framework dex.
777   std::filesystem::create_directory(android_system_ext_ + "/framework");
778   std::string system_ext_framework_multi_location_path =
779       android_system_ext_ + "/framework/multifoo.jar";
780   ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_multi_location_path));
781   TestLocation(system_ext_framework_multi_location_path, hiddenapi::Domain::kPlatform);
782 }
783 
TEST_F(HiddenApiTest,DexDomain_SystemSystemExtFrameworkDir_MultiDex)784 TEST_F(HiddenApiTest, DexDomain_SystemSystemExtFrameworkDir_MultiDex) {
785   // Load multidex file from a system/system_ext/framework directory and check that it is flagged
786   // as a framework dex.
787   std::filesystem::create_directory(GetAndroidRoot() + "/system_ext");
788   std::filesystem::create_directory(GetAndroidRoot() + "/system_ext/framework");
789   std::string system_ext_framework_multi_location_path =
790        GetAndroidRoot() + "/system_ext/framework/multifoo.jar";
791   ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_multi_location_path));
792   TestLocation(system_ext_framework_multi_location_path, hiddenapi::Domain::kPlatform);
793 }
794 
795 }  // namespace art
796