Fix coverity issue 1149129
[apps/native/volume-app.git] / src / view.c
index 093053e..7f25b1e 100755 (executable)
@@ -18,6 +18,7 @@
 #include <feedback.h>
 #include <vconf.h>
 #include <vconf-keys.h>
+#include <app.h>
 
 #include "main.h"
 #include "_util_efl.h"
@@ -39,6 +40,7 @@ struct _view_s_info {
        Evas_Object *icon_setting;
        Evas_Object *slider;
        Evas_Object *warning_popup;
+       Evas_Object *ao_volume;
 
        Evas_Object *lockscreen_splash;
 
@@ -59,6 +61,7 @@ static struct _view_s_info view_info = {
        .icon_setting = NULL,
        .slider = NULL,
        .warning_popup = NULL,
+       .ao_volume = NULL,
 
        .lockscreen_splash = NULL,
 
@@ -70,7 +73,7 @@ static struct _view_s_info view_info = {
        .pre_sound_type = SOUND_TYPE_RINGTONE
 };
 
-static void _button_cb(void *data, Evas_Object *obj, void *event_info);
+static void _button_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
 static void _button_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
 static void _app_control_error_check(int ret);
 static void _hide_launcher(void *data, Evas_Object *obj, const char *emission, const char *source);
@@ -81,6 +84,26 @@ static Evas_Object* _slider_make();
 static Evas_Object* _volume_icon_make();
 static Evas_Object* _setting_icon_make();
 
+const char *volume_view_get_file_path(const char *relative)
+{
+       char *prefix = NULL;
+       static char buf[PATH_MAX];
+
+       prefix = app_get_resource_path();
+
+       if (prefix != NULL) {
+               size_t res = eina_file_path_join(buf, sizeof(buf), prefix, relative);
+               snprintf(buf, sizeof(buf), "%s%s", prefix, relative);
+               free(prefix);
+
+               if (res > sizeof(buf)) {
+                       _E("Path exceeded PATH_MAX\n");
+                       return NULL;
+               }
+       }
+       return &buf[0];
+}
+
 Evas_Object* volume_view_win_get(void)
 {
        return view_info.win;
@@ -141,13 +164,15 @@ sound_type_e volume_view_pre_sound_type_get(void)
        return view_info.pre_sound_type;
 }
 
-volume_error_e volume_view_set_default_slider(){
+volume_error_e volume_view_set_default_slider()
+{
        Evas_Object *slider = volume_view_slider_get();
        elm_object_style_set(slider, "default");
        return VOLUME_ERROR_OK;
 }
 
-volume_error_e volume_view_set_warning_slider(){
+volume_error_e volume_view_set_warning_slider()
+{
        Evas_Object *slider = volume_view_slider_get();
        elm_object_style_set(slider, "warning");
        Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
@@ -173,12 +198,11 @@ int volume_mute_toggle_set()
                volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 0);
                volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
 
-               if(VOLUME_ERROR_OK != volume_view_slider_value_set(0))
+               if (VOLUME_ERROR_OK != volume_view_slider_value_set(0))
                        _E("Failed to set slider value");
 
                return 0;
-       }
-       else {
+       } else {
                volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 1);
                volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
 
@@ -272,9 +296,8 @@ volume_error_e volume_view_open_warning_popup(void)
 void volume_view_destroy_warning_popup(void)
 {
        _D("Destroy warning popup");
-       if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_FALSE)) {
+       if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_FALSE))
                _E("Failed to set warning status");
-       }
 
        evas_object_del(view_info.warning_popup);
        view_info.warning_popup = NULL;
