• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "stationary_server.h"
17 #ifdef MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
18 #include "hisysevent.h"
19 #endif // MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
20 #ifdef MSDP_HIVIEWDFX_HITRACE_ENABLE
21 #include "hitrace_meter.h"
22 #endif // MSDP_HIVIEWDFX_HITRACE_ENABLE
23 
24 #include "default_params.h"
25 #include "devicestatus_define.h"
26 #include "devicestatus_dumper.h"
27 #include "devicestatus_hisysevent.h"
28 #include "stationary_data.h"
29 #include "stationary_params.h"
30 
31 #undef LOG_TAG
32 #define LOG_TAG "StationaryServer"
33 
34 namespace OHOS {
35 namespace Msdp {
36 namespace DeviceStatus {
37 namespace {
38 #ifdef MOTION_ENABLE
39 constexpr int32_t MOTION_TYPE_STAND = 3602;
40 constexpr int32_t STATUS_ENTER = 1;
41 constexpr int32_t STATUS_EXIT = 0;
42 std::map<Type, int32_t> MOTION_TYPE_MAP {
43     { Type::TYPE_STAND, MOTION_TYPE_STAND },
44 };
45 std::map<int32_t, Type> DEVICE_STATUS_TYPE_MAP {
46     { MOTION_TYPE_STAND, Type::TYPE_STAND },
47 };
48 #else
49 constexpr int32_t RET_NO_SUPPORT = 801;
50 #endif
51 } // namespace
52 
53 #ifdef MOTION_ENABLE
OnMotionChanged(const MotionEvent & motionEvent)54 void MotionCallback::OnMotionChanged(const MotionEvent &motionEvent)
55 {
56     Data data;
57     data.type = DEVICE_STATUS_TYPE_MAP[motionEvent.type];
58     switch (motionEvent.status) {
59         case STATUS_ENTER:
60             data.value = VALUE_ENTER;
61             break;
62         case STATUS_EXIT:
63             data.value = VALUE_EXIT;
64             break;
65         default:
66             data.value = VALUE_INVALID;
67             break;
68     }
69     event_(data);
70 }
71 
OnRemoteDied(const wptr<IRemoteObject> & remote)72 void RemoteDevStaCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
73 {
74     event_(remote);
75 }
76 #endif
77 
StationaryServer()78 StationaryServer::StationaryServer()
79 {
80     manager_.Init();
81 #ifdef MOTION_ENABLE
82     auto deathRecipientCB = [this](const wptr<IRemoteObject> &remote) {
83         this->StationaryServerDeathRecipient(remote);
84     };
85     devStaCBDeathRecipient_ = new (std::nothrow) RemoteDevStaCallbackDeathRecipient(deathRecipientCB);
86 #endif
87 }
88 
Enable(CallingContext & context,MessageParcel & data,MessageParcel & reply)89 int32_t StationaryServer::Enable(CallingContext &context, MessageParcel &data, MessageParcel &reply)
90 {
91     CALL_DEBUG_ENTER;
92     return RET_ERR;
93 }
94 
Disable(CallingContext & context,MessageParcel & data,MessageParcel & reply)95 int32_t StationaryServer::Disable(CallingContext &context, MessageParcel &data, MessageParcel &reply)
96 {
97     CALL_DEBUG_ENTER;
98     return RET_ERR;
99 }
100 
Start(CallingContext & context,MessageParcel & data,MessageParcel & reply)101 int32_t StationaryServer::Start(CallingContext &context, MessageParcel &data, MessageParcel &reply)
102 {
103     CALL_DEBUG_ENTER;
104     return RET_ERR;
105 }
106 
Stop(CallingContext & context,MessageParcel & data,MessageParcel & reply)107 int32_t StationaryServer::Stop(CallingContext &context, MessageParcel &data, MessageParcel &reply)
108 {
109     CALL_DEBUG_ENTER;
110     return RET_ERR;
111 }
112 
AddWatch(CallingContext & context,uint32_t id,MessageParcel & data,MessageParcel & reply)113 int32_t StationaryServer::AddWatch(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply)
114 {
115     if (id != StationaryRequestID::SUBSCRIBE_STATIONARY) {
116         FI_HILOGE("Unexpected request ID (%{public}u)", id);
117         return RET_ERR;
118     }
119     SubscribeStationaryParam param {};
120 
121     if (!param.Unmarshalling(data)) {
122         FI_HILOGE("SubscribeStationaryParam::Unmarshalling fail");
123         return RET_ERR;
124     }
125     if (param.type_ == Type::TYPE_STAND) {
126 #ifdef MOTION_ENABLE
127         return SubscribeMotion(param.type_, param.callback_);
128 #else
129         return RET_NO_SUPPORT;
130 #endif
131     } else {
132         Subscribe(context, param.type_, param.event_, param.latency_, param.callback_);
133     }
134     return RET_OK;
135 }
136 
RemoveWatch(CallingContext & context,uint32_t id,MessageParcel & data,MessageParcel & reply)137 int32_t StationaryServer::RemoveWatch(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply)
138 {
139     if (id != StationaryRequestID::UNSUBSCRIBE_STATIONARY) {
140         FI_HILOGE("Unexpected request ID (%{public}u)", id);
141         return RET_ERR;
142     }
143     UnsubscribeStationaryParam param {};
144 
145     if (!param.Unmarshalling(data)) {
146         FI_HILOGE("UnsubscribeStationaryParam::Unmarshalling fail");
147         return RET_ERR;
148     }
149     if (param.type_ == Type::TYPE_STAND) {
150 #ifdef MOTION_ENABLE
151         return UnsubscribeMotion(param.type_, param.callback_);
152 #else
153         return RET_NO_SUPPORT;
154 #endif
155     } else {
156         Unsubscribe(context, param.type_, param.event_, param.callback_);
157     }
158     return RET_OK;
159 }
160 
SetParam(CallingContext & context,uint32_t id,MessageParcel & data,MessageParcel & reply)161 int32_t StationaryServer::SetParam(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply)
162 {
163     CALL_DEBUG_ENTER;
164     return RET_ERR;
165 }
166 
GetParam(CallingContext & context,uint32_t id,MessageParcel & data,MessageParcel & reply)167 int32_t StationaryServer::GetParam(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply)
168 {
169     if (id != StationaryRequestID::GET_STATIONARY_DATA) {
170         FI_HILOGE("Unexpected request ID (%{public}u)", id);
171         return RET_ERR;
172     }
173     GetStaionaryDataParam param {};
174 
175     if (!param.Unmarshalling(data)) {
176         FI_HILOGE("GetStaionaryDataParam::Unmarshalling fail");
177         return RET_ERR;
178     }
179     GetStaionaryDataReply dataReply { GetCache(context, param.type_) };
180     if (!dataReply.Marshalling(reply)) {
181         FI_HILOGE("GetStaionaryDataReply::Marshalling fail");
182         return RET_ERR;
183     }
184     return RET_OK;
185 }
186 
Control(CallingContext & context,uint32_t id,MessageParcel & data,MessageParcel & reply)187 int32_t StationaryServer::Control(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply)
188 {
189     CALL_DEBUG_ENTER;
190     return RET_ERR;
191 }
192 
DumpDeviceStatusSubscriber(int32_t fd) const193 void StationaryServer::DumpDeviceStatusSubscriber(int32_t fd) const
194 {
195     DS_DUMPER->DumpDeviceStatusSubscriber(fd);
196 }
197 
DumpDeviceStatusChanges(int32_t fd) const198 void StationaryServer::DumpDeviceStatusChanges(int32_t fd) const
199 {
200     DS_DUMPER->DumpDeviceStatusChanges(fd);
201 }
202 
DumpCurrentDeviceStatus(int32_t fd)203 void StationaryServer::DumpCurrentDeviceStatus(int32_t fd)
204 {
205     std::vector<Data> datas;
206 
207     for (auto type = TYPE_ABSOLUTE_STILL; type <= TYPE_LID_OPEN; type = static_cast<Type>(type + 1)) {
208         Data data = manager_.GetLatestDeviceStatusData(type);
209         if (data.value != OnChangedValue::VALUE_INVALID) {
210             datas.emplace_back(data);
211         }
212     }
213     DS_DUMPER->DumpDeviceStatusCurrentStatus(fd, datas);
214 }
215 
Subscribe(CallingContext & context,Type type,ActivityEvent event,ReportLatencyNs latency,sptr<IRemoteDevStaCallback> callback)216 void StationaryServer::Subscribe(CallingContext &context, Type type, ActivityEvent event,
217     ReportLatencyNs latency, sptr<IRemoteDevStaCallback> callback)
218 {
219     FI_HILOGI("SubscribeStationary(type:%{public}d,event:%{public}d,latency:%{public}d)", type, event, latency);
220     auto appInfo = std::make_shared<AppInfo>();
221     appInfo->uid = context.uid;
222     appInfo->pid = context.pid;
223     appInfo->tokenId = context.tokenId;
224     manager_.GetPackageName(appInfo->tokenId, appInfo->packageName);
225     appInfo->type = type;
226     appInfo->callback = callback;
227     DS_DUMPER->SaveAppInfo(appInfo);
228 #ifdef MSDP_HIVIEWDFX_HITRACE_ENABLE
229     StartTrace(HITRACE_TAG_MSDP, "serviceSubscribeStart");
230 #endif // MSDP_HIVIEWDFX_HITRACE_ENABLE
231     manager_.Subscribe(type, event, latency, callback);
232 #ifdef MSDP_HIVIEWDFX_HITRACE_ENABLE
233     FinishTrace(HITRACE_TAG_MSDP);
234 #endif // MSDP_HIVIEWDFX_HITRACE_ENABLE
235     ReportSensorSysEvent(context, type, true);
236     WriteSubscribeHiSysEvent(appInfo->uid, appInfo->packageName, type);
237 }
238 
Unsubscribe(CallingContext & context,Type type,ActivityEvent event,sptr<IRemoteDevStaCallback> callback)239 void StationaryServer::Unsubscribe(CallingContext &context, Type type,
240     ActivityEvent event, sptr<IRemoteDevStaCallback> callback)
241 {
242     FI_HILOGI("UnsubscribeStationary(type:%{public}d,event:%{public}d)", type, event);
243     auto appInfo = std::make_shared<AppInfo>();
244     appInfo->uid = context.uid;
245     appInfo->pid = context.pid;
246     appInfo->tokenId = context.tokenId;
247     appInfo->packageName = DS_DUMPER->GetPackageName(appInfo->tokenId);
248     appInfo->type = type;
249     appInfo->callback = callback;
250     DS_DUMPER->RemoveAppInfo(appInfo);
251 #ifdef MSDP_HIVIEWDFX_HITRACE_ENABLE
252     StartTrace(HITRACE_TAG_MSDP, "serviceUnSubscribeStart");
253 #endif // MSDP_HIVIEWDFX_HITRACE_ENABLE
254     manager_.Unsubscribe(type, event, callback);
255 #ifdef MSDP_HIVIEWDFX_HITRACE_ENABLE
256     FinishTrace(HITRACE_TAG_MSDP);
257 #endif // MSDP_HIVIEWDFX_HITRACE_ENABLE
258     ReportSensorSysEvent(context, type, false);
259     WriteUnSubscribeHiSysEvent(appInfo->uid, appInfo->packageName, type);
260 }
261 
GetCache(CallingContext & context,const Type & type)262 Data StationaryServer::GetCache(CallingContext &context, const Type &type)
263 {
264     return manager_.GetLatestDeviceStatusData(type);
265 }
266 
ReportSensorSysEvent(CallingContext & context,int32_t type,bool enable)267 void StationaryServer::ReportSensorSysEvent(CallingContext &context, int32_t type, bool enable)
268 {
269 #ifdef MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
270     std::string packageName;
271     manager_.GetPackageName(context.tokenId, packageName);
272     int32_t ret = HiSysEventWrite(
273         OHOS::HiviewDFX::HiSysEvent::Domain::MSDP,
274         std::string(enable ? "Subscribe" : "Unsubscribe"),
275         OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
276         "UID", context.uid,
277         "PKGNAME", packageName,
278         "TYPE", type);
279     if (ret != 0) {
280         FI_HILOGE("HiviewDFX write failed, error:%{public}d", ret);
281     }
282 #endif // MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
283 }
284 
285 #ifdef MOTION_ENABLE
SubscribeMotion(Type type,sptr<IRemoteDevStaCallback> callback)286 int32_t StationaryServer::SubscribeMotion(Type type, sptr<IRemoteDevStaCallback> callback)
287 {
288     FI_HILOGD("Enter");
289     std::lock_guard lockGrd(mtx_);
290     int32_t ret = 0;
291     if (motionCallback_ == nullptr) {
292         FI_HILOGI("create motion callback and subscribe");
293         auto event = [this, type](const Data &data) {
294             this->NotifyMotionCallback(type, data);
295         };
296         motionCallback_ = new (std::nothrow) MotionCallback(event);
297         ret = SubscribeCallback(MOTION_TYPE_MAP[type], motionCallback_);
298         if (ret != RET_OK) {
299             FI_HILOGE("subscribe motion failed, ret = %{public}d", ret);
300             motionCallback_ = nullptr;
301             return ret;
302         }
303     }
304     FI_HILOGI("motionCallback is not null, subscribe ok");
305     auto iter = deviceStatusMotionCallbacks_.find(type);
306     if (iter == deviceStatusMotionCallbacks_.end()) {
307         deviceStatusMotionCallbacks_[type] = std::set<sptr<IRemoteDevStaCallback>, DevStaCallbackCmp>();
308     }
309     deviceStatusMotionCallbacks_[type].insert(callback);
310     auto object = callback->AsObject();
311     object->AddDeathRecipient(devStaCBDeathRecipient_);
312     if (motionCallback_ != nullptr && cacheData_.find(type) != cacheData_.end()) {
313         callback->OnDeviceStatusChanged(cacheData_[type]);
314     }
315     return ret;
316 }
317 
UnsubscribeMotion(Type type,sptr<IRemoteDevStaCallback> callback)318 int32_t StationaryServer::UnsubscribeMotion(Type type, sptr<IRemoteDevStaCallback> callback)
319 {
320     FI_HILOGI("Enter");
321     std::lock_guard lockGrd(mtx_);
322     int32_t ret = 0;
323     auto iter = deviceStatusMotionCallbacks_.find(type);
324     if (iter == deviceStatusMotionCallbacks_.end()) {
325         FI_HILOGE("dont find callback set in callbacks, failed");
326         return RET_ERR;
327     }
328     auto callbackIter = deviceStatusMotionCallbacks_[type].find(callback);
329     if (callbackIter == deviceStatusMotionCallbacks_[type].end()) {
330         FI_HILOGE("dont find callback in callback set, failed");
331         return RET_ERR;
332     }
333     deviceStatusMotionCallbacks_[type].erase(callbackIter);
334     auto object = callback->AsObject();
335     object->RemoveDeathRecipient(devStaCBDeathRecipient_);
336     if (deviceStatusMotionCallbacks_[type].size() == 0) {
337         ret = UnsubscribeCallback(MOTION_TYPE_MAP[type], motionCallback_);
338         motionCallback_ = nullptr;
339         if (ret != RET_OK) {
340             FI_HILOGE("unsubscribe motion failed, ret = %{public}d", ret);
341             return ret;
342         }
343         FI_HILOGI("unsubscribe motion succ");
344         auto cacheIter = cacheData_.find(type);
345         if (cacheIter != cacheData_.end()) {
346             cacheData_.erase(cacheIter);
347             FI_HILOGI("cache data clear");
348         }
349     }
350     return ret;
351 }
352 
StationaryServerDeathRecipient(const wptr<IRemoteObject> & remote)353 void StationaryServer::StationaryServerDeathRecipient(const wptr<IRemoteObject> &remote)
354 {
355     FI_HILOGW("Enter recv death notice");
356     sptr<IRemoteObject> client = remote.promote();
357     if (client == nullptr) {
358         FI_HILOGE("OnRemoteDied failed, client is nullptr");
359         return;
360     }
361     sptr<IRemoteDevStaCallback> callback = iface_cast<IRemoteDevStaCallback>(client);
362     if (callback == nullptr) {
363         FI_HILOGE("OnRemoteDied failed, callback is nullptr");
364         return;
365     }
366     std::vector<std::pair<Type, sptr<IRemoteDevStaCallback>>> delCallbacks;
367     {
368         std::lock_guard lockGrd(mtx_);
369         for (auto &[type, set] : deviceStatusMotionCallbacks_) {
370             for (auto &callbackInSet : set) {
371                 if (callbackInSet->AsObject() == callback->AsObject()) {
372                     delCallbacks.push_back(std::make_pair(type, callbackInSet));
373                 }
374             }
375         }
376     }
377     for (auto &[delType, delCallback] : delCallbacks) {
378         UnsubscribeMotion(delType, delCallback);
379         FI_HILOGW("remote died, unsubscribe motion");
380     }
381 }
382 
NotifyMotionCallback(Type type,const Data & data)383 void StationaryServer::NotifyMotionCallback(Type type, const Data &data)
384 {
385     FI_HILOGI("Enter, type %{public}d, data.value %{public}d", type, data.value);
386     std::lock_guard lockGrd(mtx_);
387     cacheData_[type] = data;
388     auto iter = deviceStatusMotionCallbacks_.find(type);
389     if (iter == deviceStatusMotionCallbacks_.end()) {
390         FI_HILOGW("callbacks is empty");
391         return;
392     }
393     for (auto callback : iter->second) {
394         callback->OnDeviceStatusChanged(data);
395     }
396 }
397 #endif
398 } // namespace DeviceStatus
399 } // namespace Msdp
400 } // namespace OHOS