2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Flora License, Version 1.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
8 * http://floralicense.org/license/
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.
20 * Created on: Jan 8, 2014
21 * Author: Sunyeop Hwang
23 #include <unicode/ustring.h>
24 #include <unicode/ucol.h>
25 #include <package-manager.h>
26 #include <pkgmgr-info.h>
28 #include "setting-double.h"
29 #include "setting_data_vconf.h"
32 static Evas_Object *g_double_genlist = NULL;
33 static Evas_Object *g_double_app_genlist = NULL;
34 static Eina_List *app_list = NULL;
35 static int list_index = 1;
36 struct _double_menu_item *pitem_none = NULL;
37 struct _double_menu_item *pitem_recent = NULL;
38 /*pkgmgr_client *pc = NULL; */
39 /*pkgmgr_client *pc2 = NULL; */
40 static UCollator *coll = NULL;
42 static struct _double_menu_item *_get_selected_app()
44 struct _double_menu_item *pitem = NULL;
48 appid = vconf_get_str(VCONFKEY_WMS_POWERKEY_DOUBLE_PRESSING);
50 if (appid && strlen(appid)) {
51 if (!strcmp(appid, "none")) {
53 } else if (!strcmp(appid, "recent")) {
56 Eina_List *list = NULL;
57 EINA_LIST_FOREACH(app_list, list, pitem) {
58 if (pitem->pkgid && pitem->appid) {
59 char buf[1024] = {0, };
60 snprintf(buf, sizeof(buf) - 1, "%s/%s", pitem->pkgid, pitem->appid);
61 if (!strcmp(appid, buf)) {
62 DBG("pkgid/appid for double power key is %s/%s", pitem->pkgid, pitem->appid);
73 static int _sort_app_list_cb(const void *d1, const void *d2)
75 UChar app1[128] = { 0, };
76 UChar app2[128] = { 0, };
78 struct _double_menu_item *r1 = (struct _double_menu_item *) d1;
79 struct _double_menu_item *r2 = (struct _double_menu_item *) d2;
81 u_uastrcpy(app1, r1->name);
82 u_uastrcpy(app2, r2->name);
84 /*DBG("before ucol_open"); */
85 /*UErrorCode status = U_ZERO_ERROR; */
86 /*UCollator *coll = ucol_open(getenv("LANG"), &status); */
87 UCollationResult ret = ucol_strcoll(coll, app1, -1, app2, -1);
89 /*ucol_close(coll); */
103 static int _app_list_cb(pkgmgrinfo_appinfo_h handle, void *user_data)
105 appdata *ad = user_data;
107 ERR("appdata is null");
115 pkgmgrinfo_appinfo_h tmp_handle;
117 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
119 if (ret < 0 || !appid) {
120 ERR("pkgmgrinfo_appinfo_get_appid error");
124 ret = pkgmgrinfo_appinfo_get_appinfo(appid, &tmp_handle);
125 if (ret != PMINFO_R_OK) {
126 ERR("pkgmgrinfo_appinfo_get_appinfo error");
129 ret = pkgmgrinfo_appinfo_get_pkgid(tmp_handle, &pkgid);
130 if (ret != PMINFO_R_OK) {
131 ERR("pkgmgrinfo_appinfo_get_pkgid error");
132 pkgmgrinfo_appinfo_destroy_appinfo(tmp_handle);
135 ret = pkgmgrinfo_appinfo_get_label(tmp_handle, &name);
136 if (ret != PMINFO_R_OK) {
137 ERR("pkgmgrinfo_appinfo_get_label error");
138 pkgmgrinfo_appinfo_destroy_appinfo(tmp_handle);
142 if (strcmp(name, "Call")) {
143 struct _double_menu_item *pitem = NULL;
144 pitem = (struct _double_menu_item *)calloc(1, sizeof(struct _double_menu_item));
146 memset(pitem, 0x0, sizeof(struct _double_menu_item));
148 pitem->index = ++list_index;
149 pitem->appid = strdup(appid);
150 pitem->pkgid = strdup(pkgid);
151 pitem->name = strdup(name);
153 app_list = eina_list_sorted_insert(app_list, _sort_app_list_cb, pitem);
158 pkgmgrinfo_appinfo_destroy_appinfo(tmp_handle);
162 static void _clear_app_list()
164 struct _double_menu_item *pitem = NULL;
165 Eina_List *list = NULL;
167 EINA_LIST_FOREACH(app_list, list, pitem) {
171 app_list = eina_list_free(app_list);
175 static void _make_app_list(void *data)
179 ERR("appdata is null");
187 pkgmgrinfo_appinfo_filter_h handle = NULL;
189 if (pkgmgrinfo_appinfo_filter_create(&handle) != PMINFO_R_OK) {
190 ERR("pkgmgrinfo_appinfo_filter_create error");
194 if (pkgmgrinfo_appinfo_filter_add_bool(handle, PMINFO_APPINFO_PROP_APP_NODISPLAY, 0)
196 ERR("pkgmgrinfo_appinfo_filter_add_bool error");
197 pkgmgrinfo_appinfo_filter_destroy(handle);
201 if (pkgmgrinfo_appinfo_filter_foreach_appinfo(handle, _app_list_cb, ad)
203 ERR("pkgmgrinfo_appinfo_filter_foreach_appinfo error");
204 pkgmgrinfo_appinfo_filter_destroy(handle);
208 pkgmgrinfo_appinfo_filter_destroy(handle);
210 /*app_list = eina_list_sort(app_list, eina_list_count(app_list), _sort_app_list_cb); */
213 static void _gl_double_del(void *data, Evas_Object *obj)
215 Double_Item_Data *id = data;
220 static char *_gl_double_title_get(void *data, Evas_Object *obj, const char *part)
222 char buf[1024] = {0, };
224 if (!strcmp(part, "elm.text.1") || !strcmp(part, "elm.text")) {
225 snprintf(buf, sizeof(buf) - 1, "%s", _("IDS_ST_MBODY_DOUBLE_PRESS_ABB"));
226 DBG("elm.text.1 : %s", buf);
227 } else if (!strcmp(part, "elm.text.2")) {
228 struct _double_menu_item *selected_app = _get_selected_app();
230 snprintf(buf, sizeof(buf) - 1, "%s", _(selected_app->name));
231 DBG("elm.text.2 : %s", buf);
238 static char *_gl_double_app_title_get(void *data, Evas_Object *obj, const char *part)
240 Double_Item_Data *id = data;
242 if (!strcmp(part, "elm.text")) {
243 return strdup(_(id->pitem->name));
249 static Evas_Object *_gl_double_app_radio_get(void *data, Evas_Object *obj, const char *part)
251 Evas_Object *radio = NULL;
252 Evas_Object *radio_main = evas_object_data_get(obj, "radio_main");
253 Double_Item_Data *id = data;
255 if (!strcmp(part, "elm.icon")) {
256 radio = elm_radio_add(obj);
257 elm_object_style_set(radio, "list");
258 elm_radio_state_value_set(radio, id->pitem->index);
259 evas_object_size_hint_align_set(radio, EVAS_HINT_FILL, EVAS_HINT_FILL);
260 evas_object_size_hint_weight_set(radio, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
261 evas_object_propagate_events_set(radio, EINA_FALSE);
262 evas_object_repeat_events_set(radio, EINA_TRUE);
263 elm_radio_group_add(radio, radio_main);
269 static void _gl_double_app_sel_cb(void *data, Evas_Object *obj, void *event_info)
271 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
272 elm_genlist_item_selected_set(item, EINA_FALSE);
273 Double_Item_Data *id = (Double_Item_Data *)elm_object_item_data_get(item);
278 ERR("appdata or id is null!!");
282 if (id->pitem && id->pitem->index == 0) {
283 char buf[1024] = {0, };
284 snprintf(buf, sizeof(buf) - 1, "none");
285 vconf_set_str(VCONFKEY_WMS_POWERKEY_DOUBLE_PRESSING, buf);
286 } else if (id->pitem && id->pitem->index == 1) {
287 char buf[1024] = {0, };
288 snprintf(buf, sizeof(buf) - 1, "recent");
289 vconf_set_str(VCONFKEY_WMS_POWERKEY_DOUBLE_PRESSING, buf);
290 } else if (id->pitem && id->pitem->appid && strlen(id->pitem->appid)) {
291 char buf[1024] = {0, };
292 DBG("%s/%s is selected", id->pitem->pkgid, id->pitem->appid);
293 snprintf(buf, sizeof(buf) - 1, "%s/%s", id->pitem->pkgid, id->pitem->appid);
294 vconf_set_str(VCONFKEY_WMS_POWERKEY_DOUBLE_PRESSING, buf);
297 elm_naviframe_item_pop(ad->nf);
299 if (!ad->double_rdg) {
300 evas_object_del(ad->double_rdg);
301 ad->double_rdg = NULL;
305 static void change_double_pressing_cb(keynode_t *key, void *data)
310 ERR("appdata is null!!");
313 if (g_double_app_genlist) {
314 struct _double_menu_item *selected_app = NULL;
315 selected_app = _get_selected_app();
317 elm_radio_value_set(ad->double_rdg, selected_app->index);
319 elm_radio_value_set(ad->double_rdg, -1);
322 Elm_Object_Item *item = NULL;
323 item = elm_genlist_first_item_get(g_double_app_genlist);
326 Double_Item_Data *id = (Double_Item_Data *)elm_object_item_data_get(item);
327 if (id->pitem == selected_app) {
328 elm_genlist_item_show(item, ELM_GENLIST_ITEM_SCROLLTO_TOP);
331 item = elm_genlist_item_next_get(item);
335 if (g_double_genlist) {
336 elm_genlist_realized_items_update(g_double_genlist);
340 static void update_double_app_list(void *data)
345 ERR("appdata is null!!");
351 if (g_double_genlist) {
352 elm_genlist_realized_items_update(g_double_genlist);
355 if (g_double_app_genlist) {
356 struct _double_menu_item *selected_app = NULL;
357 struct _double_menu_item *pitem = NULL;
358 Eina_List *list = NULL;
359 Elm_Object_Item *sel_it = NULL;
361 elm_genlist_clear(g_double_app_genlist);
363 Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
364 itc->item_style = "1text.1icon.1";
365 itc->func.text_get = _gl_double_app_title_get;
366 itc->func.content_get = _gl_double_app_radio_get;
367 itc->func.del = _gl_double_del;
369 selected_app = _get_selected_app();
371 Double_Item_Data *id_none = calloc(sizeof(Double_Item_Data), 1);
373 id_none->pitem = pitem_none;
374 id_none->item = elm_genlist_item_append(g_double_app_genlist, itc, id_none, NULL,
375 ELM_GENLIST_ITEM_NONE,
376 _gl_double_app_sel_cb, ad);
378 if (id_none->pitem == selected_app) {
379 sel_it = id_none->item;
383 Double_Item_Data *id_recent = calloc(sizeof(Double_Item_Data), 1);
385 id_recent->pitem = pitem_recent;
386 id_recent->item = elm_genlist_item_append(g_double_app_genlist, itc, id_recent, NULL,
387 ELM_GENLIST_ITEM_NONE,
388 _gl_double_app_sel_cb, ad);
390 if (id_recent->pitem == selected_app) {
391 sel_it = id_recent->item;
395 EINA_LIST_FOREACH(app_list, list, pitem) {
396 Double_Item_Data *id = calloc(sizeof(Double_Item_Data), 1);
399 id->item = elm_genlist_item_append(g_double_app_genlist, itc, id, NULL,
400 ELM_GENLIST_ITEM_NONE,
401 _gl_double_app_sel_cb, ad);
403 if (id->pitem == selected_app) {
410 elm_radio_value_set(ad->double_rdg, selected_app->index);
412 elm_radio_value_set(ad->double_rdg, -1);
415 elm_genlist_item_show(sel_it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
417 elm_genlist_item_class_free(itc);
422 static void change_language_cb(keynode_t *key, void *data)
427 ERR("appdata is null!!");
431 UErrorCode status = U_ZERO_ERROR;
436 const char *lang = vconf_get_str(VCONFKEY_LANGSET);
437 coll = ucol_open(lang, &status);
439 update_double_app_list(ad);
442 static int _double_press_check_appinfo(void *data, char *appid)
447 ERR("appdata is null!!");
451 pkgmgrinfo_appinfo_h tmp_handle;
454 DBG("appid:%s", appid);
455 r = pkgmgrinfo_appinfo_get_appinfo(appid, &tmp_handle);
456 if (r != PMINFO_R_OK) {
457 ERR("pkgmgrinfo_appinfo_get_appinfo error : %d", r);
461 r = pkgmgrinfo_appinfo_is_nodisplay(tmp_handle, &nodisplay);
462 if (r != PMINFO_R_OK) {
463 ERR("pkgmgrinfo_appinfo_is_nodisplay error");
468 update_double_app_list(ad);
474 static void change_app_state_cb(keynode_t *key, void *data)
479 ERR("appdata is null!!");
483 char appid[256] = {0, };
484 char type[7] = {0, };
488 value = vconf_get_str(VCONFKEY_AIL_INFO_STATE);
490 if (value && (strlen(value + 7) < 256)) {
491 strcpy(appid, value + 7);
492 strncpy(type, value, 6);
493 DBG("type :%s, appid :%s", type, appid);
495 if (!strncmp(type, "delete", 6)) {
496 update_double_app_list(ad);
497 } else if (!strncmp(type, "create", 6) || !strncmp(type, "update", 6)) {
498 _double_press_check_appinfo(ad, appid);
500 DBG("appid :%s", appid);
504 void clear_double_app_cb(void *data , Evas *e, Evas_Object *obj, void *event_info)
513 pkgmgr_client_free(pc);
517 pkgmgr_client_free(pc2);
524 g_double_app_genlist = NULL;
525 unregister_vconf_changing(VCONFKEY_WMS_POWERKEY_DOUBLE_PRESSING, change_double_pressing_cb);
526 unregister_vconf_changing(VCONFKEY_LANGSET, change_language_cb);
527 unregister_vconf_changing(VCONFKEY_AIL_INFO_STATE, change_app_state_cb);
530 Evas_Object *create_double_app_list(void *data)
535 ERR("appdata is null!!");
539 Evas_Object *layout = NULL;
540 Evas_Object *genlist = NULL;
541 Elm_Object_Item *nf_it = NULL;
542 Elm_Object_Item *sel_it = NULL;
544 struct _double_menu_item *selected_app = NULL;
545 struct _double_menu_item *pitem = NULL;
546 Eina_List *list = NULL;
548 Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
549 itc->item_style = "1text.1icon.1";
550 itc->func.text_get = _gl_double_app_title_get;
551 itc->func.content_get = _gl_double_app_radio_get;
552 itc->func.del = _gl_double_del;
554 layout = elm_layout_add(ad->nf);
555 elm_layout_file_set(layout, EDJE_PATH, "setting/genlist/layout");
556 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
558 genlist = elm_genlist_add(layout);
559 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
561 selected_app = _get_selected_app();
563 Double_Item_Data *id_none = calloc(sizeof(Double_Item_Data), 1);
565 id_none->pitem = pitem_none;
566 id_none->item = elm_genlist_item_append(genlist, itc, id_none, NULL,
567 ELM_GENLIST_ITEM_NONE,
568 _gl_double_app_sel_cb, ad);
570 if (id_none->pitem == selected_app) {
571 sel_it = id_none->item;
575 Double_Item_Data *id_recent = calloc(sizeof(Double_Item_Data), 1);
577 id_recent->pitem = pitem_recent;
578 id_recent->item = elm_genlist_item_append(genlist, itc, id_recent, NULL,
579 ELM_GENLIST_ITEM_NONE,
580 _gl_double_app_sel_cb, ad);
582 if (id_recent->pitem == selected_app) {
583 sel_it = id_recent->item;
587 EINA_LIST_FOREACH(app_list, list, pitem) {
588 Double_Item_Data *id = calloc(sizeof(Double_Item_Data), 1);
591 id->item = elm_genlist_item_append(genlist, itc, id, NULL,
592 ELM_GENLIST_ITEM_NONE,
593 _gl_double_app_sel_cb, ad);
595 if (id->pitem == selected_app) {
601 ad->double_rdg = elm_radio_add(genlist);
602 elm_radio_state_value_set(ad->double_rdg, -1);
605 elm_radio_value_set(ad->double_rdg, selected_app->index);
607 elm_radio_value_set(ad->double_rdg, -1);
609 evas_object_data_set(genlist, "radio_main", ad->double_rdg);
611 elm_genlist_item_show(sel_it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
613 g_double_app_genlist = genlist;
615 elm_object_part_content_set(layout, "elm.genlist", genlist);
617 elm_genlist_item_class_free(itc);
622 static int _double_press_appinfo_cb(pkgmgrinfo_appinfo_h handle, void *data)
627 ERR("appdata is null!!");
632 pkgmgrinfo_appinfo_h tmp_handle;
635 r = pkgmgrinfo_appinfo_get_appid(handle, &appid);
636 if (r < 0 || !appid) {
637 ERR("pkgmgrinfo_appinfo_get_appid error");
640 r = pkgmgrinfo_appinfo_get_appinfo(appid, &tmp_handle);
641 if (r != PMINFO_R_OK) {
642 ERR("pkgmgrinfo_appinfo_get_appinfo error");
646 r = pkgmgrinfo_appinfo_is_nodisplay(tmp_handle, &nodisplay);
647 if (r != PMINFO_R_OK) {
648 ERR("pkgmgrinfo_appinfo_is_nodisplay error");
654 update_double_app_list(ad);
660 static int _double_press_app_event_cb(int req_id, const char *pkg_type, const char *pkgid,
661 const char key, const char *val, const void *pmsg, void *data)
666 ERR("appdata is null!!");
670 if (!pkgid || !key || !val) {
671 ERR("pkgid or key or val is null");
676 if (!strncmp(key, "end", 3) && !strncmp(val, "ok", 2)) {
677 DBG("end install/update for some pkgid");
679 pkgmgrinfo_pkginfo_h handle;
681 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
682 if (ret != PMINFO_R_OK)
684 ret = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, _double_press_appinfo_cb , data);
685 if (ret != PMINFO_R_OK) {
686 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
689 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
695 static int _double_press_app_uninstall_event_cb(int req_id, const char *pkg_type, const char *pkgid,
696 const char key, const char *val, const void *pmsg, void *data)
701 ERR("appdata is null!!");
705 if (!pkgid || !key || !val) {
706 ERR("pkgid or key or val is null");
711 if (!strncmp(key, "end", 3) && !strncmp(val, "ok", 2)) {
712 DBG("end uninstall for some pkgid");
713 update_double_app_list(ad);
718 void init_double_pressing(void *data)
723 ERR("appdata is null!!");
728 pitem_none = calloc(sizeof(struct _double_menu_item), 1);
731 pitem_none->index = 0;
732 pitem_none->appid = strdup("none");
733 pitem_none->pkgid = strdup("none");
734 pitem_none->name = strdup("IDS_LCKSCN_BODY_NONE");
738 pitem_recent = calloc(sizeof(struct _double_menu_item), 1);
741 pitem_recent->index = 1;
742 pitem_recent->appid = strdup("recent");
743 pitem_recent->pkgid = strdup("recent");
744 pitem_recent->name = strdup("IDS_ST_OPT_RECENT_APPS_ABB");
747 UErrorCode status = U_ZERO_ERROR;
752 const char *lang = vconf_get_str(VCONFKEY_LANGSET);
753 coll = ucol_open(lang, &status);
755 int event_type = PMINFO_CLIENT_STATUS_INSTALL | PMINFO_CLIENT_STATUS_UPGRADE;
759 pkgmgr_client_free(pc);
764 ad->pc = pkgmgr_client_new(PC_LISTENING);
765 pkgmgr_client_set_status_type(ad->pc, event_type);
766 pkgmgr_client_listen_status(ad->pc, _double_press_app_event_cb, ad);
769 int event_type2 = PMINFO_CLIENT_STATUS_UNINSTALL;
772 pkgmgr_client_free(pc2);
776 ad->pc2 = pkgmgr_client_new(PMINFO_LISTENING);
777 pkgmgr_client_set_status_type(ad->pc2, event_type2);
778 pkgmgr_client_listen_status(ad->pc2, _double_press_app_uninstall_event_cb, ad);
785 register_vconf_changing(VCONFKEY_WMS_POWERKEY_DOUBLE_PRESSING, change_double_pressing_cb, ad);
786 register_vconf_changing(VCONFKEY_LANGSET, change_language_cb, ad);
787 register_vconf_changing(VCONFKEY_AIL_INFO_STATE, change_app_state_cb, ad);
790 Evas_Object *create_double_list(void * data)
795 ERR("appdata is null!!");
799 Evas_Object *genlist = NULL;
800 Evas_Object *layout = NULL;
803 Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
804 itc->item_style = "2text";
805 itc->func.text_get = _gl_double_title_get;
807 layout = elm_layout_add(ad->nf);
808 elm_layout_file_set(layout, EDJE_PATH, "setting/genlist/layout");
809 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
811 genlist = elm_genlist_add(layout);
812 elm_genlist_block_count_set(genlist, 14);
813 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
814 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
816 /*elm_genlist_item_append(genlist, itc, NULL, NULL, */
817 /* ELM_GENLIST_ITEM_NONE, _double_app_list_cb, ad); */
819 elm_genlist_item_class_free(itc);
821 g_double_genlist = genlist;
823 elm_object_part_content_set(layout, "elm.genlist", genlist);
828 void clear_double_cb(void * data , Evas * e, Evas_Object * obj, void * event_info)
832 g_double_genlist = NULL;
833 g_double_app_genlist = NULL;
834 unregister_vconf_changing(VCONFKEY_WMS_POWERKEY_DOUBLE_PRESSING, change_double_pressing_cb);
835 unregister_vconf_changing(VCONFKEY_LANGSET, change_language_cb);
836 unregister_vconf_changing(VCONFKEY_AIL_INFO_STATE, change_app_state_cb);