• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #include "gnss_status_callback_host.h"
16 
17 #include "napi/native_common.h"
18 
19 #include "common_utils.h"
20 #include "ipc_skeleton.h"
21 #include "location_log.h"
22 #include "location_napi_adapter.h"
23 #include "napi_util.h"
24 
25 namespace OHOS {
26 namespace Location {
GnssStatusCallbackHost()27 GnssStatusCallbackHost::GnssStatusCallbackHost()
28 {
29     env_ = nullptr;
30     handlerCb_ = nullptr;
31     remoteDied_ = false;
32 }
33 
~GnssStatusCallbackHost()34 GnssStatusCallbackHost::~GnssStatusCallbackHost()
35 {
36 }
37 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)38 int GnssStatusCallbackHost::OnRemoteRequest(
39     uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option)
40 {
41     LBSLOGD(GNSS_STATUS_CALLBACK, "GnssStatusCallbackHost::OnRemoteRequest!");
42     if (data.ReadInterfaceToken() != GetDescriptor()) {
43         LBSLOGE(GNSS_STATUS_CALLBACK, "invalid token.");
44         return -1;
45     }
46     if (remoteDied_) {
47         LBSLOGD(GNSS_STATUS_CALLBACK, "Failed to `%{public}s`,Remote service is died!", __func__);
48         return -1;
49     }
50 
51     switch (code) {
52         case RECEIVE_STATUS_INFO_EVENT: {
53             std::unique_ptr<SatelliteStatus> statusInfo = SatelliteStatus::Unmarshalling(data);
54             Send(statusInfo);
55             break;
56         }
57         default: {
58             IPCObjectStub::OnRemoteRequest(code, data, reply, option);
59             break;
60         }
61     }
62     return 0;
63 }
64 
IsRemoteDied()65 bool GnssStatusCallbackHost::IsRemoteDied()
66 {
67     return remoteDied_;
68 }
69 
Send(std::unique_ptr<SatelliteStatus> & statusInfo)70 bool GnssStatusCallbackHost::Send(std::unique_ptr<SatelliteStatus>& statusInfo)
71 {
72     std::shared_lock<std::shared_mutex> guard(mutex_);
73 
74     uv_loop_s *loop = nullptr;
75     NAPI_CALL_BASE(env_, napi_get_uv_event_loop(env_, &loop), false);
76     if (loop == nullptr) {
77         LBSLOGE(GNSS_STATUS_CALLBACK, "loop == nullptr.");
78         return false;
79     }
80     uv_work_t *work = new (std::nothrow) uv_work_t;
81     if (work == nullptr) {
82         LBSLOGE(GNSS_STATUS_CALLBACK, "work == nullptr.");
83         return false;
84     }
85     GnssStatusAsyncContext *context = new (std::nothrow) GnssStatusAsyncContext(env_);
86     if (context == nullptr) {
87         LBSLOGE(GNSS_STATUS_CALLBACK, "context == nullptr.");
88         return false;
89     }
90     context->env = env_;
91     context->callback[SUCCESS_CALLBACK] = handlerCb_;
92     context->statusInfo = std::move(statusInfo);
93     work->data = context;
94     UvQueueWork(loop, work);
95     return true;
96 }
97 
UvQueueWork(uv_loop_s * loop,uv_work_t * work)98 void GnssStatusCallbackHost::UvQueueWork(uv_loop_s* loop, uv_work_t* work)
99 {
100     uv_queue_work(
101         loop,
102         work,
103         [](uv_work_t *work) {},
104         [](uv_work_t *work, int status) {
105             GnssStatusAsyncContext *context = nullptr;
106             napi_handle_scope scope = nullptr;
107             if (work == nullptr) {
108                 LBSLOGE(LOCATOR_CALLBACK, "work is nullptr!");
109                 return;
110             }
111             context = static_cast<GnssStatusAsyncContext *>(work->data);
112             if (context == nullptr || context->env == nullptr) {
113                 LBSLOGE(LOCATOR_CALLBACK, "context is nullptr!");
114                 delete work;
115                 return;
116             }
117             NAPI_CALL_RETURN_VOID(context->env, napi_open_handle_scope(context->env, &scope));
118             if (scope == nullptr) {
119                 LBSLOGE(GNSS_STATUS_CALLBACK, "scope is nullptr");
120                 delete context;
121                 delete work;
122                 return;
123             }
124             napi_value jsEvent = nullptr;
125             if (context->statusInfo != nullptr) {
126                 CHK_NAPI_ERR_CLOSE_SCOPE(context->env, napi_create_object(context->env, &jsEvent),
127                     scope, context, work);
128                 SatelliteStatusToJs(context->env, context->statusInfo, jsEvent);
129             }
130             if (context->callback[0] != nullptr) {
131                 napi_value undefine;
132                 napi_value handler = nullptr;
133                 CHK_NAPI_ERR_CLOSE_SCOPE(context->env, napi_get_undefined(context->env, &undefine),
134                     scope, context, work);
135                 CHK_NAPI_ERR_CLOSE_SCOPE(context->env,
136                     napi_get_reference_value(context->env, context->callback[0], &handler), scope, context, work);
137                 if (napi_call_function(context->env, nullptr, handler, 1,
138                     &jsEvent, &undefine) != napi_ok) {
139                     LBSLOGE(GNSS_STATUS_CALLBACK, "Report event failed");
140                 }
141             }
142             NAPI_CALL_RETURN_VOID(context->env, napi_close_handle_scope(context->env, scope));
143             delete context;
144             delete work;
145     });
146 }
147 
OnStatusChange(const std::unique_ptr<SatelliteStatus> & statusInfo)148 void GnssStatusCallbackHost::OnStatusChange(const std::unique_ptr<SatelliteStatus>& statusInfo)
149 {
150     LBSLOGD(GNSS_STATUS_CALLBACK, "GnssStatusCallbackHost::OnStatusChange");
151 }
152 
DeleteHandler()153 void GnssStatusCallbackHost::DeleteHandler()
154 {
155     std::shared_lock<std::shared_mutex> guard(mutex_);
156     if (handlerCb_ == nullptr || env_ == nullptr) {
157         LBSLOGE(GNSS_STATUS_CALLBACK, "handler or env is nullptr.");
158         return;
159     }
160     auto context = new (std::nothrow) AsyncContext(env_);
161     if (context == nullptr) {
162         LBSLOGE(GNSS_STATUS_CALLBACK, "context == nullptr.");
163         return;
164     }
165     context->env = env_;
166     context->callback[SUCCESS_CALLBACK] = handlerCb_;
167     DeleteQueueWork(context);
168     handlerCb_ = nullptr;
169 }
170 }  // namespace Location
171 }  // namespace OHOS
172