1 /*
2 * Copyright (C) 2024 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 <media/NativePermissionController.h>
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include <error/BinderStatusMatcher.h>
23 #include <error/ExpectedMatchers.h>
24
25 using android::binder::Status::EX_ILLEGAL_ARGUMENT;
26 using android::binder::Status::EX_ILLEGAL_STATE;
27 using android::error::BinderStatusMatcher;
28 using android::error::IsErrorAnd;
29 using android::error::IsOkAnd;
30 using com::android::media::permission::NativePermissionController;
31 using com::android::media::permission::PermissionEnum;
32 using com::android::media::permission::UidPackageState;
33
34 using ::testing::ElementsAre;
35 using ::testing::IsFalse;
36 using ::testing::IsTrue;
37
38 class NativePermissionControllerTest : public ::testing::Test {
39 protected:
40 android::sp<NativePermissionController> holder_ =
41 android::sp<NativePermissionController>::make();
42 NativePermissionController& controller_ = *holder_;
43 };
createState(uid_t uid,std::vector<std::string> packagesNames)44 static UidPackageState createState(uid_t uid, std::vector<std::string> packagesNames) {
45 UidPackageState out{};
46 out.uid = uid;
47 out.packageNames = std::move(packagesNames);
48 return out;
49 }
50
51 // --- Tests for non-populated ----
TEST_F(NativePermissionControllerTest,getPackagesForUid_NotPopulated)52 TEST_F(NativePermissionControllerTest, getPackagesForUid_NotPopulated) {
53 // Verify errors are returned
54 EXPECT_THAT(controller_.getPackagesForUid(10000),
55 IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_STATE)));
56 EXPECT_THAT(controller_.getPackagesForUid(10001),
57 IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_STATE)));
58
59 // fixed uids should work
60 EXPECT_THAT(controller_.getPackagesForUid(1000), IsOkAnd(ElementsAre(std::string{"system"})));
61 }
62
TEST_F(NativePermissionControllerTest,validateUidPackagePair_NotPopulated)63 TEST_F(NativePermissionControllerTest, validateUidPackagePair_NotPopulated) {
64 // Verify errors are returned
65 EXPECT_THAT(controller_.validateUidPackagePair(10000, "com.package"),
66 IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_STATE)));
67
68 // fixed uids should work
69 EXPECT_THAT(controller_.validateUidPackagePair(1000, "system"), IsOkAnd(IsTrue()));
70 }
71
72 // --- Tests for populatePackagesForUids ----
TEST_F(NativePermissionControllerTest,populatePackages_EmptyInput)73 TEST_F(NativePermissionControllerTest, populatePackages_EmptyInput) {
74 std::vector<UidPackageState> input;
75
76 // succeeds
77 EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
78
79 // Verify unknown uid behavior
80 EXPECT_THAT(controller_.getPackagesForUid(10000),
81 IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_ARGUMENT)));
82 }
83
TEST_F(NativePermissionControllerTest,populatePackages_ValidInput)84 TEST_F(NativePermissionControllerTest, populatePackages_ValidInput) {
85 std::vector<UidPackageState> input{
86 createState(10000, {"com.example.app1", "com.example.app2"}),
87 createState(10001, {"com.example2.app1"}),
88 };
89
90 EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
91
92 EXPECT_THAT(controller_.getPackagesForUid(10000),
93 IsOkAnd(ElementsAre("com.example.app1", "com.example.app2")));
94 EXPECT_THAT(controller_.getPackagesForUid(10001), IsOkAnd(ElementsAre("com.example2.app1")));
95 }
96
97 // --- Tests for updatePackagesForUid ---
TEST_F(NativePermissionControllerTest,updatePackages_NewUid)98 TEST_F(NativePermissionControllerTest, updatePackages_NewUid) {
99 std::vector<UidPackageState> input{
100 createState(10000, {"com.example.app1", "com.example.app2"}),
101 createState(10001, {"com.example2.app1"}),
102 };
103 UidPackageState newState = createState(12000, {"com.example.other"});
104
105 EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
106 EXPECT_THAT(controller_.updatePackagesForUid(newState), BinderStatusMatcher::isOk());
107
108 // Verify the results: only the updated package should be changed
109 EXPECT_THAT(controller_.getPackagesForUid(10000),
110 IsOkAnd(ElementsAre("com.example.app1", "com.example.app2")));
111 EXPECT_THAT(controller_.getPackagesForUid(10001), IsOkAnd(ElementsAre("com.example2.app1")));
112 EXPECT_THAT(controller_.getPackagesForUid(12000), IsOkAnd(ElementsAre("com.example.other")));
113 }
114
TEST_F(NativePermissionControllerTest,updatePackages_ExistingUid)115 TEST_F(NativePermissionControllerTest, updatePackages_ExistingUid) {
116 std::vector<UidPackageState> input{
117 createState(10000, {"com.example.app1", "com.example.app2", "com.example.app3"}),
118 createState(10001, {"com.example2.app1"}),
119 };
120
121 EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
122 // Update packages for existing uid
123 UidPackageState newState = createState(10000, {"com.example.other", "com.example.new"});
124 EXPECT_THAT(controller_.updatePackagesForUid(newState), BinderStatusMatcher::isOk());
125
126 // Verify update
127 EXPECT_THAT(controller_.getPackagesForUid(10000),
128 IsOkAnd(ElementsAre("com.example.other", "com.example.new")));
129 }
130
TEST_F(NativePermissionControllerTest,updatePackages_EmptyRemovesEntry)131 TEST_F(NativePermissionControllerTest, updatePackages_EmptyRemovesEntry) {
132 std::vector<UidPackageState> input{
133 createState(10000, {"com.example.app1"}),
134 };
135
136 EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
137
138 UidPackageState newState{}; // Empty package list
139 newState.uid = 10000;
140 EXPECT_THAT(controller_.updatePackagesForUid(newState), BinderStatusMatcher::isOk());
141 // getPackages for unknown UID should error out
142 EXPECT_THAT(controller_.getPackagesForUid(10000),
143 IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_ARGUMENT)));
144 }
145
TEST_F(NativePermissionControllerTest,validateUidPackagePair_ValidPair)146 TEST_F(NativePermissionControllerTest, validateUidPackagePair_ValidPair) {
147 std::vector<UidPackageState> input{
148 createState(10000, {"com.example.app1", "com.example.app2"}),
149 };
150
151 EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
152
153 EXPECT_THAT(controller_.validateUidPackagePair(10000, "com.example.app1"), IsOkAnd(IsTrue()));
154 }
155
TEST_F(NativePermissionControllerTest,validateUidPackagePair_InvalidPackage)156 TEST_F(NativePermissionControllerTest, validateUidPackagePair_InvalidPackage) {
157 std::vector<UidPackageState> input{
158 createState(10000, {"com.example.app1", "com.example.app2"}),
159 };
160
161 EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
162
163 EXPECT_THAT(controller_.validateUidPackagePair(10000, "com.example.other"), IsOkAnd(IsFalse()));
164 }
165
TEST_F(NativePermissionControllerTest,validateUidPackagePair_UnknownUid)166 TEST_F(NativePermissionControllerTest, validateUidPackagePair_UnknownUid) {
167 std::vector<UidPackageState> input{
168 createState(10000, {"com.example.app1", "com.example.app2"}),
169 };
170
171 EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
172
173 EXPECT_THAT(controller_.validateUidPackagePair(12000, "any.package"), IsOkAnd(IsFalse()));
174 }
175
TEST_F(NativePermissionControllerTest,populatePermissionState_InvalidPermission)176 TEST_F(NativePermissionControllerTest, populatePermissionState_InvalidPermission) {
177 EXPECT_THAT(controller_.populatePermissionState(PermissionEnum::ENUM_SIZE, {}),
178 BinderStatusMatcher::hasException(EX_ILLEGAL_ARGUMENT));
179 EXPECT_THAT(
180 controller_.populatePermissionState(
181 static_cast<PermissionEnum>(static_cast<int>(PermissionEnum::ENUM_SIZE) + 1),
182 {}),
183 BinderStatusMatcher::hasException(EX_ILLEGAL_ARGUMENT));
184 }
185
TEST_F(NativePermissionControllerTest,populatePermissionState_HoldsPermission)186 TEST_F(NativePermissionControllerTest, populatePermissionState_HoldsPermission) {
187 // Unsorted
188 std::vector<int> uids{3, 1, 2, 4, 5};
189
190 EXPECT_THAT(controller_.populatePermissionState(PermissionEnum::MODIFY_AUDIO_ROUTING, uids),
191 BinderStatusMatcher::isOk());
192
193 EXPECT_THAT(controller_.checkPermission(PermissionEnum::MODIFY_AUDIO_ROUTING, 3),
194 IsOkAnd(IsTrue()));
195 }
196
TEST_F(NativePermissionControllerTest,populatePermissionState_DoesNotHoldPermission)197 TEST_F(NativePermissionControllerTest, populatePermissionState_DoesNotHoldPermission) {
198 // Unsorted
199 std::vector<int> uids{3, 1, 2, 4, 5};
200
201 EXPECT_THAT(controller_.populatePermissionState(PermissionEnum::MODIFY_AUDIO_ROUTING, uids),
202 BinderStatusMatcher::isOk());
203
204 EXPECT_THAT(controller_.checkPermission(PermissionEnum::MODIFY_AUDIO_ROUTING, 6),
205 IsOkAnd(IsFalse()));
206 }
207
TEST_F(NativePermissionControllerTest,populatePermissionState_NotInitialized)208 TEST_F(NativePermissionControllerTest, populatePermissionState_NotInitialized) {
209 EXPECT_THAT(controller_.checkPermission(PermissionEnum::MODIFY_AUDIO_ROUTING, 3),
210 IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_STATE)));
211 }
212