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