• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "ability_runtime/cj_ability_context.h"
16 #include "calendar_manager_ffi.h"
17 #include "cj_calendar_manager.h"
18 #include "cj_calendar.h"
19 #include "cj_event_filter.h"
20 #include "native/ffi_remote_data.h"
21 #include "ipc_skeleton.h"
22 #include "calendar_define.h"
23 #include "calendar_log.h"
24 #include "calendar_env.h"
25 
26 using namespace OHOS;
27 using namespace OHOS::AbilityRuntime;
28 using namespace OHOS::CalendarApi;
29 using namespace OHOS::FFI;
30 using namespace OHOS::DataShare;
31 
32 namespace OHOS {
33 namespace CalendarApi {
ArrayI64ToVector(CArrI64 arr)34     std::vector<int64_t> ArrayI64ToVector(CArrI64 arr)
35     {
36         std::vector<int64_t> vec;
37         for (int64_t i = 0; i < arr.size; i++) {
38             vec.push_back(arr.head[i]);
39         }
40         return vec;
41     }
42 
VectorToArrayI64(const std::vector<int64_t> & vec,int32_t * errcode)43     CArrI64 VectorToArrayI64(const std::vector<int64_t> &vec, int32_t* errcode)
44     {
45         CArrI64 arr = {};
46         arr.size = vec.size();
47         if (arr.size == 0) {
48             return arr;
49         }
50         arr.head = static_cast<int64_t *>(malloc(sizeof(int64_t) * vec.size()));
51         if (arr.head == nullptr) {
52             *errcode = CJ_ERR_OUT_OF_MEMORY;
53             LOG_ERROR("CArrI64 malloc failed");
54             return arr;
55         }
56         for (size_t i = 0; i < vec.size(); i++) {
57             arr.head[i] = vec[i];
58         }
59         return arr;
60     }
61 
IMallocCString(const std::string & origin)62     char* IMallocCString(const std::string &origin)
63     {
64         if (origin.empty()) {
65             return nullptr;
66         }
67         auto length = origin.length() + 1;
68         char *res = static_cast<char *>(malloc(sizeof(char) * length));
69         if (res == nullptr) {
70             return nullptr;
71         }
72         return std::char_traits<char>::copy(res, origin.c_str(), length);
73     }
74 
BuildNativeRecurrenceRule(CRecurrenceRule recurrenceRule)75     RecurrenceRule CJCalendar::BuildNativeRecurrenceRule(CRecurrenceRule recurrenceRule)
76     {
77         RecurrenceRule nativeRecurrenceRule;
78         nativeRecurrenceRule.recurrenceFrequency = RecurrenceType(recurrenceRule.recurrenceFrequency);
79         nativeRecurrenceRule.expire = std::make_optional<int64_t>(recurrenceRule.expire);
80         nativeRecurrenceRule.count = std::make_optional<int64_t>(recurrenceRule.count);
81         nativeRecurrenceRule.interval = std::make_optional<int64_t>(recurrenceRule.interval);
82         nativeRecurrenceRule.excludedDates =
83             std::make_optional<std::vector<int64_t>>(ArrayI64ToVector(recurrenceRule.excludedDates));
84         nativeRecurrenceRule.daysOfWeek =
85             std::make_optional<std::vector<int64_t>>(ArrayI64ToVector(recurrenceRule.daysOfWeek));
86         nativeRecurrenceRule.daysOfMonth =
87             std::make_optional<std::vector<int64_t>>(ArrayI64ToVector(recurrenceRule.daysOfMonth));
88         nativeRecurrenceRule.daysOfYear =
89             std::make_optional<std::vector<int64_t>>(ArrayI64ToVector(recurrenceRule.daysOfYear));
90         nativeRecurrenceRule.weeksOfMonth =
91             std::make_optional<std::vector<int64_t>>(ArrayI64ToVector(recurrenceRule.weeksOfMonth));
92         nativeRecurrenceRule.weeksOfYear =
93             std::make_optional<std::vector<int64_t>>(ArrayI64ToVector(recurrenceRule.weeksOfYear));
94         nativeRecurrenceRule.monthsOfYear =
95             std::make_optional<std::vector<int64_t>>(ArrayI64ToVector(recurrenceRule.monthsOfYear));
96         return nativeRecurrenceRule;
97     }
98 
BuildCRecurrenceRule(RecurrenceRule nativeRecurrenceRule,int32_t * errcode)99     CRecurrenceRule CJCalendar::BuildCRecurrenceRule(RecurrenceRule nativeRecurrenceRule, int32_t* errcode)
100     {
101         CRecurrenceRule cRecurrenceRule;
102         cRecurrenceRule.recurrenceFrequency = nativeRecurrenceRule.recurrenceFrequency;
103         if (nativeRecurrenceRule.expire.has_value()) {
104             cRecurrenceRule.expire = nativeRecurrenceRule.expire.value();
105         }
106         if (nativeRecurrenceRule.count.has_value()) {
107             cRecurrenceRule.count = nativeRecurrenceRule.count.value();
108         }
109         if (nativeRecurrenceRule.interval.has_value()) {
110             cRecurrenceRule.interval = nativeRecurrenceRule.interval.value();
111         }
112 
113         if (nativeRecurrenceRule.excludedDates.has_value()) {
114             cRecurrenceRule.excludedDates = VectorToArrayI64(nativeRecurrenceRule.excludedDates.value(), errcode);
115         }
116         if (nativeRecurrenceRule.daysOfWeek.has_value()) {
117             cRecurrenceRule.daysOfWeek = VectorToArrayI64(nativeRecurrenceRule.daysOfWeek.value(), errcode);
118         }
119         if (nativeRecurrenceRule.daysOfMonth.has_value()) {
120             cRecurrenceRule.daysOfMonth = VectorToArrayI64(nativeRecurrenceRule.daysOfMonth.value(), errcode);
121         }
122         if (nativeRecurrenceRule.daysOfYear.has_value()) {
123             cRecurrenceRule.daysOfYear = VectorToArrayI64(nativeRecurrenceRule.daysOfYear.value(), errcode);
124         }
125         if (nativeRecurrenceRule.weeksOfMonth.has_value()) {
126             cRecurrenceRule.weeksOfMonth = VectorToArrayI64(nativeRecurrenceRule.weeksOfMonth.value(), errcode);
127         }
128         if (nativeRecurrenceRule.weeksOfYear.has_value()) {
129             cRecurrenceRule.weeksOfYear = VectorToArrayI64(nativeRecurrenceRule.weeksOfYear.value(), errcode);
130         }
131         if (nativeRecurrenceRule.monthsOfYear.has_value()) {
132             cRecurrenceRule.monthsOfYear = VectorToArrayI64(nativeRecurrenceRule.monthsOfYear.value(), errcode);
133         }
134         return cRecurrenceRule;
135     }
136 
BuildCLocation(Location location)137     CLocation CJCalendar::BuildCLocation(Location location)
138     {
139         CLocation clocation;
140         if (location.location.has_value()) {
141             clocation.location = IMallocCString(location.location.value());
142         }
143         if (location.longitude.has_value()) {
144             clocation.longitude = location.longitude.value();
145         }
146         if (location.latitude.has_value()) {
147             clocation.latitude = location.latitude.value();
148         }
149         return clocation;
150     }
151 
BuildCArrAttendee(vector<Attendee> attendees,int32_t * errcode)152     CArrAttendee CJCalendar::BuildCArrAttendee(vector<Attendee> attendees, int32_t* errcode)
153     {
154         CArrAttendee arr = {};
155         arr.size = attendees.size();
156         if (arr.size == 0) {
157             LOG_ERROR("Invalid size for memory allocation");
158             *errcode = CJ_ERR_OUT_OF_MEMORY;
159             return arr;
160         }
161         arr.head = static_cast<CAttendee *>(malloc(sizeof(CAttendee) * attendees.size()));
162         if (arr.head == nullptr) {
163             *errcode = CJ_ERR_OUT_OF_MEMORY;
164             LOG_ERROR("CAttendee malloc failed");
165             return arr;
166         }
167         for (size_t j = 0; j < attendees.size(); j++) {
168             arr.head[j].name = IMallocCString(attendees[j].name);
169             arr.head[j].email = IMallocCString(attendees[j].email);
170             if (attendees[j].role.has_value()) {
171                 arr.head[j].role = attendees[j].role.value();
172             }
173         }
174         return arr;
175     }
176 
CEventToEvent(CEvent event)177     Event CJCalendar::CEventToEvent(CEvent event)
178     {
179         Event nativeEvent = {};
180         nativeEvent.id = event.id;
181         nativeEvent.type = event.type == 0 ? Normal : Important;
182         nativeEvent.startTime = event.startTime;
183         nativeEvent.endTime = event.endTime;
184         nativeEvent.title = std::make_optional<std::string>(event.title);
185         nativeEvent.location->location = event.location.location;
186         nativeEvent.location->longitude = event.location.longitude;
187         nativeEvent.location->latitude = event.location.latitude;
188         nativeEvent.isAllDay = std::make_optional<bool>(event.isAllDay);
189         for (int64_t i = 0; i < event.attendee.size; i++) {
190             Attendee attendee;
191             attendee.name = event.attendee.head[i].name;
192             attendee.email = event.attendee.head[i].email;
193             attendee.role = std::make_optional<RoleType>(RoleType(event.attendee.head[i].role));
194             nativeEvent.attendees.push_back(attendee);
195         }
196         if (event.timeZone != nullptr && strlen(event.timeZone) > 0) {
197             nativeEvent.timeZone = std::make_optional<std::string>(event.timeZone);
198         }
199         std::vector<int> vec;
200         for (int64_t i = 0; i < event.reminderTime.size; i++) {
201             vec.push_back(static_cast<int>(event.reminderTime.head[i]));
202         }
203         nativeEvent.reminderTime = vec;
204         nativeEvent.recurrenceRule =
205             std::make_optional<RecurrenceRule>(BuildNativeRecurrenceRule(event.recurrenceRule));
206 
207         if (event.description != nullptr && strlen(event.description) > 0) {
208             nativeEvent.description = std::make_optional<std::string>(event.description);
209         }
210         nativeEvent.service->type = event.service.type;
211         nativeEvent.service->uri = event.service.uri;
212         if (event.service.description != nullptr && strlen(event.service.description) > 0) {
213             nativeEvent.service->description = std::make_optional<std::string>(event.service.description);
214         }
215         if (event.identifier != nullptr && strlen(event.identifier) > 0) {
216             nativeEvent.identifier = std::make_optional<std::string>(event.identifier);
217         }
218         nativeEvent.isLunar = std::make_optional<bool>(event.isLunar);
219         return nativeEvent;
220     }
221 
CRecurrenceRuleFree(CRecurrenceRule cRecurrenceRule)222     void CJCalendar::CRecurrenceRuleFree(CRecurrenceRule cRecurrenceRule)
223     {
224         if (cRecurrenceRule.excludedDates.head != nullptr) {
225             free(cRecurrenceRule.excludedDates.head);
226         }
227         if (cRecurrenceRule.daysOfWeek.head != nullptr) {
228             free(cRecurrenceRule.daysOfWeek.head);
229         }
230         if (cRecurrenceRule.daysOfMonth.head != nullptr) {
231             free(cRecurrenceRule.daysOfMonth.head);
232         }
233         if (cRecurrenceRule.daysOfYear.head != nullptr) {
234             free(cRecurrenceRule.daysOfYear.head);
235         }
236         if (cRecurrenceRule.weeksOfMonth.head != nullptr) {
237             free(cRecurrenceRule.weeksOfMonth.head);
238         }
239         if (cRecurrenceRule.weeksOfYear.head != nullptr) {
240             free(cRecurrenceRule.weeksOfYear.head);
241         }
242         if (cRecurrenceRule.monthsOfYear.head != nullptr) {
243             free(cRecurrenceRule.monthsOfYear.head);
244         }
245     }
246 
CArrAttendeeFree(CArrAttendee cArrAttendee)247     void CJCalendar::CArrAttendeeFree(CArrAttendee cArrAttendee)
248     {
249         for (int64_t j = 0; j < cArrAttendee.size; j++) {
250             if (cArrAttendee.head[j].name!= nullptr) {
251                 free(cArrAttendee.head[j].name);
252             }
253             if (cArrAttendee.head[j].email!= nullptr) {
254                 free(cArrAttendee.head[j].email);
255             }
256         }
257     }
258 
CArrEventfree(CArrEvents arr)259     void CJCalendar::CArrEventfree(CArrEvents arr)
260     {
261         if (arr.head == nullptr) {
262             return;
263         }
264         for (int64_t i = 0; i < arr.size; i++) {
265             if (arr.head[i].title != nullptr) {
266                 free(arr.head[i].title);
267             }
268             if (arr.head[i].timeZone != nullptr) {
269                 free(arr.head[i].timeZone);
270             }
271             if (arr.head[i].description != nullptr) {
272                 free(arr.head[i].description);
273             }
274             if (arr.head[i].service.description != nullptr) {
275                 free(arr.head[i].service.description);
276             }
277             if (arr.head[i].service.type != nullptr) {
278                 free(arr.head[i].service.type);
279             }
280             if (arr.head[i].service.uri != nullptr) {
281                 free(arr.head[i].service.uri);
282             }
283             if (arr.head[i].identifier != nullptr) {
284                 free(arr.head[i].identifier);
285             }
286             if (arr.head[i].reminderTime.head != nullptr) {
287                 free(arr.head[i].reminderTime.head);
288             }
289             if (arr.head[i].attendee.head != nullptr) {
290                 CArrAttendeeFree(arr.head[i].attendee);
291                 free(arr.head[i].attendee.head);
292             }
293             if (arr.head[i].location.location != nullptr) {
294                 free(arr.head[i].location.location);
295             }
296             CRecurrenceRuleFree(arr.head[i].recurrenceRule);
297             free(&arr.head[i]);
298         }
299     }
300 
VectorToCArrEvents(std::vector<Event> events,int32_t * errcode)301     CArrEvents CJCalendar::VectorToCArrEvents(std::vector<Event> events, int32_t* errcode)
302     {
303         CArrEvents arr = {};
304         arr.head = static_cast<CEvent *>(malloc(sizeof(CEvent) * events.size()));
305         if (arr.head == nullptr) {
306             *errcode = CJ_ERR_OUT_OF_MEMORY;
307             return arr;
308         }
309         arr.size = static_cast<int64_t>(events.size());
310         for (size_t i = 0; i < events.size(); i++) {
311             memset_s(&arr.head[i], sizeof(arr.head[i]), 0, sizeof(arr.head[i]));
312             arr.head[i].id = static_cast<int64_t>(events[i].id.value());
313             arr.head[i].type = events[i].type;
314             arr.head[i].startTime = events[i].startTime;
315             arr.head[i].endTime = events[i].endTime;
316             arr.head[i].title = IMallocCString(events[i].title.value_or(""));
317             if (events[i].location.has_value()) {
318                 arr.head[i].location = BuildCLocation(events[i].location.value());
319             }
320             arr.head[i].isAllDay = events[i].isAllDay.value_or(false);
321             arr.head[i].attendee = BuildCArrAttendee(events[i].attendees, errcode);
322             arr.head[i].timeZone = IMallocCString(events[i].timeZone.value_or(""));
323             if (events[i].reminderTime.has_value() && events[i].reminderTime.value().size() > 0) {
324                 vector<int> reminderTime = events[i].reminderTime.value();
325                 arr.head[i].reminderTime.size = static_cast<int64_t>(reminderTime.size());
326                 arr.head[i].reminderTime.head = static_cast<int64_t *>(malloc(sizeof(int64_t) * reminderTime.size()));
327                 if (arr.head[i].reminderTime.head == nullptr) {
328                     *errcode = CJ_ERR_OUT_OF_MEMORY;
329                     return arr;
330                 }
331                 for (int64_t j = 0; j < arr.head[i].reminderTime.size; j++) {
332                     arr.head[i].reminderTime.head[j] = static_cast<int64_t>(reminderTime[j]);
333                 }
334             }
335             if (events[i].recurrenceRule.has_value()) {
336                 arr.head[i].recurrenceRule = BuildCRecurrenceRule(events[i].recurrenceRule.value(), errcode);
337             }
338             arr.head[i].description = IMallocCString(events[i].description.value_or(""));
339             if (events[i].service.has_value()) {
340                 arr.head[i].service.type = IMallocCString(events[i].service.value().type);
341                 arr.head[i].service.uri = IMallocCString(events[i].service.value().uri);
342                 arr.head[i].service.description = IMallocCString(events[i].service.value().description.value_or(""));
343             }
344             arr.head[i].identifier = IMallocCString(events[i].identifier.value_or(""));
345             arr.head[i].isLunar = events[i].isLunar.value_or(false);
346         }
347         return arr;
348     }
349 
CJCalendar(std::shared_ptr<Native::CJNativeCalendar> calendar)350     CJCalendar::CJCalendar(std::shared_ptr<Native::CJNativeCalendar> calendar)
351     {
352         calendar_ = calendar;
353     }
354 
GetNative()355     std::shared_ptr<Native::CJNativeCalendar>& CJCalendar::GetNative()
356     {
357         return calendar_;
358     }
359 
AddEvent(CEvent event,int32_t * errcode)360     int64_t CJCalendar::AddEvent(CEvent event, int32_t* errcode)
361     {
362         Event nativeEvent = CEventToEvent(event);
363         auto cnative = GetNative();
364         if (cnative == nullptr) {
365             LOG_ERROR("cnative is nullptr");
366             *errcode = CJ_ERR_NULL_PTR;
367             return -1;
368         }
369         Native::DumpEvent(nativeEvent);
370         int64_t eventId = cnative->AddEvent(nativeEvent);
371         return eventId;
372     }
373 
AddEvents(CArrEvents event,int32_t * errcode)374     void CJCalendar::AddEvents(CArrEvents event, int32_t* errcode)
375     {
376         std::vector<Event> nativeEvents;
377         for (int64_t i = 0; i < event.size; i++) {
378             nativeEvents.push_back(CEventToEvent(event.head[i]));
379         }
380         if (calendar_ == nullptr) {
381             LOG_ERROR("calendar_ is nullptr");
382             *errcode = CJ_ERR_NULL_PTR;
383             return;
384         }
385         int count = calendar_->AddEvents(nativeEvents);
386         if (count < 0) {
387             LOG_ERROR("add events failed");
388             *errcode = CJ_ERR_NULL_PTR;
389             return;
390         }
391     }
392 
DeleteEvent(int64_t eventId,int32_t * errcode)393     void CJCalendar::DeleteEvent(int64_t eventId, int32_t* errcode)
394     {
395         if (calendar_ == nullptr) {
396             LOG_ERROR("calendar_ is nullptr");
397             *errcode = CJ_ERR_NULL_PTR;
398             return;
399         }
400         bool ret = calendar_->DeleteEvent(eventId);
401         if (!ret) {
402             LOG_ERROR("delete event failed");
403             *errcode = CJ_ERR_NULL_PTR;
404             return;
405         }
406     }
407 
DeleteEvents(CArrI64 eventIds,int32_t * errcode)408     void CJCalendar::DeleteEvents(CArrI64 eventIds, int32_t* errcode)
409     {
410         std::vector<int> ids;
411         for (int64_t i = 0; i < eventIds.size; i++) {
412             ids.push_back(static_cast<int>(eventIds.head[i]));
413         }
414         if (calendar_ == nullptr) {
415             LOG_ERROR("calendar_ is nullptr");
416             *errcode = CJ_ERR_NULL_PTR;
417             return;
418         }
419         int count = calendar_->DeleteEvents(ids);
420         if (count < 0) {
421             LOG_ERROR("delete events failed");
422             *errcode = CJ_ERR_NULL_PTR;
423             return;
424         }
425     }
426 
UpdateEvent(CEvent event,int32_t * errcode)427     void CJCalendar::UpdateEvent(CEvent event, int32_t* errcode)
428     {
429         Event nativeEvent = CEventToEvent(event);
430         if (calendar_ == nullptr) {
431             LOG_ERROR("calendar_ is nullptr");
432             *errcode = CJ_ERR_NULL_PTR;
433             return;
434         }
435         bool ret = calendar_->UpdateEvent(nativeEvent);
436         if (!ret) {
437             LOG_ERROR("update event failed");
438             *errcode = CJ_ERR_NULL_PTR;
439             return;
440         }
441     }
442 
GetEvents(int64_t eventFilterId,CArrString eventKey,int32_t * errcode)443     CArrEvents CJCalendar::GetEvents(int64_t eventFilterId, CArrString eventKey, int32_t* errcode)
444     {
445         std::vector<std::string> keys;
446         for (int64_t i = 0; i < eventKey.size; i++) {
447             keys.push_back(eventKey.head[i]);
448         }
449         auto instance = FFIData::GetData<CJEventFilter>(eventFilterId);
450         std::shared_ptr<Native::EventFilter> eventFilter = nullptr;
451         if (instance!= nullptr && instance->eventFilter_!= nullptr) {
452             eventFilter = instance->eventFilter_;
453         }
454         CArrEvents arr = {};
455         if (calendar_ == nullptr) {
456             LOG_ERROR("calendar_ is nullptr");
457             *errcode = CJ_ERR_NULL_PTR;
458             return arr;
459         }
460         std::vector<Event> events = calendar_->GetEvents(eventFilter, keys);
461         arr = VectorToCArrEvents(events, errcode);
462         if (*errcode != 0) {
463             CArrEventfree(arr);
464         }
465         return arr;
466     }
467 
GetConfig(int32_t * errcode)468     CCalendarConfig CJCalendar::GetConfig(int32_t* errcode)
469     {
470         CCalendarConfig config = {};
471         if (calendar_ == nullptr) {
472             LOG_ERROR("calendar_ is nullptr");
473             *errcode = CJ_ERR_NULL_PTR;
474             return config;
475         }
476         CalendarConfig nativeConfig = calendar_->GetConfig();
477         config.enableReminder = nativeConfig.enableReminder.value();
478         config.color = std::get<int64_t>(nativeConfig.color);
479         return config;
480     }
481 
SetConfig(CCalendarConfig config,int32_t * errcode)482     void CJCalendar::SetConfig(CCalendarConfig config, int32_t* errcode)
483     {
484         CalendarConfig nativeConfig;
485         nativeConfig.enableReminder = config.enableReminder;
486         nativeConfig.color = config.color;
487         if (calendar_ == nullptr) {
488             LOG_ERROR("calendar_ is nullptr");
489             *errcode = CJ_ERR_NULL_PTR;
490             return;
491         }
492 
493         bool ret = calendar_->SetConfig(nativeConfig);
494         if (!ret) {
495             LOG_ERROR("set config failed");
496             *errcode = CJ_ERR_NULL_PTR;
497             return;
498         }
499     }
500 
GetAccount(int32_t * errcode)501     CCalendarAccount CJCalendar::GetAccount(int32_t* errcode)
502     {
503         CCalendarAccount account;
504         if (calendar_ == nullptr) {
505             LOG_ERROR("calendar_ is nullptr");
506             *errcode = CJ_ERR_NULL_PTR;
507             return account;
508         }
509         CalendarAccount nativeAccount = calendar_->GetAccount();
510         account.name = IMallocCString(nativeAccount.name);
511         account.type = IMallocCString(nativeAccount.type);
512         account.displayName = IMallocCString(nativeAccount.displayName.value());
513         return account;
514     }
515 }
516 }