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