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 "intention_service.h"
17
18 #include <ipc_skeleton.h>
19 #include <string_ex.h>
20 #include <xcollie/xcollie.h>
21 #include <xcollie/xcollie_define.h>
22
23 #include "devicestatus_define.h"
24 #include "i_plugin.h"
25
26 #undef LOG_TAG
27 #define LOG_TAG "IntentionService"
28
29 namespace OHOS {
30 namespace Msdp {
31 namespace DeviceStatus {
32 namespace {
33 constexpr int32_t SERVER_TIMEOUT { 5 };
34 }
35
IntentionService(IContext * context)36 IntentionService::IntentionService(IContext *context)
37 : context_(context), socketServer_(context), cooperate_(context), drag_(context), dumper_(context, stationary_),
38 boomerangDumper_(context, boomerang_)
39 {}
40
Dump(int32_t fd,const std::vector<std::u16string> & args)41 int32_t IntentionService::Dump(int32_t fd, const std::vector<std::u16string> &args)
42 {
43 std::vector<std::string> argList;
44 std::transform(args.begin(), args.end(), std::back_inserter(argList),
45 [](const std::u16string &arg) {
46 return Str16ToStr8(arg);
47 });
48 dumper_.Dump(fd, argList);
49 return RET_OK;
50 }
51
Enable(Intention intention,MessageParcel & data,MessageParcel & reply)52 int32_t IntentionService::Enable(Intention intention, MessageParcel &data, MessageParcel &reply)
53 {
54 CallingContext context {
55 .intention = intention,
56 .fullTokenId = IPCSkeleton::GetCallingFullTokenID(),
57 .tokenId = IPCSkeleton::GetCallingTokenID(),
58 .uid = IPCSkeleton::GetCallingUid(),
59 .pid = IPCSkeleton::GetCallingPid(),
60 };
61 CHKPR(context_, RET_ERR);
62 int32_t ret = context_->GetDelegateTasks().PostSyncTask([&] {
63 IPlugin *plugin = LoadPlugin(context.intention);
64 CHKPR(plugin, RET_ERR);
65 return plugin->Enable(context, data, reply);
66 });
67 if (ret != RET_OK) {
68 FI_HILOGE("Enable failed, ret:%{public}d", ret);
69 }
70 return ret;
71 }
72
Disable(Intention intention,MessageParcel & data,MessageParcel & reply)73 int32_t IntentionService::Disable(Intention intention, MessageParcel &data, MessageParcel &reply)
74 {
75 CallingContext context {
76 .intention = intention,
77 .fullTokenId = IPCSkeleton::GetCallingFullTokenID(),
78 .tokenId = IPCSkeleton::GetCallingTokenID(),
79 .uid = IPCSkeleton::GetCallingUid(),
80 .pid = IPCSkeleton::GetCallingPid(),
81 };
82 CHKPR(context_, RET_ERR);
83 int32_t ret = context_->GetDelegateTasks().PostSyncTask([&] {
84 IPlugin *plugin = LoadPlugin(context.intention);
85 CHKPR(plugin, RET_ERR);
86 return plugin->Disable(context, data, reply);
87 });
88 if (ret != RET_OK) {
89 FI_HILOGE("Disable failed, ret:%{public}d", ret);
90 }
91 return ret;
92 }
93
Start(Intention intention,MessageParcel & data,MessageParcel & reply)94 int32_t IntentionService::Start(Intention intention, MessageParcel &data, MessageParcel &reply)
95 {
96 CallingContext context {
97 .intention = intention,
98 .fullTokenId = IPCSkeleton::GetCallingFullTokenID(),
99 .tokenId = IPCSkeleton::GetCallingTokenID(),
100 .uid = IPCSkeleton::GetCallingUid(),
101 .pid = IPCSkeleton::GetCallingPid(),
102 };
103 CHKPR(context_, RET_ERR);
104 int32_t ret = context_->GetDelegateTasks().PostSyncTask([&] {
105 IPlugin *plugin = LoadPlugin(context.intention);
106 CHKPR(plugin, RET_ERR);
107 return plugin->Start(context, data, reply);
108 });
109 if (ret != RET_OK) {
110 FI_HILOGE("Start failed, ret:%{public}d", ret);
111 }
112 return ret;
113 }
114
Stop(Intention intention,MessageParcel & data,MessageParcel & reply)115 int32_t IntentionService::Stop(Intention intention, MessageParcel &data, MessageParcel &reply)
116 {
117 CallingContext context {
118 .intention = intention,
119 .fullTokenId = IPCSkeleton::GetCallingFullTokenID(),
120 .tokenId = IPCSkeleton::GetCallingTokenID(),
121 .uid = IPCSkeleton::GetCallingUid(),
122 .pid = IPCSkeleton::GetCallingPid(),
123 };
124 CHKPR(context_, RET_ERR);
125 int32_t ret = context_->GetDelegateTasks().PostSyncTask([&] {
126 IPlugin *plugin = LoadPlugin(context.intention);
127 CHKPR(plugin, RET_ERR);
128 return plugin->Stop(context, data, reply);
129 });
130 if (ret != RET_OK) {
131 FI_HILOGE("Stop failed, ret:%{public}d", ret);
132 }
133 return ret;
134 }
135
AddWatch(Intention intention,uint32_t id,MessageParcel & data,MessageParcel & reply)136 int32_t IntentionService::AddWatch(Intention intention, uint32_t id, MessageParcel &data, MessageParcel &reply)
137 {
138 CHKPR(context_, RET_ERR);
139 int32_t timerId = HiviewDFX::XCollie::GetInstance().SetTimer("DeviceStatusIntensionServerAddWatch", SERVER_TIMEOUT,
140 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
141 CallingContext context {
142 .intention = intention,
143 .fullTokenId = IPCSkeleton::GetCallingFullTokenID(),
144 .tokenId = IPCSkeleton::GetCallingTokenID(),
145 .uid = IPCSkeleton::GetCallingUid(),
146 .pid = IPCSkeleton::GetCallingPid(),
147 };
148 int32_t ret = context_->GetDelegateTasks().PostSyncTask([&] {
149 IPlugin *plugin = LoadPlugin(context.intention);
150 CHKPR(plugin, RET_ERR);
151 return plugin->AddWatch(context, id, data, reply);
152 });
153 if (ret != RET_OK) {
154 FI_HILOGE("AddWatch failed, ret:%{public}d", ret);
155 }
156 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
157 return ret;
158 }
159
RemoveWatch(Intention intention,uint32_t id,MessageParcel & data,MessageParcel & reply)160 int32_t IntentionService::RemoveWatch(Intention intention, uint32_t id, MessageParcel &data, MessageParcel &reply)
161 {
162 CallingContext context {
163 .intention = intention,
164 .fullTokenId = IPCSkeleton::GetCallingFullTokenID(),
165 .tokenId = IPCSkeleton::GetCallingTokenID(),
166 .uid = IPCSkeleton::GetCallingUid(),
167 .pid = IPCSkeleton::GetCallingPid(),
168 };
169 CHKPR(context_, RET_ERR);
170 int32_t ret = context_->GetDelegateTasks().PostSyncTask([&] {
171 IPlugin *plugin = LoadPlugin(context.intention);
172 CHKPR(plugin, RET_ERR);
173 return plugin->RemoveWatch(context, id, data, reply);
174 });
175 if (ret != RET_OK) {
176 FI_HILOGE("RemoveWatch failed, ret:%{public}d", ret);
177 }
178 return ret;
179 }
180
SetParam(Intention intention,uint32_t id,MessageParcel & data,MessageParcel & reply)181 int32_t IntentionService::SetParam(Intention intention, uint32_t id, MessageParcel &data, MessageParcel &reply)
182 {
183 CallingContext context {
184 .intention = intention,
185 .fullTokenId = IPCSkeleton::GetCallingFullTokenID(),
186 .tokenId = IPCSkeleton::GetCallingTokenID(),
187 .uid = IPCSkeleton::GetCallingUid(),
188 .pid = IPCSkeleton::GetCallingPid(),
189 };
190 CHKPR(context_, RET_ERR);
191 int32_t ret = context_->GetDelegateTasks().PostSyncTask([&] {
192 IPlugin *plugin = LoadPlugin(context.intention);
193 CHKPR(plugin, RET_ERR);
194 return plugin->SetParam(context, id, data, reply);
195 });
196 if (ret != RET_OK) {
197 FI_HILOGE("SetParam failed, ret:%{public}d", ret);
198 }
199 return ret;
200 }
201
GetParam(Intention intention,uint32_t id,MessageParcel & data,MessageParcel & reply)202 int32_t IntentionService::GetParam(Intention intention, uint32_t id, MessageParcel &data, MessageParcel &reply)
203 {
204 CallingContext context {
205 .intention = intention,
206 .fullTokenId = IPCSkeleton::GetCallingFullTokenID(),
207 .tokenId = IPCSkeleton::GetCallingTokenID(),
208 .uid = IPCSkeleton::GetCallingUid(),
209 .pid = IPCSkeleton::GetCallingPid(),
210 };
211 CHKPR(context_, RET_ERR);
212 int32_t ret = context_->GetDelegateTasks().PostSyncTask([&] {
213 IPlugin *plugin = LoadPlugin(context.intention);
214 CHKPR(plugin, RET_ERR);
215 return plugin->GetParam(context, id, data, reply);
216 });
217 if (ret != RET_OK) {
218 FI_HILOGE("GetParam failed, ret:%{public}d", ret);
219 }
220 return ret;
221 }
222
Control(Intention intention,uint32_t id,MessageParcel & data,MessageParcel & reply)223 int32_t IntentionService::Control(Intention intention, uint32_t id, MessageParcel &data, MessageParcel &reply)
224 {
225 CHKPR(context_, RET_ERR);
226 int32_t timerId = HiviewDFX::XCollie::GetInstance().SetTimer("DeviceStatusIntensionServerControl", SERVER_TIMEOUT,
227 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
228 CallingContext context {
229 .intention = intention,
230 .fullTokenId = IPCSkeleton::GetCallingFullTokenID(),
231 .tokenId = IPCSkeleton::GetCallingTokenID(),
232 .uid = IPCSkeleton::GetCallingUid(),
233 .pid = IPCSkeleton::GetCallingPid(),
234 };
235 int32_t ret = context_->GetDelegateTasks().PostSyncTask([&] {
236 IPlugin *plugin = LoadPlugin(context.intention);
237 CHKPR(plugin, RET_ERR);
238 return plugin->Control(context, id, data, reply);
239 });
240 if (ret != RET_OK) {
241 FI_HILOGE("Control failed, ret:%{public}d", ret);
242 }
243 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
244 return ret;
245 }
246
LoadPlugin(Intention intention)247 IPlugin* IntentionService::LoadPlugin(Intention intention)
248 {
249 CALL_DEBUG_ENTER;
250 switch (intention) {
251 case Intention::SOCKET: {
252 return &socketServer_;
253 }
254 case Intention::STATIONARY: {
255 return &stationary_;
256 }
257 case Intention::COOPERATE: {
258 return &cooperate_;
259 }
260 case Intention::DRAG: {
261 return &drag_;
262 }
263 case Intention::BOOMERANG: {
264 return &boomerang_;
265 }
266 default: {
267 return nullptr;
268 }
269 }
270 }
271 } // namespace DeviceStatus
272 } // namespace Msdp
273 } // namespace OHOS
274