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 // This is only used for log messages, so its state doesn't matter.
192 const hiddenapi::AccessContext placeholder_context(/* is_trusted= */ false);
193
194 // Choose parameters such that there are no side effects (AccessMethod::kCheck)
195 // and that the member is not on the exemptions list (here we choose one which
196 // is not even in boot class path).
197 return ShouldDenyAccessToMemberImpl(/* member= */ class1_field1_,
198 list,
199 /* runtime_flags= */ 0,
200 /* caller_context= */ placeholder_context,
201 /* callee_context= */ placeholder_context,
202 hiddenapi::AccessMethod::kCheck);
203 }
204
ShouldDenyAccess(hiddenapi::ApiList list1,hiddenapi::ApiList list2)205 bool ShouldDenyAccess(hiddenapi::ApiList list1, hiddenapi::ApiList list2)
206 REQUIRES_SHARED(Locks::mutator_lock_) {
207 return ShouldDenyAccess(hiddenapi::ApiList::Combine(list1, list2));
208 }
209
TestLocation(const std::string & location,hiddenapi::Domain expected_domain)210 void TestLocation(const std::string& location, hiddenapi::Domain expected_domain) {
211 // Create a temp file with a unique name based on `location` to isolate tests
212 // that may run in parallel. b/238730923
213 const std::string_view suffix = ".jar";
214 const std::string_view placeholder = "XXXXXX"; // See `mkstemps()`.
215 ASSERT_TRUE(location.ends_with(suffix));
216 std::unique_ptr<char[]> unique_location(new char[location.length() + placeholder.length() + 1]);
217 ASSERT_TRUE(unique_location != nullptr);
218 size_t stem_length = location.length() - suffix.length();
219 memcpy(unique_location.get(), location.data(), stem_length);
220 memcpy(unique_location.get() + stem_length, placeholder.data(), placeholder.length());
221 memcpy(unique_location.get() + stem_length + placeholder.length(),
222 location.data() + stem_length,
223 suffix.length());
224 unique_location[location.length() + placeholder.length()] = 0;
225 int fd = mkstemps(unique_location.get(), suffix.length());
226 ASSERT_TRUE(fd != -1) << strerror(errno);
227
228 // Copy "Main" to the temp file.
229 std::string error_msg;
230 {
231 File file(fd, /*check_usage=*/ true);
232 bool copied = Copy(GetTestDexFileName("Main").c_str(), &file, &error_msg);
233 int flush_close_result = file.FlushCloseOrErase();
234 if (!copied && flush_close_result == 0) {
235 // Silently remove the temp file before reporting the `Copy()` failure.
236 std::string ignored_error_msg;
237 Remove(unique_location.get(), &ignored_error_msg);
238 }
239 ASSERT_TRUE(copied) << error_msg;
240 ASSERT_EQ(flush_close_result, 0);
241 }
242
243 ScopedObjectAccess soa(Thread::Current());
244 std::vector<std::unique_ptr<const DexFile>> dex_files;
245 ObjPtr<mirror::ClassLoader> class_loader;
246 ASSERT_TRUE(
247 LoadDexFiles(unique_location.get(), soa.Self(), &dex_files, &class_loader, &error_msg))
248 << error_msg;
249 ASSERT_GE(dex_files.size(), 1u);
250 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
251 dex_files,
252 expected_domain,
253 &error_msg)) << error_msg;
254
255 dex_files.clear();
256 ASSERT_TRUE(Remove(unique_location.get(), &error_msg)) << error_msg;
257 }
258
259 protected:
260 Thread* self_;
261 jobject jclass_loader_;
262 ArtField* class1_field1_;
263 ArtField* class1_field12_;
264 ArtMethod* class1_init_;
265 ArtMethod* class1_method1_;
266 ArtMethod* class1_method1_i_;
267 ArtMethod* class1_method12_;
268 ArtField* class12_field1_;
269 ArtMethod* class12_method1_;
270 ArtField* class2_field1_;
271 ArtMethod* class2_method1_;
272 ArtMethod* class2_method1_i_;
273 ArtField* class3_field1_;
274 ArtMethod* class3_method1_;
275 ArtMethod* class3_method1_i_;
276 };
277
TEST_F(HiddenApiTest,CheckGetActionFromRuntimeFlags)278 TEST_F(HiddenApiTest, CheckGetActionFromRuntimeFlags) {
279 ScopedObjectAccess soa(self_);
280
281 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kJustWarn);
282 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
283 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
284 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
285 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
286 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
287 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
288 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), false);
289 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), false);
290
291 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
292 runtime_->SetTargetSdkVersion(
293 static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetO().GetMaxAllowedSdkVersion()));
294 SetChangeIdState(kHideMaxtargetsdkPHiddenApis, false);
295 SetChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
296 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
297 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
298 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
299 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
300 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
301 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
302 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), false);
303 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
304
305 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
306 runtime_->SetTargetSdkVersion(
307 static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetO().GetMaxAllowedSdkVersion()) + 1);
308 SetChangeIdState(kHideMaxtargetsdkPHiddenApis, false);
309 SetChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
310 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
311 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
312 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
313 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
314 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
315 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
316 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
317 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
318 SetChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
319 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
320 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
321 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
322 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
323 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
324 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
325 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
326 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
327
328 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
329 runtime_->SetTargetSdkVersion(
330 static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetP().GetMaxAllowedSdkVersion()) + 1);
331 SetChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
332 SetChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
333 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
334 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
335 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
336 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
337 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
338 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
339 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
340 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
341
342 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
343 runtime_->SetTargetSdkVersion(
344 static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetQ().GetMaxAllowedSdkVersion()) + 1);
345 SetChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
346 SetChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
347 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
348 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
349 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
350 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
351 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
352 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
353 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
354 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
355
356 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
357 runtime_->SetTargetSdkVersion(
358 static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetR().GetMaxAllowedSdkVersion()) + 1);
359 SetChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
360 SetChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
361 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
362 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
363 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
364 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), true);
365 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
366 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
367 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
368 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
369
370 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
371 runtime_->SetTargetSdkVersion(
372 static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetS().GetMaxAllowedSdkVersion()) + 1);
373 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
374 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
375 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), true);
376 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), true);
377 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
378 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
379 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
380 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
381 }
382
TEST_F(HiddenApiTest,CheckTestApiEnforcement)383 TEST_F(HiddenApiTest, CheckTestApiEnforcement) {
384 ScopedObjectAccess soa(self_);
385
386 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
387 runtime_->SetTargetSdkVersion(
388 static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetR().GetMaxAllowedSdkVersion()) + 1);
389
390 // clang-format off
391
392 // Default case where all TestApis are treated like non-TestApi.
393 runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
394 SetChangeIdState(kAllowTestApiAccess, false);
395 ASSERT_EQ(
396 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Sdk()), false);
397 ASSERT_EQ(
398 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Unsupported()), false);
399 ASSERT_EQ(
400 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetR()), true);
401 ASSERT_EQ(
402 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetQ()), true);
403 ASSERT_EQ(
404 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetP()), true);
405 ASSERT_EQ(
406 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetO()), true);
407 ASSERT_EQ(
408 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Blocked()), true);
409
410 // A case where we want to allow access to TestApis.
411 runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kDisabled);
412 SetChangeIdState(kAllowTestApiAccess, false);
413 ASSERT_EQ(
414 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Sdk()), false);
415 ASSERT_EQ(
416 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Unsupported()), false);
417 ASSERT_EQ(
418 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetR()), false);
419 ASSERT_EQ(
420 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetQ()), false);
421 ASSERT_EQ(
422 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetP()), false);
423 ASSERT_EQ(
424 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetO()), false);
425 ASSERT_EQ(
426 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Blocked()), false);
427
428 // A second case where we want to allow access to TestApis.
429 runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
430 SetChangeIdState(kAllowTestApiAccess, true);
431 ASSERT_EQ(
432 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Sdk()), false);
433 ASSERT_EQ(
434 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Unsupported()), false);
435 ASSERT_EQ(
436 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetR()), false);
437 ASSERT_EQ(
438 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetQ()), false);
439 ASSERT_EQ(
440 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetP()), false);
441 ASSERT_EQ(
442 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetO()), false);
443 ASSERT_EQ(
444 ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Blocked()), false);
445
446 // clang-format on
447 }
448
TEST_F(HiddenApiTest,CheckMembersRead)449 TEST_F(HiddenApiTest, CheckMembersRead) {
450 ASSERT_NE(nullptr, class1_field1_);
451 ASSERT_NE(nullptr, class1_field12_);
452 ASSERT_NE(nullptr, class1_init_);
453 ASSERT_NE(nullptr, class1_method1_);
454 ASSERT_NE(nullptr, class1_method1_i_);
455 ASSERT_NE(nullptr, class1_method12_);
456 ASSERT_NE(nullptr, class12_field1_);
457 ASSERT_NE(nullptr, class12_method1_);
458 ASSERT_NE(nullptr, class2_field1_);
459 ASSERT_NE(nullptr, class2_method1_);
460 ASSERT_NE(nullptr, class2_method1_i_);
461 ASSERT_NE(nullptr, class3_field1_);
462 ASSERT_NE(nullptr, class3_method1_);
463 ASSERT_NE(nullptr, class3_method1_i_);
464 }
465
TEST_F(HiddenApiTest,CheckEverythingMatchesL)466 TEST_F(HiddenApiTest, CheckEverythingMatchesL) {
467 ScopedObjectAccess soa(self_);
468 std::string prefix("L");
469 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
470 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
471 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
472 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
473 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
474 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
475 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
476 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
477 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
478 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
479 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
480 ASSERT_TRUE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
481 ASSERT_TRUE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
482 ASSERT_TRUE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
483 }
484
TEST_F(HiddenApiTest,CheckPackageMatch)485 TEST_F(HiddenApiTest, CheckPackageMatch) {
486 ScopedObjectAccess soa(self_);
487 std::string prefix("Lmypackage/packagea/");
488 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
489 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
490 ASSERT_TRUE(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_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
495 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
496 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
497 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
498 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
499 ASSERT_FALSE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
500 ASSERT_FALSE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
501 ASSERT_FALSE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
502 }
503
TEST_F(HiddenApiTest,CheckClassMatch)504 TEST_F(HiddenApiTest, CheckClassMatch) {
505 ScopedObjectAccess soa(self_);
506 std::string prefix("Lmypackage/packagea/Class1");
507 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
508 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
509 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
510 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
511 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
512 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
513 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
514 ASSERT_TRUE(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,CheckClassExactMatch)520 TEST_F(HiddenApiTest, CheckClassExactMatch) {
521 ScopedObjectAccess soa(self_);
522 std::string prefix("Lmypackage/packagea/Class1;");
523 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
524 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
525 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
526 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
527 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
528 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
529 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
530 ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
531 ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
532 ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
533 }
534
TEST_F(HiddenApiTest,CheckMethodMatch)535 TEST_F(HiddenApiTest, CheckMethodMatch) {
536 ScopedObjectAccess soa(self_);
537 std::string prefix("Lmypackage/packagea/Class1;->method1");
538 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
539 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
540 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
541 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
542 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
543 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
544 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
545 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
546 }
547
TEST_F(HiddenApiTest,CheckMethodExactMatch)548 TEST_F(HiddenApiTest, CheckMethodExactMatch) {
549 ScopedObjectAccess soa(self_);
550 std::string prefix("Lmypackage/packagea/Class1;->method1(");
551 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
552 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
553 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
554 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
555 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
556 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
557 }
558
TEST_F(HiddenApiTest,CheckMethodSignatureMatch)559 TEST_F(HiddenApiTest, CheckMethodSignatureMatch) {
560 ScopedObjectAccess soa(self_);
561 std::string prefix("Lmypackage/packagea/Class1;->method1(I)");
562 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
563 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
564 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
565 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
566 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
567 }
568
TEST_F(HiddenApiTest,CheckMethodSignatureAndReturnMatch)569 TEST_F(HiddenApiTest, CheckMethodSignatureAndReturnMatch) {
570 ScopedObjectAccess soa(self_);
571 std::string prefix("Lmypackage/packagea/Class1;->method1()V");
572 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
573 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
574 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
575 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
576 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
577 }
578
TEST_F(HiddenApiTest,CheckFieldMatch)579 TEST_F(HiddenApiTest, CheckFieldMatch) {
580 ScopedObjectAccess soa(self_);
581 std::string prefix("Lmypackage/packagea/Class1;->field1");
582 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
583 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
584 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
585 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
586 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
587 }
588
TEST_F(HiddenApiTest,CheckFieldExactMatch)589 TEST_F(HiddenApiTest, CheckFieldExactMatch) {
590 ScopedObjectAccess soa(self_);
591 std::string prefix("Lmypackage/packagea/Class1;->field1:");
592 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
593 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
594 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
595 }
596
TEST_F(HiddenApiTest,CheckFieldTypeMatch)597 TEST_F(HiddenApiTest, CheckFieldTypeMatch) {
598 ScopedObjectAccess soa(self_);
599 std::string prefix("Lmypackage/packagea/Class1;->field1:I");
600 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
601 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
602 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
603 }
604
TEST_F(HiddenApiTest,CheckConstructorMatch)605 TEST_F(HiddenApiTest, CheckConstructorMatch) {
606 ScopedObjectAccess soa(self_);
607 std::string prefix("Lmypackage/packagea/Class1;-><init>");
608 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
609 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
610 }
611
TEST_F(HiddenApiTest,CheckConstructorExactMatch)612 TEST_F(HiddenApiTest, CheckConstructorExactMatch) {
613 ScopedObjectAccess soa(self_);
614 std::string prefix("Lmypackage/packagea/Class1;-><init>()V");
615 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
616 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
617 }
618
TEST_F(HiddenApiTest,CheckMethodSignatureTrailingCharsNoMatch)619 TEST_F(HiddenApiTest, CheckMethodSignatureTrailingCharsNoMatch) {
620 ScopedObjectAccess soa(self_);
621 std::string prefix("Lmypackage/packagea/Class1;->method1()Vfoo");
622 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
623 }
624
TEST_F(HiddenApiTest,CheckConstructorTrailingCharsNoMatch)625 TEST_F(HiddenApiTest, CheckConstructorTrailingCharsNoMatch) {
626 ScopedObjectAccess soa(self_);
627 std::string prefix("Lmypackage/packagea/Class1;-><init>()Vfoo");
628 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
629 }
630
TEST_F(HiddenApiTest,CheckFieldTrailingCharsNoMatch)631 TEST_F(HiddenApiTest, CheckFieldTrailingCharsNoMatch) {
632 ScopedObjectAccess soa(self_);
633 std::string prefix("Lmypackage/packagea/Class1;->field1:Ifoo");
634 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
635 }
636
TEST_F(HiddenApiTest,CheckMemberSignatureForProxyClass)637 TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) {
638 ScopedObjectAccess soa(self_);
639 StackHandleScope<4> hs(soa.Self());
640 Handle<mirror::ClassLoader> class_loader(
641 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader_)));
642
643 // Find interface we will create a proxy for.
644 Handle<mirror::Class> h_iface =
645 hs.NewHandle(FindClass("Lmypackage/packagea/Interface;", class_loader));
646 ASSERT_TRUE(h_iface != nullptr);
647
648 // Create the proxy class.
649 std::vector<Handle<mirror::Class>> interfaces;
650 interfaces.push_back(h_iface);
651 Handle<mirror::Class> proxyClass = hs.NewHandle(proxy_test::GenerateProxyClass(
652 soa, jclass_loader_, runtime_->GetClassLinker(), "$Proxy1234", interfaces));
653 ASSERT_TRUE(proxyClass != nullptr);
654 ASSERT_TRUE(proxyClass->IsProxyClass());
655 ASSERT_TRUE(proxyClass->IsInitialized());
656
657 // Find the "method" virtual method.
658 ArtMethod* method = nullptr;
659 for (auto& m : proxyClass->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
660 if (strcmp("method", m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetName()) == 0) {
661 method = &m;
662 break;
663 }
664 }
665 ASSERT_TRUE(method != nullptr);
666
667 // Find the "interfaces" static field. This is generated for all proxies.
668 ArtField* field = nullptr;
669 for (size_t i = 0; i < proxyClass->NumFields(); ++i) {
670 ArtField* f = proxyClass->GetField(i);
671 if (strcmp("interfaces", f->GetName()) == 0) {
672 field = f;
673 break;
674 }
675 }
676 ASSERT_TRUE(field != nullptr);
677 ASSERT_TRUE(field->IsStatic());
678
679 // Test the signature. We expect the signature from the interface class.
680 std::ostringstream ss_method;
681 MemberSignature(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)).Dump(ss_method);
682 ASSERT_EQ("Lmypackage/packagea/Interface;->method()V", ss_method.str());
683
684 // Test the signature. We expect the signature of the proxy class.
685 std::ostringstream ss_field;
686 MemberSignature(field).Dump(ss_field);
687 ASSERT_EQ("L$Proxy1234;->interfaces:[Ljava/lang/Class;", ss_field.str());
688 }
689
TEST_F(HiddenApiTest,DexDomain_DataDir)690 TEST_F(HiddenApiTest, DexDomain_DataDir) {
691 // Load file from a non-system directory and check that it is not flagged as framework.
692 std::string data_location_path = android_data_ + "/foo.jar";
693 ASSERT_FALSE(LocationIsOnSystemFramework(data_location_path));
694 TestLocation(data_location_path, hiddenapi::Domain::kApplication);
695 }
696
TEST_F(HiddenApiTest,DexDomain_SystemDir)697 TEST_F(HiddenApiTest, DexDomain_SystemDir) {
698 // Load file from a system, non-framework directory and check that it is not flagged as framework.
699 std::string system_location_path = GetAndroidRoot() + "/foo.jar";
700 ASSERT_FALSE(LocationIsOnSystemFramework(system_location_path));
701 TestLocation(system_location_path, hiddenapi::Domain::kApplication);
702 }
703
TEST_F(HiddenApiTest,DexDomain_SystemExtDir)704 TEST_F(HiddenApiTest, DexDomain_SystemExtDir) {
705 // Load file from a system_ext, non-framework directory and check that it is not flagged as
706 // framework.
707 std::string system_ext_location_path = android_system_ext_ + "/foo.jar";
708 ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_location_path));
709 TestLocation(system_ext_location_path, hiddenapi::Domain::kApplication);
710 }
711
TEST_F(HiddenApiTest,DexDomain_SystemSystemExtDir)712 TEST_F(HiddenApiTest, DexDomain_SystemSystemExtDir) {
713 // Load file from a system/system_ext, non-framework directory and check that it is not flagged as
714 // framework.
715 std::filesystem::create_directory(GetAndroidRoot() + "/system_ext");
716 std::string system_ext_location_path = GetAndroidRoot() + "/system_ext/foo.jar";
717 ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_location_path));
718 TestLocation(system_ext_location_path, hiddenapi::Domain::kApplication);
719 }
720
TEST_F(HiddenApiTest,DexDomain_SystemFrameworkDir)721 TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir) {
722 // Load file from a system/framework directory and check that it is flagged as a framework dex.
723 std::filesystem::create_directory(GetAndroidRoot() + "/framework");
724 std::string system_framework_location_path = GetAndroidRoot() + "/framework/foo.jar";
725 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_location_path));
726 TestLocation(system_framework_location_path, hiddenapi::Domain::kPlatform);
727 }
728
TEST_F(HiddenApiTest,DexDomain_SystemExtFrameworkDir)729 TEST_F(HiddenApiTest, DexDomain_SystemExtFrameworkDir) {
730 // Load file from a system_ext/framework directory and check that it is flagged as a framework dex.
731 std::filesystem::create_directory(android_system_ext_ + "/framework");
732 std::string system_ext_framework_location_path = android_system_ext_ + "/framework/foo.jar";
733 ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_location_path));
734 TestLocation(system_ext_framework_location_path, hiddenapi::Domain::kPlatform);
735 }
736
TEST_F(HiddenApiTest,DexDomain_SystemSystemExtFrameworkDir)737 TEST_F(HiddenApiTest, DexDomain_SystemSystemExtFrameworkDir) {
738 // Load file from a system/system_ext/framework directory and check that it is flagged as a
739 // framework dex.
740 std::filesystem::create_directory(GetAndroidRoot() + "/system_ext");
741 std::filesystem::create_directory(GetAndroidRoot() + "/system_ext/framework");
742 std::string system_ext_framework_location_path =
743 GetAndroidRoot() + "/system_ext/framework/foo.jar";
744 ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_location_path));
745 TestLocation(system_ext_framework_location_path, hiddenapi::Domain::kPlatform);
746 }
747
TEST_F(HiddenApiTest,DexDomain_DataDir_MultiDex)748 TEST_F(HiddenApiTest, DexDomain_DataDir_MultiDex) {
749 // Load multidex file from a non-system directory and check that it is not flagged as framework.
750 std::string data_multi_location_path = android_data_ + "/multifoo.jar";
751 ASSERT_FALSE(LocationIsOnSystemFramework(data_multi_location_path));
752 TestLocation(data_multi_location_path, hiddenapi::Domain::kApplication);
753 }
754
TEST_F(HiddenApiTest,DexDomain_SystemDir_MultiDex)755 TEST_F(HiddenApiTest, DexDomain_SystemDir_MultiDex) {
756 // Load multidex file from a system, non-framework directory and check that it is not flagged
757 // as framework.
758 std::string system_multi_location_path = GetAndroidRoot() + "/multifoo.jar";
759 ASSERT_FALSE(LocationIsOnSystemFramework(system_multi_location_path));
760 TestLocation(system_multi_location_path, hiddenapi::Domain::kApplication);
761 }
762
TEST_F(HiddenApiTest,DexDomain_SystemExtDir_MultiDex)763 TEST_F(HiddenApiTest, DexDomain_SystemExtDir_MultiDex) {
764 // Load multidex file from a system_ext, non-framework directory and check that it is not flagged
765 // as framework.
766 std::string system_ext_multi_location_path = android_system_ext_ + "/multifoo.jar";
767 ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_multi_location_path));
768 TestLocation(system_ext_multi_location_path, hiddenapi::Domain::kApplication);
769 }
770
TEST_F(HiddenApiTest,DexDomain_SystemSystemExtDir_MultiDex)771 TEST_F(HiddenApiTest, DexDomain_SystemSystemExtDir_MultiDex) {
772 // Load multidex file from a system/system_ext, non-framework directory and check that it is not
773 // flagged as framework.
774 std::filesystem::create_directory(GetAndroidRoot() + "/system_ext");
775 std::string system_ext_multi_location_path =
776 GetAndroidRoot() + "/system_ext/multifoo.jar";
777 ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_multi_location_path));
778 TestLocation(system_ext_multi_location_path, hiddenapi::Domain::kApplication);
779 }
780
TEST_F(HiddenApiTest,DexDomain_SystemFrameworkDir_MultiDex)781 TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir_MultiDex) {
782 // Load multidex file from a system/framework directory and check that it is flagged as a
783 // framework dex.
784 std::filesystem::create_directory(GetAndroidRoot() + "/framework");
785 std::string system_framework_multi_location_path = GetAndroidRoot() + "/framework/multifoo.jar";
786 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_multi_location_path));
787 TestLocation(system_framework_multi_location_path, hiddenapi::Domain::kPlatform);
788 }
789
TEST_F(HiddenApiTest,DexDomain_SystemExtFrameworkDir_MultiDex)790 TEST_F(HiddenApiTest, DexDomain_SystemExtFrameworkDir_MultiDex) {
791 // Load multidex file from a system_ext/framework directory and check that it is flagged as a
792 // framework dex.
793 std::filesystem::create_directory(android_system_ext_ + "/framework");
794 std::string system_ext_framework_multi_location_path =
795 android_system_ext_ + "/framework/multifoo.jar";
796 ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_multi_location_path));
797 TestLocation(system_ext_framework_multi_location_path, hiddenapi::Domain::kPlatform);
798 }
799
TEST_F(HiddenApiTest,DexDomain_SystemSystemExtFrameworkDir_MultiDex)800 TEST_F(HiddenApiTest, DexDomain_SystemSystemExtFrameworkDir_MultiDex) {
801 // Load multidex file from a system/system_ext/framework directory and check that it is flagged
802 // as a framework dex.
803 std::filesystem::create_directory(GetAndroidRoot() + "/system_ext");
804 std::filesystem::create_directory(GetAndroidRoot() + "/system_ext/framework");
805 std::string system_ext_framework_multi_location_path =
806 GetAndroidRoot() + "/system_ext/framework/multifoo.jar";
807 ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_multi_location_path));
808 TestLocation(system_ext_framework_multi_location_path, hiddenapi::Domain::kPlatform);
809 }
810
811 } // namespace art
812