blob: 5a948d1398c53d674e5e301f362456defe80d7c1 [file] [log] [blame]
Mathew Inwood7d74ef52018-03-16 14:18:33 +00001/*
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
David Brazdila5c3a802019-03-08 14:59:41 +000019#include <fstream>
David Brazdilbfaba282019-03-15 11:35:51 +000020#include <sstream>
David Brazdila5c3a802019-03-08 14:59:41 +000021
22#include "base/file_utils.h"
David Brazdil2bb2fbd2018-11-13 18:24:26 +000023#include "base/sdk_version.h"
David Brazdila5c3a802019-03-08 14:59:41 +000024#include "base/stl_util.h"
Mathew Inwood7d74ef52018-03-16 14:18:33 +000025#include "common_runtime_test.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010026#include "jni/jni_internal.h"
David Brazdil1f9d3c32018-05-02 16:53:06 +010027#include "proxy_test.h"
David Brazdila5c3a802019-03-08 14:59:41 +000028#include "well_known_classes.h"
Mathew Inwood7d74ef52018-03-16 14:18:33 +000029
30namespace art {
31
Andreas Gampeaa120012018-03-28 16:23:24 -070032using hiddenapi::detail::MemberSignature;
David Brazdilf50ac102018-10-17 18:00:06 +010033using hiddenapi::detail::ShouldDenyAccessToMemberImpl;
Andreas Gampeaa120012018-03-28 16:23:24 -070034
atrost2dea0792020-02-25 20:11:47 +000035// Should be the same as dalvik.system.VMRuntime.HIDE_MAXTARGETSDK_P_HIDDEN_APIS and
36// dalvik.system.VMRuntime.HIDE_MAXTARGETSDK_Q_HIDDEN_APIS.
37static constexpr uint64_t kHideMaxtargetsdkPHiddenApis = 149997251;
38static constexpr uint64_t kHideMaxtargetsdkQHiddenApis = 149994052;
39
Mathew Inwood7d74ef52018-03-16 14:18:33 +000040class HiddenApiTest : public CommonRuntimeTest {
41 protected:
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010042 void SetUp() override {
Mathew Inwood7d74ef52018-03-16 14:18:33 +000043 // Do the normal setup.
44 CommonRuntimeTest::SetUp();
45 self_ = Thread::Current();
46 self_->TransitionFromSuspendedToRunnable();
David Brazdil1f9d3c32018-05-02 16:53:06 +010047 jclass_loader_ = LoadDex("HiddenApiSignatures");
Mathew Inwood7d74ef52018-03-16 14:18:33 +000048 bool started = runtime_->Start();
49 CHECK(started);
50
51 class1_field1_ = getArtField("mypackage/packagea/Class1", "field1", "I");
52 class1_field12_ = getArtField("mypackage/packagea/Class1", "field12", "I");
53 class1_init_ = getArtMethod("mypackage/packagea/Class1", "<init>", "()V");
54 class1_method1_ = getArtMethod("mypackage/packagea/Class1", "method1", "()V");
55 class1_method1_i_ = getArtMethod("mypackage/packagea/Class1", "method1", "(I)V");
56 class1_method12_ = getArtMethod("mypackage/packagea/Class1", "method12", "()V");
57 class12_field1_ = getArtField("mypackage/packagea/Class12", "field1", "I");
58 class12_method1_ = getArtMethod("mypackage/packagea/Class12", "method1", "()V");
59 class2_field1_ = getArtField("mypackage/packagea/Class2", "field1", "I");
60 class2_method1_ = getArtMethod("mypackage/packagea/Class2", "method1", "()V");
61 class2_method1_i_ = getArtMethod("mypackage/packagea/Class2", "method1", "(I)V");
62 class3_field1_ = getArtField("mypackage/packageb/Class3", "field1", "I");
63 class3_method1_ = getArtMethod("mypackage/packageb/Class3", "method1", "()V");
64 class3_method1_i_ = getArtMethod("mypackage/packageb/Class3", "method1", "(I)V");
65 }
66
67 ArtMethod* getArtMethod(const char* class_name, const char* name, const char* signature) {
68 JNIEnv* env = Thread::Current()->GetJniEnv();
69 jclass klass = env->FindClass(class_name);
70 jmethodID method_id = env->GetMethodID(klass, name, signature);
71 ArtMethod* art_method = jni::DecodeArtMethod(method_id);
72 return art_method;
73 }
74
75 ArtField* getArtField(const char* class_name, const char* name, const char* signature) {
76 JNIEnv* env = Thread::Current()->GetJniEnv();
77 jclass klass = env->FindClass(class_name);
78 jfieldID field_id = env->GetFieldID(klass, name, signature);
79 ArtField* art_field = jni::DecodeArtField(field_id);
80 return art_field;
81 }
82
atrost2dea0792020-02-25 20:11:47 +000083 void setChangeIdState(uint64_t change, bool enabled) {
84 std::set<uint64_t> disabled_changes = runtime_->GetDisabledCompatChanges();
85 if (enabled) {
86 disabled_changes.erase(change);
87 } else {
88 disabled_changes.insert(change);
89 }
90 runtime_->SetDisabledCompatChanges(disabled_changes);
91 }
92
David Brazdilf50ac102018-10-17 18:00:06 +010093 bool ShouldDenyAccess(hiddenapi::ApiList list) REQUIRES_SHARED(Locks::mutator_lock_) {
94 // Choose parameters such that there are no side effects (AccessMethod::kNone)
95 // and that the member is not on the exemptions list (here we choose one which
96 // is not even in boot class path).
97 return ShouldDenyAccessToMemberImpl(/* member= */ class1_field1_,
98 list,
99 /* access_method= */ hiddenapi::AccessMethod::kNone);
100 }
101
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000102 protected:
103 Thread* self_;
David Brazdil1f9d3c32018-05-02 16:53:06 +0100104 jobject jclass_loader_;
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000105 ArtField* class1_field1_;
106 ArtField* class1_field12_;
107 ArtMethod* class1_init_;
108 ArtMethod* class1_method1_;
109 ArtMethod* class1_method1_i_;
110 ArtMethod* class1_method12_;
111 ArtField* class12_field1_;
112 ArtMethod* class12_method1_;
113 ArtField* class2_field1_;
114 ArtMethod* class2_method1_;
115 ArtMethod* class2_method1_i_;
116 ArtField* class3_field1_;
117 ArtMethod* class3_method1_;
118 ArtMethod* class3_method1_i_;
119};
120
Mathew Inwooda8503d92018-04-05 16:10:25 +0100121TEST_F(HiddenApiTest, CheckGetActionFromRuntimeFlags) {
David Brazdilf50ac102018-10-17 18:00:06 +0100122 ScopedObjectAccess soa(self_);
123
Mathew Inwooda8503d92018-04-05 16:10:25 +0100124 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kJustWarn);
David Brazdildcfa89b2018-10-31 11:04:10 +0000125 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
126 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
Artur Satayev201ffea2019-10-31 14:58:03 +0000127 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000128 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000129 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
130 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), false);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100131
David Brazdilf50ac102018-10-17 18:00:06 +0100132 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
David Brazdildcfa89b2018-10-31 11:04:10 +0000133 runtime_->SetTargetSdkVersion(
134 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()));
atrost2dea0792020-02-25 20:11:47 +0000135 setChangeIdState(kHideMaxtargetsdkPHiddenApis, false);
136 setChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000137 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
138 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
Artur Satayev201ffea2019-10-31 14:58:03 +0000139 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000140 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000141 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
142 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100143
David Brazdilf50ac102018-10-17 18:00:06 +0100144 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
David Brazdildcfa89b2018-10-31 11:04:10 +0000145 runtime_->SetTargetSdkVersion(
146 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()) + 1);
atrost2dea0792020-02-25 20:11:47 +0000147 setChangeIdState(kHideMaxtargetsdkPHiddenApis, false);
148 setChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000149 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
150 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
Artur Satayev201ffea2019-10-31 14:58:03 +0000151 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000152 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
153 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
154 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
atrost2dea0792020-02-25 20:11:47 +0000155 setChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
156 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
157 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
158 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), true);
159 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
160 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
161 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
David Brazdil80d16282018-11-01 09:55:09 +0000162
163 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
164 runtime_->SetTargetSdkVersion(
165 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxP().GetMaxAllowedSdkVersion()) + 1);
atrost2dea0792020-02-25 20:11:47 +0000166 setChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
167 setChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
David Brazdil80d16282018-11-01 09:55:09 +0000168 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
169 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
Artur Satayev201ffea2019-10-31 14:58:03 +0000170 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), false);
171 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), true);
172 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
173 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
174
175 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
176 runtime_->SetTargetSdkVersion(
177 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxQ().GetMaxAllowedSdkVersion()) + 1);
atrost2dea0792020-02-25 20:11:47 +0000178 setChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
179 setChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
Artur Satayev201ffea2019-10-31 14:58:03 +0000180 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
181 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
182 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), true);
David Brazdil80d16282018-11-01 09:55:09 +0000183 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), true);
David Brazdildcfa89b2018-10-31 11:04:10 +0000184 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
185 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100186}
187
Artur Satayev267366c2019-10-31 14:59:26 +0000188TEST_F(HiddenApiTest, CheckTestApiEnforcement) {
189 ScopedObjectAccess soa(self_);
190
191 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
192 runtime_->SetTargetSdkVersion(
193 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxQ().GetMaxAllowedSdkVersion()) + 1);
194
195 // Default case where all TestApis are treated like non-TestApi.
196 runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
197 ASSERT_EQ(
198 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Whitelist()), false);
199 ASSERT_EQ(
200 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Greylist()), false);
201 ASSERT_EQ(
202 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxQ()), true);
203 ASSERT_EQ(
204 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxP()), true);
205 ASSERT_EQ(
206 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxO()), true);
207 ASSERT_EQ(
208 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Blacklist()), true);
209
210 // A case where we want to allow access to TestApis.
211 runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kDisabled);
212 ASSERT_EQ(
213 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Whitelist()), false);
214 ASSERT_EQ(
215 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Greylist()), false);
216 ASSERT_EQ(
217 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxQ()), false);
218 ASSERT_EQ(
219 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxP()), false);
220 ASSERT_EQ(
221 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxO()), false);
222 ASSERT_EQ(
223 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Blacklist()), false);
224}
225
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000226TEST_F(HiddenApiTest, CheckMembersRead) {
227 ASSERT_NE(nullptr, class1_field1_);
228 ASSERT_NE(nullptr, class1_field12_);
229 ASSERT_NE(nullptr, class1_init_);
230 ASSERT_NE(nullptr, class1_method1_);
231 ASSERT_NE(nullptr, class1_method1_i_);
232 ASSERT_NE(nullptr, class1_method12_);
233 ASSERT_NE(nullptr, class12_field1_);
234 ASSERT_NE(nullptr, class12_method1_);
235 ASSERT_NE(nullptr, class2_field1_);
236 ASSERT_NE(nullptr, class2_method1_);
237 ASSERT_NE(nullptr, class2_method1_i_);
238 ASSERT_NE(nullptr, class3_field1_);
239 ASSERT_NE(nullptr, class3_method1_);
240 ASSERT_NE(nullptr, class3_method1_i_);
241}
242
243TEST_F(HiddenApiTest, CheckEverythingMatchesL) {
244 ScopedObjectAccess soa(self_);
245 std::string prefix("L");
Andreas Gampeaa120012018-03-28 16:23:24 -0700246 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
247 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
248 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
249 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
250 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
251 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
252 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
253 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
254 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
255 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
256 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
257 ASSERT_TRUE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
258 ASSERT_TRUE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
259 ASSERT_TRUE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000260}
261
262TEST_F(HiddenApiTest, CheckPackageMatch) {
263 ScopedObjectAccess soa(self_);
264 std::string prefix("Lmypackage/packagea/");
Andreas Gampeaa120012018-03-28 16:23:24 -0700265 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
266 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
267 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
268 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
269 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
270 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
271 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
272 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
273 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
274 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
275 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
276 ASSERT_FALSE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
277 ASSERT_FALSE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
278 ASSERT_FALSE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000279}
280
281TEST_F(HiddenApiTest, CheckClassMatch) {
282 ScopedObjectAccess soa(self_);
283 std::string prefix("Lmypackage/packagea/Class1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700284 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
285 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
286 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
287 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
288 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
289 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
290 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
291 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
292 ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
293 ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
294 ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000295}
296
297TEST_F(HiddenApiTest, CheckClassExactMatch) {
298 ScopedObjectAccess soa(self_);
299 std::string prefix("Lmypackage/packagea/Class1;");
Andreas Gampeaa120012018-03-28 16:23:24 -0700300 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
301 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
302 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
303 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
304 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
305 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
306 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
307 ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
308 ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
309 ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000310}
311
312TEST_F(HiddenApiTest, CheckMethodMatch) {
313 ScopedObjectAccess soa(self_);
314 std::string prefix("Lmypackage/packagea/Class1;->method1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700315 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
316 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
317 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
318 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
319 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
320 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
321 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
322 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000323}
324
325TEST_F(HiddenApiTest, CheckMethodExactMatch) {
326 ScopedObjectAccess soa(self_);
327 std::string prefix("Lmypackage/packagea/Class1;->method1(");
Andreas Gampeaa120012018-03-28 16:23:24 -0700328 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
329 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
330 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
331 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
332 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
333 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000334}
335
336TEST_F(HiddenApiTest, CheckMethodSignatureMatch) {
337 ScopedObjectAccess soa(self_);
338 std::string prefix("Lmypackage/packagea/Class1;->method1(I)");
Andreas Gampeaa120012018-03-28 16:23:24 -0700339 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
340 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
341 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
342 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
343 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000344}
345
346TEST_F(HiddenApiTest, CheckMethodSignatureAndReturnMatch) {
347 ScopedObjectAccess soa(self_);
348 std::string prefix("Lmypackage/packagea/Class1;->method1()V");
Andreas Gampeaa120012018-03-28 16:23:24 -0700349 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
350 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
351 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
352 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
353 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000354}
355
356TEST_F(HiddenApiTest, CheckFieldMatch) {
357 ScopedObjectAccess soa(self_);
358 std::string prefix("Lmypackage/packagea/Class1;->field1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700359 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
360 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
361 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
362 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
363 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000364}
365
366TEST_F(HiddenApiTest, CheckFieldExactMatch) {
367 ScopedObjectAccess soa(self_);
368 std::string prefix("Lmypackage/packagea/Class1;->field1:");
Andreas Gampeaa120012018-03-28 16:23:24 -0700369 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
370 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
371 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000372}
373
374TEST_F(HiddenApiTest, CheckFieldTypeMatch) {
375 ScopedObjectAccess soa(self_);
376 std::string prefix("Lmypackage/packagea/Class1;->field1:I");
Andreas Gampeaa120012018-03-28 16:23:24 -0700377 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
378 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
379 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000380}
381
382TEST_F(HiddenApiTest, CheckConstructorMatch) {
383 ScopedObjectAccess soa(self_);
384 std::string prefix("Lmypackage/packagea/Class1;-><init>");
Andreas Gampeaa120012018-03-28 16:23:24 -0700385 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
386 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000387}
388
389TEST_F(HiddenApiTest, CheckConstructorExactMatch) {
390 ScopedObjectAccess soa(self_);
391 std::string prefix("Lmypackage/packagea/Class1;-><init>()V");
Andreas Gampeaa120012018-03-28 16:23:24 -0700392 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
393 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000394}
395
396TEST_F(HiddenApiTest, CheckMethodSignatureTrailingCharsNoMatch) {
397 ScopedObjectAccess soa(self_);
398 std::string prefix("Lmypackage/packagea/Class1;->method1()Vfoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700399 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000400}
401
402TEST_F(HiddenApiTest, CheckConstructorTrailingCharsNoMatch) {
403 ScopedObjectAccess soa(self_);
404 std::string prefix("Lmypackage/packagea/Class1;-><init>()Vfoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700405 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000406}
407
408TEST_F(HiddenApiTest, CheckFieldTrailingCharsNoMatch) {
409 ScopedObjectAccess soa(self_);
410 std::string prefix("Lmypackage/packagea/Class1;->field1:Ifoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700411 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000412}
413
David Brazdil1f9d3c32018-05-02 16:53:06 +0100414TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) {
415 ScopedObjectAccess soa(self_);
416 StackHandleScope<4> hs(soa.Self());
417 Handle<mirror::ClassLoader> class_loader(
418 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader_)));
419
420 // Find interface we will create a proxy for.
421 Handle<mirror::Class> h_iface(hs.NewHandle(
422 class_linker_->FindClass(soa.Self(), "Lmypackage/packagea/Interface;", class_loader)));
423 ASSERT_TRUE(h_iface != nullptr);
424
425 // Create the proxy class.
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100426 std::vector<Handle<mirror::Class>> interfaces;
427 interfaces.push_back(h_iface);
David Brazdil1f9d3c32018-05-02 16:53:06 +0100428 Handle<mirror::Class> proxyClass = hs.NewHandle(proxy_test::GenerateProxyClass(
429 soa, jclass_loader_, runtime_->GetClassLinker(), "$Proxy1234", interfaces));
430 ASSERT_TRUE(proxyClass != nullptr);
431 ASSERT_TRUE(proxyClass->IsProxyClass());
432 ASSERT_TRUE(proxyClass->IsInitialized());
433
434 // Find the "method" virtual method.
435 ArtMethod* method = nullptr;
436 for (auto& m : proxyClass->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
437 if (strcmp("method", m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetName()) == 0) {
438 method = &m;
439 break;
440 }
441 }
442 ASSERT_TRUE(method != nullptr);
443
444 // Find the "interfaces" static field. This is generated for all proxies.
445 ArtField* field = nullptr;
446 for (size_t i = 0; i < proxyClass->NumStaticFields(); ++i) {
447 ArtField* f = proxyClass->GetStaticField(i);
448 if (strcmp("interfaces", f->GetName()) == 0) {
449 field = f;
450 break;
451 }
452 }
453 ASSERT_TRUE(field != nullptr);
454
455 // Test the signature. We expect the signature from the interface class.
456 std::ostringstream ss_method;
David Brazdil6a1dab42019-02-28 18:45:15 +0000457 MemberSignature(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)).Dump(ss_method);
David Brazdil1f9d3c32018-05-02 16:53:06 +0100458 ASSERT_EQ("Lmypackage/packagea/Interface;->method()V", ss_method.str());
459
460 // Test the signature. We expect the signature of the proxy class.
461 std::ostringstream ss_field;
462 MemberSignature(field).Dump(ss_field);
463 ASSERT_EQ("L$Proxy1234;->interfaces:[Ljava/lang/Class;", ss_field.str());
464}
465
David Brazdila5c3a802019-03-08 14:59:41 +0000466static bool Copy(const std::string& src, const std::string& dst, /*out*/ std::string* error_msg) {
467 std::ifstream src_stream(src, std::ios::binary);
468 std::ofstream dst_stream(dst, std::ios::binary);
469 dst_stream << src_stream.rdbuf();
470 src_stream.close();
471 dst_stream.close();
472 if (src_stream.good() && dst_stream.good()) {
473 return true;
474 } else {
475 *error_msg = "Copy " + src + " => " + dst + " (src_good="
476 + (src_stream.good() ? "true" : "false") + ", dst_good="
477 + (dst_stream.good() ? "true" : "false") + ")";
478 return false;
479 }
480}
481
482static bool LoadDexFiles(const std::string& path,
483 ScopedObjectAccess& soa,
484 /* out */ std::vector<std::unique_ptr<const DexFile>>* dex_files,
485 /* out */ ObjPtr<mirror::ClassLoader>* class_loader,
486 /* out */ std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
487 if (!ArtDexFileLoader().Open(path.c_str(),
488 path,
489 /* verify= */ true,
490 /* verify_checksum= */ true,
491 error_msg,
492 dex_files)) {
493 return false;
494 }
495
496 ClassLinker* const linker = Runtime::Current()->GetClassLinker();
497
498 StackHandleScope<2> hs(soa.Self());
499 Handle<mirror::Class> h_class = hs.NewHandle(soa.Decode<mirror::Class>(
500 WellKnownClasses::dalvik_system_PathClassLoader));
501 Handle<mirror::ClassLoader> h_loader = hs.NewHandle(linker->CreateWellKnownClassLoader(
502 soa.Self(),
503 MakeNonOwningPointerVector(*dex_files),
504 h_class,
505 /* parent_loader= */ ScopedNullHandle<mirror::ClassLoader>(),
506 /* shared_libraries= */ ScopedNullHandle<mirror::ObjectArray<mirror::ClassLoader>>()));
507 for (const auto& dex_file : *dex_files) {
508 linker->RegisterDexFile(*dex_file.get(), h_loader.Get());
509 }
510
511 *class_loader = h_loader.Get();
512 return true;
513}
514
515static bool CheckAllDexFilesInDomain(ObjPtr<mirror::ClassLoader> loader,
516 const std::vector<std::unique_ptr<const DexFile>>& dex_files,
David Brazdilbfaba282019-03-15 11:35:51 +0000517 hiddenapi::Domain expected_domain,
518 /* out */ std::string* error_msg)
David Brazdila5c3a802019-03-08 14:59:41 +0000519 REQUIRES_SHARED(Locks::mutator_lock_) {
520 for (const auto& dex_file : dex_files) {
521 hiddenapi::AccessContext context(loader, dex_file.get());
522 if (context.GetDomain() != expected_domain) {
David Brazdilbfaba282019-03-15 11:35:51 +0000523 std::stringstream ss;
524 ss << dex_file->GetLocation() << ": access context domain does not match "
David Brazdila5c3a802019-03-08 14:59:41 +0000525 << "(expected=" << static_cast<uint32_t>(expected_domain)
526 << ", actual=" << static_cast<uint32_t>(context.GetDomain()) << ")";
David Brazdilbfaba282019-03-15 11:35:51 +0000527 *error_msg = ss.str();
David Brazdila5c3a802019-03-08 14:59:41 +0000528 return false;
529 }
530 if (dex_file->GetHiddenapiDomain() != expected_domain) {
David Brazdilbfaba282019-03-15 11:35:51 +0000531 std::stringstream ss;
532 ss << dex_file->GetLocation() << ": dex file domain does not match "
David Brazdila5c3a802019-03-08 14:59:41 +0000533 << "(expected=" << static_cast<uint32_t>(expected_domain)
534 << ", actual=" << static_cast<uint32_t>(dex_file->GetHiddenapiDomain()) << ")";
David Brazdilbfaba282019-03-15 11:35:51 +0000535 *error_msg = ss.str();
David Brazdila5c3a802019-03-08 14:59:41 +0000536 return false;
537 }
538 }
539
540 return true;
541}
542
543TEST_F(HiddenApiTest, DexDomain_DataDir) {
544 // Load file from a non-system directory and check that it is not flagged as framework.
545 std::string data_location_path = android_data_ + "/foo.jar";
546 ASSERT_FALSE(LocationIsOnSystemFramework(data_location_path.c_str()));
547
548 ScopedObjectAccess soa(Thread::Current());
549 std::vector<std::unique_ptr<const DexFile>> dex_files;
550 std::string error_msg;
551 ObjPtr<mirror::ClassLoader> class_loader;
552
553 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), data_location_path, &error_msg)) << error_msg;
554 ASSERT_TRUE(LoadDexFiles(data_location_path, soa, &dex_files, &class_loader, &error_msg))
555 << error_msg;
556 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000557 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
558 dex_files,
559 hiddenapi::Domain::kApplication,
560 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000561
562 dex_files.clear();
563 ASSERT_EQ(0, remove(data_location_path.c_str()));
564}
565
566TEST_F(HiddenApiTest, DexDomain_SystemDir) {
567 // Load file from a system, non-framework directory and check that it is not flagged as framework.
568 std::string system_location_path = GetAndroidRoot() + "/foo.jar";
569 ASSERT_FALSE(LocationIsOnSystemFramework(system_location_path.c_str()));
570
571 ScopedObjectAccess soa(Thread::Current());
572 std::vector<std::unique_ptr<const DexFile>> dex_files;
573 std::string error_msg;
574 ObjPtr<mirror::ClassLoader> class_loader;
575
576 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_location_path, &error_msg)) << error_msg;
577 ASSERT_TRUE(LoadDexFiles(system_location_path, soa, &dex_files, &class_loader, &error_msg))
578 << error_msg;
579 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000580 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
581 dex_files,
582 hiddenapi::Domain::kApplication,
583 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000584
585 dex_files.clear();
586 ASSERT_EQ(0, remove(system_location_path.c_str()));
587}
588
Chris Gross5477b8e2020-04-24 09:36:45 -0700589TEST_F(HiddenApiTest, DexDomain_SystemExtDir) {
590 // Load file from a system_ext, non-framework directory and check that it is not flagged as framework.
591 std::string system_ext_location_path = android_system_ext_ + "/foo.jar";
592 ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_location_path.c_str()));
593
594 ScopedObjectAccess soa(Thread::Current());
595 std::vector<std::unique_ptr<const DexFile>> dex_files;
596 std::string error_msg;
597 ObjPtr<mirror::ClassLoader> class_loader;
598
599 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_ext_location_path, &error_msg)) << error_msg;
600 ASSERT_TRUE(LoadDexFiles(system_ext_location_path, soa, &dex_files, &class_loader, &error_msg))
601 << error_msg;
602 ASSERT_GE(dex_files.size(), 1u);
603 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
604 dex_files,
605 hiddenapi::Domain::kApplication,
606 &error_msg)) << error_msg;
607
608 dex_files.clear();
609 ASSERT_EQ(0, remove(system_ext_location_path.c_str()));
610}
611
David Brazdila5c3a802019-03-08 14:59:41 +0000612TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir) {
613 // Load file from a system/framework directory and check that it is flagged as a framework dex.
614 std::string system_framework_location_path = GetAndroidRoot() + "/framework/foo.jar";
615 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_location_path.c_str()));
616
617 ScopedObjectAccess soa(Thread::Current());
618 std::vector<std::unique_ptr<const DexFile>> dex_files;
619 std::string error_msg;
620 ObjPtr<mirror::ClassLoader> class_loader;
621
622 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_framework_location_path, &error_msg))
623 << error_msg;
624 ASSERT_TRUE(LoadDexFiles(system_framework_location_path,
625 soa,
626 &dex_files,
627 &class_loader,
628 &error_msg)) << error_msg;
629 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000630 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
631 dex_files,
632 hiddenapi::Domain::kPlatform,
633 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000634
635 dex_files.clear();
636 ASSERT_EQ(0, remove(system_framework_location_path.c_str()));
637}
638
Chris Gross5477b8e2020-04-24 09:36:45 -0700639TEST_F(HiddenApiTest, DexDomain_SystemExtFrameworkDir) {
640 // Load file from a system_ext/framework directory and check that it is flagged as a framework dex.
641 std::string system_ext_framework_location_path = android_system_ext_ + "/framework/foo.jar";
642 ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_location_path.c_str()));
643
644 ScopedObjectAccess soa(Thread::Current());
645 std::vector<std::unique_ptr<const DexFile>> dex_files;
646 std::string error_msg;
647 ObjPtr<mirror::ClassLoader> class_loader;
648
649 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_ext_framework_location_path, &error_msg))
650 << error_msg;
651 ASSERT_TRUE(LoadDexFiles(system_ext_framework_location_path,
652 soa,
653 &dex_files,
654 &class_loader,
655 &error_msg)) << error_msg;
656 ASSERT_GE(dex_files.size(), 1u);
657 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
658 dex_files,
659 hiddenapi::Domain::kPlatform,
660 &error_msg)) << error_msg;
661
662 dex_files.clear();
663 ASSERT_EQ(0, remove(system_ext_framework_location_path.c_str()));
664}
665
David Brazdila5c3a802019-03-08 14:59:41 +0000666TEST_F(HiddenApiTest, DexDomain_DataDir_MultiDex) {
667 // Load multidex file from a non-system directory and check that it is not flagged as framework.
668 std::string data_multi_location_path = android_data_ + "/multifoo.jar";
669 ASSERT_FALSE(LocationIsOnSystemFramework(data_multi_location_path.c_str()));
670
671 ScopedObjectAccess soa(Thread::Current());
672 std::vector<std::unique_ptr<const DexFile>> dex_files;
673 std::string error_msg;
674 ObjPtr<mirror::ClassLoader> class_loader;
675
676 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"), data_multi_location_path, &error_msg))
677 << error_msg;
678 ASSERT_TRUE(LoadDexFiles(data_multi_location_path, soa, &dex_files, &class_loader, &error_msg))
679 << error_msg;
680 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000681 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
682 dex_files,
683 hiddenapi::Domain::kApplication,
684 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000685
686 dex_files.clear();
687 ASSERT_EQ(0, remove(data_multi_location_path.c_str()));
688}
689
690TEST_F(HiddenApiTest, DexDomain_SystemDir_MultiDex) {
691 // Load multidex file from a system, non-framework directory and check that it is not flagged
692 // as framework.
693 std::string system_multi_location_path = GetAndroidRoot() + "/multifoo.jar";
694 ASSERT_FALSE(LocationIsOnSystemFramework(system_multi_location_path.c_str()));
695
696 ScopedObjectAccess soa(Thread::Current());
697 std::vector<std::unique_ptr<const DexFile>> dex_files;
698 std::string error_msg;
699 ObjPtr<mirror::ClassLoader> class_loader;
700
701 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"), system_multi_location_path, &error_msg))
702 << error_msg;
703 ASSERT_TRUE(LoadDexFiles(system_multi_location_path, soa, &dex_files, &class_loader, &error_msg))
704 << error_msg;
705 ASSERT_GT(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000706 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
707 dex_files,
708 hiddenapi::Domain::kApplication,
709 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000710
711 dex_files.clear();
712 ASSERT_EQ(0, remove(system_multi_location_path.c_str()));
713}
714
Chris Gross5477b8e2020-04-24 09:36:45 -0700715TEST_F(HiddenApiTest, DexDomain_SystemExtDir_MultiDex) {
716 // Load multidex file from a system_ext, non-framework directory and check that it is not flagged
717 // as framework.
718 std::string system_ext_multi_location_path = android_system_ext_ + "/multifoo.jar";
719 ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_multi_location_path.c_str()));
720
721 ScopedObjectAccess soa(Thread::Current());
722 std::vector<std::unique_ptr<const DexFile>> dex_files;
723 std::string error_msg;
724 ObjPtr<mirror::ClassLoader> class_loader;
725
726 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"), system_ext_multi_location_path, &error_msg))
727 << error_msg;
728 ASSERT_TRUE(LoadDexFiles(system_ext_multi_location_path, soa, &dex_files, &class_loader, &error_msg))
729 << error_msg;
730 ASSERT_GT(dex_files.size(), 1u);
731 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
732 dex_files,
733 hiddenapi::Domain::kApplication,
734 &error_msg)) << error_msg;
735
736 dex_files.clear();
737 ASSERT_EQ(0, remove(system_ext_multi_location_path.c_str()));
738}
739
David Brazdila5c3a802019-03-08 14:59:41 +0000740TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir_MultiDex) {
741 // Load multidex file from a system/framework directory and check that it is flagged as a
742 // framework dex.
743 std::string system_framework_multi_location_path = GetAndroidRoot() + "/framework/multifoo.jar";
744 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_multi_location_path.c_str()));
745
746 ScopedObjectAccess soa(Thread::Current());
747 std::vector<std::unique_ptr<const DexFile>> dex_files;
748 std::string error_msg;
749 ObjPtr<mirror::ClassLoader> class_loader;
750
751 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"),
752 system_framework_multi_location_path,
753 &error_msg)) << error_msg;
754 ASSERT_TRUE(LoadDexFiles(system_framework_multi_location_path,
755 soa,
756 &dex_files,
757 &class_loader,
758 &error_msg)) << error_msg;
759 ASSERT_GT(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000760 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
761 dex_files,
762 hiddenapi::Domain::kPlatform,
763 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000764
765 dex_files.clear();
766 ASSERT_EQ(0, remove(system_framework_multi_location_path.c_str()));
767}
768
Chris Gross5477b8e2020-04-24 09:36:45 -0700769TEST_F(HiddenApiTest, DexDomain_SystemExtFrameworkDir_MultiDex) {
770 // Load multidex file from a system_ext/framework directory and check that it is flagged as a
771 // framework dex.
772 std::string system_ext_framework_multi_location_path = android_system_ext_ + "/framework/multifoo.jar";
773 ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_multi_location_path.c_str()));
774
775 ScopedObjectAccess soa(Thread::Current());
776 std::vector<std::unique_ptr<const DexFile>> dex_files;
777 std::string error_msg;
778 ObjPtr<mirror::ClassLoader> class_loader;
779
780 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"),
781 system_ext_framework_multi_location_path,
782 &error_msg)) << error_msg;
783 ASSERT_TRUE(LoadDexFiles(system_ext_framework_multi_location_path,
784 soa,
785 &dex_files,
786 &class_loader,
787 &error_msg)) << error_msg;
788 ASSERT_GT(dex_files.size(), 1u);
789 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
790 dex_files,
791 hiddenapi::Domain::kPlatform,
792 &error_msg)) << error_msg;
793
794 dex_files.clear();
795 ASSERT_EQ(0, remove(system_ext_framework_multi_location_path.c_str()));
796}
797
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000798} // namespace art