Add safety warning popup 79/93279/10 submit/tizen/20161101.074323
authorjunkyu han <junkyu.han@samsung.com>
Fri, 21 Oct 2016 11:05:03 +0000 (20:05 +0900)
committerjunkyu han <junkyu.han@samsung.com>
Tue, 1 Nov 2016 06:12:55 +0000 (15:12 +0900)
Change-Id: I42a48f08d697406209a18033671badf8ec444cc8

17 files changed:
CMakeLists.txt
data/volume_app.edc
include/bt.h
include/control.h
include/earphone.h [new file with mode: 0644]
include/key_event.h
include/timer.h
include/view.h
org.tizen.volume.xml
packaging/org.tizen.volume.spec
src/bt.c
src/control.c
src/earphone.c [new file with mode: 0644]
src/key_event.c
src/sound.c
src/timer.c
src/view.c

index e02f17f..0dd0b73 100755 (executable)
@@ -9,6 +9,7 @@ SET(SRCS
        src/timer.c
        src/sound.c
        src/bt.c
+       src/earphone.c
 )
 
 SET(VENDOR "tizen")
@@ -40,6 +41,7 @@ pkg_check_modules(pkgs REQUIRED
        edje
        capi-media-sound-manager
        capi-network-bluetooth
+       capi-system-device
        vconf
        syspopup
        syspopup-caller
index d1591bd..9996672 100755 (executable)
@@ -281,17 +281,8 @@ RESOURCE_IMAGE_PRESS("00_volume_icon_settings_pressed.png");
                                        rel2 {relative: WIN_X_MAX_L WIN_Y_MAX_L; to: "clipper";}
                                }
                                description {
-                                       state: "warning_displayed" 0.0;
+                                       state: "warning" 0.0;
                                        inherit: "default" 0.0;
-                                       color : 0 0 0 0;
-                                       rel2 {relative: WIN_X_MAX WARRING_Y_MAX; to: "clipper";}
-                               }
-                               description {
-                                       state: "warning_displayed_l" 0.0;
-                                       inherit: "default" 0.0;
-                                       color : 0 0 0 0;
-                                       rel1 {relative: WIN_X_MIN_L WIN_Y_MIN_L; to: "clipper";}
-                                       rel2 {relative: WIN_X_MAX_L WARRING_Y_MAX_L; to: "clipper";}
                                }
                        }
 
@@ -320,6 +311,11 @@ RESOURCE_IMAGE_PRESS("00_volume_icon_settings_pressed.png");
                                        rel1.to : "bg";
                                        rel2.to : "bg";
                                }
+                               description {
+                                       state : "warning" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+                               }
                        }
                        part {
                                name : "ic_sound";
@@ -344,6 +340,11 @@ RESOURCE_IMAGE_PRESS("00_volume_icon_settings_pressed.png");
                                        rel1 { relative : IC_SOUND_X_MIN_L IC_SOUND_Y_MIN_L; to : "clipper";}
                                        rel2 { relative : IC_SOUND_X_MAX_L IC_SOUND_Y_MAX_L; to : "clipper";}
                                }
+                               description {
+                                       state : "warning" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+                               }
 
                        }
 
@@ -376,6 +377,11 @@ RESOURCE_IMAGE_PRESS("00_volume_icon_settings_pressed.png");
                                        rel1 { relative : IC_SETTING_X_EFFECT IC_SETTING_Y_EFFECT; to : "clipper";}
                                        rel2 { relative : IC_SETTING_X_EFFECT IC_SETTING_Y_EFFECT; to : "clipper";}
                                }
+                               description {
+                                       state : "warning" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+                               }
                        }
                        part {
                                name : "ic_setting_ef";
@@ -407,6 +413,11 @@ RESOURCE_IMAGE_PRESS("00_volume_icon_settings_pressed.png");
                                        inherit: "default" 0.0;
                                        visible: 1;
                                }
+                               description {
+                                       state : "warning" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+                               }
                        }
                        part {
                                name : "divider";
@@ -431,6 +442,11 @@ RESOURCE_IMAGE_PRESS("00_volume_icon_settings_pressed.png");
                                        rel1 { relative : DIVIDER_X_MIN_L DIVIDER_Y_MIN_L; to : "clipper";}
                                        rel2 { relative : DIVIDER_X_MAX_L DIVIDER_Y_MAX_L; to : "clipper";}
                                }
+                               description {
+                                       state : "warning" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+                               }
                        }
                        part {
                                name : "sw.slider";
@@ -454,39 +470,11 @@ RESOURCE_IMAGE_PRESS("00_volume_icon_settings_pressed.png");
                                        rel1 { relative : IC_CONTENT_X_MIN_L IC_CONTENT_Y_MIN_L; to : "clipper";}
                                        rel2 { relative : IC_CONTENT_X_MAX_L IC_CONTENT_Y_MAX_L; to : "clipper";}
                                }
-                       }
-
-                       part {
-                               name: "warning_rect";
-                               type: TEXTBLOCK;
-                               clip_to: "clipper";
-                               scale: 1;
                                description {
-                                       state: "default" 0.0;
-                                       visible: 0;
-                                       rel1 { relative: WARRNING_TEXT_X_MIN  WARRNING_TEXT_Y_MIN; to: "clipper";}
-                                       rel2 { relative: WARRNING_TEXT_X_MAX  WARRNING_TEXT_Y_MAX; to: "clipper";}
-                                       text {
-                                               style: "textblock_style";
-                                       }
-                               }
-                               description {
-                                       state: "landscape" 0.0;
+                                       state : "warning" 0.0;
                                        inherit: "default" 0.0;
                                        visible: 0;
                                }
-                               description {
-                                       state: "warning_displayed" 0.0;
-                                       inherit: "default" 0.0;
-                                       visible: 1;
-                               }
-                               description {
-                                       state: "warning_displayed_l" 0.0;
-                                       inherit: "default" 0.0;
-                                       visible: 1;
-                                       rel1 { relative: WARRNING_TEXT_X_MIN_L  WARRNING_TEXT_Y_MIN_L; to: "clipper";}
-                                       rel2 { relative: WARRNING_TEXT_X_MAX_L  WARRNING_TEXT_Y_MAX_L; to: "clipper";}
-                               }
                        }
                }
                programs {
@@ -532,6 +520,18 @@ RESOURCE_IMAGE_PRESS("00_volume_icon_settings_pressed.png");
                                target : "sw.slider";
                                target : "divider";
                        }
