• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "calendar_napi.h"
17 #include "calendar_log.h"
18 #include "napi_util.h"
19 #include "napi_queue.h"
20 #include "native_util.h"
21 
22 namespace {
23     const std::string CALENDAR_CLASS_NAME = "Calendar";
24 }
25 
26 namespace OHOS::CalendarApi {
27 
Constructor(napi_env env)28 napi_value CalendarNapi::Constructor(napi_env env)
29 {
30     const napi_property_descriptor properties[] = {
31         DECLARE_NAPI_FUNCTION("addEvent", AddEvent),
32         DECLARE_NAPI_FUNCTION("addEvents", AddEvents),
33         DECLARE_NAPI_FUNCTION("deleteEvent", DeleteEvent),
34         DECLARE_NAPI_FUNCTION("deleteEvents", DeleteEvents),
35         DECLARE_NAPI_FUNCTION("updateEvent", UpdateEvent),
36         DECLARE_NAPI_FUNCTION("updateEvents", UpdateEvents),
37         DECLARE_NAPI_FUNCTION("getEvents", GetEvents),
38         DECLARE_NAPI_FUNCTION("getConfig", GetConfig),
39         DECLARE_NAPI_FUNCTION("setConfig", SetConfig),
40         DECLARE_NAPI_FUNCTION("getAccount", GetAccount),
41     };
42     size_t count = sizeof(properties) / sizeof(properties[0]);
43     return NapiUtil::DefineClass(env, "Calendar", properties, count, CalendarNapi::New);
44 }
45 
46 /*
47  * [JS API Prototype]
48  *      var calendar = new Calendar();
49  */
New(napi_env env,napi_callback_info info)50 napi_value CalendarNapi::New(napi_env env, napi_callback_info info)
51 {
52     auto ctxt = std::make_shared<ContextBase>();
53     auto input = [env, ctxt](size_t argc, napi_value* argv) {
54         CHECK_ARGS_RETURN_VOID(ctxt, argc <= 1, "invalid arguments!");
55     };
56     ctxt->GetCbInfoSync(env, info, input);
57     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
58 
59     auto calendar = new (std::nothrow) CalendarNapi();
60     NAPI_ASSERT(env, calendar != nullptr, "no memory for calendar");
61 
62     auto finalize = [](napi_env env, void* data, void* hint) {
63         LOG_DEBUG("calendar finalize.");
64         auto* calendar = reinterpret_cast<CalendarNapi*>(data);
65         CHECK_RETURN_VOID(calendar != nullptr, "finalize null!");
66         delete calendar;
67     };
68     if (napi_wrap(env, ctxt->self, calendar, finalize, nullptr, nullptr) != napi_ok) {
69         delete calendar;
70         GET_AND_THROW_LAST_ERROR(env);
71         return nullptr;
72     }
73     return ctxt->self;
74 }
75 
ToJson(napi_env env,napi_value inner,CalendarNapi * & out)76 napi_status CalendarNapi::ToJson(napi_env env, napi_value inner, CalendarNapi*& out)
77 {
78     LOG_DEBUG("CalendarNapi::ToJson");
79     return NapiUtil::Unwrap(env, inner, reinterpret_cast<void**>(&out), CalendarNapi::Constructor(env));
80 }
81 
SetNative(std::shared_ptr<Native::Calendar> & calendar)82 void CalendarNapi::SetNative(std::shared_ptr<Native::Calendar>& calendar)
83 {
84     calendar_ = calendar;
85 }
GetNative()86 std::shared_ptr<Native::Calendar>& CalendarNapi::GetNative()
87 {
88     return calendar_;
89 }
90 
AddEvent(napi_env env,napi_callback_info info)91 napi_value CalendarNapi::AddEvent(napi_env env, napi_callback_info info)
92 {
93     LOG_INFO("AddEvent");
94     struct AddEventContext : public ContextBase {
95         Event event;
96         int eventId;
97     };
98     auto ctxt = std::make_shared<AddEventContext>();
99     auto input = [env, ctxt](size_t argc, napi_value* argv) {
100         // required atleast 1 arguments :: <eventFilter>
101         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
102         ctxt->status = NapiUtil::GetValue(env, argv[0], ctxt->event);
103         CHECK_STATUS_RETURN_VOID(ctxt, "AddEvent failed!");
104         Native::DumpEvent(ctxt->event);
105         CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid keys!");
106     };
107     ctxt->GetCbInfo(env, info, input);
108     auto execute = [ctxt]() {
109         auto calendar = reinterpret_cast<CalendarNapi*>(ctxt->native);
110         CHECK_RETURN_VOID(calendar != nullptr, "CalendarNapi nullptr");
111         auto nativeCalendar = calendar->GetNative();
112         CHECK_RETURN_VOID(nativeCalendar != nullptr, "nativeCalendar nullptr");
113         ctxt->eventId = nativeCalendar->AddEvent(ctxt->event);
114         ctxt->status = (ctxt->eventId > 0) ? napi_ok : napi_generic_failure;
115         CHECK_STATUS_RETURN_VOID(ctxt, "AddEvent failed!");
116     };
117     auto output = [env, ctxt](napi_value& result) {
118         ctxt->status = NapiUtil::SetValue(ctxt->env, ctxt->eventId, result);
119         CHECK_STATUS_RETURN_VOID(ctxt, "output failed");
120     };
121     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output);
122 }
123 
AddEvents(napi_env env,napi_callback_info info)124 napi_value CalendarNapi::AddEvents(napi_env env, napi_callback_info info)
125 {
126     LOG_INFO("AddEvents");
127     struct AddEventsContext : public ContextBase {
128         std::vector<Event> events;
129         int count;
130     };
131     auto ctxt = std::make_shared<AddEventsContext>();
132     auto input = [env, ctxt](size_t argc, napi_value* argv) {
133         // required atleast 1 arguments :: <eventFilter>
134         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
135         ctxt->status = NapiUtil::GetValue(env, argv[0], ctxt->events);
136         CHECK_STATUS_RETURN_VOID(ctxt, "GetValue failed!");
137         CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid keys!");
138     };
139     ctxt->GetCbInfo(env, info, input);
140     auto execute = [ctxt]() {
141         auto calendar = reinterpret_cast<CalendarNapi*>(ctxt->native);
142         CHECK_RETURN_VOID(calendar != nullptr, "CalendarNapi nullptr");
143         auto nativeCalendar = calendar->GetNative();
144         CHECK_RETURN_VOID(nativeCalendar != nullptr, "nativeCalendar nullptr");
145         ctxt->count = nativeCalendar->AddEvents(ctxt->events);
146         ctxt->status = (ctxt->count > 0) ? napi_ok : napi_generic_failure;
147         CHECK_STATUS_RETURN_VOID(ctxt, "AddEvent failed!");
148     };
149     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
150 }
151 
DeleteEvent(napi_env env,napi_callback_info info)152 napi_value CalendarNapi::DeleteEvent(napi_env env, napi_callback_info info)
153 {
154     LOG_INFO("DeleteEvent");
155     struct DeleteEventContext : public ContextBase {
156         bool result;
157         int eventId;
158     };
159     auto ctxt = std::make_shared<DeleteEventContext>();
160     auto input = [env, ctxt](size_t argc, napi_value* argv) {
161         // required atleast 1 arguments :: <number>
162         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
163         NapiUtil::GetValue(env, argv[0], ctxt->eventId);
164         CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid keys!");
165     };
166     ctxt->GetCbInfo(env, info, input);
167     auto execute = [ctxt]() {
168         auto calendar = reinterpret_cast<CalendarNapi*>(ctxt->native);
169         CHECK_RETURN_VOID(calendar != nullptr, "CalendarNapi nullptr");
170         auto nativeCalendar = calendar->GetNative();
171         CHECK_RETURN_VOID(nativeCalendar != nullptr, "nativeCalendar nullptr");
172         ctxt->result = nativeCalendar->DeleteEvent(ctxt->eventId);
173     };
174     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
175 }
176 
DeleteEvents(napi_env env,napi_callback_info info)177 napi_value CalendarNapi::DeleteEvents(napi_env env, napi_callback_info info)
178 {
179     LOG_INFO("DeleteEvents");
180     struct DeleteEventsContext : public ContextBase {
181         int result;
182         std::vector<int> ids;
183     };
184     auto ctxt = std::make_shared<DeleteEventsContext>();
185     auto input = [env, ctxt](size_t argc, napi_value* argv) {
186         // required atleast 1 arguments :: <number>
187         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
188         NapiUtil::GetValue(env, argv[0], ctxt->ids);
189         CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid keys!");
190     };
191     ctxt->GetCbInfo(env, info, input);
192     auto execute = [ctxt]() {
193         auto calendar = reinterpret_cast<CalendarNapi*>(ctxt->native);
194         CHECK_RETURN_VOID(calendar != nullptr, "CalendarNapi nullptr");
195         auto nativeCalendar = calendar->GetNative();
196         CHECK_RETURN_VOID(nativeCalendar != nullptr, "nativeCalendar nullptr");
197         ctxt->result = nativeCalendar->DeleteEvents(ctxt->ids);
198     };
199     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
200 }
201 
UpdateEvent(napi_env env,napi_callback_info info)202 napi_value CalendarNapi::UpdateEvent(napi_env env, napi_callback_info info)
203 {
204     LOG_INFO("UpdateEvent");
205     struct UpdateEventContext : public ContextBase {
206         bool result;
207         Event event;
208     };
209     auto ctxt = std::make_shared<UpdateEventContext>();
210     auto input = [env, ctxt](size_t argc, napi_value* argv) {
211         // required atleast 1 arguments :: <number>
212         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
213         NapiUtil::GetValue(env, argv[0], ctxt->event);
214         CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid keys!");
215     };
216     ctxt->GetCbInfo(env, info, input);
217     auto execute = [ctxt]() {
218         auto calendar = reinterpret_cast<CalendarNapi*>(ctxt->native);
219         CHECK_RETURN_VOID(calendar != nullptr, "CalendarNapi nullptr");
220         auto nativeCalendar = calendar->GetNative();
221         CHECK_RETURN_VOID(nativeCalendar != nullptr, "nativeCalendar nullptr");
222         ctxt->result = nativeCalendar->UpdateEvent(ctxt->event);
223     };
224     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
225 }
226 
UpdateEvents(napi_env env,napi_callback_info info)227 napi_value CalendarNapi::UpdateEvents(napi_env env, napi_callback_info info)
228 {
229     LOG_INFO("UpdateEvents");
230     struct DeleteEventsContext : public ContextBase {
231         int result;
232         std::vector<Event> events;
233         CalendarNapi *calendar;
234     };
235     auto ctxt = std::make_shared<DeleteEventsContext>();
236     auto input = [env, ctxt](size_t argc, napi_value* argv) {
237         // required atleast 1 arguments :: <number>
238         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
239         NapiUtil::GetValue(env, argv[0], ctxt->events);
240         CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid keys!");
241     };
242     ctxt->GetCbInfo(env, info, input);
243     auto execute = [ctxt]() {
244         auto calendar = reinterpret_cast<CalendarNapi*>(ctxt->native);
245         CHECK_RETURN_VOID(calendar != nullptr, "CalendarNapi nullptr");
246         auto nativeCalendar = calendar->GetNative();
247         CHECK_RETURN_VOID(nativeCalendar != nullptr, "nativeCalendar nullptr");
248         ctxt->result = nativeCalendar->UpdateEvents(ctxt->events);
249     };
250     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
251 }
252 
GetEvents(napi_env env,napi_callback_info info)253 napi_value CalendarNapi::GetEvents(napi_env env, napi_callback_info info)
254 {
255     struct GetEventsContext : public ContextBase {
256         EventFilterNapi* eventFilter;
257         std::vector<std::string> eventKeys;
258         std::vector<Event> events;
259     };
260     auto ctxt = std::make_shared<GetEventsContext>();
261     auto input = [env, ctxt](size_t argc, napi_value* argv) {
262         CHECK_ARGS_RETURN_VOID(ctxt, argc <= 2, "invalid arguments!");
263         if (argc >= 1) {
264             napi_valuetype type = napi_undefined;
265             napi_typeof(env, argv[0], &type);
266             CHECK_ARGS_RETURN_VOID(ctxt, type == napi_object, "type error!");
267             ctxt->status = NapiUtil::GetValue(env, argv[0], ctxt->eventFilter);
268             CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid keys!");
269         }
270         if (argc == 2) {
271             // required atleast 2 arguments :: <eventKey>
272             napi_valuetype type = napi_undefined;
273             napi_typeof(env, argv[0], &type);
274             ctxt->status = NapiUtil::GetValue(env, argv[1], ctxt->eventKeys);
275             CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[1], i.e. invalid keys!");
276         }
277     };
278     ctxt->GetCbInfo(env, info, input);
279 
280     auto execute = [ctxt]() {
281         std::shared_ptr<Native::EventFilter> nativeFilter = nullptr;
282         if (ctxt->eventFilter != nullptr) {
283             nativeFilter = ctxt->eventFilter->GetNative();
284         }
285         auto calendar = reinterpret_cast<CalendarNapi*>(ctxt->native);
286         CHECK_RETURN_VOID(calendar != nullptr, "CalendarNapi nullptr");
287         auto nativeCalendar = calendar->GetNative();
288         CHECK_RETURN_VOID(nativeCalendar != nullptr, "nativeCalendar nullptr");
289         ctxt->events = nativeCalendar->GetEvents(nativeFilter, ctxt->eventKeys);
290         ctxt->status = (true) ? napi_ok : napi_generic_failure;
291         CHECK_STATUS_RETURN_VOID(ctxt, "GetEvents failed!");
292     };
293     auto output = [env, ctxt](napi_value& result) {
294         ctxt->status = NapiUtil::SetValue(ctxt->env, ctxt->events, result);
295         CHECK_STATUS_RETURN_VOID(ctxt, "output failed");
296     };
297     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output);
298 }
299 
GetConfig(napi_env env,napi_callback_info info)300 napi_value CalendarNapi::GetConfig(napi_env env, napi_callback_info info)
301 {
302     LOG_INFO("GetConfig");
303     size_t argc = 0;
304     napi_value thisVar = nullptr;
305     auto status = napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
306     if (status != napi_ok) {
307         LOG_ERROR("GetConfig napi_get_cb_info failed %{public}d", status);
308         return nullptr;
309     }
310     CalendarNapi *calendarNapi = nullptr;
311     status = napi_unwrap(env, thisVar, (void **)&calendarNapi);
312     if (status != napi_ok) {
313         LOG_ERROR("GetConfig napi_unwrap failed %{public}d", status);
314         return nullptr;
315     }
316     if (calendarNapi == nullptr) {
317         LOG_ERROR("GetConfig reinterpret_cast failed");
318         return nullptr;
319     }
320     auto nativeCalendar = calendarNapi->GetNative();
321     CHECK_RETURN(nativeCalendar != nullptr, "GetConfig -> get nativeCalendar nullptr", nullptr);
322     auto config = nativeCalendar->GetConfig();
323     LOG_DEBUG("config.enableReminder:%{public}d", config.enableReminder.value_or(-1));
324     if (std::get_if<1>(&config.color)) {
325         LOG_DEBUG("config.color:%{public}s", std::to_string(std::get<1>(config.color)).c_str());
326     } else {
327         LOG_ERROR("config.color is null");
328     }
329     napi_value result;
330     status = NapiUtil::SetValue(env, config, result);
331     if (status != napi_ok) {
332         LOG_ERROR("SetValue failed %{public}d", status);
333         return nullptr;
334     }
335     return result;
336 }
337 
SetConfig(napi_env env,napi_callback_info info)338 napi_value CalendarNapi::SetConfig(napi_env env, napi_callback_info info)
339 {
340     LOG_INFO("SetConfig");
341     struct SetConfigContext : public ContextBase {
342         int result;
343         CalendarConfig config;
344         CalendarNapi *calendar;
345     };
346     auto ctxt = std::make_shared<SetConfigContext>();
347     auto input = [env, ctxt](size_t argc, napi_value* argv) {
348         // required atleast 1 arguments :: <CalendarConfig>
349         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
350         NapiUtil::GetValue(env, argv[0], ctxt->config);
351         CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid config!");
352     };
353     ctxt->GetCbInfo(env, info, input);
354     auto execute = [ctxt]() {
355         auto calendar = reinterpret_cast<CalendarNapi*>(ctxt->native);
356         CHECK_RETURN_VOID(calendar != nullptr, "CalendarNapi nullptr");
357         auto nativeCalendar = calendar->GetNative();
358         CHECK_RETURN_VOID(nativeCalendar != nullptr, "nativeCalendar nullptr");
359         ctxt->result = nativeCalendar->SetConfig(ctxt->config);
360     };
361     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
362 }
363 
GetAccount(napi_env env,napi_callback_info info)364 napi_value CalendarNapi::GetAccount(napi_env env, napi_callback_info info)
365 {
366     LOG_INFO("GetAccount");
367     size_t argc = 0;
368     napi_value thisVar = nullptr;
369     auto status = napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
370     if (status != napi_ok) {
371         LOG_ERROR("GetAccount napi_get_cb_info failed %{public}d", status);
372         return nullptr;
373     }
374     CalendarNapi *calendarNapi = nullptr;
375     status = napi_unwrap(env, thisVar, (void **)&calendarNapi);
376     if (status != napi_ok) {
377         LOG_ERROR("GetAccount napi_unwrap failed %{public}d", status);
378         return nullptr;
379     }
380     if (calendarNapi == nullptr) {
381         LOG_ERROR("GetAccount reinterpret_cast failed");
382         return nullptr;
383     }
384     auto nativeCalendar = calendarNapi->GetNative();
385     CHECK_RETURN(nativeCalendar != nullptr, "GetAccount -> get nativeCalendar nullptr", nullptr);
386     auto account = nativeCalendar->GetAccount();
387     LOG_DEBUG("account.name:%{public}s", account.name.c_str());
388     LOG_DEBUG("account.type:%{public}s", account.type.c_str());
389     if (account.displayName) {
390         LOG_DEBUG("account.displayName:%{public}s", account.displayName.value().c_str());
391     }
392     napi_value result;
393     status = NapiUtil::SetValue(env, account, result);
394     if (status != napi_ok) {
395         LOG_ERROR("SetValue failed %{public}d", status);
396         return nullptr;
397     }
398     return result;
399 }
400 
CalendarAccountConstructor(napi_env env,napi_callback_info info)401 napi_value CalendarAccountConstructor(napi_env env, napi_callback_info info)
402 {
403     napi_value thisArg = nullptr;
404     void* data = nullptr;
405 
406     napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, &data);
407 
408     napi_value global = nullptr;
409     napi_get_global(env, &global);
410 
411     return thisArg;
412 }
413 
CalendarAccountInit(napi_env env,napi_value exports)414 static void CalendarAccountInit(napi_env env, napi_value exports)
415 {
416     napi_value name = nullptr;
417     napi_value type = nullptr;
418     napi_value displayName = nullptr;
419 
420     napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &name);
421     napi_create_string_utf8(env, "type", NAPI_AUTO_LENGTH, &type);
422     napi_create_string_utf8(env, "displayName", NAPI_AUTO_LENGTH, &displayName);
423 
424     napi_property_descriptor calendarAccountProperties[] = {
425         DECLARE_NAPI_PROPERTY("name", name),
426         DECLARE_NAPI_PROPERTY("type", type),
427         DECLARE_NAPI_PROPERTY("displayName", displayName),
428     };
429     napi_value result = nullptr;
430     napi_define_class(env, "CalendarAccount", NAPI_AUTO_LENGTH, CalendarAccountConstructor, nullptr,
431         sizeof(calendarAccountProperties) / sizeof(napi_property_descriptor), calendarAccountProperties, &result);
432     napi_set_named_property(env, exports, "CalendarAccount", result);
433 }
434 
Init(napi_env env,napi_value exports)435 napi_value CalendarNapi::Init(napi_env env, napi_value exports)
436 {
437     auto status = napi_set_named_property(env, exports, "Calendar", CalendarNapi::Constructor(env));
438     LOG_INFO("init Calendar %{public}d", status);
439     CalendarAccountInit(env, exports);
440     return exports;
441 }
442 }