@@ -289,7 +312,7 @@ volume_error_e volume_view_slider_value_set(int val)
 {
        _D("Slider value set : %d", val);
        retv_if(view_info.is_slider_touching, VOLUME_ERROR_FAIL);
-       retv_if(val<0, VOLUME_ERROR_FAIL);
+       retv_if(val < 0, VOLUME_ERROR_FAIL);
 
        elm_slider_value_set(view_info.slider, val);
 
@@ -304,12 +327,12 @@ void volume_view_volume_icon_set(sound_type_e sound_type, int sound, int vibrati
        if (sound == -1 || vibration == -1) {
                img = IMG_VOLUME_ICON_MUTE;
                _D("img : %s", img);
-               elm_image_file_set(view_info.icon_volume, EDJ_APP, img);
+               elm_image_file_set(view_info.icon_volume, volume_view_get_file_path(EDJ_APP), img);
                return;
        }
 
-       switch (sound_type)
-       {
+       switch (sound_type) {
+       case SOUND_TYPE_ALARM:
        case SOUND_TYPE_RINGTONE:
                if (sound)
                        img = IMG_VOLUME_ICON;
@@ -319,32 +342,59 @@ void volume_view_volume_icon_set(sound_type_e sound_type, int sound, int vibrati
                        img = IMG_VOLUME_ICON_MUTE;
                break;
        case SOUND_TYPE_MEDIA:
-               img = IMG_VOLUME_ICON_MEDIA;
+               if (volume_sound_sound_manager_volume_get(sound_type) > 0)
+                       img = IMG_VOLUME_ICON;
+               else
+                       img = IMG_VOLUME_ICON_MUTE;
                break;
        case SOUND_TYPE_CALL:
                if (bt_opened)
-                       img = IMG_VOLUME_ICON_CALL;
+                       img = IMG_VOLUME_ICON_HEADPHONE;
                else
                        img = IMG_VOLUME_ICON_CALL;
                break;
        case SOUND_TYPE_NOTIFICATION:
                if (sound)
                        img = IMG_VOLUME_ICON_NOTI;
-               else if(vibration)
+               else if (vibration)
                        img = IMG_VOLUME_ICON_NOTI_VIB;
                else
                        img = IMG_VOLUME_ICON_NOTI_MUTE;
                break;
-       case SOUND_TYPE_ALARM:
-               img = IMG_VOLUME_ICON_MEDIA;
-               break;
        default:
                img = IMG_VOLUME_ICON;
                break;
        }
 
        _D("img : %s", img);
-       elm_image_file_set(view_info.icon_volume, EDJ_APP, img);
+       elm_image_file_set(view_info.icon_volume, volume_view_get_file_path(EDJ_APP), img);
+}
+
+void volume_view_volume_icon_name_set_for_access(sound_type_e sound_type)
+{
+       _D("Volume icon name set");
+       char buf[2056];
+
+       switch (sound_type) {
+       case SOUND_TYPE_RINGTONE:
+               snprintf(buf, sizeof(buf), "%s%s", _("IDS_ST_HEADER_RINGTONES"), "volume");
+               break;
+       case SOUND_TYPE_MEDIA:
+               snprintf(buf, sizeof(buf), "%s", _("IDS_ACCS_BODY_MEDIA_VOLUME_TTS"));
+               break;
+       case SOUND_TYPE_CALL:
+               snprintf(buf, sizeof(buf), "%s%s", _("IDS_ACCS_SK2_CALL"), "volume");
+               break;
+       case SOUND_TYPE_NOTIFICATION:
+               snprintf(buf, sizeof(buf), "%s%s", _("IDS_ST_BODY_NOTIFICATION"), "volume");
+               break;
+       default:
+               snprintf(buf, sizeof(buf), "%s%s", _("IDS_ST_HEADER_RINGTONES"), "volume");
+               break;
+       }
+
+       _D("volume accessible name: %s", buf);
+       elm_atspi_accessible_name_set(view_info.ao_volume, buf);
 }
 
 void volume_view_setting_icon_set(const char *file)
@@ -355,8 +405,8 @@ void volume_view_setting_icon_set(const char *file)
        Evas_Object *icon_setting = view_info.icon_setting;
        ret_if(!icon_setting);
 
-       if (EINA_TRUE != elm_image_file_set(icon_setting, EDJ_APP, file)) {
-               _E("Failed to set image file : %s, Group", EDJ_APP, file);
+       if (EINA_TRUE != elm_image_file_set(icon_setting, volume_view_get_file_path(EDJ_APP), file)) {
+               _E("Failed to set image file : %s, Group", file);
        };
 }
 
@@ -369,7 +419,7 @@ void volume_view_setting_icon_callback_add(void)
        ret_if(!icon_setting);
 
        evas_object_event_callback_add(icon_setting, EVAS_CALLBACK_MOUSE_DOWN, _button_mouse_down_cb, NULL);
-       evas_object_smart_callback_add(icon_setting, "clicked", _button_cb, NULL);
+       elm_object_signal_callback_add(view_info.ly_outer, "setting_icon_touched", "launch_setting", _button_cb, NULL);
 
        view_info.is_registered_callback = EINA_TRUE;
 }
@@ -382,7 +432,7 @@ void volume_view_setting_icon_callback_del(void)
        Evas_Object *icon_setting = view_info.icon_setting;
        ret_if(!icon_setting);
 
-       evas_object_smart_callback_del(icon_setting, "clicked", _button_cb );
+       elm_object_signal_callback_del(view_info.ly_outer, "setting_icon_touched", "launch_setting", _button_cb);
        evas_object_event_callback_del(icon_setting, EVAS_CALLBACK_MOUSE_DOWN, _button_mouse_down_cb);
 
        view_info.is_registered_callback = EINA_FALSE;
@@ -413,17 +463,17 @@ volume_error_e volume_view_send_warning_signal(Eina_Bool warning)
        } else {
                int current_angle = volume_control_get_current_angle();
                _D("Current angle: %d", current_angle);
-        switch(current_angle){
-        case 90 :
-        case 270 :
-            _D("show,landscape");
-            elm_object_signal_emit(view_info.ly_outer, "show,landscape", "bg");
-            break;
-        default :
-            _D("show,portrait");
-            elm_object_signal_emit(view_info.ly_outer, "show,portrait", "bg");
-            break;
-        }
+               switch (current_angle) {
+               case 90:
+               case 270:
+                       _D("show,landscape");
+                       elm_object_signal_emit(view_info.ly_outer, "show,landscape", "bg");
+                       break;
+               default:
+                       _D("show,portrait");
+                       elm_object_signal_emit(view_info.ly_outer, "show,portrait", "bg");
+                       break;
+               }
        }
        return VOLUME_ERROR_OK;
 }
