Fix build error for gcc 12.2.0
[platform/core/appfw/appcore-widget.git] / src / efl_base / widget_app.cc
1 /*
2 * Copyright (c) 2015 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
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 <Elementary.h>
18 #include <app_event_internal.hh>
19 #include <aul.h>
20 #include <aul_app_com.h>
21 #include <aul_widget.h>
22 #include <dlog.h>
23 #include <glib.h>
24 #include <stdlib.h>
25 #include <system_info.h>
26 #include <widget_errno.h>
27 #include <widget_instance.h>
28
29 #include <stdexcept>
30
31 #include "common/export_private.hh"
32 #include "common/log_private.hh"
33 #include "include/widget_app.h"
34 #include "include/widget_app_internal.h"
35 #include "include/widget_base.hh"
36
37 using namespace tizen_cpp;
38 namespace {
39
40 constexpr const int kIconifyTimeout = 500;
41 constexpr const char kFeatureShellAppWidget[] =
42     "http://tizen.org/feature/shell.appwidget";
43 constexpr int APP_EVENT_MAX = 7;
44 constexpr IAppCore::IEvent::Type __app_event_converter[APP_EVENT_MAX] = {
45   [APP_EVENT_LOW_MEMORY] = IAppCore::IEvent::Type::LOW_MEMORY,
46   [APP_EVENT_LOW_BATTERY] = IAppCore::IEvent::Type::LOW_BATTERY,
47   [APP_EVENT_LANGUAGE_CHANGED] = IAppCore::IEvent::Type::LANG_CHANGE,
48   [APP_EVENT_DEVICE_ORIENTATION_CHANGED]
49       = IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED,
50   [APP_EVENT_REGION_FORMAT_CHANGED] = IAppCore::IEvent::Type::REGION_CHANGE,
51   [APP_EVENT_SUSPENDED_STATE_CHANGED]
52       = IAppCore::IEvent::Type::SUSPENDED_STATE_CHANGE,
53 };
54
55 class AppWidget : public WidgetBase {
56  public:
57   AppWidget(widget_app_lifecycle_callback_s* callback, void* user_data)
58       : callback_(callback), user_data_(user_data) {}
59
60   int OnCreate() override {
61     WidgetBase::OnCreate();
62     if (callback_ && callback_->create) {
63       if (callback_->create(user_data_) == nullptr) {
64         _E("Failed to create widget");
65         return -1;
66       }
67
68       _D("Widget app is created");
69       aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
70       return 0;
71     }
72
73     return -1;
74   }
75
76   int OnTerminate() override {
77     if (callback_ && callback_->terminate) {
78       callback_->terminate(user_data_);
79       WidgetBase::OnTerminate();
80       _D("Widget app is terminated");
81       aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
82       return 0;
83     }
84
85     WidgetBase::OnTerminate();
86     return -1;
87   }
88
89   void OnLoopInit(int argc, char** argv) override {
90     elm_init(argc, argv);
91   }
92
93   void OnLoopFinish() override {
94     elm_shutdown();
95   }
96
97   void OnLoopRun() override {
98     elm_run();
99   }
100
101   void OnLoopExit() override {
102     elm_exit();
103   }
104
105   int OnTrimMemory() override {
106     _D("Trim memory");
107     elm_cache_all_flush();
108     return WidgetBase::OnTrimMemory();
109   }
110
111  private:
112   widget_app_lifecycle_callback_s* callback_;
113   void* user_data_;
114 };
115
116 class AppWidgetContext : public WidgetContext {
117  public:
118   class Factory : public AppCoreMultiWindowBase::Context::IFactory {
119    public:
120     Factory(std::string widget_id,
121         widget_instance_lifecycle_callback_s callback, void* user_data)
122         : widget_id_(std::move(widget_id)),
123           callback_(callback),
124           user_data_(user_data) {
125     }
126
127     std::unique_ptr<Context> Create(std::string inst_id,
128         AppCoreMultiWindowBase* app) override {
129       return std::unique_ptr<Context>(
130           new AppWidgetContext(widget_id_, std::move(inst_id), app,
131               callback_, user_data_));
132     }
133
134    private:
135     std::string widget_id_;
136     widget_instance_lifecycle_callback_s callback_;
137     void* user_data_;
138   };
139
140   AppWidgetContext(std::string context_id, std::string inst_id,
141       AppCoreMultiWindowBase* app,
142       widget_instance_lifecycle_callback_s callback, void* user_data)
143       : WidgetContext(std::move(context_id), std::move(inst_id), app),
144           callback_(callback), user_data_(user_data) {}
145
146   bool OnCreate(const tizen_base::Bundle& contents, int w, int h) override {
147     int ret = -1;
148     if (callback_.create) {
149       ret = callback_.create(reinterpret_cast<widget_context_h>(this),
150           contents.GetHandle(), w, h, user_data_);
151       aul_widget_write_log(LOG_TAG, "[%s:%d]  ret : %d",
152           __FUNCTION__, __LINE__, ret);
153     }
154
155     return ret == 0;
156   }
157
158   void OnDestroy(DestroyType reason,
159       const tizen_base::Bundle& contents) override {
160     if (callback_.destroy) {
161       callback_.destroy(reinterpret_cast<widget_context_h>(this),
162           reason == DestroyType::PERMANENT ? WIDGET_APP_DESTROY_TYPE_PERMANENT :
163           WIDGET_APP_DESTROY_TYPE_TEMPORARY, contents.GetHandle(), user_data_);
164       aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
165     }
166
167     UnsetIconifyTimer();
168   }
169
170   void OnPause() override {
171     UnsetIconifyTimer();
172     SetIconifyTimer();
173
174     WidgetContext::OnPause();
175     if (callback_.pause) {
176       callback_.pause(reinterpret_cast<widget_context_h>(this), user_data_);
177     }
178   }
179
180   void OnResume() override {
181     UnsetIconifyTimer();
182
183     if (is_iconified_) {
184       Ecore_Wl2_Window* win = ecore_evas_wayland2_window_get(
185           ecore_evas_ecore_evas_get(evas_object_evas_get(win_)));
186       if (win) {
187         ecore_wl2_window_iconified_set(win, EINA_FALSE);
188         is_iconified_ = false;
189         _D("Set iconify false");
190       }
191     }
192
193     WidgetContext::OnResume();
194     if (callback_.resume) {
195       callback_.resume(reinterpret_cast<widget_context_h>(this), user_data_);
196     }
197   }
198
199   void OnResize(int w, int h) override {
200     WidgetContext::OnResize(w, h);
201
202     if (win_)
203       evas_object_resize(win_, w, h);
204     else
205       _E("Failed to find window");
206
207     if (callback_.resize) {
208       callback_.resize(reinterpret_cast<widget_context_h>(this),
209           w, h, user_data_);
210     }
211   }
212
213   void OnUpdate(const tizen_base::Bundle& contents, bool force) override {
214     WidgetContext::OnUpdate(contents, force);
215     if (callback_.update) {
216       callback_.update(reinterpret_cast<widget_context_h>(this),
217           contents.GetHandle(), force, user_data_);
218     }
219   }
220
221   void SetTag(void* tag) {
222     tag_ = tag;
223   }
224
225   void* GetTag() const {
226     return tag_;
227   }
228
229   Evas_Object* GetWindow() const {
230     return win_;
231   }
232
233   void SetWindow(Evas_Object* win) {
234     win_ = win;
235   }
236
237  private:
238   void SetIconifyTimer() {
239     if (iconify_timer_)
240       return;
241
242     iconify_timer_ = g_timeout_add(kIconifyTimeout,
243         [](gpointer user_data) -> gboolean{
244           AppWidgetContext* cxt = static_cast<AppWidgetContext*>(user_data);
245           Ecore_Wl2_Window* win = ecore_evas_wayland2_window_get(
246               ecore_evas_ecore_evas_get(evas_object_evas_get(cxt->win_)));
247           if (win) {
248             ecore_wl2_window_iconified_set(win, EINA_TRUE);
249             cxt->is_iconified_ = true;
250             _D("Set iconify true");
251           }
252
253           cxt->iconify_timer_ = 0;
254           return G_SOURCE_REMOVE;
255         }, this);
256   }
257
258   void UnsetIconifyTimer() {
259     if (iconify_timer_) {
260       g_source_remove(iconify_timer_);
261       iconify_timer_ = 0;
262     }
263   }
264
265  private:
266   widget_instance_lifecycle_callback_s callback_;
267   void* user_data_;
268   Evas_Object* win_ = nullptr;
269   guint iconify_timer_ = 0;
270   bool is_iconified_ = false;
271   void* tag_ = nullptr;
272 };
273
274 std::unique_ptr<AppWidget> __app_widget;
275 std::list<std::shared_ptr<AppEvent>> __pending_app_events;
276
277 }  // namespace
278
279 API int widget_app_main(int argc, char** argv,
280     widget_app_lifecycle_callback_s* callback, void* user_data) {
281   bool feature;
282   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
283   if (ret < 0)
284     return WIDGET_ERROR_FAULT;
285
286   if (!feature)
287     return WIDGET_ERROR_NOT_SUPPORTED;
288
289   if (argc <= 0 || argv == nullptr || callback == nullptr) {
290     _E("Invalid parameter");
291     return WIDGET_ERROR_INVALID_PARAMETER;
292   }
293
294   if (callback->create == nullptr) {
295     _E("widget_app_create_cb() callback must be registered");
296     return WIDGET_ERROR_INVALID_PARAMETER;
297   }
298
299   try {
300     __app_widget = std::make_unique<AppWidget>(callback, user_data);
301     for (auto& i : __pending_app_events)
302       __app_widget->AddEvent(i);
303
304     __app_widget->Run(argc, argv);
305   } catch (std::runtime_error& e) {
306     return WIDGET_ERROR_FAULT;
307   }
308
309   return WIDGET_ERROR_NONE;
310 }
311
312 API int widget_app_exit(void) {
313   bool feature;
314   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
315   if (ret < 0)
316     return WIDGET_ERROR_FAULT;
317
318   if (!feature)
319     return WIDGET_ERROR_NOT_SUPPORTED;
320
321   if (__app_widget.get() == nullptr)
322     return WIDGET_ERROR_FAULT;
323
324   __app_widget->Exit();
325   return WIDGET_ERROR_NONE;
326 }
327
328 API int widget_app_terminate_context(widget_context_h context) {
329   bool feature;
330   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
331   if (ret < 0)
332     return WIDGET_ERROR_FAULT;
333
334   if (!feature)
335     return WIDGET_ERROR_NOT_SUPPORTED;
336
337   if (context == nullptr) {
338     _E("Invalid parameter");
339     return WIDGET_ERROR_INVALID_PARAMETER;
340   }
341
342   auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
343   cxt->ExitAsync();
344   return WIDGET_ERROR_NONE;
345 }
346
347 API int widget_app_foreach_context(widget_context_cb cb, void* data) {
348   bool feature;
349   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
350   if (ret < 0)
351     return WIDGET_ERROR_FAULT;
352
353   if (!feature)
354     return WIDGET_ERROR_NOT_SUPPORTED;
355
356   if (cb == nullptr) {
357     _E("Invalid parameter");
358     return WIDGET_ERROR_INVALID_PARAMETER;
359   }
360
361   if (__app_widget.get() == nullptr)
362     return WIDGET_ERROR_FAULT;
363
364   auto l = __app_widget->GetContexts();
365   for (auto& i : l) {
366     if (!cb(reinterpret_cast<widget_context_h>(i.get()), data))
367       break;
368   }
369
370   return WIDGET_ERROR_NONE;
371 }
372
373 API int widget_app_add_event_handler(app_event_handler_h* event_handler,
374     app_event_type_e event_type, app_event_cb callback, void* user_data) {
375   bool feature;
376   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
377   if (ret < 0)
378     return WIDGET_ERROR_FAULT;
379
380   if (!feature)
381     return WIDGET_ERROR_NOT_SUPPORTED;
382
383   if (event_handler == nullptr || callback == nullptr)
384     return WIDGET_ERROR_INVALID_PARAMETER;
385
386   if (event_type < APP_EVENT_LOW_MEMORY ||
387       event_type > APP_EVENT_REGION_FORMAT_CHANGED)
388     return WIDGET_ERROR_INVALID_PARAMETER;
389
390   if (event_type == APP_EVENT_DEVICE_ORIENTATION_CHANGED)
391     return WIDGET_ERROR_NOT_SUPPORTED;
392
393   auto* app_event = new (std::nothrow) AppEvent(
394       ::__app_event_converter[event_type], callback, user_data);
395   if (app_event == nullptr) {
396     _E("Out of memory");
397     return WIDGET_ERROR_OUT_OF_MEMORY;
398   }
399
400   auto* h = new (std::nothrow) std::shared_ptr<AppEvent>(app_event);
401   if (h == nullptr) {
402     _E("Out of memory");
403     delete app_event;
404     return WIDGET_ERROR_OUT_OF_MEMORY;
405   }
406
407   if (__app_widget.get() != nullptr)
408     __app_widget->AddEvent(*h);
409   else
410     __pending_app_events.push_back(*h);
411
412   *event_handler = reinterpret_cast<app_event_handler_h>(h);
413   return WIDGET_ERROR_NONE;
414 }
415
416 API int widget_app_remove_event_handler(app_event_handler_h event_handler) {
417   bool feature;
418   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
419   if (ret < 0)
420     return WIDGET_ERROR_FAULT;
421
422   if (!feature)
423     return WIDGET_ERROR_NOT_SUPPORTED;
424
425   if (event_handler == nullptr)
426     return WIDGET_ERROR_INVALID_PARAMETER;
427
428   auto* h = reinterpret_cast<std::shared_ptr<AppEvent>*>(event_handler);
429
430   if (__app_widget.get() != nullptr) {
431     if (!__app_widget->RemoveEvent(*h))
432       return WIDGET_ERROR_INVALID_PARAMETER;
433   } else {
434     __pending_app_events.remove(*h);
435   }
436
437   delete h;
438   return WIDGET_ERROR_NONE;
439 }
440
441 API const char* widget_app_get_id(widget_context_h context) {
442   bool feature;
443   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
444   if (ret < 0) {
445     set_last_result(WIDGET_ERROR_FAULT);
446     return nullptr;
447   }
448
449   if (!feature) {
450     set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
451     return nullptr;
452   }
453
454   if (context == nullptr) {
455     set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
456     return nullptr;
457   }
458
459   auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
460   const std::string& id = cxt->GetInstId();
461   set_last_result(WIDGET_ERROR_NONE);
462   return id.c_str();
463 }
464
465 API int widget_app_get_elm_win(widget_context_h context, Evas_Object** win) {
466   bool feature;
467   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
468   if (ret < 0)
469     return WIDGET_ERROR_FAULT;
470
471   if (!feature)
472     return WIDGET_ERROR_NOT_SUPPORTED;
473
474   if (context == nullptr || win == nullptr) {
475     _E("Invalid parameter");
476     return WIDGET_ERROR_INVALID_PARAMETER;
477   }
478
479   auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
480   const std::string& id = cxt->GetInstId();
481
482   Evas_Object* ret_win = elm_win_add(nullptr, id.c_str(), ELM_WIN_BASIC);
483   if (ret_win == nullptr) {
484     _E("Failed to create window");
485     return WIDGET_ERROR_FAULT;
486   }
487
488   elm_win_wm_rotation_preferred_rotation_set(ret_win, -1);
489   int rots[3] = { 0, };
490   elm_win_wm_rotation_available_rotations_set(ret_win, rots, 1);
491
492   Ecore_Wl2_Window* wl_win = ecore_evas_wayland2_window_get(
493       ecore_evas_ecore_evas_get(evas_object_evas_get(ret_win)));
494   if (wl_win == nullptr) {
495     _E("Failed to get wayland window");
496     evas_object_del(ret_win);
497     return WIDGET_ERROR_FAULT;
498   }
499
500   ecore_wl2_window_class_set(wl_win, id.c_str());
501   elm_win_aux_hint_add(ret_win, "wm.policy.win.user.geometry", "1");
502   cxt->WindowBind(id, wl_win);
503
504   /* Set data to use in accessibility */
505   std::string plug_id = id + ":" + std::to_string(getpid());
506   evas_object_data_set(ret_win, "___PLUGID", strdup(plug_id.c_str()));
507   evas_object_event_callback_add(ret_win, EVAS_CALLBACK_DEL,
508       [](void *data, Evas *e, Evas_Object *obj, void *event_info) {
509         char* plug_id = static_cast<char*>(
510             evas_object_data_del(obj, "___PLUGID"));
511         free(plug_id);
512       }, nullptr);
513
514   int win_id = ecore_wl2_window_id_get(wl_win);
515   _D("Window created: %d", win_id);
516
517   cxt->SetWindow(ret_win);
518   *win = ret_win;
519   return WIDGET_ERROR_NONE;
520 }
521
522 API widget_class_h widget_app_class_add(widget_class_h widget_class,
523     const char* class_id, widget_instance_lifecycle_callback_s callback,
524     void* user_data) {
525   bool feature;
526   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
527   if (ret < 0) {
528     set_last_result(WIDGET_ERROR_FAULT);
529     return nullptr;
530   }
531
532   if (!feature) {
533     set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
534     return nullptr;
535   }
536
537   if (class_id == nullptr || callback.create == nullptr) {
538     _E("Invalid parameter");
539     set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
540     return nullptr;
541   }
542
543   if (__app_widget.get() == nullptr) {
544     set_last_result(WIDGET_ERROR_FAULT);
545     return nullptr;
546   }
547
548   auto factory = std::shared_ptr<AppCoreMultiWindowBase::Context::IFactory>(
549       new (std::nothrow) AppWidgetContext::Factory(
550           class_id, callback, user_data));
551   if (factory.get() == nullptr) {
552     set_last_result(WIDGET_ERROR_OUT_OF_MEMORY);
553     return nullptr;
554   }
555
556   __app_widget->AddContextFactory(std::move(factory), class_id);
557   set_last_result(WIDGET_ERROR_NONE);
558   static int dummy = 1;
559   widget_class_h cls = reinterpret_cast<widget_class_h>(&dummy);
560   return cls;
561 }
562
563 API widget_class_h widget_app_class_create(
564     widget_instance_lifecycle_callback_s callback, void* user_data) {
565   bool feature;
566   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
567   if (ret < 0) {
568     set_last_result(WIDGET_ERROR_FAULT);
569     return nullptr;
570   }
571
572   if (!feature) {
573     set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
574     return nullptr;
575   }
576
577   if (callback.create == nullptr) {
578     _E("Invalid parameter");
579     set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
580     return nullptr;
581   }
582
583   char* appid = nullptr;
584   app_get_id(&appid);
585   if (appid == nullptr) {
586     LOGE("app_get_id() is failed");
587     return nullptr;
588   }
589   std::unique_ptr<char, decltype(std::free)*> ptr(appid, std::free);
590
591   return static_cast<widget_class_h>(
592       widget_app_class_add(nullptr, appid, callback, user_data));
593 }
594
595 API int widget_app_context_set_tag(widget_context_h context, void* tag) {
596   bool feature;
597   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
598   if (ret < 0)
599     return WIDGET_ERROR_FAULT;
600
601   if (!feature)
602     return WIDGET_ERROR_NOT_SUPPORTED;
603
604   if (context == nullptr) {
605     _E("Invalid parameter");
606     return WIDGET_ERROR_INVALID_PARAMETER;
607   }
608
609   auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
610   cxt->SetTag(tag);
611   return WIDGET_ERROR_NONE;
612 }
613
614 API int widget_app_context_get_tag(widget_context_h context, void** tag) {
615   bool feature;
616   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
617   if (ret < 0)
618     return WIDGET_ERROR_FAULT;
619
620   if (!feature)
621     return WIDGET_ERROR_NOT_SUPPORTED;
622
623   if (context == nullptr || tag == nullptr) {
624     _E("Invalid parameter");
625     return WIDGET_ERROR_INVALID_PARAMETER;
626   }
627
628   auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
629   *tag = cxt->GetTag();
630   return WIDGET_ERROR_NONE;
631 }
632
633 API int widget_app_context_set_content_info(widget_context_h context,
634     bundle* content_info) {
635   bool feature;
636   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
637   if (ret < 0)
638     return WIDGET_ERROR_FAULT;
639
640   if (!feature)
641     return WIDGET_ERROR_NOT_SUPPORTED;
642
643   if (context == nullptr || content_info == nullptr) {
644     _E("Invalid parameter");
645     return WIDGET_ERROR_INVALID_PARAMETER;
646   }
647
648   auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
649   ret = cxt->SetContents(tizen_base::Bundle(content_info));
650   if (ret != WIDGET_ERROR_NONE) {
651     _E("Failed to set content");
652     return static_cast<widget_error_e>(ret);
653   }
654
655   return WIDGET_ERROR_NONE;
656 }
657
658 API int widget_app_context_set_title(widget_context_h context,
659     const char* title) {
660   bool feature;
661   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
662   if (ret < 0)
663     return WIDGET_ERROR_FAULT;
664
665   if (!feature)
666     return WIDGET_ERROR_NOT_SUPPORTED;
667
668   if (context == nullptr || title == nullptr) {
669     _E("Invalid parameter");
670     return WIDGET_ERROR_INVALID_PARAMETER;
671   }
672
673   auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
674   if (cxt->GetWindow())
675     elm_win_title_set(cxt->GetWindow(), title);
676
677   return WIDGET_ERROR_NONE;
678 }
679
680 API int widget_app_restart(void) {
681   bool feature;
682   int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
683   if (ret < 0)
684     return WIDGET_ERROR_FAULT;
685
686   if (!feature)
687     return WIDGET_ERROR_NOT_SUPPORTED;
688
689   if (__app_widget.get() == nullptr)
690     return WIDGET_ERROR_IO_ERROR;
691
692   std::string class_id;
693   auto l = __app_widget->GetContexts();
694   for (auto& i : l) {
695     class_id = i->GetContextId();
696     break;
697   }
698
699   if (class_id.empty())
700     return WIDGET_ERROR_IO_ERROR;
701
702   tizen_base::Bundle b;
703   int status = AUL_WIDGET_INSTANCE_EVENT_APP_RESTART_REQUEST;
704   std::vector<unsigned char> v;
705   auto* p = reinterpret_cast<const uint8_t*>(&status);
706   std::copy(p, p + sizeof(int), std::back_inserter(v));
707
708   b.Add(AUL_K_WIDGET_ID, class_id);
709   b.Add(AUL_K_WIDGET_STATUS, v);
710
711   std::string endpoint = __app_widget->GetViewerEndpoint();
712   ret = aul_app_com_send(endpoint.empty() ? nullptr : endpoint.c_str(),
713       b.GetHandle());
714   if (ret != AUL_R_OK) {
715     _E("Failed to send restart request");
716     return WIDGET_ERROR_IO_ERROR;
717   }
718
719   return WIDGET_ERROR_NONE;
720 }