b3408ff3ce8bc1c1602d9419f18348d27063babe
[platform/core/appfw/watchface-complication.git] / watchface-editor / watchface-editor.cc
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <glib.h>
20 #include <dlog.h>
21 #include <app_control.h>
22 #include <aul.h>
23 #include <iostream>
24
25 #include <string>
26
27 #include "watchface-editor/include/watchface-editor.h"
28 #include "watchface-complication/complication.hh"
29 #include "watchface-editor/editables-editor.hh"
30 #include "watchface-common/watchface-util.hh"
31 #include "watchface-common/shared-handle.hh"
32
33 #ifdef LOG_TAG
34 #undef LOG_TAG
35 #endif
36
37 #define LOG_TAG "WATCHFACE_COMPLICATION"
38
39 using namespace std;
40 using namespace tizen_base;
41 using namespace watchface_complication;
42
43 class CallbackInfo {
44  public:
45   CallbackInfo(watchface_editor_request_edit_cb cb, void* user_data)
46     : cb_(cb), user_data_(user_data) {
47   }
48
49   CallbackInfo(CallbackInfo&& b) noexcept {
50     cb_ = b.cb_;
51     user_data_ = b.user_data_;
52     b.cb_ = nullptr;
53     b.user_data_ = nullptr;
54   }
55
56   void Invoke(const std::string& appid, editable_list_h list_h) {
57     cb_(appid.c_str(), list_h, user_data_);
58   }
59
60   watchface_editor_request_edit_cb GetCallback() {
61     return cb_;
62   }
63
64  private:
65   watchface_editor_request_edit_cb cb_;
66   void* user_data_;
67 };
68
69 class SetupCallbackInfo {
70  public:
71   SetupCallbackInfo(std::string& setup_appid, int editable_id,
72                watchface_editor_setup_result_cb cb, void* user_data)
73     : setup_appid_(setup_appid), editable_id_(editable_id),
74                            cb_(cb), user_data_(user_data) {
75   }
76
77   SetupCallbackInfo(SetupCallbackInfo&& b) noexcept {
78     setup_appid_ = b.setup_appid_;
79     editable_id_ = b.editable_id_;
80     cb_ = b.cb_;
81     user_data_ = b.user_data_;
82     b.cb_ = nullptr;
83     b.user_data_ = nullptr;
84   }
85
86   void Invoke(bundle* new_context) {
87     cb_(editable_id_, new_context, user_data_);
88   }
89
90   bool CompareInfo(const std::string& setup_appid, int editable_id) {
91     if (editable_id == editable_id_ && setup_appid_.compare(setup_appid) == 0)
92       return true;
93
94     return false;
95   }
96
97  private:
98   std::string setup_appid_;
99   int editable_id_;
100   watchface_editor_setup_result_cb cb_;
101   void* user_data_;
102 };
103
104 class EditResultCallbackInfo {
105  public:
106   EditResultCallbackInfo(watchface_editor_edit_result_cb cb,
107       int editable_id, int sequence, void* user_data)
108     : cb_(cb), editable_id_(editable_id), sequence_(sequence), user_data_(user_data) {
109   }
110
111   EditResultCallbackInfo(EditResultCallbackInfo&& info) noexcept {
112     cb_ = info.cb_;
113     editable_id_ = info.editable_id_;
114     sequence_ = info.sequence_;
115     user_data_ = info.user_data_;
116   }
117
118   void Invoke(const watchface_editable_h handle, int result) {
119     cb_(handle, (watchface_complication_error_e)result, user_data_);
120   }
121
122   bool CompareInfo(int sequence, int editable_id) {
123     if (editable_id == editable_id_ && sequence == sequence_)
124       return true;
125
126     return false;
127   }
128
129  private:
130   watchface_editor_edit_result_cb cb_;
131   int editable_id_;
132   int sequence_;
133   void* user_data_;
134 };
135
136 static void _delete_shared_editable(gpointer data)
137 {
138   SharedHandle<IEditable>* ptr = (SharedHandle<IEditable>*)data;
139   shared_ptr<IEditable> ed = ptr->GetPtr();
140   delete ptr;
141 }
142
143 class EditablesEditorStub : public EditablesEditor {
144  public:
145   EditablesEditorStub() : EditablesEditor() {
146   }
147
148   virtual ~EditablesEditorStub() = default;
149   void OnRequestEdit(const std::string& appid,
150                      std::list<std::shared_ptr<IEditable>> e_list) override {
151     GList* list = nullptr;
152     for (auto& i : e_list) {
153       LOGI("edit item %d", i.get()->GetEditableId());
154       list = g_list_append(list, SharedHandle<IEditable>::Make(i));
155     }
156     for (auto& i : cb_list_) {
157       i->Invoke(appid, list);
158     }
159     g_list_free_full(list, _delete_shared_editable);
160     LOGI("request edit!! %s", appid.c_str());
161   }
162
163   void OnSetupReply(const std::string& appid,
164                  int editable_id, std::unique_ptr<Bundle> context) override {
165     LOGI("Setup reply!! %s, %d", appid.c_str(), editable_id);
166     for (auto& i : setup_cb_list_) {
167       if (i.get()->CompareInfo(appid, editable_id)) {
168           i.get()->Invoke(context.get()->GetHandle());
169           setup_cb_list_.remove(i);
170           return;
171       }
172     }
173     LOGE("Not exist callback info");
174   }
175
176   void OnEditResult(shared_ptr<IEditable> editable, int result) override {
177     for (auto& i : edit_cb_list_) {
178       if (i.get()->CompareInfo(editable->GetEditSequence(),
179           editable->GetEditableId())) {
180         SharedHandle<IEditable>* share = SharedHandle<IEditable>::Make(editable);
181         i.get()->Invoke((void*)share, result);
182         delete share;
183       }
184     }
185   }
186
187   void AddSetupCallbackInfo(unique_ptr<SetupCallbackInfo> ci) {
188     setup_cb_list_.emplace_back(move(ci));
189   }
190
191   void RemoveSetupCallbackInfo(unique_ptr<SetupCallbackInfo> ci) {
192     for (auto& i : setup_cb_list_) {
193       if (i.get() == ci.get()) {
194         setup_cb_list_.remove(i);
195         break;
196       }
197     }
198   }
199
200   int AddCallbackInfo(unique_ptr<CallbackInfo> ci) {
201     for (auto& i : cb_list_) {
202       if (i.get()->GetCallback() == ci->GetCallback()) {
203         LOGI("already registered callback");
204         return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
205       }
206     }
207
208     cb_list_.emplace_back(move(ci));
209     return WATCHFACE_COMPLICATION_ERROR_NONE;
210   }
211
212   int RemoveCallbackInfo(watchface_editor_request_edit_cb ci) {
213     for (auto& i : cb_list_) {
214       if (i.get()->GetCallback() == ci) {
215         cb_list_.remove(i);
216         return WATCHFACE_COMPLICATION_ERROR_NONE;
217       }
218     }
219     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
220   }
221
222   int AddEditResultCallbackInfo(watchface_editor_edit_result_cb cb,
223       int editable_id, int sequence, void* user_data) {
224     for (auto& i : edit_cb_list_) {
225       if (i.get()->CompareInfo(editable_id, sequence)) {
226         LOGI("already registered callback");
227         return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
228       }
229     }
230
231     edit_cb_list_.emplace_back(unique_ptr<EditResultCallbackInfo>(
232       new EditResultCallbackInfo(cb, editable_id, sequence, user_data)));
233     return WATCHFACE_COMPLICATION_ERROR_NONE;
234   }
235
236   int RemoveEditResultCallbackInfo(int editable_id, int sequence) {
237     for (auto& i : edit_cb_list_) {
238       if (i.get()->CompareInfo(editable_id, sequence)) {
239         edit_cb_list_.remove(i);
240         return WATCHFACE_COMPLICATION_ERROR_NONE;
241       }
242     }
243     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
244   }
245
246  private:
247   std::list<std::unique_ptr<CallbackInfo>> cb_list_;
248   std::list<std::unique_ptr<SetupCallbackInfo>> setup_cb_list_;
249   std::list<std::unique_ptr<EditResultCallbackInfo>> edit_cb_list_;
250 };
251
252 static std::unique_ptr<EditablesEditorStub> __stub = nullptr;
253 extern "C" EXPORT_API int watchface_editor_add_request_edit_cb(
254     watchface_editor_request_edit_cb cb, void* user_data) {
255   if (!watchface_complication::util::CheckWatchFeatureEnabled())
256     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
257
258   if (cb == NULL) {
259     LOGE("Invalid parameter");
260     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
261   }
262
263   if (__stub == nullptr) {
264     try {
265       __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
266     } catch (const std::exception& e) {
267       LOGE("Exception occurred : %s", e.what());
268       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
269     }
270   }
271
272   unique_ptr<CallbackInfo> ci = unique_ptr<CallbackInfo>(
273       new (std::nothrow) CallbackInfo(cb, user_data));
274   if (ci.get() == nullptr) {
275     LOGE("Out of memory");
276     return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
277   }
278   return __stub->AddCallbackInfo(move(ci));
279 }
280
281 extern "C" EXPORT_API int watchface_editor_remove_request_edit_cb(
282     watchface_editor_request_edit_cb cb) {
283   if (!watchface_complication::util::CheckWatchFeatureEnabled())
284     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
285
286   if (cb == NULL || __stub == nullptr) {
287     LOGE("Invalid parameter");
288     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
289   }
290
291   return __stub->RemoveCallbackInfo(cb);
292 }
293
294 extern "C" EXPORT_API int watchface_editor_edit_preview(
295     const watchface_editable_h handle, int cur_data_idx) {
296   int ret;
297
298   if (!watchface_complication::util::CheckWatchFeatureEnabled())
299     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
300
301   if (handle == nullptr) {
302     LOGE("Invalid parameter");
303     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
304   }
305
306   SharedHandle<IEditable>* ptr = static_cast<SharedHandle<IEditable>*>(handle);
307   shared_ptr<IEditable> ed = ptr->GetPtr();
308   ret = ed->SetCurDataIdx(cur_data_idx);
309   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
310     return ret;
311
312   __stub->EditPreview(ed, cur_data_idx, 0, true);
313
314   return WATCHFACE_COMPLICATION_ERROR_NONE;
315 }
316
317
318 extern "C" EXPORT_API int watchface_editor_edit_preview_with_result(
319     const watchface_editable_h handle,
320     int cur_data_idx, watchface_editor_edit_result_cb result_cb,
321     int timeout, bool auto_reply, void *user_data) {
322   int ret;
323
324   if (!watchface_complication::util::CheckWatchFeatureEnabled())
325     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
326
327   if (handle == nullptr || result_cb == nullptr || (auto_reply && timeout <= 0)
328       || timeout < 0) {
329     LOGE("Invalid parameter");
330     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
331   }
332
333   SharedHandle<IEditable>* ptr = static_cast<SharedHandle<IEditable>*>(handle);
334   shared_ptr<IEditable> ed = ptr->GetPtr();
335   ret = ed->SetCurDataIdx(cur_data_idx);
336   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
337     return ret;
338
339   __stub->EditPreview(ed, cur_data_idx, timeout, auto_reply);
340   __stub->AddEditResultCallbackInfo(result_cb,
341       ed->GetEditableId(), ed->GetEditSequence(), user_data);
342
343   return WATCHFACE_COMPLICATION_ERROR_NONE;
344 }
345
346 static int __init_stub() {
347   if (__stub != nullptr)
348     return WATCHFACE_COMPLICATION_ERROR_NONE;
349   try {
350     __stub = std::unique_ptr<EditablesEditorStub>(new EditablesEditorStub());
351   } catch (const std::bad_alloc &ba) {
352     LOGE("EditablesEditorStub::Exception bad_alloc");
353     return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
354   } catch (Exception &ex) {
355     LOGE("%s %d", ex.what(), ex.GetErrorCode());
356     return ex.GetErrorCode();
357   }
358   return WATCHFACE_COMPLICATION_ERROR_NONE;
359 }
360
361 extern "C" EXPORT_API int watchface_editor_edit_complete(void) {
362   if (!watchface_complication::util::CheckWatchFeatureEnabled())
363     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
364   int ret = __init_stub();
365   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
366     return ret;
367   return __stub->EditComplete();
368 }
369
370 extern "C" EXPORT_API int watchface_editor_edit_cancel(void) {
371   if (!watchface_complication::util::CheckWatchFeatureEnabled())
372     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
373   int ret = __init_stub();
374   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
375     return ret;
376
377   return __stub->EditCancel();
378 }
379
380 extern "C" EXPORT_API int watchface_editor_notify_edit_ready(
381     const char* appid) {
382   if (!watchface_complication::util::CheckWatchFeatureEnabled())
383     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
384
385   if (appid == NULL) {
386     LOGE("Invalid parameter");
387     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
388   }
389
390   int ret = __init_stub();
391   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
392     return ret;
393   return __stub->NotifyEditReady(std::string(appid));
394 }
395
396 extern "C" EXPORT_API int watchface_editor_editable_list_dup(
397   editable_list_h source, editable_list_h* dest) {
398   if (!watchface_complication::util::CheckWatchFeatureEnabled())
399     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
400
401   if (source == NULL || dest == NULL) {
402     LOGE("Invalid parameter");
403     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
404   }
405
406   GList* iter = source;
407   while (iter) {
408     SharedHandle<IEditable>* ptr =
409         static_cast<SharedHandle<IEditable>*>(iter->data);
410     *dest = g_list_append(*dest, SharedHandle<IEditable>::Make(ptr->GetPtr()));
411     iter = iter->next;
412   }
413   return WATCHFACE_COMPLICATION_ERROR_NONE;
414 }
415
416 extern "C" EXPORT_API int watchface_editor_editable_list_destroy(
417     editable_list_h list) {
418   /* list items are managed by EditablesEditor */
419   if (!watchface_complication::util::CheckWatchFeatureEnabled())
420     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
421
422   if (list == NULL) {
423     LOGE("Invalid parameter");
424     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
425   }
426
427   g_list_free_full(list, _delete_shared_editable);
428   return WATCHFACE_COMPLICATION_ERROR_NONE;
429 }
430
431 extern "C" EXPORT_API int watchface_editor_editable_list_get_size(
432     editable_list_h list, int* size) {
433   if (!watchface_complication::util::CheckWatchFeatureEnabled())
434     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
435
436   if (list == NULL || size == NULL) {
437     LOGE("Invalid parameter");
438     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
439   }
440   *size = g_list_length(list);
441   return WATCHFACE_COMPLICATION_ERROR_NONE;
442 }
443
444 extern "C" EXPORT_API int watchface_editor_editable_list_get_nth(
445   editable_list_h list, int nth, watchface_editable_h* handle) {
446   if (!watchface_complication::util::CheckWatchFeatureEnabled())
447     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
448
449   if (list == NULL || nth < 0 || nth >= static_cast<int>(g_list_length(list)) ||
450     handle == NULL) {
451     LOGE("Invalid parameter");
452     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
453   }
454
455   GList* iter = g_list_first(list);
456   int idx = 0;
457   while (iter) {
458     if (idx == nth) {
459       *handle = iter->data;
460       break;
461     }
462     idx++;
463     iter = iter->next;
464   }
465
466   return WATCHFACE_COMPLICATION_ERROR_NONE;
467 }
468
469 extern "C" EXPORT_API int watchface_editor_editable_candidate_list_get_size(
470   watchface_editable_h handle, int* size) {
471   if (!watchface_complication::util::CheckWatchFeatureEnabled())
472     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
473
474   if (handle == NULL || size == NULL) {
475     LOGE("Invalid parameter");
476     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
477   }
478
479   SharedHandle<IEditable>* ptr = static_cast<SharedHandle<IEditable>*>(handle);
480   shared_ptr<IEditable> ed = ptr->GetPtr();
481   std::list<std::shared_ptr<Bundle>> const& list = ed->GetCandidates();
482   *size = list.size();
483   return WATCHFACE_COMPLICATION_ERROR_NONE;
484 }
485
486 extern "C" EXPORT_API int watchface_editor_editable_candidate_list_get_nth(
487   watchface_editable_h handle, int nth, bundle** data) {
488   if (!watchface_complication::util::CheckWatchFeatureEnabled())
489     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
490
491   if (handle == NULL || data == NULL) {
492     LOGE("Invalid parameter");
493     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
494   }
495
496   bundle* tmp;
497   SharedHandle<IEditable>* ptr = static_cast<SharedHandle<IEditable>*>(handle);
498   shared_ptr<IEditable> ed = ptr->GetPtr();
499   const std::list<std::shared_ptr<Bundle>>& list = ed->GetCandidates();
500   const std::list<std::shared_ptr<Bundle>>::const_iterator it
501                                   = list.begin();
502   auto nx = std::next(it, nth);
503   tmp = bundle_dup((*nx)->GetHandle());
504   if (tmp == NULL)
505     return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
506
507   *data = tmp;
508   return WATCHFACE_COMPLICATION_ERROR_NONE;
509 }
510
511 extern "C" EXPORT_API int watchface_editor_get_setup_appid(
512     watchface_editable_h handle, char** setup_appid) {
513   if (!watchface_complication::util::CheckWatchFeatureEnabled())
514     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
515
516   if (handle == NULL || setup_appid == NULL)
517     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
518
519   char* tmp;
520   SharedHandle<IEditable>* ptr = static_cast<SharedHandle<IEditable>*>(handle);
521   shared_ptr<IEditable> ed = ptr->GetPtr();
522   std::string appid = ed->GetSetupAppId();
523   if (appid.empty())
524     return WATCHFACE_COMPLICATION_ERROR_NO_DATA;
525
526   tmp = strdup(appid.c_str());
527   if (tmp == NULL)
528     return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
529
530   *setup_appid = tmp;
531   return WATCHFACE_COMPLICATION_ERROR_NONE;
532 }
533
534 extern "C" EXPORT_API int watchface_editor_set_context(
535     watchface_editable_h handle, bundle* new_context) {
536   if (!watchface_complication::util::CheckWatchFeatureEnabled())
537     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
538
539   if (handle == NULL) {
540     LOGE("Invalid parameter");
541     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
542   }
543
544   int re = WATCHFACE_COMPLICATION_ERROR_NONE;
545   SharedHandle<IEditable>* ptr = static_cast<SharedHandle<IEditable>*>(handle);
546   shared_ptr<IEditable> ed = ptr->GetPtr();
547   if (new_context) {
548     try {
549       std::unique_ptr<Bundle> b(new Bundle(new_context));
550       re = ed->SetContext(std::move(b));
551     } catch (const std::exception& e) {
552       LOGE("Exception occurred : %s", e.what());
553       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
554     }
555   } else {
556     re = ed->SetContext(std::unique_ptr<Bundle>{});
557   }
558   return re;
559 }
560
561 extern "C" EXPORT_API int watchface_editor_is_setup_app_exist(
562     watchface_editable_h handle, bool* exist) {
563   if (!watchface_complication::util::CheckWatchFeatureEnabled())
564     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
565
566   if (handle == NULL) {
567     LOGE("Invalid parameter");
568     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
569   }
570   SharedHandle<IEditable>* ptr = static_cast<SharedHandle<IEditable>*>(handle);
571   shared_ptr<IEditable> ed = ptr->GetPtr();
572   std::string appid = ed->GetSetupAppId();
573   if (appid.empty())
574     *exist = false;
575   *exist = true;
576   return WATCHFACE_COMPLICATION_ERROR_NONE;
577 }
578
579 static int _add_extra_data(app_control_h service, const char* key,
580     const char* value) {
581   int ret = app_control_add_extra_data(service, key, value);
582   if (ret != APP_CONTROL_ERROR_NONE) {
583     if (ret == APP_CONTROL_ERROR_OUT_OF_MEMORY) {
584       LOGE("Fail to add extra data - out of memory");
585       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
586     }
587     LOGE("Fail to add extra data %d", ret);
588     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
589   }
590   return WATCHFACE_COMPLICATION_ERROR_NONE;
591 }
592
593 extern "C" EXPORT_API int watchface_editor_launch_setup_app(
594     watchface_editable_h handle, watchface_editor_setup_result_cb cb,
595     void* user_data) {
596   if (!watchface_complication::util::CheckWatchFeatureEnabled())
597     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
598
599   if (handle == NULL || cb == NULL) {
600     LOGE("Invalid parameter");
601     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
602   }
603
604   SharedHandle<IEditable>* share = static_cast<SharedHandle<IEditable>*>(handle);
605   shared_ptr<IEditable> ed = share->GetPtr();
606   std::string appid = ed->GetSetupAppId();
607   Bundle* context_data;
608   char ed_id[256] = {0, };
609   app_control_h service = nullptr;
610   if (APP_CONTROL_ERROR_NONE != app_control_create(&service)) {
611     LOGE("Fail to create app control");
612     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
613   }
614
615   auto ptr = unique_ptr<app_control_s,
616     decltype(app_control_destroy)*>(service, app_control_destroy);
617
618   LOGI("LAUNCH !!! %s", appid.c_str());
619   int ret = app_control_set_app_id(ptr.get(), appid.c_str());
620   if (ret != APP_CONTROL_ERROR_NONE) {
621     LOGE("Fail to set appid");
622     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
623   }
624
625   ret = _add_extra_data(ptr.get(), SETUP_EDITOR_APPID_KEY,
626       util::GetAppId().c_str());
627   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
628     LOGE("Fail to add setup appid ");
629     return ret;
630   }
631
632   snprintf(ed_id, sizeof(ed_id), "%d", ed->GetEditableId());
633   LOGI("add ed_id %s", ed_id);
634   ret = _add_extra_data(ptr.get(), SETUP_EDITABLE_ID_KEY, ed_id);
635   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
636     LOGE("Fail to add ed_id %s", ed_id);
637     return ret;
638   }
639
640   context_data = (ed->GetContext()).get();
641   if (context_data != nullptr) {
642     try {
643       ret = _add_extra_data(ptr.get(), SETUP_CONTEXT_DATA_KEY,
644           reinterpret_cast<char*>(context_data->ToRaw().first.get()));
645     } catch (const std::bad_alloc &ba) {
646       LOGE("Exception bad_alloc");
647       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
648     }
649
650     if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
651       LOGE("Fail to add setup_context_data %d", ret);
652       return ret;
653     }
654   }
655
656   ret = app_control_send_launch_request(ptr.get(), nullptr, nullptr);
657   if (ret != APP_CONTROL_ERROR_NONE) {
658     LOGE("Failed to launch:%d", ret);
659     return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
660   }
661
662   unique_ptr<SetupCallbackInfo> ci = unique_ptr<SetupCallbackInfo>(
663       new (std::nothrow) SetupCallbackInfo(
664         appid, ed->GetEditableId(), cb, user_data));
665
666   ret = __init_stub();
667   if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
668     return ret;
669   __stub->AddSetupCallbackInfo(move(ci));
670
671   return WATCHFACE_COMPLICATION_ERROR_NONE;
672 }
673
674 extern "C" EXPORT_API int watchface_editor_get_complication_provider_id(
675     const bundle* complication, char** provider_id) {
676   if (!watchface_complication::util::CheckWatchFeatureEnabled())
677     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
678
679   if (complication == NULL || provider_id == NULL)
680     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
681
682   char* val = NULL;
683   char* tmp;
684
685   bundle_get_str(const_cast<bundle*>(complication),
686       Complication::GetProviderIdKey(), &val);
687   if (val != NULL) {
688     tmp = strdup(val);
689     if (tmp == NULL)
690       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
691     *provider_id = tmp;
692   } else {
693     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
694   }
695
696   return WATCHFACE_COMPLICATION_ERROR_NONE;
697 }
698
699 extern "C" EXPORT_API int watchface_editor_get_complication_type(
700     const bundle* complication, watchface_complication_type_e* cur_type) {
701   if (!watchface_complication::util::CheckWatchFeatureEnabled())
702     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
703
704   if (complication == NULL || cur_type == NULL)
705     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
706
707   char* val = NULL;
708
709   bundle_get_str(const_cast<bundle*>(complication),
710       Complication::GetProviderTypeKey(), &val);
711   if (val != NULL)
712     *cur_type = static_cast<watchface_complication_type_e>(atoi(val));
713   else
714     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
715
716   return WATCHFACE_COMPLICATION_ERROR_NONE;
717 }
718
719 extern "C" EXPORT_API int watchface_editor_get_complication_provider_name(
720     const bundle* candidate_data, char** provider_name) {
721   if (!watchface_complication::util::CheckWatchFeatureEnabled())
722     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
723
724   if (candidate_data == NULL || provider_name == NULL)
725     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
726
727   char* val = NULL;
728   char* tmp = NULL;
729   bundle_get_str(const_cast<bundle*>(candidate_data),
730       Complication::GetProviderIdKey(), &val);
731   if (val != NULL) {
732     std::string label = DBManager::GetLabel(val);
733     if (!label.empty()) {
734       tmp = strdup(label.c_str());
735       if (tmp == NULL)
736         return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
737       *provider_name = tmp;
738     } else {
739       LOGE("fail to get name (%s)", val);
740       return WATCHFACE_COMPLICATION_ERROR_NO_DATA;
741     }
742   } else {
743     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
744   }
745
746   return WATCHFACE_COMPLICATION_ERROR_NONE;
747 }
748
749 extern "C" EXPORT_API int watchface_editor_get_complication_provider_icon(
750     const bundle* candidate_data, char** icon) {
751   if (!watchface_complication::util::CheckWatchFeatureEnabled())
752     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
753
754   if (candidate_data == NULL || icon == NULL)
755     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
756
757   char* val = NULL;
758   bundle_get_str(const_cast<bundle*>(candidate_data),
759       Complication::GetProviderIdKey(), &val);
760   if (val != NULL) {
761     std::string ic = DBManager::GetIcon(val, DBManager::GetSystemLocale());
762     if (ic.empty())
763       ic = DBManager::GetIcon(val, "No Locale");
764     if (!ic.empty()) {
765       char* shared_path;
766       aul_get_app_shared_resource_path_by_appid(
767           DBManager::GetProviderAppId(val).c_str(), &shared_path);
768       std::string app_path = std::string(shared_path) + ic;
769       free(shared_path);
770       LOGI("icon path : (%s)", app_path.c_str());
771       *icon = strdup(app_path.c_str());
772     } else {
773       LOGE("fail to get name (%s)", val);
774       return WATCHFACE_COMPLICATION_ERROR_NO_DATA;
775     }
776   } else {
777     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
778   }
779
780   return WATCHFACE_COMPLICATION_ERROR_NONE;
781 }
782
783 extern "C" EXPORT_API int watchface_editor_get_complication_is_supported(
784     const bundle* candidate_data, bool* is_supported,
785     watchface_editor_error_e* error, char** error_message) {
786   char* dup_error;
787   char* val = NULL;
788
789   if (!watchface_complication::util::CheckWatchFeatureEnabled())
790     return WATCHFACE_COMPLICATION_ERROR_NOT_SUPPORTED;
791
792   if (candidate_data == NULL || is_supported == NULL ||
793       error == NULL || error_message == NULL)
794     return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
795
796   bundle_get_str(const_cast<bundle*>(candidate_data),
797       Complication::GetPrivilegeErrorKey(), &val);
798   if (val != NULL) {
799     dup_error = strdup(val);
800     if (dup_error == NULL) {
801       LOGE("Out of memory");
802       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
803     }
804     *error = WATCHFACE_EDITOR_ERROR_PERMISSION_DENY;
805     *error_message = dup_error;
806     *is_supported = false;
807     return WATCHFACE_COMPLICATION_ERROR_NONE;
808   }
809
810   bundle_get_str(const_cast<bundle*>(candidate_data),
811       Complication::GetSupportedEventsErrorKey(), &val);
812   if (val != NULL) {
813     int events = atoi(val);
814     if (events < 0 ||
815       (WATCHFACE_COMPLICATION_EVENT_NONE |
816        WATCHFACE_COMPLICATION_EVENT_TAP |
817        WATCHFACE_COMPLICATION_EVENT_DOUBLE_TAP) < events)
818        return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
819     dup_error = strdup(val);
820     if (dup_error == NULL) {
821       LOGE("Out of memory");
822       return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
823     }
824     *error = WATCHFACE_EDITOR_ERROR_EVENT_NOT_SUPPORT;
825     *error_message = dup_error;
826     *is_supported = false;
827     return WATCHFACE_COMPLICATION_ERROR_NONE;
828   }
829   *error = WATCHFACE_EDITOR_ERROR_NONE;
830   *is_supported = true;
831   return WATCHFACE_COMPLICATION_ERROR_NONE;
832 }