@@ -432,13 +482,12 @@ volume_error_e volume_view_window_show(sound_type_e type)
 {
        _D("Volume view window SHOW is [%p]", view_info.win);
 
-       elm_win_iconified_set(view_info.win, EINA_FALSE);
+       elm_win_activate(view_info.win);
 
-       if (type == SOUND_TYPE_CALL) {
+       if (type == SOUND_TYPE_CALL)
                _D("Sound type is Call");
-       } else {
+       else
                volume_view_setting_icon_callback_add();
-       }
 
        return VOLUME_ERROR_OK;
 }
@@ -477,40 +526,43 @@ Evas_Object *add_layout(Evas_Object *parent, const char *file, const char *group
 
 void _connect_to_wm(Evas_Object *win)
 {
-       _D("Mack connection with window manager");
-
+       _D("Make connection with window manager");
        tzsh_window tz_win;
 
        view_info.tzsh = tzsh_create(TZSH_TOOLKIT_TYPE_EFL);
-       if (!view_info.tzsh) {
+       if (!view_info.tzsh)
                _E("Failed to get connection to Tizen window manager");
-       }
 
        tz_win = elm_win_window_id_get(win);
-       if (!tz_win) {
+       if (!tz_win)
                _E("Failed to get Tizen window manager");
-       }
 
+       /*
+        * Tizen SDK do not support tzsh yet
+        * If you want to build with ABS you should Block this code
+        */
+#if 0
        view_info.volume_service = tzsh_volume_service_create(view_info.tzsh, tz_win);
-       if (!view_info.volume_service) {
+       if (!view_info.volume_service)
                _E("Failed to get volume service");
-       }
+#endif
 }
 
 static void _down_for_hide(void *data, Evas_Object *obj, const char* emission, const char* source)
 {
-       LOGD("Down for HIDE");
+       _D("Down for HIDE");
 
-       volume_control_hide_view();
+       if (VOLUME_ERROR_OK != volume_control_hide_view())
+               _E("Failed to close volume");
 }
 
 volume_error_e volume_view_layout_create(Evas_Object *win)
 {
-       LOGD("Layout create");
+       _D("Layout create");
 
        retv_if(!win, VOLUME_ERROR_FAIL);
 
-       Evas_Object *ly_outer = add_layout(win, EDJ_APP, "volume_layout");
+       Evas_Object *ly_outer = add_layout(win, volume_view_get_file_path(EDJ_APP), "volume_layout");
        retv_if(!ly_outer, VOLUME_ERROR_FAIL);
        elm_win_resize_object_add(win, ly_outer);
        elm_object_signal_callback_add(ly_outer, "hide,popup", "event", _hide_launcher, NULL);
@@ -545,6 +597,11 @@ static void _iconified_cb(void *data, Evas_Object *obj, void *event_info)
        _D("ICONIFIED IS CALLED");
 }
 
+static void _deiconified_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       _D("ICONIFIED IS CANCELED");
+}
+
 Evas_Object *add_volume_window(const char *name)
 {
        Evas_Object *eo = NULL;
@@ -568,6 +625,7 @@ Evas_Object *add_volume_window(const char *name)
        _D("volume screen size => x: %d, y: %d, w: %d, h: %d", x, y, w, h);
 
        evas_object_smart_callback_add(eo, "iconified", _iconified_cb, NULL);
+       evas_object_smart_callback_add(eo, "normal", _deiconified_cb, NULL);
 
        return eo;
 }
