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