Apply consistent log messages.
[platform/core/system/system-popup.git] / src / overheat / overheat.c
1 /*
2  *  system-popup
3  *
4  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18 */
19
20 #include "popup-common.h"
21
22 #define BUF_MAX 512
23 #define SYSTEMD_STOP_POWER_OFF 4
24
25 #define DEVICED_BUS_NAME        "org.tizen.system.deviced"
26 #define REBOOT_OBJECT_PATH     "/Org/Tizen/System/DeviceD/Reboot"
27 #define REBOOT_INTERFACE_NAME  DEVICED_BUS_NAME".reboot"
28
29 #define REBOOT_METHOD            "reboot"
30 #define REBOOT_OPERATION_OFF     "poweroff"
31
32 /* Overheat Timer*/
33 #define OVERHEAT_BUS_NAME              "org.tizen.system.popup"
34 #define OVERHEAT_OBJECT_PATH           "/Org/Tizen/System/Popup"
35 #define OVERHEAT_INTERFACE_NAME        OVERHEAT_BUS_NAME
36 #define OVERHEAT_PATH                   OVERHEAT_OBJECT_PATH"/Overheat"
37 #define OVERHEAT_INTERFACE              OVERHEAT_INTERFACE_NAME".Overheat"
38 #define SIGNAL_OVERHEAT_TIME            "TimeUpdate"
39
40 #define OVERTEMP_TIMEOUT  30
41
42 static int overtemp_timer = OVERTEMP_TIMEOUT;
43 static Evas_Object *timer_label;
44
45 static const struct popup_ops overheat_ops;
46 static const struct popup_ops overheat_poweroff_warning_ops;
47 static const struct popup_ops remove_overheat_popups_ops;
48 static void register_handlers(const struct popup_ops *ops);
49 static void unregister_handlers(const struct popup_ops *ops);
50 static void overheat_poweroff(const struct popup_ops *ops);
51 static int overheat_launch(bundle *b, const struct popup_ops *ops);
52 static void overheat_poweroff_warning_terminate(const struct popup_ops *ops);
53 static int add_dbus_signal_handler(const struct popup_ops *ops);
54 static void remove_dbus_signal_handler(void);
55 static __attribute__ ((constructor)) void overheat_register_popup(void);
56 static E_DBus_Signal_Handler *overheat_sig_handler = NULL;
57
58 static char *items[] = {
59         "IDS_IDLE_HEADER_PHONE_OVERHEATING_ABB",
60         "IDS_QP_POP_YOUR_DEVICE_IS_OVERHEATING_IT_WILL_NOW_POWER_OFF_TO_COOL_DOWN",
61         "IDS_IDLE_POP_PD_SECONDS_ARE_LEFT_BEFORE_YOUR_DEVICE_POWERS_OFF",
62         "IDS_ST_BUTTON_TURN_OFF_NOW",
63         "IDS_COM_SK_CANCEL"
64 };
65
66 char* gl_text_get(int index)
67 {
68         char *text = NULL, buffer[BUF_MAX] = {'\0',};
69
70         if (index == 2) {
71                 text = _(items[2]);
72                 snprintf(buffer, sizeof(buffer), text, overtemp_timer);
73
74                 return strdup(buffer);
75         } else return strdup(_(items[index]));
76 }
77
78 static void
79 _popup_turnoff_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
80 {
81         const struct popup_ops *ops = data;
82
83         overheat_poweroff(ops);
84 }
85
86 static void
87 _popup_cancel_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
88 {
89         const struct popup_ops *ops = data;
90         bundle *b = NULL;
91
92         unload_simple_popup(ops);
93         load_simple_popup(b, &overheat_poweroff_warning_ops);
94 }
95
96 static void update_overtemp_time(void *data, DBusMessage *msg)
97 {
98         DBusError err;
99         int time = 0;
100         int ret;
101
102         ret = dbus_message_is_signal(msg, OVERHEAT_INTERFACE, SIGNAL_OVERHEAT_TIME);
103         if (!ret) {
104                 _E("No overheat SIG.");
105                 return;
106         }
107
108         dbus_error_init(&err);
109         if (dbus_message_get_args(msg, &err,
110                 DBUS_TYPE_INT32, &time,
111                 DBUS_TYPE_INVALID) == 0) {
112                 dbus_error_free(&err);
113                 return;
114         }
115         dbus_error_free(&err);
116
117         overtemp_timer = time;
118         elm_object_text_set(timer_label, gl_text_get(2));
119         if (!overtemp_timer)
120                 remove_dbus_signal_handler();
121 }
122
123 static void unregister_handlers(const struct popup_ops *ops)
124 {
125         return;
126 }
127
128 static void register_handlers(const struct popup_ops *ops)
129 {
130         return;
131 }
132
133 static void overheat_poweroff(const struct popup_ops *ops)
134 {
135         static int bPowerOff = 0;
136         char *param[2];
137         char data[8];
138         int ret;
139
140         if (bPowerOff == 1)
141                 return;
142         bPowerOff = 1;
143
144         unload_simple_popup(ops);
145
146         param[0] = REBOOT_OPERATION_OFF;
147         snprintf(data, sizeof(data), "0");
148         param[1] = data;
149         ret = popup_dbus_method_sync(DEVICED_BUS_NAME,
150                         REBOOT_OBJECT_PATH,
151                         REBOOT_INTERFACE_NAME,
152                         REBOOT_METHOD,
153                         "si", param);
154         if (ret < 0)
155                 _E("Failed to request poweroff to deviced: %d", ret);
156 }
157
158 static int overheat_poweroff_warning_launch(bundle *b, const struct popup_ops *ops)
159 {
160         register_handlers(ops);
161         return 0;
162 }
163
164 static int add_dbus_signal_handler(const struct popup_ops *ops)
165 {
166         E_DBus_Connection *conn;
167
168         conn = get_dbus_connection();
169         if (!conn) {
170                 _E("Failed to get dbus connection.");
171                 return -ENOMEM;
172         }
173
174         overheat_sig_handler = e_dbus_signal_handler_add(
175                         conn, NULL,
176                         OVERHEAT_PATH,
177                         OVERHEAT_INTERFACE,
178                         SIGNAL_OVERHEAT_TIME,
179                         update_overtemp_time,
180                         (void *)ops);
181         if (!overheat_sig_handler) {
182                 _E("Failed to add signal handler.");
183                 return -ENOMEM;
184         }
185
186         return 0;
187 }
188
189 static void remove_dbus_signal_handler(void)
190 {
191         E_DBus_Connection *conn;
192
193         if (!overheat_sig_handler) {
194                 _E("No available sig handler for overheat.");
195                 return;
196         }
197
198         conn = get_dbus_connection();
199         if (!conn) {
200                 overheat_sig_handler = NULL;
201                 _E("No Dbus connection for overheat sig.");
202                 return;
203         }
204
205         e_dbus_signal_handler_del(conn, overheat_sig_handler);
206         overheat_sig_handler = NULL;
207 }
208
209 static int overheat_launch(bundle *b, const struct popup_ops *ops)
210 {
211         int ret;
212
213         register_handlers(ops);
214
215         ret = add_dbus_signal_handler(ops);
216         if (ret < 0)
217                 _E("Failed to add dbus handler: %d", ret);
218
219         return 0;
220 }
221
222 static void overheat_terminate(const struct popup_ops *ops)
223 {
224         unregister_handlers(ops);
225         remove_dbus_signal_handler();
226 }
227
228 static void overheat_poweroff_warning_terminate(const struct popup_ops *ops)
229 {
230         unregister_handlers(ops);
231 }
232
233 static bool overheat_skip(bundle *b, const struct popup_ops *ops)
234 {
235         struct object_ops *obj;
236         int ret;
237
238         ret = get_object_by_ops(&overheat_ops, &obj);
239         if (ret == 0 && obj->popup)
240                 return true;
241
242         ret = get_object_by_ops(&overheat_poweroff_warning_ops, &obj);
243         if (ret == 0 && obj->popup)
244                 return true;
245
246         return false;
247 }
248
249 int overheat_popup(bundle *b, const struct popup_ops *ops)
250 {
251         Evas_Object *popup;
252         Evas_Object *layout;
253         Evas_Object *btn;
254         Evas_Object *progressbar;
255         Evas_Object *scroller1, *scroller2;
256         Evas_Object *label1;
257         Evas_Object *win;
258         struct object_ops *obj;
259         int ret;
260
261         ret = get_object_by_ops(ops, &obj);
262         if (ret < 0) {
263                 _E("Failed to get object: %d", ret);
264                 return -EINVAL;
265         }
266
267         win = get_window();
268         if (!win)
269                 return -ENOMEM;
270
271         evas_object_show(win);
272
273         popup = elm_popup_add(win);
274         if (!popup)
275                 return -ENOMEM;
276
277         /* title */
278         elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
279         elm_object_part_text_set(popup, "title,text", gl_text_get(0));
280         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
281
282         /* layout */
283         layout = elm_layout_add(popup);
284         elm_layout_file_set(layout, ELM_OVERHEAT_EDC, "overheat_view_layout");
285         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
286
287         /* cancel button */
288         btn = elm_button_add(popup);
289         elm_object_style_set(btn, "bottom");
290         elm_object_text_set(btn, gl_text_get(4));
291         elm_object_part_content_set(popup, "button1", btn);
292         evas_object_smart_callback_add(btn, "clicked", _popup_cancel_btn_clicked_cb, ops);
293
294         /* turn off button */
295         btn = elm_button_add(popup);
296         elm_object_style_set(btn, "bottom");
297         elm_object_text_set(btn, gl_text_get(3));
298         elm_object_part_content_set(popup, "button2", btn);
299         evas_object_smart_callback_add(btn, "clicked", _popup_turnoff_btn_clicked_cb, ops);
300
301         /* back key */
302         eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, event_back_key_up, (void*)ops);
303
304         /* scrollers */
305         scroller1 = elm_scroller_add(layout);
306         elm_scroller_bounce_set(scroller1, EINA_TRUE, EINA_TRUE);
307         elm_scroller_policy_set(scroller1, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
308         elm_object_part_content_set(layout, "elm.swallow.content1", scroller1);
309
310         scroller2 = elm_scroller_add(layout);
311         elm_scroller_bounce_set(scroller2, EINA_TRUE, EINA_TRUE);
312         elm_scroller_policy_set(scroller2, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
313         elm_object_part_content_set(layout, "elm.swallow.content2", scroller2);
314
315         /* labels */
316         label1 = elm_label_add(scroller1);
317         elm_object_style_set(label1, "popup/default");
318         elm_label_line_wrap_set(label1, ELM_WRAP_MIXED);
319         elm_object_text_set(label1, gl_text_get(1));
320         evas_object_size_hint_weight_set(label1, EVAS_HINT_EXPAND, 0.0);
321         evas_object_size_hint_align_set(label1, EVAS_HINT_FILL, EVAS_HINT_FILL);
322         evas_object_show(label1);
323         elm_object_content_set(scroller1, label1);
324
325         timer_label = elm_label_add(scroller2);
326         elm_object_style_set(timer_label, "popup/default");
327         elm_label_line_wrap_set(timer_label, ELM_WRAP_MIXED);
328         elm_object_text_set(timer_label, gl_text_get(2));
329
330         evas_object_size_hint_weight_set(timer_label, EVAS_HINT_EXPAND, 0.0);
331         evas_object_size_hint_align_set(timer_label, EVAS_HINT_FILL, EVAS_HINT_FILL);
332         evas_object_show(timer_label);
333         elm_object_content_set(scroller2, timer_label);
334
335         /* progressbar */
336         progressbar = elm_progressbar_add(layout);
337         elm_object_style_set(progressbar, "process_large");
338         evas_object_size_hint_align_set(progressbar, EVAS_HINT_FILL, 0.5);
339         evas_object_size_hint_weight_set(progressbar, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
340         elm_progressbar_pulse(progressbar, EINA_TRUE);
341         elm_object_part_content_set(layout, "processing", progressbar);
342         evas_object_data_set(popup, "progressbar", progressbar);
343
344         elm_object_content_set(popup, layout);
345         evas_object_show(popup);
346         obj->popup = popup;
347
348         return 0;
349 }
350
351 static int remove_all_overheat_popups(bundle *b, const struct popup_ops *ops)
352 {
353         unload_simple_popup(&overheat_ops);
354         unload_simple_popup(&overheat_poweroff_warning_ops);
355         terminate_if_no_popup();
356
357         return 0;
358 }
359
360 static const struct popup_ops remove_overheat_popups_ops = {
361         .name           = "remove_overheat_popups",
362         .show           = remove_all_overheat_popups,
363 };
364
365 static const struct popup_ops overheat_ops = {
366         .name           = "overheat", //overheat first popup
367         .pattern        = FEEDBACK_PATTERN_LOWBATT,
368         .show           = overheat_popup,
369         .skip           = overheat_skip,
370         .pre            = overheat_launch,
371         .terminate  = overheat_terminate,
372 };
373
374 static const struct popup_ops overheat_poweroff_warning_ops = {
375         .name           = "overheat_poweroff_warning", //overheat second popup
376         .show           = load_simple_popup,
377         .title          = "IDS_IDLE_HEADER_PHONE_POWERING_OFF_ABB",
378         .content        = "IDS_QP_POP_YOUR_DEVICE_OVERHEATED_IT_POWERED_OFF_TO_PREVENT_DAMAGE_MSG",
379         .left_text      = "IDS_COM_SK_OK",
380         .pre            = overheat_poweroff_warning_launch,
381         .terminate  = overheat_poweroff_warning_terminate,
382 };
383
384 /* Constructor to register lowbattery button */
385 static __attribute__ ((constructor)) void overheat_register_popup(void)
386 {
387         register_popup(&overheat_ops);
388         register_popup(&overheat_poweroff_warning_ops);
389         register_popup(&remove_overheat_popups_ops);
390 }