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