+                       program {
+                               name : "show,warning";
+                               signal : "show,warning";
+                               source : "bg";
+                               action : STATE_SET "warning" 0.0;
+                               target : "popup_bg";
+                               target : "bg";
+                               target : "ic_sound";
+                               target : "ic_setting";
+                               target : "sw.slider";
+                               target : "divider";
+                       }
                        program{
                                name : "hide_effect";
                                signal : "hide_effect";
@@ -555,38 +555,6 @@ RESOURCE_IMAGE_PRESS("00_volume_icon_settings_pressed.png");
                                action: SIGNAL_EMIT "hide,popup" "event";
                        }
                        program{
-                               name: "show_warning";
-                               signal: "show_warning";
-                               source: "clipper";
-                               action: STATE_SET "warning_displayed" 0.0;
-                               target: "warning_rect";
-                               target: "bg";
-                       }
-                       program{
-                               name: "show_warning_l";
-                               signal: "show_warning_l";
-                               source: "clipper";
-                               action: STATE_SET "warning_displayed_l" 0.0;
-                               target: "warning_rect";
-                               target: "bg";
-                       }
-                       program{
-                               name: "hide_warning";
-                               signal: "hide_warning";
-                               source: "clipper";
-                               action: STATE_SET "default" 0.0;
-                               target: "warning_rect";
-                               target: "bg";
-                       }
-                       program{
-                               name: "hide_warning_l";
-                               signal: "hide_warning_l";
-                               source: "clipper";
-                               action: STATE_SET "landscape" 0.0;
-                               target: "warning_rect";
-                               target: "bg";
-                       }
-                       program{
                                name: "slider_touching_on";
                                signal: "slider_touching_on";
                                source: "clipper";
index c873d14..285d621 100644 (file)
@@ -20,6 +20,6 @@
 
 extern int bt_get_bt_volume(void);
 extern void bt_init_sco(void);
-extern void bt_deinit_sco(void);
+extern void bt_fini_sco(void);
 
 #endif
index 3c7fee8..8430f7e 100755 (executable)
@@ -35,6 +35,10 @@ extern int volume_control_get_viewport_height();
 extern int volume_control_get_viewport_width();
 extern void volume_control_show_hide_worning();
 extern Eina_Bool volume_control_viewport_is_warning_visible();
+extern void volume_control_set_safety_limit(Eina_Bool limit);
+extern Eina_Bool volume_control_get_safety_limit();
+extern Eina_Bool volume_control_get_time_for_safety_limit();
+extern void volume_control_set_time_for_safety_limit();
 
 extern bundle *volume_control_reset_get_bundle(void);
 extern Eina_Bool volume_control_get_is_deleting(void);
@@ -49,7 +53,7 @@ extern int volume_control_get_vconf_idlelock(void);
 
 extern int volume_control_check_status(int *lock, sound_type_e *sound_type);
 
-extern Eina_Bool volume_control_show_view(int status, sound_type_e sound_type, int sound, bool bt_opened);
+extern Eina_Bool volume_control_show_view(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected);
 extern int volume_control_hide_view(void);
 extern volume_error_e volume_control_close_bt_display();
 
diff --git a/include/earphone.h b/include/earphone.h
new file mode 100644 (file)
index 0000000..cd5cc33
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __VOLUME_EARPHONE_H__
+#define __VOLUME_EARPHONE_H__
+
+extern void earphone_init(void);
+extern void earphone_fini(void);
+extern int earphone_get_earphone_is_connected(void);
+
+#endif
index b43e6d6..34f4a15 100755 (executable)
@@ -23,6 +23,7 @@
 #define KEY_MUTE "XF86AudioMute"
 #define KEY_BACK "XF86Back"
 #define KEY_CANCEL "Cancel"
+#define SAFETY_LIMIT 9
 
 extern Ecore_X_Window volume_key_event_input_window_get(void);
 extern Ecore_Event_Handler *volume_key_event_handler_volume_up_get(void);
index 8e62ca7..355daa1 100755 (executable)
@@ -33,7 +33,8 @@ typedef enum {
        TYPE_TIMER_SLIDER,
        TYPE_TIMER_SD,
        TYPE_TIMER_SU,
-       TYPE_TIMER_BT
+       TYPE_TIMER_BT,
+       TYPE_TIMER_WARNING_POPUP,
 } volume_timer_type;
 
 extern Ecore_Timer *volume_timer_popup_timer_get(void);
index 8b917c0..dcb6d78 100755 (executable)
@@ -20,7 +20,7 @@
 #define __VOLUME_VIEW_H__
 
 extern sound_type_e volume_view_pre_sound_type_get(void);
-extern volume_error_e volume_change_slider_max_value(sound_type_e type);
+extern volume_error_e volume_view_change_slider_by_type(sound_type_e type, bool bt_opened, int earphone_connected);
 
 extern Evas_Object *volume_view_win_get(void);
 extern tzsh_h volume_view_tzsh_get(void);
@@ -30,10 +30,13 @@ extern Evas_Object *volume_view_outer_layout_get(void);
 extern Evas_Object *volume_view_icon_volume_get(void);
 extern Evas_Object *volume_view_icon_setting_get(void);
 extern Evas_Object *volume_view_slider_get(void);
+extern Evas_Object *volume_view_warning_popup_get(void);
 extern Eina_Bool volume_view_is_registered_callback_get(void);
 extern Eina_Bool volume_view_is_slider_touching_get(void);
 extern void volume_view_is_registered_callback_set(Eina_Bool val);
 extern int volume_mute_toggle_set(void);
+extern volume_error_e volume_view_open_warning_popup(void);
+extern void volume_view_destroy_warning_popup(void);
 
 extern volume_error_e volume_view_slider_value_set(int val);
 extern void volume_view_volume_icon_set(sound_type_e sound_type, int sound, int vibration, bool bt_opened);
@@ -48,7 +51,7 @@ extern Evas_Object *volume_view_window_create(void);
 
 extern Evas_Object* show_lockscreen_splash(const char *bg_path);
 extern volume_error_e hide_lockscreen_splash(void);
-extern void volume_service_region_set(Evas_Object *win, Eina_Bool is_warning_visible);
+extern volume_error_e volume_view_send_warning_signal(Eina_Bool warning);
 
 
 #endif /* __VOLUME_VIEW_H__ */
index f67e70a..a6daa75 100755 (executable)
@@ -16,6 +16,7 @@
                <privilege>http://tizen.org/privilege/systemsettings.admin</privilege>
                <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
                <privilege>http://tizen.org/privilege/keygrab</privilege>
+               <privilege>http://tizen.org/privilege/display</privilege>
        </privileges>
 
 </manifest>
index ea1a6ee..8467426 100755 (executable)
@@ -26,6 +26,7 @@ BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(notification)
 BuildRequires:  pkgconfig(feedback)
 BuildRequires:  pkgconfig(capi-network-bluetooth)
+BuildRequires:  pkgconfig(capi-system-device)
 BuildRequires:  pkgconfig(tzsh-volume-service)
 
 BuildRequires:  cmake
index 94ed31c..9e4164b 100644 (file)
--- a/src/bt.c
+++ b/src/bt.c
@@ -61,7 +61,7 @@ void bt_init_sco(void)
                _E("volume bt register changed cb failed");
 }
 
