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