[LICENSE] change to Flora-1.1 license
[profile/tv/apps/native/screen-reader.git] / src / smart_notification.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * This file is a modified version of BSD licensed file and
5  * licensed under the Flora License, Version 1.1 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://floralicense.org/license/
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an AS IS BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * Please, see the LICENSE file for the original copyright owner and
18  * license.
19  */
20
21 #include <Ecore.h>
22 #include <Ecore_Evas.h>
23 #include <Evas.h>
24 #include <atspi/atspi.h>
25 #include <tone_player.h>
26 #include "logger.h"
27 #include "screen_reader_tts.h"
28 #include "screen_reader_haptic.h"
29 #include "smart_notification.h"
30
31 #define RED  "\x1B[31m"
32 #define RESET "\033[0m"
33
34 static Eina_Bool status = EINA_FALSE;
35
36 static void _smart_notification_focus_chain_end(void);
37 static void _smart_notification_realized_items(int start_idx, int end_idx);
38
39 /**
40  * @brief Smart Notifications event handler
41  *
42  * @param nt Notification event type
43  * @param start_index int first visible items index smart_notification_realized_items
44  * @param end_index int last visible items index used for smart_notification_realized_items
45  */
46 void smart_notification(Notification_Type nt, int start_index, int end_index)
47 {
48    DEBUG("START");
49    if(!status)
50       return;
51
52    switch(nt)
53       {
54       case FOCUS_CHAIN_END_NOTIFICATION_EVENT:
55          _smart_notification_focus_chain_end();
56          break;
57       case REALIZED_ITEMS_NOTIFICATION_EVENT:
58          _smart_notification_realized_items(start_index, end_index);
59          break;
60       default:
61          DEBUG("Gesture type %d not handled in switch", nt);
62       }
63 }
64
65 /**
66  * @brief Used for getting first and last index of visible items
67  *
68  * @param scrollable_object AtspiAccessible object on which scroll was triggered
69  * @param start_index int first visible items index smart_notification_realized_items
70  * @param end_index int last visible items index used for smart_notification_realized_items
71  */
72 void get_realized_items_count(AtspiAccessible *scrollable_object, int *start_idx, int *end_idx)
73 {
74    DEBUG("START");
75    int count_child, jdx;
76    AtspiAccessible *child_iter;
77    AtspiStateType state =  ATSPI_STATE_SHOWING;
78
79    if(!scrollable_object)
80       {
81          DEBUG("No scrollable object");
82          return;
83       }
84
85    count_child = atspi_accessible_get_child_count(scrollable_object, NULL);
86
87    for(jdx = 0; jdx < count_child; jdx++)
88       {
89          child_iter = atspi_accessible_get_child_at_index(scrollable_object, jdx, NULL);
90          if (!child_iter) continue;
91
92          AtspiStateSet* state_set = atspi_accessible_get_state_set(child_iter);
93
94          gboolean is_visible = atspi_state_set_contains(state_set, state);
95          if(is_visible)
96             {
97                *start_idx = jdx;
98                DEBUG("Item with index %d is visible", jdx);
99             }
100          else
101             DEBUG("Item with index %d is NOT visible", jdx);
102       }
103    *end_idx = *start_idx + 8;
104 }
105
106 /**
107  * @brief Scroll-start/Scroll-end event callback
108  *
109  * @param event AtspiEvent
110  * @param user_data UNUSED
111  */
112
113 static void
114 _scroll_event_cb(AtspiEvent *event, gpointer user_data)
115 {
116    if(!status)
117       return;
118
119    int start_index, end_index;
120    start_index = 0;
121    end_index = 0;
122
123    gchar *role_name = atspi_accessible_get_role_name(event->source, NULL);
124    fprintf(stderr, "Event: %s: %d, obj: %p: role: %s\n",
125            event->type, event->detail1, event->source,
126            role_name);
127    g_free(role_name);
128
129    if (!strcmp(event->type, "object:scroll-start"))
130       {
131          DEBUG("Scrolling started");
132          tts_speak("Scrolling started", EINA_TRUE);
133       }
134    else if (!strcmp(event->type, "object:scroll-end"))
135       {
136          DEBUG("Scrolling finished");
137          tts_speak("Scrolling finished", EINA_FALSE);
138          get_realized_items_count((AtspiAccessible *)event->source, &start_index, &end_index);
139          _smart_notification_realized_items(start_index, end_index);
140       }
141 }
142
143 /**
144  * @brief Initializer for smart notifications
145  *
146  *
147  */
148 void smart_notification_init(void)
149 {
150    DEBUG("Smart Notification init!");
151
152    AtspiEventListener *listener;
153
154    listener = atspi_event_listener_new(_scroll_event_cb, NULL, NULL);
155    atspi_event_listener_register(listener, "object:scroll-start", NULL);
156    atspi_event_listener_register(listener, "object:scroll-end", NULL);
157
158    haptic_module_init();
159
160    status = EINA_TRUE;
161 }
162
163 /**
164  * @brief Smart notifications shutdown
165  *
166  */
167 void smart_notification_shutdown(void)
168 {
169    status = EINA_FALSE;
170 }
171
172 /**
173  * @brief Smart notifications focus chain event handler
174  *
175  */
176 static void _smart_notification_focus_chain_end(void)
177 {
178    if(!status)
179       return;
180
181    DEBUG(RED"Smart notification - FOCUS CHAIN END"RESET);
182
183    tone_player_stop(0);
184    tone_player_start(TONE_TYPE_SUP_CONFIRM, SOUND_TYPE_MEDIA, 200, NULL);
185 }
186
187 /**
188  * @brief Smart notifications realized items event handler
189  *
190  */
191 static void _smart_notification_realized_items(int start_idx, int end_idx)
192 {
193    if(!status)
194       return;
195
196    if(start_idx == end_idx)
197       return;
198
199    DEBUG(RED"Smart notification - Visible items notification"RESET);
200
201    char buf[256];
202
203    snprintf(buf, sizeof(buf), _("IDS_REACHED_ITEMS_NOTIFICATION"), start_idx, end_idx);
204
205    tts_speak(strdup(buf), EINA_FALSE);
206 }