-void bt_deinit_sco(void)
+void bt_fini_sco(void)
 {
        _D("SCO volume Deinitialize");
        if (_bt_unregister_changed_cb() != BT_ERROR_NONE)
index 7043e0e..3d18ecd 100755 (executable)
@@ -21,6 +21,7 @@
 #include <bluetooth_internal.h>
 #include <bluetooth_extension.h>
 #include <bundle_internal.h>
+#include <aul.h>
 
 #include "main.h"
 #include "_util_efl.h"
@@ -31,6 +32,7 @@
 #include "timer.h"
 #include "key_event.h"
 #include "bt.h"
+#include "earphone.h"
 #include "tzsh_volume_service.h"
 
 #define VCONF_KEY_FMRADIO_RECORDING "memory/private/Sound/FMRadioRecording"
@@ -44,6 +46,8 @@ struct _control_s_info{
        Eina_Bool is_warning_visible;
        Eina_Bool reset_once;
        Eina_Bool show_once;
+       Eina_Bool safety_limit;
+       Eina_Bool time_for_safety_limit;
 
        int current_angle;
        int viewport_width;
@@ -60,6 +64,8 @@ static struct _control_s_info control_info = {
        .is_warning_visible = EINA_FALSE,
        .reset_once = EINA_FALSE,
        .show_once = EINA_FALSE,
+       .safety_limit = EINA_TRUE,
+       .time_for_safety_limit = EINA_TRUE,
 
        .current_angle = 0,
        .viewport_width = 0,
@@ -73,6 +79,7 @@ static void _idle_lock_state_vconf_changed_cb(keynode_t *key, void *data);
 static void _starter_user_volume_key_vconf_changed_cb(keynode_t *key, void *data);
 static void _control_set_window_rotation(Evas_Object *win);
 static void _rotate_changed_cb(void *data, Evas_Object *obj, void *event_info);
+static void _volume_service_region_set(Evas_Object *win, Evas_Object *warning_popup);
 
 bundle* volume_control_reset_get_bundle(void)
 {
@@ -99,17 +106,58 @@ sound_type_e volume_control_get_sound_type_at_show(void)
        return control_info.sound_type_at_show;
 }
 
-int volume_control_get_viewport_height()
+int volume_control_get_viewport_height(void)
 {
        return control_info.viewport_height;
 }
 
-int volume_control_get_viewport_width()
+int volume_control_get_viewport_width(void)
 {
        return control_info.viewport_width;
 }
 
-Eina_Bool volume_control_viewport_is_warning_visible()
+Eina_Bool volume_control_get_safety_limit(void)
+{
+       return control_info.safety_limit;
+}
+
+void volume_control_set_safety_limit(Eina_Bool limit)
+{
+       control_info.safety_limit = limit;
+}
+
+void volume_control_set_time_for_safety_limit(void)
+{
+       time_t raw_time;
+       struct tm *time_info;
+
+       time(&raw_time);
+       time_info = localtime(&raw_time);
+       _D("Current time [%d] %d:%d-%d", time_info->tm_mday, time_info->tm_hour, time_info->tm_min, time_info->tm_sec);
+
+       control_info.time_for_safety_limit = time_info->tm_mday * 3600 * 24 + time_info->tm_hour * 3600 + time_info->tm_min * 60 + time_info->tm_sec;
+}
+
+Eina_Bool volume_control_get_time_for_safety_limit(void)
+{
+       time_t raw_time;
+       struct tm *time_info;
+       int diff = 0;
+       int convert_sec = 0;
+
+       time(&raw_time);
+       time_info = localtime(&raw_time);
+       _D("Current time [%d] %d:%d-%d", time_info->tm_mday, time_info->tm_hour, time_info->tm_min, time_info->tm_sec);
+
+       convert_sec = time_info->tm_mday * 3600 * 24 + time_info->tm_hour * 3600 + time_info->tm_min * 60 + time_info->tm_sec;
+
+       diff = convert_sec - control_info.time_for_safety_limit;
+       _D("%d hour is passed after checking warning popup", diff);
+
+       return diff >= 20 * 3600 ? EINA_TRUE : EINA_FALSE;
+}
+
+Eina_Bool volume_control_viewport_is_warning_visible(void)
 {
     return control_info.is_warning_visible;
 }
@@ -216,22 +264,22 @@ int volume_control_get_vconf_idlelock(void)
                ) ? IDLELOCK_ON : IDLELOCK_OFF;
 }
 
-
 int volume_control_check_status(int *lock, sound_type_e *sound_type)
 {
        *lock = volume_control_get_vconf_idlelock();
        *sound_type = volume_sound_sound_manager_type_get();
+
        _D("lock : %d / sound_type : %d", *lock, *sound_type);
 
-       if(*lock == IDLELOCK_ON)
+       if (*lock == IDLELOCK_ON)
        {
-               if(*sound_type == SOUND_TYPE_RINGTONE)
+               if (*sound_type == SOUND_TYPE_RINGTONE)
                {
                        _D("IDLELOCK is ON / sound type is Ringtone");
                        return LOCK_AND_NOT_MEDIA;
                }
 
-               if(*sound_type != SOUND_TYPE_RINGTONE)
+               if (*sound_type != SOUND_TYPE_RINGTONE)
                {
                        _D("IDLELOCK is ON / sound type is not Ringtone(media or alaram)");
                        return LOCK_AND_MEDIA;
@@ -243,60 +291,21 @@ int volume_control_check_status(int *lock, sound_type_e *sound_type)
        return UNLOCK_STATUS;
 }
 
-void volume_control_show_hide_worning()
-{
-       Evas_Object *ly_outer = volume_view_outer_layout_get();
-       sound_type_e sound_type = volume_sound_sound_manager_type_get();
-       int volume = volume_sound_sound_manager_volume_get(sound_type);
-
-       if(sound_type == SOUND_TYPE_MEDIA
-        && volume>VOLUME_MAX_SAFETY_VOLUME_LEVEL)
-       {
-               if(!control_info.is_warning_visible)
-               {
-                       control_info.is_warning_visible = EINA_TRUE;
-
-                       if(control_info.current_angle == 90 || control_info.current_angle == 270)
-                       {
-                               elm_object_signal_emit(ly_outer, "show_warning_l", "clipper"); //landscape
-                       }
-                       else
-                       {
-                               elm_object_signal_emit(ly_outer, "show_warning", "clipper"); //landscape
-                       }
-               }
-       }
-       else if(control_info.is_warning_visible)
-       {
-               control_info.is_warning_visible = EINA_FALSE;
-
-               if(control_info.current_angle == 90 || control_info.current_angle == 270)
-               {
-                       elm_object_signal_emit(ly_outer, "hide_warning_l", "clipper"); //landscape
-               }
-               else
-               {
-                       elm_object_signal_emit(ly_outer, "hide_warning", "clipper"); //landscape
-               }
-       }
-}
-
 static Eina_Bool _volume_region_set_timer_cb(void *data)
 {
        Evas_Object *win = data;
 
-       volume_service_region_set(win, EINA_FALSE);
+       _volume_service_region_set(win, volume_view_warning_popup_get());
 
        return EINA_FALSE;
 }
 
-Eina_Bool volume_control_show_view(int status, sound_type_e sound_type, int sound, bool bt_opened)
+Eina_Bool volume_control_show_view(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected)
 {
        _D("Volume control show");
        Evas_Object *win = NULL;
        int volume = 0;
        int vibration = 0;
-       sound_type_e pre_sound_type;
 
        retv_if(control_info.is_deleting, EINA_FALSE);
 
@@ -305,76 +314,55 @@ Eina_Bool volume_control_show_view(int status, sound_type_e sound_type, int soun
        win = volume_view_win_get();
        retv_if(!win, EINA_FALSE);
 
-       pre_sound_type = volume_view_pre_sound_type_get();
+       control_info.sound_type_at_show = sound_type;
 
-       if(status == LOCK_AND_NOT_MEDIA)
-       {
+       if (status == LOCK_AND_NOT_MEDIA) {
                _D("Lock and Not Media");
-               if(evas_object_visible_get(win))
-               {
-                       if(VOLUME_ERROR_OK != volume_control_hide_view())
-                       {
+               if (evas_object_visible_get(win)) {
+                       if (VOLUME_ERROR_OK != volume_control_hide_view()) {
                                _E("Failed to close volume");
                        }
 
-                       if(VOLUME_ERROR_OK != volume_control_cache_flush())
-                       {
+                       if (VOLUME_ERROR_OK != volume_control_cache_flush()) {
                                _E("Failed to flush cache");
                        }
                }
                return EINA_FALSE;
        } else {
-               _D("UNLOCK or LOCK_AND_MEDIA");
-               control_info.sound_type_at_show = sound_type;
-
-               if (sound_type != pre_sound_type) {
-                       if (VOLUME_ERROR_OK != volume_change_slider_max_value(sound_type)) {
+               if (status == LOCK_AND_MEDIA) {
+                       _D("LOCK_AND_MEDIA");
+               } else {
+                       _D("UNLOCK");
+                       if (VOLUME_ERROR_OK != volume_view_change_slider_by_type(sound_type, bt_opened, earphone_connected)) {
                                _E("Failed to changed max volume");
                        }
-               }
 
-               if(status == UNLOCK_STATUS)     {
                        if(VOLUME_ERROR_OK != volume_view_window_show(sound_type)) {
                                _E("Failed to show volume window");
                        }
                        ecore_timer_add(0.1f, _volume_region_set_timer_cb, win);
-               }
-
-               control_info.is_launching = EINA_TRUE;
 
-               if(bt_opened == 1 && sound_type == SOUND_TYPE_CALL)
-               {
-                       _D("bt is opened and is calling");
-                       volume = bt_get_bt_volume();
-                       _D("bt volume is : %d", volume);
-
-                       if(VOLUME_ERROR_OK != volume_view_slider_value_set(volume))
-                       {
-                               _E("Failed to set volume value to slider");
-                       }
-               }
-               else
-               {
-                       volume = volume_sound_sound_manager_volume_get(sound_type);
-                       _D("volume : %d", volume);
+                       control_info.is_launching = EINA_TRUE;
 
-                       vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
-                       _D("vibration : %d", vibration);
+                       if (bt_opened == 1 && sound_type == SOUND_TYPE_CALL) {
+                               volume = bt_get_bt_volume();
+                       } else {        
+                               volume = volume_sound_sound_manager_volume_get(sound_type);
+                               _D("volume value: %d", volume);
+                               vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
+                               _D("vibration : %d", vibration);
 
-                       if(((vibration == 1 && sound == 0) || sound == 0) && sound_type == SOUND_TYPE_RINGTONE)
-                       {
-                               volume = 0;
-                       }
+                               if(((vibration == 1 && sound == 0) || sound == 0) && sound_type == SOUND_TYPE_RINGTONE) {
+                                       volume = 0;
+                               }
 
-                       if(VOLUME_ERROR_OK != volume_view_slider_value_set(volume))
-                       {
-                               _E("Failed to set volume value to slider");
+                               if(VOLUME_ERROR_OK != volume_view_slider_value_set(volume)) {
+                                       _E("Failed to set volume value to slider");
+                               }
+                               volume_view_volume_icon_set(sound_type, sound, vibration, bt_opened);
                        }
                }
 
-               //@TODO: need to check
-               volume_view_volume_icon_set(sound_type, sound, vibration, bt_opened);
-
                return EINA_TRUE;
        }
 }
@@ -388,8 +376,7 @@ volume_error_e volume_control_close_bt_display(void)
        control_info.is_deleting = EINA_TRUE;
 
        /* hide window */
-       if(VOLUME_ERROR_OK != volume_view_window_hide())
-       {
+       if (VOLUME_ERROR_OK != volume_view_window_hide()) {
                _E("Failed to hide window");
        }
 
@@ -413,6 +400,7 @@ volume_error_e volume_control_hide_view(void)
        volume_timer_del(TYPE_TIMER_SD);
        volume_timer_del(TYPE_TIMER_SLIDER);
        volume_timer_del(TYPE_TIMER_POPUP);
+       volume_timer_del(TYPE_TIMER_WARNING_POPUP);
 
        /* hide window */
        if (VOLUME_ERROR_OK != volume_view_window_hide()) {
@@ -430,14 +418,12 @@ volume_error_e volume_control_hide_view(void)
 void volume_control_register_vconfkey(void)
 {
        /* other app grab volume key => close volume */
-       if(vconf_notify_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb, NULL) != 0)
-       {
+       if (vconf_notify_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb, NULL) != 0) {
                _E("Failed to register callback function : VCONFKEY_STARTER_USE_VOLUME_KEY");
        }
 
        /* Lock screen status vconf changed callback */
-       if(vconf_notify_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb, NULL) != 0)
-       {
+       if (vconf_notify_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb, NULL) != 0) {
                _E("Failed to notify vconfkey : VCONFKEY_IDLE_LOCK_STATE");
        }
 
@@ -449,14 +435,12 @@ void volume_control_register_vconfkey(void)
 void volume_control_unregister_vconfkey(void)
 {
        /* other app grab volume key => close volume */
-       if(vconf_ignore_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb) < 0)
-       {
+       if (vconf_ignore_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb) < 0) {
                _E("Failed to ignore vconfkey : VCONFKEY_STARTER_USE_VOLUME_KEY");
        }
 
        /* Lock screen status vconf changed callback */
-       if(vconf_ignore_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb) < 0)
-       {
+       if (vconf_ignore_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb) < 0) {
                _E("Failed to ignore vconfkey : VCONFKEY_IDLE_LOCK_STATE");
        }
 
@@ -471,14 +455,12 @@ volume_error_e volume_control_pause(void)
        Evas_Object *win = volume_view_win_get();
        retv_if(!win, VOLUME_ERROR_FAIL);
 
-       if(evas_object_visible_get(win)) {
-               if(VOLUME_ERROR_OK != volume_control_hide_view())
-               {
+       if (evas_object_visible_get(win)) {
+               if(VOLUME_ERROR_OK != volume_control_hide_view()) {
                        _E("Failed to close volume");
                }
 
-               if(VOLUME_ERROR_OK != volume_control_cache_flush())
-               {
+               if (VOLUME_ERROR_OK != volume_control_cache_flush()) {
                        _E("Failed to flush cache");
                }
        }
@@ -497,6 +479,7 @@ volume_error_e volume_control_reset(bundle *b)
        int volume = 0;
        int sound = 0;
        int error = 0;
+       int earphone_connected = 0;
        bool bt_opened = false;
        sound_type_e sound_type = 0;
        const char *show_volume = NULL;
@@ -511,23 +494,21 @@ volume_error_e volume_control_reset(bundle *b)
        _D("sound status : %d", sound);
 
        error = bt_ag_is_sco_opened(&bt_opened);
-       if(error != BT_ERROR_NONE)
-       {
+       if (error != BT_ERROR_NONE) {
                _E("bt_ag_is_sco_opened return [%d]", error);
        }
-       _D("BT state %d", bt_opened);
+       earphone_connected = earphone_get_earphone_is_connected();
+       _D("BT state %d, Earphone state: %d", bt_opened, earphone_connected);
 
        show_volume = bundle_get_val(b, SHOWVOLUME);
        retv_if(!show_volume, VOLUME_ERROR_FAIL);
 
-       if(!strncasecmp(show_volume, ISTRUE, strlen(ISTRUE)))
-       {
+       if (!strncasecmp(show_volume, ISTRUE, strlen(ISTRUE))) {
                _D("Bundle : %s", show_volume);
-               if(lock == IDLELOCK_OFF)
-               {
+               if (lock == IDLELOCK_OFF) {
                        _D("Show Volume");
                        volume_timer_add(3.0, TYPE_TIMER_POPUP);
-                       volume_control_show_view(status, sound_type, sound, bt_opened);
+                       volume_control_show_view(status, sound_type, sound, bt_opened, earphone_connected);
                }
        }
 
@@ -574,23 +555,27 @@ volume_error_e volume_control_initialize(void)
 
        /* BT initialize and register changed callback */
        bt_init_sco();
+       earphone_init();
 
        return VOLUME_ERROR_OK;
 }
 
 void volume_control_deinitialize(void)
 {
+       /* Unregister earphone changed callback */
+       earphone_fini();
+       /* Unregister bt changed callback */
+       bt_fini_sco();
+
        /* Unregister vconfkey changed callback */
        volume_control_unregister_vconfkey();
 
        /* Unregister sound vconfkey changed callback */
        volume_sound_vconfkey_unregister();
 
-       /* Unregister bt changed callback */
-       bt_deinit_sco();
 }
 
-void volume_service_region_set(Evas_Object *win, Eina_Bool is_warning_visible)
+static void _volume_service_region_set(Evas_Object *win, Evas_Object *warning_popup)
 {
        _D("X input event shape");
        Evas_Object *ly = NULL;
@@ -613,36 +598,43 @@ void volume_service_region_set(Evas_Object *win, Eina_Bool is_warning_visible)
        int current_angle = volume_control_get_current_angle();
        _D("Current angle : %d", current_angle);
 
-       ly = volume_view_outer_layout_get();
-       if (!ly) {
-               _E("Failed to load edje");
-               return;
-       }
+       if (!warning_popup) {
+               ly = volume_view_outer_layout_get();
+               if (!ly) {
+                       _E("Failed to load edje");
+                       return;
+               }
 
-       edje_object_part_geometry_get(_EDJ(ly), "bg", &x, &y, &w, &h);
-       _D("The position of bg x: %d, y: %d, w: %d, h: %d", x, y, w, h);
+               edje_object_part_geometry_get(_EDJ(ly), "bg", &x, &y, &w, &h);
+               _D("The position of bg x: %d, y: %d, w: %d, h: %d", x, y, w, h);
 
-       if (current_angle == 90) {
-               tmp_x = x;
-               tmp_y = y;
-               tmp_w = w;
-               tmp_h = h;
+               if (current_angle == 90) {
+                       tmp_x = x;
+                       tmp_y = y;
+                       tmp_w = w;
+                       tmp_h = h;
 
-               x = tmp_y;
-               y = tmp_x;
-               w = tmp_h;
-               h = tmp_w;
-       }
-       else if (current_angle == 270) {
-               tmp_x = x;
-               tmp_y = y;
-               tmp_w = w;
-               tmp_h = h;
-
-               x = volume_control_get_viewport_width()-tmp_y-tmp_h;
-               y = tmp_x;
-               w = tmp_h;
-               h = tmp_w;
+                       x = tmp_y;
+                       y = tmp_x;
+                       w = tmp_h;
+                       h = tmp_w;
+               }
+               else if (current_angle == 270) {
+                       tmp_x = x;
+                       tmp_y = y;
+                       tmp_w = w;
+                       tmp_h = h;
+
+                       x = volume_control_get_viewport_width()-tmp_y-tmp_h;
+                       y = tmp_x;
+                       w = tmp_h;
+                       h = tmp_w;
+               }
+       } else {
+               x = 0;
+               y = 0;
+               w = 720;
+               h = 1280;
        }
 
        rect = tzsh_region_create(tzsh);
@@ -672,22 +664,14 @@ static void _rotate_changed_cb(void *data, Evas_Object *obj, void *event_info)
                case 270 :
                        _D("show,landscape");
                        elm_object_signal_emit(ly_outer, "show,landscape", "bg");
-                       if(control_info.is_warning_visible)
-                       {
-                               elm_object_signal_emit(ly_outer, "show_warning_l", "clipper");
-                       }
                        break;
                default :
                        _D("show,portrait");
                        elm_object_signal_emit(ly_outer, "show,portrait", "bg");
-                       if(control_info.is_warning_visible)
-                       {
-                               elm_object_signal_emit(ly_outer, "show_warning", "clipper");
-                       }
                        break;
                }
 
-               volume_service_region_set(obj, control_info.is_warning_visible);
+               _volume_service_region_set(obj, volume_view_warning_popup_get());
        }
 }
 
@@ -763,6 +747,10 @@ static void _idle_lock_state_vconf_changed_cb(keynode_t *key, void *data)
 
 static void _notify_pm_lcdoff_cb(keynode_t * node, void *data)
 {
+       if (volume_view_warning_popup_get()) {
+               volume_view_destroy_warning_popup();
+       }
+
        if(VOLUME_ERROR_OK != volume_control_hide_view())
        {
                _E("Failed to close volume");
diff --git a/src/earphone.c b/src/earphone.c
new file mode 100644 (file)
index 0000000..c0386a1
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "main.h"
+#include "_util_log.h"
+
+int earphone_is_connected;
+
+static void _volume_earphone_changed_cb(keynode_t *node, void *data)
+{
+       int status = 0;
+       int ret;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_EARJACK, &status);
+       if (ret < 0) {
+               return;
+       }
+
+       switch (status) {
+               case VCONFKEY_SYSMAN_EARJACK_3WIRE:
+               case VCONFKEY_SYSMAN_EARJACK_4WIRE:
+               case VCONFKEY_SYSMAN_EARJACK_TVOUT:
+                       _D("Earphone is connected");
+                       earphone_is_connected = 1;
+                       break;
+               default:
+                       _D("Earphone is disconnected");
+                       earphone_is_connected = 0;
+                       break;
+       }
+}
+
+static int register_earphone_module(void *data)
+{
+       int ret;
+
+       ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_EARJACK, _volume_earphone_changed_cb, NULL);
+       if (ret < 0) {
+               _E("Failed to set earphone changed callback");
+               return VOLUME_ERROR_FAIL;
+       }
+
+       _volume_earphone_changed_cb(NULL, NULL);
+
+       return VOLUME_ERROR_OK;
+}
+
+static int deregister_earphone_module(void *data)
+{
+       int ret;
+
+       ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_EARJACK, _volume_earphone_changed_cb);
+       if (ret < 0) {
+               _E("Failed to set earphone changed callback");
+               return VOLUME_ERROR_FAIL;
+       }
+
+       return VOLUME_ERROR_OK;
+}
+
+void earphone_init(void)
+{
+       _D("Initialization Earphone");
+
+       int ret;
+
+       ret = register_earphone_module(NULL);
+       _D("Initializaion result: %d", ret);
+}
+
+void earphone_fini(void)
+{
+       _D("Deinitialization Earphone");
+       int ret;
+
+       ret = deregister_earphone_module(NULL);
+       _D("Deinitialization result: %d", ret);
+}
+
+int earphone_get_earphone_is_connected(void)
+{
+       return earphone_is_connected;
+}
index 4d0b8b9..82816bb 100755 (executable)
@@ -21,6 +21,7 @@
 #include <bluetooth.h>
 #include <bluetooth_internal.h>
 #include <bluetooth_extension.h>
+#include <device/display.h>
 
 #include "main.h"
 #include "_util_log.h"
 #include "timer.h"
 #include "key_event.h"
 #include "bt.h"
+#include "earphone.h"
 
 #define VCONFKEY_ALARM_VOLUME_POPUP_ENABLE  "memory/alarm/volume_popup_enable"
 #define VOLUME_INPUT_WIN_NAME "volumekey-input-window"
+#define SAFETY_LIMIT 9
 
 struct _key_event_s_info {
        Ecore_X_Window input_win;
@@ -68,8 +71,8 @@ static struct _key_event_s_info key_event_info = {
 static Eina_Bool _key_release_cb(void *data, int type, void *event);
 static Eina_Bool _key_press_cb(void *data, int type, void *event);
 static volume_error_e _volume_popup_check_in_alarm_type(sound_type_e sound_type);
-static volume_error_e _volume_down_key_press(sound_type_e sound_type, int sound, bool bt_opened);
-static volume_error_e _volume_up_key_press(sound_type_e sound_type, int sound, bool bt_opened);
+static volume_error_e _volume_down_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected);
+static volume_error_e _volume_up_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected);
 static volume_error_e _mute_key_press();
 
 Ecore_Event_Handler* volume_key_event_handler_volume_up_get(void)
@@ -114,6 +117,7 @@ static volume_error_e _mute_key_press()
        int status = 0;
        int sound = 0;
        int error = 0;
+       int earphone_connected = 0;
        bool bt_opened = false;
        sound_type_e sound_type = 0;
 
@@ -124,12 +128,15 @@ static volume_error_e _mute_key_press()
        _D("sound status : %d", sound);
 
        error = bt_ag_is_sco_opened(&bt_opened);
-       if(error != BT_ERROR_NONE)
+       if(error != BT_ERROR_NONE) {
                _E("bt_ag_is_sco_opened return [%d]", error);
+       }
+
+       earphone_connected = earphone_get_earphone_is_connected();
 
-       _D("BT state %d", bt_opened);
+       _D("BT state %d, Earphone state: %d", bt_opened, earphone_connected);
 
-       volume_control_show_view(status, sound_type, sound, bt_opened);
+       volume_control_show_view(status, sound_type, sound, bt_opened, earphone_connected);
 
        if (sound_type == SOUND_TYPE_MEDIA) {
                if (key_event_info.is_mute == EINA_FALSE) {
@@ -168,7 +175,7 @@ static volume_error_e _mute_key_press()
        }
 }
 
-static volume_error_e _volume_up_key_press(sound_type_e sound_type, int sound, bool bt_opened)
+static volume_error_e _volume_up_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected)
 {
        int sound_step = 0;
        int sound_level = 0;
@@ -247,6 +254,37 @@ static volume_error_e _volume_up_key_press(sound_type_e sound_type, int sound, b
                }
        }
        else {
+               if (sound_type == SOUND_TYPE_MEDIA && (bt_opened || earphone_connected) && sound_level + 1 > SAFETY_LIMIT) {
+                       if (volume_control_get_safety_limit()) {
+                               display_state_e state;
+                               if (device_display_get_state(&state) != DEVICE_ERROR_NONE) {
+                                       _E("Failed to get display state");
+                               }
+                               if (state == DISPLAY_STATE_SCREEN_OFF || state == DISPLAY_STATE_SCREEN_DIM) {
+                                       device_display_change_state(DISPLAY_STATE_NORMAL);
+                                       if(FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_VIBRATION_ON)) {
+                                               _E("Failed to play vibration");
+                                       }
+                               }
+                               if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_TRUE)) {
+                                       _E("Failed to set warning status");
+                               }
+                               if (status == LOCK_AND_MEDIA) {
+                                       /* Check LCD */
+                                       volume_view_window_show(sound_type);
+                               }
+                               volume_sound_level_set(sound_type, SAFETY_LIMIT);
+                               volume_view_slider_value_set(SAFETY_LIMIT);
+                               if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
+                                       _E("Failed to open waring popup!!");
+                                       return VOLUME_ERROR_FAIL;
+                               }
+                               volume_timer_del(TYPE_TIMER_SU);
+                               volume_timer_del(TYPE_TIMER_SD);
+                               volume_timer_add(10.0, TYPE_TIMER_WARNING_POPUP);
+                               return VOLUME_ERROR_OK;
+                       }
+               }
                if (sound_level != sound_step) {
                        volume_sound_level_set(sound_type, sound_level+1);
                        volume_view_slider_value_set(sound_level+1);
@@ -269,7 +307,7 @@ static volume_error_e _volume_up_key_press(sound_type_e sound_type, int sound, b
        return VOLUME_ERROR_OK;
 }
 
-static volume_error_e _volume_down_key_press(sound_type_e sound_type, int sound, bool bt_opened)
+static volume_error_e _volume_down_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected)
 {
        key_event_info.is_mute = EINA_FALSE;
 
@@ -331,7 +369,35 @@ static volume_error_e _volume_down_key_press(sound_type_e sound_type, int sound,
        }
        /* Sound type is not ringtone. Need to adjust sound level */
        else {
-               if (val != 0) {
+               if (volume_control_get_safety_limit() && sound_type == SOUND_TYPE_MEDIA
+                       && (bt_opened || earphone_connected) && val > SAFETY_LIMIT) {
+                       display_state_e state;
+                       if (device_display_get_state(&state) != DEVICE_ERROR_NONE) {
+                               _E("Failed to get display state");
+                       }
+                       if (state == DISPLAY_STATE_SCREEN_OFF || state == DISPLAY_STATE_SCREEN_DIM) {
+                               device_display_change_state(DISPLAY_STATE_NORMAL);
+                               if(FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_VIBRATION_ON)) {
+                                       _E("Failed to play vibration");
+                               }
+                       }
+                       if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_TRUE)) {
+                               _E("Failed to set warning status");
+                       }
+                       if (status == LOCK_AND_MEDIA) {
+                               /* Check LCD */
+                               volume_view_window_show(sound_type);
+                       }
+                       volume_sound_level_set(sound_type, SAFETY_LIMIT);
+                       volume_view_slider_value_set(SAFETY_LIMIT);
+                       if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
+                               _E("Failed to open waring popup!!");
+                               return VOLUME_ERROR_FAIL;
+                       }
+                       volume_timer_del(TYPE_TIMER_SU);
+                       volume_timer_del(TYPE_TIMER_SD);
+                       volume_timer_add(10.0, TYPE_TIMER_WARNING_POPUP);
+               } else if (val != 0) {
                        volume_sound_level_set(sound_type, val - 1);
                        volume_view_slider_value_set(val - 1);
                        _D("new sound value: %d", val-1);
@@ -376,6 +442,7 @@ static Eina_Bool _key_press_cb(void *data, int type, void *event)
        int key_status = 0;
        int status = 0;
        int error = 0;
+       int earphone_connected = 0;
        bool bt_opened = false;
        sound_type_e sound_type = 0;
        Evas_Object *win = NULL;
@@ -389,6 +456,16 @@ static Eina_Bool _key_press_cb(void *data, int type, void *event)
        win = volume_view_win_get();
        retv_if(!win, ECORE_CALLBACK_CANCEL);
 
+       if (volume_view_warning_popup_get()) {
+               _D("Safety warning popup is exist");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       if (!volume_control_get_safety_limit() && volume_control_get_time_for_safety_limit()) {
+               _D("Already passed 20 hour after checking warning popup, open warning again");
+               volume_control_set_safety_limit(EINA_TRUE);
+       }
+
        if(!strncmp(ev->keyname, KEY_CANCEL, strlen(KEY_CANCEL)) || !strncmp(ev->keyname, KEY_BACK, strlen(KEY_BACK))) {
                _D("%s is pressed", ev->keyname);
                return ECORE_CALLBACK_CANCEL;
@@ -431,28 +508,29 @@ static Eina_Bool _key_press_cb(void *data, int type, void *event)
        _D("sound status : %d", sound);
 
        error = bt_ag_is_sco_opened(&bt_opened);
-       if(error != BT_ERROR_NONE)
+       if(error != BT_ERROR_NONE) {
                _E("bt_ag_is_sco_opened return [%d]", error);
-
-       _D("BT state %d", bt_opened);
+       }
+       earphone_connected = earphone_get_earphone_is_connected();
+       _D("module state - bt: %d, earphone: %d", bt_opened, earphone_connected);
 
        if(VOLUME_ERROR_OK != _volume_popup_check_in_alarm_type(sound_type)) {
                _E("Failed to set volume popup");
                return ECORE_CALLBACK_CANCEL;
        }
 
-       volume_control_show_view(status, sound_type, sound, bt_opened);
+       volume_control_show_view(status, sound_type, sound, bt_opened, earphone_connected);
 
        key_event_info.is_pressing = EINA_TRUE;
 
        volume_timer_del(TYPE_TIMER_POPUP);
 
        if (!strncmp(ev->keyname, KEY_VOLUMEUP, strlen(KEY_VOLUMEUP))) {
-               if(VOLUME_ERROR_OK != _volume_up_key_press(sound_type, sound, bt_opened))
+               if(VOLUME_ERROR_OK != _volume_up_key_press(status, sound_type, sound, bt_opened, earphone_connected))
                        _E("Failed to press volume up key");
        }
        else if (!strncmp(ev->keyname, KEY_VOLUMEDOWN, strlen(KEY_VOLUMEDOWN))) {
-               if(VOLUME_ERROR_OK != _volume_down_key_press(sound_type, sound, bt_opened))
+               if(VOLUME_ERROR_OK != _volume_down_key_press(status, sound_type, sound, bt_opened, earphone_connected))
                        _E("Failed to press volume down key");
        }
 
@@ -495,8 +573,11 @@ static Eina_Bool _key_release_cb(void *data, int type, void *event)
 
        volume_timer_del(TYPE_TIMER_POPUP);
 
-       if(volume_view_is_slider_touching_get() == EINA_FALSE)
-               volume_timer_add(3.0, TYPE_TIMER_POPUP);
+       if(volume_view_is_slider_touching_get() == EINA_FALSE) {
+               if (!volume_view_warning_popup_get()) {
+                       volume_timer_add(3.0, TYPE_TIMER_POPUP);
+               }
+       }
 
        _D("key release fini");
        return ECORE_CALLBACK_CANCEL;
index 1661cee..696c951 100755 (executable)
@@ -234,8 +234,9 @@ void volume_sound_change_set(int val)
 
                volume_sound_play();
        } else {
-               if (sound_type != SOUND_TYPE_MEDIA)
+               if (sound_type != SOUND_TYPE_MEDIA) {
                        volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 0);
+               }
                volume_view_slider_value_set(0);
                volume_sound_level_set(sound_type, 0);
 
index c8bd61c..c8986b3 100755 (executable)
 
 #include <vconf.h>
 #include <vconf-keys.h>
+#include <bluetooth.h>
+#include <bluetooth_internal.h>
+#include <bluetooth_extension.h>
+#include <vconf-keys.h>
+#include <device/display.h>
+#include <feedback.h>
 
 #include "main.h"
 #include "_util_log.h"
@@ -23,6 +29,9 @@
 #include "control.h"
 #include "sound.h"
 #include "timer.h"
+#include "key_event.h"
+#include "bt.h"
+#include "earphone.h"
 
 #define DEL_TIMER(x) \
        if (x) {\
@@ -44,6 +53,7 @@ struct _timer_s_info {
        Ecore_Timer *lu_timer; /* long up timer */
        Ecore_Timer *ld_timer; /* long down timer */
        Ecore_Timer *bt_timer; /* long down timer */
+       Ecore_Timer *warning_popup_timer; /* long down timer */
 };
 
 static struct _timer_s_info timer_info = {
@@ -54,6 +64,7 @@ static struct _timer_s_info timer_info = {
        .lu_timer = NULL,
        .ld_timer = NULL,
        .bt_timer = NULL,
+       .warning_popup_timer = NULL,
 };
 
 static Eina_Bool _timer_short_down_cb(void *data);
@@ -61,6 +72,7 @@ static Eina_Bool _timer_short_up_cb(void *data);
 static Eina_Bool _timer_slider_cb(void *data);
 static Eina_Bool _timer_popup_cb(void *data);
 static Eina_Bool _timer_bt_cb(void *data);
+static Eina_Bool _timer_warning_popup_cb(void *data);
 
 Ecore_Timer *volume_timer_bt_timer_get(void)
 {
@@ -89,7 +101,7 @@ Ecore_Timer *volume_timer_sd_timer_get(void)
 
 void volume_timer_add(double time, volume_timer_type type)
 {
-       _D("VOLUME TIMER ADD");
+       _D("VOLUME TIMER ADD: %d", type);
        if (type == TYPE_TIMER_POPUP) {
                ADD_TIMER(timer_info.popup_timer, time, _timer_popup_cb, NULL);
        } else if (type == TYPE_TIMER_SLIDER) {
@@ -100,6 +112,8 @@ void volume_timer_add(double time, volume_timer_type type)
                ADD_TIMER(timer_info.su_timer, time, _timer_short_up_cb, NULL);
        } else if (type == TYPE_TIMER_BT) {
                ADD_TIMER(timer_info.bt_timer, time, _timer_bt_cb, NULL);
+       } else if (type == TYPE_TIMER_WARNING_POPUP) {
+               ADD_TIMER(timer_info.warning_popup_timer, time, _timer_warning_popup_cb, NULL);
        } else {
                _E("Failed to get type : type error(%d)", type);
                return;
@@ -108,6 +122,7 @@ void volume_timer_add(double time, volume_timer_type type)
 
 void volume_timer_del(volume_timer_type type)
 {
+       _D("volume timer del: %d", type);
        if (type == TYPE_TIMER_POPUP) {
                DEL_TIMER(timer_info.popup_timer);
        } else if (type == TYPE_TIMER_SLIDER) {
@@ -118,6 +133,8 @@ void volume_timer_del(volume_timer_type type)
                DEL_TIMER(timer_info.su_timer);
        } else if (type == TYPE_TIMER_BT) {
                DEL_TIMER(timer_info.bt_timer);
+       } else if (type == TYPE_TIMER_WARNING_POPUP) {
+               DEL_TIMER(timer_info.warning_popup_timer);
        } else {
                _E("Failed to get type : type error(%d)", type);
                return;
@@ -144,6 +161,18 @@ static Eina_Bool _timer_popup_cb(void *data)
        return ECORE_CALLBACK_CANCEL;
 }
 
+static Eina_Bool _timer_warning_popup_cb(void *data)
+{
+       volume_view_destroy_warning_popup();
+
+       if (VOLUME_ERROR_OK != volume_control_hide_view())
+               _E("Failed to close volume");
+       if (VOLUME_ERROR_OK != volume_control_cache_flush())
+               _E("Failed to flush cache");
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
 static Eina_Bool _timer_slider_cb(void *data)
 {
        Evas_Object *slider = volume_view_slider_get();
@@ -195,6 +224,10 @@ static Eina_Bool _timer_slider_cb(void *data)
 static Eina_Bool _timer_short_up_cb(void *data)
 {
        _D("volume is in LongPress");
+       bool bt_opened = false;
+       int error = 0;
+       int earphone_connected = 0;
+
        Evas_Object *win = volume_view_win_get();
        if (!win) {
                _E("Window is NULL");
@@ -228,6 +261,48 @@ static Eina_Bool _timer_short_up_cb(void *data)
        }
        _D("sound value : %d", val);
 
+       error = bt_ag_is_sco_opened(&bt_opened);
+       if(error != BT_ERROR_NONE) {
+               _E("bt_ag_is_sco_opened return [%d]", error);
+       }
+       earphone_connected = earphone_get_earphone_is_connected();
+       _D("module state - bt: %d, earphone: %d", bt_opened, earphone_connected);
+
+       if (sound_type == SOUND_TYPE_MEDIA && (bt_opened || earphone_connected) && val + 1 > SAFETY_LIMIT) {
+               if (volume_control_get_safety_limit()) {
+                       sound_type_e type = 0;
+                       display_state_e state;
+                       int lock = IDLELOCK_ON;
+                       int status = volume_control_check_status(&lock, &type);
+                       if (device_display_get_state(&state) != DEVICE_ERROR_NONE) {
+                               _E("Failed to get display state");
+                       }
+                       if (state == DISPLAY_STATE_SCREEN_OFF || state == DISPLAY_STATE_SCREEN_DIM) {
+                               device_display_change_state(DISPLAY_STATE_NORMAL);
+                               if(FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_VIBRATION_ON)) {
+                                       _E("Failed to play vibration");
+                               }
+                       }
+                       if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_TRUE)) {
+                               _E("Failed to set warning status");
+                       }
+                       if (status == LOCK_AND_MEDIA) {
+                               /* Check LCD */
+                               volume_view_window_show(sound_type);
+                       }
+                       volume_sound_level_set(sound_type, SAFETY_LIMIT);
+                       volume_view_slider_value_set(SAFETY_LIMIT);
+                       if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
+                               _E("Failed to open waring popup!!");
+                               return VOLUME_ERROR_FAIL;
+                       }
+                       volume_timer_del(TYPE_TIMER_SU);
+                       volume_timer_del(TYPE_TIMER_SD);
+                       volume_timer_add(10.0, TYPE_TIMER_WARNING_POPUP);
+                       return VOLUME_ERROR_OK;
+               }
+       }
+
        if (val == sound_step) {
                _D("already sound value : %d", sound_step);
                return ECORE_CALLBACK_RENEW;
index bf28250..093053e 100755 (executable)
@@ -38,6 +38,7 @@ struct _view_s_info {
        Evas_Object *icon_volume;
        Evas_Object *icon_setting;
        Evas_Object *slider;
+       Evas_Object *warning_popup;
 
        Evas_Object *lockscreen_splash;
 
@@ -57,6 +58,7 @@ static struct _view_s_info view_info = {
        .icon_volume = NULL,
        .icon_setting = NULL,
        .slider = NULL,
+       .warning_popup = NULL,
 
        .lockscreen_splash = NULL,
 
@@ -119,6 +121,11 @@ Evas_Object* volume_view_slider_get(void)
        return view_info.slider;
 }
 
+Evas_Object* volume_view_warning_popup_get(void)
+{
+       return view_info.warning_popup;
+}
+
 Eina_Bool volume_view_is_registered_callback_get(void)
 {
        return view_info.is_registered_callback;
@@ -191,12 +198,20 @@ int volume_mute_toggle_set()
        }
 }
 
-volume_error_e volume_change_slider_max_value(sound_type_e type)
+volume_error_e volume_view_change_slider_by_type(sound_type_e type, bool bt_opened, int earphone_connected)
 {
-       _D("Slider max change for state: %d", type);
+       _D("Slider change for state: %d", type);
        int ret = 0;
        int step = 0;
 
+       if (type == SOUND_TYPE_MEDIA && (bt_opened || earphone_connected)) {
+               _D("=Change to warning slider=");
+               elm_object_style_set(view_info.slider, "warning");
+       } else {
+               _D("=Change to normal slider=");
+               elm_object_style_set(view_info.slider, "default");
+       }
+
        ret = sound_manager_get_max_volume(type, &step);
        if (ret < 0) {
                _E("Failed to get max volume for sound_type: %d", type);
@@ -211,6 +226,65 @@ volume_error_e volume_change_slider_max_value(sound_type_e type)
        return VOLUME_ERROR_OK;
 }
 
+static void _cancel_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       volume_view_destroy_warning_popup();
+}
+
+static void _ok_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       _D("Increase button is clicked");
+       volume_control_set_safety_limit(EINA_FALSE);
+       volume_control_set_time_for_safety_limit();
+
+       volume_view_destroy_warning_popup();
+}
+
+volume_error_e volume_view_open_warning_popup(void)
+{
+       Evas_Object *popup = NULL;
+       Evas_Object *cancel_btn = NULL;
+       Evas_Object *ok_btn = NULL;
+
+       popup = elm_popup_add(view_info.win);
+       elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
+       evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_object_text_set(popup, "Listening at a high volume for a long time may damage your hearing. The volume will be increaed above safe levels.");
+
+       cancel_btn = elm_button_add(popup);
+       elm_object_style_set(cancel_btn, "popup");
+       elm_object_text_set(cancel_btn, "Cancel");
+       elm_object_part_content_set(popup, "button2", cancel_btn);
+       evas_object_smart_callback_add(cancel_btn, "clicked", _cancel_clicked_cb, popup);
+
+       ok_btn = elm_button_add(popup);
+       elm_object_style_set(ok_btn, "popup");
+       elm_object_text_set(ok_btn, "Increase");
+       elm_object_part_content_set(popup, "button1", ok_btn);
+       evas_object_smart_callback_add(ok_btn, "clicked", _ok_clicked_cb, popup);
+
+       view_info.warning_popup = popup;
+       evas_object_show(popup);
+
+       return VOLUME_ERROR_OK;
+}
+
+void volume_view_destroy_warning_popup(void)
+{
+       _D("Destroy warning popup");
+       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;
+
+       if (VOLUME_ERROR_OK != volume_control_hide_view())
+               _E("Failed to close volume");
+       if (VOLUME_ERROR_OK != volume_control_cache_flush())
+               _E("Failed to flush cache");
+}
+
 volume_error_e volume_view_slider_value_set(int val)
 {
        _D("Slider value set : %d", val);
@@ -269,8 +343,6 @@ void volume_view_volume_icon_set(sound_type_e sound_type, int sound, int vibrati
                break;
        }
 
-       volume_view_set_default_slider();
-
        _D("img : %s", img);
        elm_image_file_set(view_info.icon_volume, EDJ_APP, img);
 }
@@ -333,6 +405,29 @@ Evas_Object *add_slider(Evas_Object *parent, int min, int max, int val)
        return slider;
 }
 
+volume_error_e volume_view_send_warning_signal(Eina_Bool warning)
+{
+       if (warning) {
+               _D("Show warning popup, and hide volume popup");
+               elm_object_signal_emit(view_info.ly_outer, "show,warning", "bg");
+       } 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;
+        }
+       }
+       return VOLUME_ERROR_OK;
+}
+
 volume_error_e volume_view_window_show(sound_type_e type)
 {
        _D("Volume view window SHOW is [%p]", view_info.win);