4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
23 #include <appcore-efl.h>
24 #include <ui-gadget.h>
30 #include <dbus/dbus.h>
31 #include <dbus/dbus-glib-lowlevel.h>
33 #include "ug-client.h"
35 #include <tzplatform_config.h>
41 #define PATH_UG_LAUNCHER tzplatform_mkpath(TZ_SYS_BIN,"ug-launcher")
43 #define LOG_TAG "UI_GADGET_CLIENT"
45 static int home_screen_pid = 0;
46 static DBusConnection *bus;
47 static int ug_dbus_signal_handler_initialized = 0;
48 static bool is_app_pause = false;
50 static void prt_usage(const char *cmd)
52 fprintf(stderr, "Usage: %s [-f] [-F] -n <UG NAME> [-d <Arguments>]\n",
54 fprintf(stderr, " Options:\n");
55 fprintf(stderr, " -d argument\n");
56 fprintf(stderr, " -F Fullview mode (Default)\n");
57 fprintf(stderr, " -f Frameview mode\n");
58 fprintf(stderr, " Example:\n");
60 " %s -F -n helloUG-efl -d \"name,John Doe\" -d \"age,30\"\n",
65 static void win_del(void *data, Evas_Object *obj, void *event)
70 static void main_quit_cb(void *data, Evas_Object *obj,
71 const char *emission, const char *source)
76 static int ug_send_rotate_event(int angle)
79 LOGD("ug_send_rotate_event angle : %d", angle);
82 ret = ug_send_event(UG_EVENT_ROTATE_PORTRAIT);
85 ret = ug_send_event(UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN);
88 ret = ug_send_event(UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN);
91 ret = ug_send_event(UG_EVENT_ROTATE_LANDSCAPE);
94 LOGW("wrong angle(%d) for send rotate event",angle);
101 static void rotate(void *data, Evas_Object *obj, void *event)
103 int changed_angle = 0;
104 struct appdata *ad = data;
106 changed_angle = elm_win_rotation_get((const Evas_Object *)obj);
107 if(changed_angle == -1) {
108 LOGE("elm_win_rotation_get error");
112 LOGD("rotate call back : changed angle(%d) / current angle(%d)",
113 changed_angle, ad->rotate);
115 if(ad->rotate != changed_angle) {
116 ug_send_rotate_event(changed_angle);
119 ad->rotate = changed_angle;
124 void _ug_client_layout_cb(ui_gadget_h ug, enum ug_mode mode, void *priv)
134 base = ug_get_layout(ug);
136 LOGE("base layout is null");
141 case UG_MODE_FULLVIEW:
142 evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
144 ug_disable_effect(ug);
145 elm_object_content_set(ad->ly_main, base);
146 evas_object_show(base);
148 case UG_MODE_FRAMEVIEW:
149 elm_object_part_content_set(ad->ly_main, "content", base);
156 void _ug_client_result_cb(ui_gadget_h ug, service_h reply, void *priv)
158 struct appdata *ad = NULL;
166 ret = service_get_extra_data (reply, UG_SERVICE_DATA_RESULT, &value);
167 if((ret == SERVICE_ERROR_NONE) && (value)) {
168 result = atoi(value);
169 LOGD("reply result is %d", result);
171 LOGW("get reply result error(%d) . result will be SERVICE_RESULT_SUCCEEDED", ret);
172 result = SERVICE_RESULT_SUCCEEDED;
177 LOGE("appdata is null");
181 ret = service_reply_to_launch_request(reply, ad->request, (service_result_e)result);
182 if (ret != SERVICE_ERROR_NONE)
183 LOGE("service_reply_to_launch_request failed, %d", ret);
186 void _ug_client_destroy_cb(ui_gadget_h ug, void *priv)
188 struct appdata *ad = NULL;
195 LOGE("appdata is null. win lower is fail");
197 LOGD("window lower");
198 elm_win_lower(ad->win);
204 void _ug_client_end_cb(ui_gadget_h ug, void *priv)
209 LOGD("_ug_client_end_cb invoked");
214 static void profile_changed_cb(void *data, Evas_Object * obj, void *event)
216 const char *profile = elm_config_profile_get();
218 LOGE("!!! profile_changed_cb(%s) !!!", profile);
220 if (strcmp(profile, "desktop") == 0)
221 elm_win_indicator_mode_set(obj, ELM_WIN_INDICATOR_HIDE);
224 static Evas_Object *create_win(const char *name)
230 eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
232 elm_win_title_set(eo, name);
233 elm_win_conformant_set(eo, EINA_TRUE);
234 evas_object_smart_callback_add(eo, "delete,request",
236 /* disable destktop mode
237 evas_object_smart_callback_add(eo, "profile,changed", profile_changed_cb, NULL); */
238 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(eo));
239 evas_output_size_get(ee, &w, &h);
240 evas_object_resize(eo, w, h);
242 elm_win_indicator_mode_set(eo,ELM_WIN_INDICATOR_SHOW);
248 static Evas_Object *_ug_client_load_edj(Evas_Object *parent, const char *file,
253 eo = elm_layout_add(parent);
255 r = elm_layout_file_set(eo, file, group);
260 evas_object_size_hint_weight_set(eo,
267 static int low_memory(void *data)
269 return ug_send_event(UG_EVENT_LOW_MEMORY);
272 static int low_battery(void *data)
274 return ug_send_event(UG_EVENT_LOW_BATTERY);
277 static int lang_changed(void *data)
281 lang = vconf_get_str(VCONFKEY_LANGSET);
283 LOGD("lang : %s", lang);
284 elm_language_set((const char*)lang);
287 LOGW("language get error");
290 return ug_send_event(UG_EVENT_LANG_CHANGE);
293 static int region_changed(void *data)
295 return ug_send_event(UG_EVENT_REGION_CHANGE);
298 static int app_create(void *data)
300 struct appdata *ad = data;
303 Evas_Object *conform;
307 win = create_win(PACKAGE);
312 UG_INIT_EFL(ad->win, UG_OPT_INDICATOR_ENABLE);
314 bg = elm_bg_add(win);
315 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
316 elm_win_resize_object_add(win, bg);
317 evas_object_show(bg);
319 conform = elm_conformant_add(win);
320 evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
321 ad->conform = conform;
324 ly = _ug_client_load_edj(conform, EDJ_FILE, GRP_MAIN);
327 elm_win_resize_object_add(win, conform);
329 evas_object_show(conform);
330 elm_object_content_set(conform, ly);
331 edje_object_signal_callback_add(elm_layout_edje_get(ly),
332 "EXIT", "*", main_quit_cb, NULL);
338 angle = elm_win_rotation_get((const Evas_Object *)win);
339 LOGE("rotate : %d", angle);
341 ug_send_rotate_event(angle);
344 LOGE("elm win rotation get error");
347 if(elm_win_wm_rotation_supported_get(win)) {
348 int rots[4] = { 0, 90, 180, 270 };
349 elm_win_wm_rotation_available_rotations_set(win, (const int*)&rots, 4);
351 LOGW("wm rotation supported get error");
354 evas_object_smart_callback_add(win, "wm,rotation,changed", rotate, data);
356 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, low_memory, ad);
357 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, low_battery, ad);
358 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, lang_changed, ad);
359 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, region_changed, ad);
364 static void _ug_client_home_screen_top_cb(void *data)
366 struct appdata *ad = data;
368 if((!ad->is_transient) && (home_screen_pid)) {
369 LOGW("home key pressed. window is not transient. ug client will be terminated");
375 static DBusHandlerResult
376 _ug_client_dbus_signal_filter(DBusConnection *conn, DBusMessage *message,
380 const char *interface;
381 int home_pid_by_dbus;
385 dbus_error_init(&error);
387 sender = dbus_message_get_sender(message);
389 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
391 if (dbus_bus_get_unix_user(conn, sender, &error) != 0) {
392 LOGW("reject by security issue - no allowed sender\n");
393 dbus_error_free(&error);
394 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
397 interface = dbus_message_get_interface(message);
398 if (interface == NULL) {
399 LOGW("reject by security issue - no interface\n");
400 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
403 if (dbus_message_is_signal(
404 message, interface, "home_launch")) {
406 LOGD("interface signal is home_launch");
408 if (dbus_message_get_args(message, &error, DBUS_TYPE_UINT32,
409 &home_pid_by_dbus, DBUS_TYPE_INVALID) == FALSE) {
410 LOGW("Failed to get data: %s", error.message);
411 dbus_error_free(&error);
412 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
415 LOGD("pid : %d", home_pid_by_dbus);
417 home_screen_pid = home_pid_by_dbus;
420 LOGD("home_launch signal under app_pause.\
421 if home screen is top, app will be terminated");
422 _ug_client_home_screen_top_cb(user_data);
426 return DBUS_HANDLER_RESULT_HANDLED;
429 static int _ug_client_dbus_listen_signal(void *data)
434 if (ug_dbus_signal_handler_initialized)
437 dbus_threads_init_default();
439 dbus_error_init(&error);
440 bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
442 LOGW("Failed to connect to the D-BUS daemon: %s", error.message);
443 dbus_error_free(&error);
446 dbus_connection_setup_with_g_main(bus, NULL);
449 "path='%s',type='signal',interface='%s'", "/aul/dbus_handler",
450 "org.tizen.aul.signal");
451 /* listening to messages */
452 dbus_bus_add_match(bus, rule, &error);
453 if (dbus_error_is_set(&error)) {
454 LOGW("Fail to rule set: %s", error.message);
455 dbus_error_free(&error);
459 if (dbus_connection_add_filter(bus,
460 _ug_client_dbus_signal_filter, data, NULL) == FALSE) {
461 LOGW("dbus conntaction add fileter fail");
465 LOGD("bus : %p / filter func pointer : %p", bus , _ug_client_dbus_signal_filter);
467 ug_dbus_signal_handler_initialized = 1;
472 static void _ug_client_dbus_signal_handler_fini(void *data)
477 if (!ug_dbus_signal_handler_initialized)
480 if(!dbus_connection_get_is_connected(bus)) {
481 LOGD("dbus connection(%p) is not connected", bus);
485 dbus_connection_remove_filter(bus, _ug_client_dbus_signal_filter, data);
487 dbus_error_init(&error);
490 "path='%s',type='signal',interface='%s'", "/aul/dbus_handler",
491 "org.tizen.aul.signal");
492 dbus_bus_remove_match(bus, rule, &error);
493 if (dbus_error_is_set(&error)) {
494 LOGE("Fail to rule unset: %s", error.message);
495 dbus_error_free(&error);
499 dbus_connection_close(bus);
501 LOGD("ug dbus signal finialized");
504 ug_dbus_signal_handler_initialized = 0;
510 static int app_terminate(void *data)
512 struct appdata *ad = data;
514 LOGD("app_terminate called");
516 _ug_client_dbus_signal_handler_fini(data);
518 evas_object_smart_callback_del(ad->win, "wm,rotation,changed", rotate);
523 evas_object_del(ad->ly_main);
528 evas_object_del(ad->win);
532 service_destroy(ad->request);
538 LOGD("app_terminate end");
543 static int app_pause(void *data)
545 struct appdata *ad = data;
547 LOGD("app_pause called");
551 #if ENABLE_TRANSIENT_SUB_MODE
552 if (!ad->is_transient) {
553 LOGD("app_pause received. close ug service");
562 static int app_resume(void *data)
569 static int svc_cb(void *data)
571 LOGD("svc_cb called");
575 static int app_reset(bundle *b, void *data)
577 struct appdata *ad = data;
578 struct ug_cbs cbs = { 0, };
580 enum ug_mode mode = UG_MODE_FULLVIEW;
582 Ecore_X_Window id2 = elm_win_xwindow_get(ad->win);
584 ret = appsvc_request_transient_app(b, id2, svc_cb, "svc test");
587 LOGD("fail to request transient app: return value(%d)", ret);
588 if(_ug_client_dbus_listen_signal(data) < 0) {
589 LOGW("home screen dbus register error");
592 /* check home screen raise */
593 ad->is_transient = 1;
597 elm_win_activate(ad->win);
598 evas_object_show(ad->win);
601 if (ad->data) /* ug-launcher */
602 service_create_event(ad->data, &service);
604 service_create_event(b, &service);
607 service_clone(&ad->request, service);
608 service_destroy(service);
611 cbs.layout_cb = _ug_client_layout_cb;
612 cbs.destroy_cb = _ug_client_destroy_cb;
613 cbs.result_cb = _ug_client_result_cb;
614 cbs.end_cb = _ug_client_end_cb;
617 mode = ad->is_frameview ? UG_MODE_FRAMEVIEW : UG_MODE_FULLVIEW;
619 ad->ug = ug_create(NULL, ad->name, mode, ad->request, &cbs);
620 if (ad->ug == NULL) {
621 LOGE("ug_create fail: %s", ad->name);
628 static int update_argument(const char *optarg, struct appdata *ad)
632 key = strtok((char *)optarg, ",");
636 val = optarg + strlen(key) + 1;
639 ad->data = bundle_create();
642 bundle_add(ad->data, key, val);
646 int main(int argc, char *argv[])
650 struct appcore_ops ops = {
651 .create = app_create,
652 .terminate = app_terminate,
654 .resume = app_resume,
659 memset(&ad, 0x0, sizeof(struct appdata));
662 cmdlen = strlen(argv[0]);
663 if (strncmp(argv[0], "ug-launcher", cmdlen) == 0
664 || strncmp(argv[0], PATH_UG_LAUNCHER , cmdlen) == 0) {
665 while ((opt = getopt(argc, argv, "n:d:")) != -1) {
669 ad.name = strdup(optarg);
678 if (update_argument(optarg, &ad)) {
680 bundle_free(ad.data);
695 argc = 1; // remove appsvc bundle
696 } else { /* ug-client */
698 name = strrchr(argv[0], '/');
702 ad.name = strdup(&name[1]);
704 return appcore_efl_main(PACKAGE, &argc, &argv, &ops);