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