• 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_manager_napi.h"
17 #include <optional>
18 #include "calendar_log.h"
19 #include "napi_util.h"
20 #include "napi_queue.h"
21 #include "calendar_napi.h"
22 #include "native_calendar_manager.h"
23 #include "napi_env.h"
24 
25 #include "abs_shared_result_set.h"
26 #include "data_ability_helper.h"
27 #include "data_ability_predicates.h"
28 #include "values_bucket.h"
29 
30 using namespace OHOS::AppExecFwk;
31 using namespace OHOS::DataShare;
32 
33 namespace {
34     const std::string CALENDAR_MANAGER_CLASS_NAME = "CalendarManager";
35     static thread_local napi_ref g_constructorRef = nullptr;
36     constexpr uint32_t INITIAL_REFCOUNT = 1;
37 }
38 namespace OHOS::CalendarApi {
CreateCalendar(napi_env env,napi_callback_info info)39 napi_value CalendarManagerNapi::CreateCalendar(napi_env env, napi_callback_info info)
40 {
41     LOG_INFO("napi CreateCalendar called");
42     struct CreateCalendarContext : public ContextBase {
43         CalendarAccount account;
44         CalendarNapi *calendar;
45         int id;
46         napi_ref ref = nullptr;
47     };
48     auto ctxt = std::make_shared<CreateCalendarContext>();
49     auto input = [env, ctxt](size_t argc, napi_value* argv) {
50         // required 1 arguments :: <CalendarAccount>
51         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
52         NapiUtil::GetValue(env, argv[0], ctxt->account);
53         CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid keys!");
54         ctxt->ref = NapiUtil::NewWithRef(env, argc, argv, reinterpret_cast<void**>(&ctxt->calendar),
55             CalendarNapi::Constructor(env));
56     };
57     ctxt->GetCbInfo(env, info, input);
58 
59     auto execute = [ctxt]() {
60         auto nativteCalendar = Native::CalendarManager::GetInstance().CreateCalendar(ctxt->account);
61         ctxt->status = (nativteCalendar != nullptr) ? napi_ok : napi_generic_failure;
62         CHECK_STATUS_RETURN_VOID(ctxt, "CreateCalendar failed!");
63         ctxt->calendar->SetNative(nativteCalendar);
64         ctxt->id = nativteCalendar->GetId();
65     };
66     auto output = [env, ctxt](napi_value& result) {
67         ctxt->status = napi_get_reference_value(env, ctxt->ref, &result);
68         CHECK_STATUS_RETURN_VOID(ctxt, "CreateCalendar output get ref value failed");
69         ctxt->status = NapiUtil::SetNamedProperty(env, "id", ctxt->id, result);
70         CHECK_STATUS_RETURN_VOID(ctxt, "CreateCalendar SetNamedProperty id failed");
71         ctxt->status = napi_delete_reference(env, ctxt->ref);
72         CHECK_STATUS_RETURN_VOID(ctxt, "CreateCalendar output del ref failed");
73     };
74     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output);
75 }
76 
DeleteCalendar(napi_env env,napi_callback_info info)77 napi_value CalendarManagerNapi::DeleteCalendar(napi_env env, napi_callback_info info)
78 {
79     LOG_INFO("napi DeleteCalendar called");
80     struct DelCalendarContext : public ContextBase {
81         CalendarAccount account;
82         CalendarNapi *calendar;
83         bool delResult = false;
84     };
85     auto ctxt = std::make_shared<DelCalendarContext>();
86     auto input = [env, ctxt](size_t argc, napi_value* argv) {
87         // required 1 arguments :: <Calendar>
88         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
89         napi_valuetype type = napi_undefined;
90         napi_typeof(env, argv[0], &type);
91         CHECK_ARGS_RETURN_VOID(ctxt, type == napi_object, "type error!");
92         ctxt->status = CalendarNapi::ToJson(env, argv[0], ctxt->calendar);
93         CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid keys!");
94     };
95     ctxt->GetCbInfo(env, info, input);
96 
97     auto execute = [ctxt]() {
98         CHECK_RETURN_VOID(ctxt->calendar, "calendar is nullptr");
99         auto nativeCalendar = ctxt->calendar->GetNative();
100         CHECK_RETURN_VOID(nativeCalendar, "calendar is nullptr");
101         ctxt->delResult = Native::CalendarManager::GetInstance()
102             .DeleteCalendar(*(nativeCalendar.get()));
103         CHECK_RETURN_VOID(ctxt->delResult, "DeleteCalendar failed!");
104     };
105     auto output = [env, ctxt](napi_value& result) {
106         NapiUtil::SetValue(env, ctxt->delResult, result);
107         CHECK_STATUS_RETURN_VOID(ctxt, "output del ref failed");
108     };
109     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output);
110 }
111 
112 struct GetCalendarContext : public ContextBase {
113     std::optional<CalendarAccount> account;
114     CalendarNapi *calendar = nullptr;
115     napi_ref ref = nullptr;
116     int id = -1;
117 
GetCbInfoOHOS::CalendarApi::GetCalendarContext118     void GetCbInfo(napi_env env, napi_callback_info info)
119     {
120         auto input = [env, this](size_t argc, napi_value* argv) {
121             // required at least 1 arguments :: <CalendarAccount>
122             CHECK_ARGS_RETURN_VOID(this, argc <= 1, "invalid arguments!");
123             if (argc == 0) {
124                 this->account = std::nullopt;
125             } else {
126                 CalendarAccount tmpAccount;
127                 NapiUtil::GetValue(env, argv[0], tmpAccount);
128                 this->account = tmpAccount;
129             }
130             CHECK_STATUS_RETURN_VOID(this, "invalid arg[0], i.e. invalid keys!");
131             ref = NapiUtil::NewWithRef(env, argc, argv, reinterpret_cast<void**>(&calendar),
132                 CalendarNapi::Constructor(env));
133         };
134         LOG_DEBUG("call ContextBase::GetCbInfo");
135         ContextBase::GetCbInfo(env, info, input);
136     }
137 };
138 
GetCalendar(napi_env env,napi_callback_info info)139 napi_value CalendarManagerNapi::GetCalendar(napi_env env, napi_callback_info info)
140 {
141     LOG_DEBUG("GetCalendar in");
142     auto ctxt = std::make_shared<GetCalendarContext>();
143     ctxt->GetCbInfo(env, info);
144 
145     auto execute = [ctxt]() {
146         auto nativteCalendar = Native::CalendarManager::GetInstance().GetCalendar(ctxt->account);
147         ctxt->status = (nativteCalendar != nullptr) ? napi_ok : napi_generic_failure;
148         CHECK_STATUS_RETURN_VOID(ctxt, "GetCalendar failed!");
149         ctxt->calendar->SetNative(nativteCalendar);
150         ctxt->id = nativteCalendar->GetId();
151     };
152     auto output = [env, ctxt](napi_value& result) {
153         ctxt->status = napi_get_reference_value(env, ctxt->ref, &result);
154         CHECK_STATUS_RETURN_VOID(ctxt, "GetCalendar output get ref value failed");
155         ctxt->status = NapiUtil::SetNamedProperty(env, "id", ctxt->id, result);
156         CHECK_STATUS_RETURN_VOID(ctxt, "GetCalendar SetNamedProperty id failed");
157         ctxt->status = napi_delete_reference(env, ctxt->ref);
158         CHECK_STATUS_RETURN_VOID(ctxt, "GetCalendar output del ref failed");
159     };
160     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output);
161 }
162 
GetAllCalendars(napi_env env,napi_callback_info info)163 napi_value CalendarManagerNapi::GetAllCalendars(napi_env env, napi_callback_info info)
164 {
165     LOG_DEBUG("napi GetAllCalendars called");
166     struct GetAllCalendarContext : public ContextBase {
167         napi_callback_info info;
168         std::vector<napi_ref> refs;
169     };
170 
171     auto ctxt = std::make_shared<GetAllCalendarContext>();
172     auto input = [env, ctxt](size_t argc, napi_value* argv) {
173         CHECK_ARGS_RETURN_VOID(ctxt, argc == 0, "invalid arguments!");
174         auto nativteCalendars = Native::CalendarManager::GetInstance().GetAllCalendars();
175         for (auto &calendar : nativteCalendars) {
176             CalendarNapi *calendarNapi = nullptr;
177             auto ref = NapiUtil::NewWithRef(env, argc, argv, reinterpret_cast<void**>(&calendarNapi),
178                 CalendarNapi::Constructor(env));
179             CHECK_RETURN_VOID(calendarNapi != nullptr, "new CalendarNapi failed!");
180             calendarNapi->SetNative(calendar);
181             napi_value value;
182             ctxt->status = napi_get_reference_value(env, ref, &value);
183             CHECK_STATUS_RETURN_VOID(ctxt, "napi_get_reference_value failed");
184             ctxt->status = NapiUtil::SetNamedProperty(env, "id", calendar->GetId(), value);
185             CHECK_STATUS_RETURN_VOID(ctxt, "SetNamedProperty id failed");
186             ctxt->refs.emplace_back(ref);
187         }
188     };
189     ctxt->GetCbInfo(env, info, input);
190 
191     auto execute = [env, ctxt]()->void {
192     };
193 
194     auto output = [env, ctxt](napi_value& result) {
195         ctxt->status = napi_create_array_with_length(env, ctxt->refs.size(), &result);
196         CHECK_STATUS_RETURN_VOID(ctxt, "create array failed!");
197         int index = 0;
198         for (auto& ref : ctxt->refs) {
199             napi_value value;
200             ctxt->status = napi_get_reference_value(env, ref, &value);
201             CHECK_STATUS_RETURN_VOID(ctxt, "get ref value failed!");
202             ctxt->status = napi_set_element(env, result, index++, value);
203             CHECK_STATUS_RETURN_VOID(ctxt, "napi_set_element failed!");
204             ctxt->status = napi_delete_reference(env, ref);
205             CHECK_STATUS_RETURN_VOID(ctxt, "napi_delete_reference failed!");
206         }
207     };
208     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output);
209 }
210 
GetCalendarManager(napi_env env,napi_callback_info info)211 napi_value GetCalendarManager(napi_env env, napi_callback_info info)
212 {
213     LOG_INFO("napi GetCalendarManager called");
214     const int argsOne = 1;
215     napi_value result = nullptr;
216     napi_value cons = nullptr;
217     size_t requireArgc = argsOne;
218     size_t argc = argsOne;
219     napi_value args[argsOne] = {nullptr};
220     if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
221         return nullptr;
222     }
223 
224     if (argc > requireArgc || napi_get_reference_value(env, g_constructorRef, &cons) != napi_ok) {
225         return nullptr;
226     }
227 
228     if (napi_new_instance(env, cons, argsOne, args, &result) != napi_ok) {
229         return nullptr;
230     }
231     CalendarManagerNapi *calendarManager = nullptr;
232     if (napi_unwrap(env, result, (void **)&calendarManager) != napi_ok) {
233         LOG_ERROR("Faild to get fileAccessHelper");
234         return nullptr;
235     }
236 
237     if (calendarManager == nullptr) {
238         LOG_ERROR("fileAccessHelper is nullptr");
239         return nullptr;
240     }
241     return result;
242 }
243 
New(napi_env env,napi_callback_info info)244 napi_value CalendarManagerNapi::New(napi_env env, napi_callback_info info)
245 {
246     auto ctxt = std::make_shared<ContextBase>();
247     auto input = [env, ctxt](size_t argc, napi_value* argv) {
248         CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!");
249         CalendarEnvNapi::GetInstance().Init(env, argv[0]);
250     };
251     ctxt->GetCbInfoSync(env, info, input);
252     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
253 
254     auto calendarManager = new (std::nothrow) CalendarManagerNapi();
255     NAPI_ASSERT(env, calendarManager != nullptr, "no memory for calendarManager");
256     auto finalize = [](napi_env env, void *data, void *hint) {
257         CalendarManagerNapi *objectInfo = static_cast<CalendarManagerNapi *>(data);
258         if (objectInfo != nullptr) {
259             delete objectInfo;
260             objectInfo = nullptr;
261         }
262     };
263     if (napi_wrap(env, ctxt->self, calendarManager, finalize, nullptr, nullptr) != napi_ok) {
264         finalize(env, calendarManager, nullptr);
265         return nullptr;
266     }
267     return ctxt->self;
268 }
269 
Init(napi_env env,napi_value exports)270 napi_value CalendarManagerNapi::Init(napi_env env, napi_value exports)
271 {
272     napi_property_descriptor properties[] = {
273         DECLARE_NAPI_FUNCTION("createCalendar", CreateCalendar),
274         DECLARE_NAPI_FUNCTION("deleteCalendar", DeleteCalendar),
275         DECLARE_NAPI_FUNCTION("getCalendar", GetCalendar),
276         DECLARE_NAPI_FUNCTION("getAllCalendars", GetAllCalendars),
277     };
278     napi_value cons = nullptr;
279     NAPI_CALL(env,
280         napi_define_class(env,
281             CALENDAR_MANAGER_CLASS_NAME.c_str(),
282             NAPI_AUTO_LENGTH,
283             New,
284             nullptr,
285             sizeof(properties) / sizeof(*properties),
286             properties,
287             &cons));
288     NAPI_CALL(env, napi_create_reference(env, cons, INITIAL_REFCOUNT, &g_constructorRef));
289     NAPI_CALL(env, napi_set_named_property(env, exports, CALENDAR_MANAGER_CLASS_NAME.c_str(), cons));
290 
291     napi_property_descriptor export_properties[] = {
292         DECLARE_NAPI_FUNCTION("getCalendarManager", GetCalendarManager),
293     };
294     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(export_properties) / sizeof(export_properties[0]),
295         export_properties));
296     return exports;
297 }
298 }