@@ -591,10 +649,8 @@ Evas_Object *volume_view_window_create(void)
 {
        Evas_Object *win = add_volume_window(PACKAGE);
        retv_if(!win, NULL);
-       _D("window is [%p]", win);
 
        view_info.win = win;
-       _D("view_info.win is [%p]", view_info.win);
 
        evas_object_show(win);
 
@@ -637,7 +693,9 @@ void _lock_sound_check(void)
                }
                _D("lock type : %d", lock_type);
 
-               feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_LOCK);
+               if (FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_LOCK)) {
+                       _E("Failed to play vibration");
+               }
        }
 }
 
@@ -657,10 +715,10 @@ Evas_Object* show_lockscreen_splash(const char* bg_path)
        _lock_sound_check();
 
        /* hide volume window */
-       if(VOLUME_ERROR_OK != volume_view_window_hide())
+       if (VOLUME_ERROR_OK != volume_view_window_hide())
                _E("Failed to hide window");
 
-       Evas_Object *win_splash = elm_win_add(NULL,"lockscreen_splash", ELM_WIN_NOTIFICATION);
+       Evas_Object *win_splash = elm_win_add(NULL, "lockscreen_splash", ELM_WIN_NOTIFICATION);
 
        if (!win_splash) {
                _E("Failed to add splash window");
@@ -724,7 +782,7 @@ static void _slider_changed_cb(void *data, Evas_Object *obj, void *event_info)
 
        val = elm_slider_value_get(view_info.slider);
        val += 0.5;
-       _D("slider value : %d", val);
+       _D("slider value : %lf", val);
 
        if (view_info.is_slider_touching)
                return;
@@ -775,49 +833,50 @@ static void _button_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *e
 static void _app_control_error_check(int ret)
 {
        if (ret != APP_CONTROL_ERROR_NONE) {
-               switch (ret)
-               {
-               case APP_CONTROL_ERROR_INVALID_PARAMETER :
+               switch (ret) {
+               case APP_CONTROL_ERROR_INVALID_PARAMETER:
                        _E("error : APP_CONTROL_ERROR_INVALID_PARAMETER");
                        break;
-               case APP_CONTROL_ERROR_OUT_OF_MEMORY :
+               case APP_CONTROL_ERROR_OUT_OF_MEMORY:
                        _E("error : APP_CONTROL_ERROR_OUT_OF_MEMORY");
                        break;
-               case APP_CONTROL_ERROR_APP_NOT_FOUND :
+               case APP_CONTROL_ERROR_APP_NOT_FOUND:
                        _E("error : APP_CONTROL_ERROR_APP_NOT_FOUND");
                        break;
-               case APP_CONTROL_ERROR_LAUNCH_REJECTED :
+               case APP_CONTROL_ERROR_LAUNCH_REJECTED:
                        _E("error : APP_CONTROL_ERROR_LAUNCH_REJECTED");
                        break;
-               default :
+               default:
                        _E("error : %d", ret);
                        break;
                }
        }
 }
 
-static void _button_cb(void *data, Evas_Object *obj, void *event_info)
+static void _button_cb(void *data, Evas_Object *obj, const char *emssion, const char *source)
 {
-       _D("volume setting is clicked");
        int ret = -1;
-       app_control_h svc;
+       app_control_h app_setting;
 
        if (evas_object_visible_get(view_info.win)) {
                volume_timer_del(TYPE_TIMER_POPUP);
 
-               ret = app_control_create(&svc);
+               volume_sound_feedback_play(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_TAP);
+
+               /* Send Launch Request to Setting */
+               ret = app_control_create(&app_setting);
                _app_control_error_check(ret);
 
-               ret = app_control_set_app_id(svc, "org.tizen.setting.volume");
+               ret = app_control_set_app_id(app_setting, "org.tizen.setting.volume");
                _app_control_error_check(ret);
 
-               ret = app_control_send_launch_request(svc, NULL, NULL);
+               ret = app_control_send_launch_request(app_setting, NULL, NULL);
                _app_control_error_check(ret);
 
                if (VOLUME_ERROR_OK != volume_control_pause())
                        _E("Failed to pause volume");
 
-               app_control_destroy(svc);
+               app_control_destroy(app_setting);
        }
 }
 
@@ -875,3 +934,45 @@ static Evas_Object* _slider_make()
        return slider;
 }
 
+static Eina_Bool _access_highlight_cb(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info)
+{
+       volume_timer_del(TYPE_TIMER_POPUP);
+       volume_timer_add(3.0, TYPE_TIMER_POPUP);
+
+       return EINA_FALSE;
+}
+
+static Eina_Bool _access_active_cb(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info)
+{
+       _button_cb(NULL, NULL, NULL, NULL);
+       return EINA_FALSE;
+}
+
+void volume_view_accessible_create(Evas_Object *win)
+{
+       Evas_Object *ao_setting = NULL;
+       char buf[2056];
+
+       /* make volume accessible icon */
+       view_info.ao_volume = elm_access_object_register(view_info.icon_volume, view_info.icon_volume);
+       elm_atspi_accessible_reading_info_type_set(view_info.ao_volume, ELM_ACCESSIBLE_READING_INFO_TYPE_NAME);
+       elm_atspi_accessible_translation_domain_set(view_info.ao_volume, PACKAGE);
+       elm_access_action_cb_set(view_info.ao_volume, ELM_ACCESS_ACTION_HIGHLIGHT, _access_highlight_cb, NULL);
+
+       /* make setting accessible icon */
+       ao_setting = elm_access_object_register(view_info.icon_setting, view_info.icon_setting);
+       snprintf(buf, sizeof(buf), "%s%s", _("IDS_ST_BUTTON_SETTINGS"), "button");
+       elm_atspi_accessible_name_set(ao_setting, buf);
+       elm_atspi_accessible_reading_info_type_set(ao_setting, ELM_ACCESSIBLE_READING_INFO_TYPE_NAME);
+       elm_atspi_accessible_translation_domain_set(ao_setting, PACKAGE);
+       elm_access_action_cb_set(ao_setting, ELM_ACCESS_ACTION_HIGHLIGHT, _access_highlight_cb, NULL);
+       elm_access_action_cb_set(ao_setting, ELM_ACCESS_ACTION_ACTIVATE, _access_active_cb, NULL);
+
+       /* Make relationship */
+       elm_atspi_accessible_relationship_append(view_info.ao_volume, ELM_ATSPI_RELATION_FLOWS_TO, view_info.slider);
+       elm_atspi_accessible_relationship_append(view_info.slider, ELM_ATSPI_RELATION_FLOWS_FROM, view_info.ao_volume);
+
+       elm_atspi_accessible_relationship_append(view_info.slider, ELM_ATSPI_RELATION_FLOWS_TO, ao_setting);
+       elm_atspi_accessible_relationship_append(ao_setting, ELM_ATSPI_RELATION_FLOWS_FROM, view_info.slider);
+}
+