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 "location_error_callback_napi.h"
17 #include "common_utils.h"
18 #include "ipc_skeleton.h"
19 #include "location_log.h"
20 #include "napi/native_common.h"
21 #include "napi_util.h"
22 #include "location_async_context.h"
23
24 namespace OHOS {
25 namespace Location {
LocationErrorCallbackNapi()26 LocationErrorCallbackNapi::LocationErrorCallbackNapi()
27 {
28 env_ = nullptr;
29 handlerCb_ = nullptr;
30 }
31
~LocationErrorCallbackNapi()32 LocationErrorCallbackNapi::~LocationErrorCallbackNapi()
33 {
34 }
35
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)36 int LocationErrorCallbackNapi::OnRemoteRequest(
37 uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option)
38 {
39 LBSLOGI(LOCATION_ERR_CALLBACK, "LocatorCallbackHost::OnRemoteRequest! code = %{public}d", code);
40 if (data.ReadInterfaceToken() != GetDescriptor()) {
41 LBSLOGE(LOCATION_ERR_CALLBACK, "invalid token.");
42 return -1;
43 }
44
45 switch (code) {
46 case RECEIVE_ERROR_INFO_EVENT: {
47 OnErrorReport(data.ReadInt32());
48 break;
49 }
50 default: {
51 IPCObjectStub::OnRemoteRequest(code, data, reply, option);
52 break;
53 }
54 }
55 return 0;
56 }
57
Send(int32_t errorCode)58 bool LocationErrorCallbackNapi::Send(int32_t errorCode)
59 {
60 LBSLOGI(LOCATION_ERR_CALLBACK, "LocatorCallbackNapi::OnRemoteRequest! errorCode = %{public}d", errorCode);
61 std::unique_lock<std::mutex> guard(mutex_);
62 uv_loop_s *loop = nullptr;
63 NAPI_CALL_BASE(env_, napi_get_uv_event_loop(env_, &loop), false);
64 if (loop == nullptr) {
65 LBSLOGE(LOCATION_ERR_CALLBACK, "loop == nullptr.");
66 return false;
67 }
68 if (handlerCb_ == nullptr) {
69 LBSLOGE(LOCATION_ERR_CALLBACK, "handler is nullptr.");
70 return false;
71 }
72 uv_work_t *work = new (std::nothrow) uv_work_t;
73 if (work == nullptr) {
74 LBSLOGE(LOCATION_ERR_CALLBACK, "work == nullptr.");
75 return false;
76 }
77 LocationErrorAsyncContext *context = new (std::nothrow) LocationErrorAsyncContext(env_);
78 if (context == nullptr) {
79 LBSLOGE(LOCATION_ERR_CALLBACK, "context == nullptr.");
80 delete work;
81 return false;
82 }
83 if (!InitContext(context)) {
84 LBSLOGE(LOCATION_ERR_CALLBACK, "InitContext fail");
85 return false;
86 }
87 context->errCode = errorCode;
88 work->data = context;
89 UvQueueWork(loop, work);
90 return true;
91 }
92
UvQueueWork(uv_loop_s * loop,uv_work_t * work)93 void LocationErrorCallbackNapi::UvQueueWork(uv_loop_s* loop, uv_work_t* work)
94 {
95 uv_queue_work(
96 loop,
97 work,
98 [](uv_work_t *work) {},
99 [](uv_work_t *work, int status) {
100 LocationErrorAsyncContext *context = nullptr;
101 napi_handle_scope scope = nullptr;
102 if (work == nullptr) {
103 LBSLOGE(LOCATION_ERR_CALLBACK, "work is nullptr!");
104 return;
105 }
106 context = static_cast<LocationErrorAsyncContext *>(work->data);
107 if (context == nullptr || context->env == nullptr) {
108 LBSLOGE(LOCATION_ERR_CALLBACK, "context is nullptr!");
109 delete work;
110 return;
111 }
112 NAPI_CALL_RETURN_VOID(context->env, napi_open_handle_scope(context->env, &scope));
113 napi_value jsEvent;
114 CHK_NAPI_ERR_CLOSE_SCOPE(context->env, napi_create_int32(context->env, context->errCode, &jsEvent),
115 scope, context, work);
116 if (scope == nullptr) {
117 LBSLOGE(LOCATION_ERR_CALLBACK, "scope is nullptr");
118 delete context;
119 delete work;
120 return;
121 }
122 if (context->callback[0] != nullptr) {
123 napi_value undefine;
124 napi_value handler = nullptr;
125 CHK_NAPI_ERR_CLOSE_SCOPE(context->env, napi_get_undefined(context->env, &undefine),
126 scope, context, work);
127 CHK_NAPI_ERR_CLOSE_SCOPE(context->env,
128 napi_get_reference_value(context->env, context->callback[0], &handler), scope, context, work);
129 if (napi_call_function(context->env, nullptr, handler, 1,
130 &jsEvent, &undefine) != napi_ok) {
131 LBSLOGE(LOCATION_ERR_CALLBACK, "Report event failed");
132 }
133 }
134 NAPI_CALL_RETURN_VOID(context->env, napi_close_handle_scope(context->env, scope));
135 delete context;
136 delete work;
137 });
138 }
139
OnLocationReport(const std::unique_ptr<Location> & location)140 void LocationErrorCallbackNapi::OnLocationReport(const std::unique_ptr<Location>& location)
141 {
142 }
143
OnLocatingStatusChange(const int status)144 void LocationErrorCallbackNapi::OnLocatingStatusChange(const int status)
145 {
146 }
147
OnErrorReport(const int errorCode)148 void LocationErrorCallbackNapi::OnErrorReport(const int errorCode)
149 {
150 LBSLOGI(LOCATION_ERR_CALLBACK, "LocatorCallbackNapi::OnRemoteRequest! errorCode = %{public}d", errorCode);
151 Send(errorCode);
152 }
153
DeleteHandler()154 void LocationErrorCallbackNapi::DeleteHandler()
155 {
156 std::unique_lock<std::mutex> guard(mutex_);
157 if (handlerCb_ == nullptr || env_ == nullptr) {
158 LBSLOGE(LOCATION_ERR_CALLBACK, "handler or env is nullptr.");
159 return;
160 }
161 NAPI_CALL_RETURN_VOID(env_, napi_delete_reference(env_, handlerCb_));
162 handlerCb_ = nullptr;
163 }
164 } // namespace Location
165 } // namespace OHOS
166