1 /*
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cooperate_server.h"
17
18 #include <chrono>
19
20 #include <tokenid_kit.h>
21
22 #include "accesstoken_kit.h"
23 #include "devicestatus_define.h"
24 #include "ipc_skeleton.h"
25 #include "utility.h"
26
27 #undef LOG_TAG
28 #define LOG_TAG "CooperateServer"
29
30 namespace OHOS {
31 namespace Msdp {
32 namespace DeviceStatus {
33 namespace {
34 constexpr int32_t REPEAT_ONCE { 1 };
35 constexpr int32_t DEFAULT_UNLOAD_COOLING_TIME_MS { 60000 };
36 }
37
CooperateServer(IContext * context)38 CooperateServer::CooperateServer(IContext *context)
39 : context_(context)
40 {
41 (void) context_;
42 (void) unloadTimerId_;
43 }
44
EnableCooperate(CallingContext & context,int32_t userData)45 int32_t CooperateServer::EnableCooperate(CallingContext &context, int32_t userData)
46 {
47 CALL_DEBUG_ENTER;
48 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
49 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
50 return ret;
51 }
52 CHKPR(context_, RET_ERR);
53 if (unloadTimerId_ >= 0) {
54 context_->GetTimerManager().RemoveTimer(unloadTimerId_);
55 }
56 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
57 CHKPR(cooperate, RET_ERR);
58 cooperate->Enable(context.tokenId, context.pid, userData);
59 return RET_OK;
60 }
61
DisableCooperate(CallingContext & context,int32_t userData)62 int32_t CooperateServer::DisableCooperate(CallingContext &context, int32_t userData)
63 {
64 CALL_DEBUG_ENTER;
65 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
66 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
67 return ret;
68 }
69 CHKPR(context_, RET_ERR);
70 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
71 CHKPR(cooperate, RET_ERR);
72 cooperate->Disable(context.pid, userData);
73 unloadTimerId_ = context_->GetTimerManager().AddTimer(DEFAULT_UNLOAD_COOLING_TIME_MS, REPEAT_ONCE,
74 []() {
75 FI_HILOGI("Unload \'cooperate\' module");
76 });
77 if (unloadTimerId_ < 0) {
78 FI_HILOGE("AddTimer failed, will not unload Cooperate");
79 }
80 return RET_OK;
81 }
82
StartCooperate(CallingContext & context,const std::string & remoteNetworkId,int32_t userData,int32_t startDeviceId,bool checkPermission)83 int32_t CooperateServer::StartCooperate(CallingContext &context, const std::string& remoteNetworkId,
84 int32_t userData, int32_t startDeviceId, bool checkPermission)
85 {
86 CALL_DEBUG_ENTER;
87 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
88 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
89 return ret;
90 }
91 CHKPR(context_, RET_ERR);
92 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
93 CHKPR(cooperate, RET_ERR);
94 return cooperate->Start(context.pid, userData, remoteNetworkId, startDeviceId, context.uid);
95 }
96
StartCooperateWithOptions(CallingContext & context,const std::string & remoteNetworkId,int32_t userData,int32_t startDeviceId,CooperateOptions options)97 int32_t CooperateServer::StartCooperateWithOptions(CallingContext &context, const std::string& remoteNetworkId,
98 int32_t userData, int32_t startDeviceId, CooperateOptions options)
99 {
100 CALL_DEBUG_ENTER;
101 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
102 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
103 return ret;
104 }
105 CHKPR(context_, RET_ERR);
106 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
107 CHKPR(cooperate, RET_ERR);
108 return cooperate->StartWithOptions(context.pid, userData, remoteNetworkId, startDeviceId, options);
109 }
110
StopCooperate(CallingContext & context,int32_t userData,bool isUnchained,bool checkPermission)111 int32_t CooperateServer::StopCooperate(CallingContext &context, int32_t userData, bool isUnchained,
112 bool checkPermission)
113 {
114 CALL_DEBUG_ENTER;
115 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
116 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
117 return ret;
118 }
119 CHKPR(context_, RET_ERR);
120 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
121 CHKPR(cooperate, RET_ERR);
122 return cooperate->Stop(context.pid, userData, isUnchained);
123 }
124
RegisterCooperateListener(CallingContext & context)125 int32_t CooperateServer::RegisterCooperateListener(CallingContext &context)
126 {
127 CALL_DEBUG_ENTER;
128 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
129 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
130 return ret;
131 }
132 CHKPR(context_, RET_ERR);
133 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
134 CHKPR(cooperate, RET_ERR);
135 return cooperate->RegisterListener(context.pid);
136 }
137
UnregisterCooperateListener(CallingContext & context)138 int32_t CooperateServer::UnregisterCooperateListener(CallingContext &context)
139 {
140 CALL_DEBUG_ENTER;
141 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
142 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
143 return ret;
144 }
145 CHKPR(context_, RET_ERR);
146 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
147 CHKPR(cooperate, RET_ERR);
148 return cooperate->UnregisterListener(context.pid);
149 }
150
RegisterHotAreaListener(CallingContext & context,int32_t userData,bool checkPermission)151 int32_t CooperateServer::RegisterHotAreaListener(CallingContext &context, int32_t userData, bool checkPermission)
152 {
153 CALL_DEBUG_ENTER;
154 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
155 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
156 return ret;
157 }
158 CHKPR(context_, RET_ERR);
159 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
160 CHKPR(cooperate, RET_ERR);
161 return cooperate->RegisterHotAreaListener(context.pid);
162 }
163
UnregisterHotAreaListener(CallingContext & context)164 int32_t CooperateServer::UnregisterHotAreaListener(CallingContext &context)
165 {
166 CALL_DEBUG_ENTER;
167 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
168 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
169 return ret;
170 }
171 CHKPR(context_, RET_ERR);
172 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
173 CHKPR(cooperate, RET_ERR);
174 return cooperate->UnregisterHotAreaListener(context.pid);
175 }
176
RegisterMouseEventListener(CallingContext & context,const std::string & networkId)177 int32_t CooperateServer::RegisterMouseEventListener(CallingContext &context, const std::string &networkId)
178 {
179 CALL_DEBUG_ENTER;
180 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
181 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
182 return ret;
183 }
184 CHKPR(context_, RET_ERR);
185 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
186 CHKPR(cooperate, RET_ERR);
187 return cooperate->RegisterEventListener(context.pid, networkId);
188 }
189
UnregisterMouseEventListener(CallingContext & context,const std::string & networkId)190 int32_t CooperateServer::UnregisterMouseEventListener(CallingContext &context, const std::string &networkId)
191 {
192 CALL_DEBUG_ENTER;
193 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
194 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
195 return ret;
196 }
197 CHKPR(context_, RET_ERR);
198 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
199 CHKPR(cooperate, RET_ERR);
200 return cooperate->UnregisterEventListener(context.pid, networkId);
201 }
202
GetCooperateStateSync(CallingContext & context,const std::string & udid,bool & state)203 int32_t CooperateServer::GetCooperateStateSync(CallingContext &context, const std::string &udid, bool &state)
204 {
205 CALL_DEBUG_ENTER;
206 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
207 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
208 return ret;
209 }
210 CHKPR(context_, RET_ERR);
211 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
212 CHKPR(cooperate, RET_ERR);
213 if (cooperate->GetCooperateState(udid, state) != RET_OK) {
214 FI_HILOGE("GetCooperateState failed");
215 return RET_ERR;
216 }
217 FI_HILOGI("GetCooperateState for udId:%{public}s successfully, state:%{public}s",
218 Utility::Anonymize(udid).c_str(), state ? "true" : "false");
219 return RET_OK;
220 }
221
GetCooperateStateAsync(CallingContext & context,const std::string & networkId,int32_t userData,bool isCheckPermission)222 int32_t CooperateServer::GetCooperateStateAsync(CallingContext &context, const std::string &networkId,
223 int32_t userData, bool isCheckPermission)
224 {
225 CALL_DEBUG_ENTER;
226 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
227 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
228 return ret;
229 }
230 CHKPR(context_, RET_ERR);
231 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
232 CHKPR(cooperate, RET_ERR);
233 return cooperate->GetCooperateState(context.pid, userData, networkId);
234 }
235
SetDamplingCoefficient(CallingContext & context,uint32_t direction,double coefficient)236 int32_t CooperateServer::SetDamplingCoefficient(CallingContext &context, uint32_t direction, double coefficient)
237 {
238 CALL_DEBUG_ENTER;
239 if (int32_t ret = CheckPermission(context); ret != RET_OK) {
240 FI_HILOGE("CheckPermission failed, ret:%{public}d", ret);
241 return ret;
242 }
243 CHKPR(context_, RET_ERR);
244 ICooperate* cooperate = context_->GetPluginManager().LoadCooperate();
245 CHKPR(cooperate, RET_ERR);
246 FI_HILOGI("SetDamplingCoefficient(0x%{public}x, %{public}.3f)", direction, coefficient);
247 return cooperate->SetDamplingCoefficient(direction, coefficient);
248 }
249
CheckCooperatePermission(CallingContext & context)250 bool CooperateServer::CheckCooperatePermission(CallingContext &context)
251 {
252 CALL_DEBUG_ENTER;
253 Security::AccessToken::AccessTokenID callerToken = context.tokenId;
254 int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken,
255 COOPERATE_PERMISSION);
256 return result == Security::AccessToken::PERMISSION_GRANTED;
257 }
258
IsSystemServiceCalling(CallingContext & context)259 bool CooperateServer::IsSystemServiceCalling(CallingContext &context)
260 {
261 const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(context.tokenId);
262 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
263 flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
264 FI_HILOGD("system service calling, flag:%{public}u", flag);
265 return true;
266 }
267 return false;
268 }
269
IsSystemCalling(CallingContext & context)270 bool CooperateServer::IsSystemCalling(CallingContext &context)
271 {
272 if (IsSystemServiceCalling(context)) {
273 return true;
274 }
275 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(context.fullTokenId);
276 }
277
CheckPermission(CallingContext & context)278 int32_t CooperateServer::CheckPermission(CallingContext &context)
279 {
280 if (!IsSystemCalling(context)) {
281 FI_HILOGE("The caller is not system hap");
282 return COMMON_NOT_SYSTEM_APP;
283 }
284 if (!CheckCooperatePermission(context)) {
285 FI_HILOGE("The caller has no COOPERATE_MANAGER permission");
286 return COMMON_PERMISSION_CHECK_ERROR;
287 }
288 return RET_OK;
289 }
290 } // namespace DeviceStatus
291 } // namespace Msdp
292 } // namespace OHOS
293