4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <sys/types.h>
25 #include <device-node.h>
30 #include <vconf-keys.h>
34 #include "core/common.h"
35 #include "core/devices.h"
36 #include "core/device-notifier.h"
37 #include "core/edbus-handler.h"
38 #include "core/udev.h"
39 #include "hall/hall-handler.h"
41 #define COOL_DOWN_DBUS_INTERFACE "org.tizen.trm.siop"
42 #define COOL_DOWN_DBUS_PATH "/Org/Tizen/Trm/Siop"
43 #define COOL_DOWN_DBUS_SIGNAL "ChangedCooldownMode"
45 #define COOL_DOWN_POPUP_NAME "cooldown-syspopup"
47 #define SIGNAL_COOL_DOWN_SHUT_DOWN "ShutDown"
48 #define SIGNAL_COOL_DOWN_NOTIFICATION "Notification"
49 #define SIGNAL_COOL_DOWN_LIMIT_ACTION "LimitAction"
50 #define SIGNAL_COOL_DOWN_RELEASE "Release"
52 #define METHOD_COOL_DOWN_STATUS "GetCoolDownStatus"
53 #define METHOD_COOL_DOWN_CHANGED "CoolDownChanged"
55 #define SIGNAL_STRING_MAX_LEN 30
57 #define COOL_DOWN_LIMIT_ACTION_WAIT 60
58 #define COOL_DOWN_SHUTDOWN_POPUP_WAIT 60
59 #define COOL_DOWN_SHUTDOWN_FORCE_WAIT 30
60 #define SYSTEMD_STOP_POWER_OFF 4
62 #define VCONFKEY_SYSMAN_COOL_DOWN_MODE "db/private/sysman/cool_down_mode"
64 enum cool_down_status_type {
65 COOL_DOWN_RELEASE = 0,
66 COOL_DOWN_NOTIFICATION = 1,
67 COOL_DOWN_SHUT_DOWN = 2,
70 enum cool_down_timer_type {
71 COOL_DOWN_LIMIT_ACTION_TIMER = 1,
72 COOL_DOWN_POPUP_TIMER = 2,
73 COOL_DOWN_SHUT_DOWN_TIMER = 3,
76 enum cool_down_timer_status {
77 COOL_DOWN_TIMER_DELETED_ALREADY = 0,
78 COOL_DOWN_TIMER_DELETED_NOW = 1,
86 static int cool_down_level = 0;
87 static const char *cool_down_status = NULL;
88 static Ecore_Timer *app_limit_timer = NULL;
89 static Ecore_Timer *shut_down_timer = NULL;
90 static const struct device_ops *hall_ic = NULL;
92 static void cool_down_timer_start(int type);
93 static int cool_down_timer_stop(int type);
95 static int hall_ic_status(void)
99 ret = device_get_status(hall_ic);
101 return HALL_IC_OPENED;
105 static int cool_down_popup(char *type)
107 struct popup_data *params;
108 static const struct device_ops *apps = NULL;
111 val = hall_ic_status();
112 if (val == HALL_IC_CLOSED) {
113 _I("cover is closed");
117 FIND_DEVICE_INT(apps, "apps");
119 params = malloc(sizeof(struct popup_data));
120 if (params == NULL) {
124 params->name = COOL_DOWN_POPUP_NAME;
126 apps->init((void *)params);
131 static Eina_Bool broadcast_cool_down_limit_action(void *data)
133 char buf[SIGNAL_STRING_MAX_LEN];
136 cool_down_timer_stop(COOL_DOWN_LIMIT_ACTION_TIMER);
138 cool_down_status = SIGNAL_COOL_DOWN_LIMIT_ACTION;
139 snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
142 broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
143 METHOD_COOL_DOWN_CHANGED, "s", param);
144 _I("%s", SIGNAL_COOL_DOWN_LIMIT_ACTION);
148 static Eina_Bool cool_down_shutdown_popup(void *data)
150 cool_down_popup(SIGNAL_COOL_DOWN_SHUT_DOWN);
151 cool_down_timer_start(COOL_DOWN_SHUT_DOWN_TIMER);
155 static Eina_Bool cool_down_shutdown_force(void *data)
157 cool_down_timer_stop(COOL_DOWN_SHUT_DOWN_TIMER);
158 vconf_set_int(VCONFKEY_SYSMAN_COOL_DOWN_MODE, COOL_DOWN_SHUT_DOWN);
159 vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, SYSTEMD_STOP_POWER_OFF);
163 static int cool_down_timer_stop(int type)
165 if (type == COOL_DOWN_NOTIFICATION) {
166 if (!app_limit_timer)
167 return COOL_DOWN_TIMER_DELETED_ALREADY;
168 ecore_timer_del(app_limit_timer);
169 app_limit_timer = NULL;
170 } else if (type == COOL_DOWN_POPUP_TIMER ||
171 type == COOL_DOWN_SHUT_DOWN_TIMER) {
172 if (!shut_down_timer)
173 return COOL_DOWN_TIMER_DELETED_ALREADY;
174 ecore_timer_del(shut_down_timer);
175 shut_down_timer = NULL;
178 return COOL_DOWN_TIMER_DELETED_NOW;
181 static void cool_down_timer_start(int type)
183 cool_down_timer_stop(type);
184 if (type == COOL_DOWN_LIMIT_ACTION_TIMER) {
185 app_limit_timer = ecore_timer_add(COOL_DOWN_LIMIT_ACTION_WAIT,
186 broadcast_cool_down_limit_action, NULL);
187 if (!app_limit_timer)
188 _E("fail to add timer");
189 } else if (type == COOL_DOWN_POPUP_TIMER) {
190 shut_down_timer = ecore_timer_add(COOL_DOWN_SHUTDOWN_POPUP_WAIT,
191 cool_down_shutdown_popup, NULL);
192 if (!shut_down_timer)
193 _E("fail to add timer");
194 } else if (type == COOL_DOWN_SHUT_DOWN_TIMER) {
195 shut_down_timer = ecore_timer_add(COOL_DOWN_SHUTDOWN_FORCE_WAIT,
196 cool_down_shutdown_force, NULL);
197 if (!shut_down_timer)
198 _E("fail to add timer");
200 _D("start %d", type);
203 static void broadcast_cool_down_status(int status)
206 char buf[SIGNAL_STRING_MAX_LEN];
211 case COOL_DOWN_RELEASE:
212 cool_down_status = SIGNAL_COOL_DOWN_RELEASE;
213 cool_down_timer_stop(COOL_DOWN_SHUT_DOWN_TIMER);
214 cool_down_timer_stop(COOL_DOWN_POPUP_TIMER);
215 cool_down_timer_stop(COOL_DOWN_LIMIT_ACTION_TIMER);
217 case COOL_DOWN_NOTIFICATION:
218 cool_down_status = SIGNAL_COOL_DOWN_NOTIFICATION;
219 cool_down_timer_stop(COOL_DOWN_SHUT_DOWN_TIMER);
220 cool_down_timer_stop(COOL_DOWN_POPUP_TIMER);
221 cool_down_timer_start(COOL_DOWN_LIMIT_ACTION_TIMER);
223 case COOL_DOWN_SHUT_DOWN:
224 ret = cool_down_timer_stop(COOL_DOWN_LIMIT_ACTION_TIMER);
225 if (ret == COOL_DOWN_TIMER_DELETED_NOW)
226 broadcast_cool_down_limit_action(NULL);
227 cool_down_status = SIGNAL_COOL_DOWN_SHUT_DOWN;
228 cool_down_timer_start(COOL_DOWN_POPUP_TIMER);
231 _E("abnormal value %d", status);
235 snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
238 broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
239 METHOD_COOL_DOWN_CHANGED, "s", param);
240 device_notify(DEVICE_NOTIFIER_COOL_DOWN, (void *)status);
241 _I("%s", cool_down_status);
244 static int cool_down_booting_done(void *data)
254 if (cool_down_level) {
255 if (cool_down_level == COOL_DOWN_SHUT_DOWN) {
256 broadcast_cool_down_status(COOL_DOWN_NOTIFICATION);
257 broadcast_cool_down_limit_action(NULL);
258 cool_down_timer_start(COOL_DOWN_POPUP_TIMER);
261 broadcast_cool_down_status(cool_down_level);
264 ret = vconf_get_int(VCONFKEY_SYSMAN_COOL_DOWN_MODE, &mode);
265 vconf_set_int(VCONFKEY_SYSMAN_COOL_DOWN_MODE, cool_down_level);
266 if (ret == 0 && mode == COOL_DOWN_SHUT_DOWN)
267 cool_down_popup(SIGNAL_COOL_DOWN_RELEASE);
272 static int cool_down_execute(void *data)
275 static int old = COOL_DOWN_RELEASE;
277 cool_down_level = *(int *)data;
278 if (old == cool_down_level)
280 _I("status %d", cool_down_level);
282 booting_done = cool_down_booting_done(NULL);
286 if (old == COOL_DOWN_RELEASE &&
287 cool_down_level == COOL_DOWN_SHUT_DOWN) {
288 old = cool_down_level;
289 broadcast_cool_down_status(COOL_DOWN_NOTIFICATION);
290 broadcast_cool_down_limit_action(NULL);
291 cool_down_timer_start(COOL_DOWN_POPUP_TIMER);
294 old = cool_down_level;
295 broadcast_cool_down_status(cool_down_level);
299 static int changed_device(int level)
305 cool_down_execute((void *)state);
310 static void cool_down_edbus_signal_handler(void *data, DBusMessage *msg)
315 if (dbus_message_is_signal(msg, COOL_DOWN_DBUS_INTERFACE, COOL_DOWN_DBUS_SIGNAL) == 0) {
316 _E("there is no cool down signal");
320 dbus_error_init(&err);
322 if (dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID) == 0) {
323 _E("there is no message");
329 static DBusMessage *dbus_get_status(E_DBus_Object *obj, DBusMessage *msg)
331 DBusMessageIter iter;
333 char buf[SIGNAL_STRING_MAX_LEN];
336 snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
337 reply = dbus_message_new_method_return(msg);
338 dbus_message_iter_init_append(reply, &iter);
339 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, ¶m);
343 static DBusMessage *dbus_device_handler(E_DBus_Object *obj, DBusMessage *msg)
346 DBusMessageIter iter;
355 dbus_error_init(&err);
357 if (!dbus_message_get_args(msg, &err,
358 DBUS_TYPE_STRING, &type_str,
359 DBUS_TYPE_INT32, &argc,
360 DBUS_TYPE_STRING, &argv[0],
361 DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
362 _E("there is no message");
367 if (argc < 0 || !argv[0] || !argv[1]){
368 _E("message is invalid!");
373 pid = get_edbus_sender_pid(msg);
374 if (kill(pid, 0) == -1) {
375 _E("%d process does not exist, dbus ignored!", pid);
384 reply = dbus_message_new_method_return(msg);
385 dbus_message_iter_init_append(reply, &iter);
386 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
391 static const struct edbus_method edbus_methods[] = {
392 { METHOD_COOL_DOWN_STATUS, NULL, "s", dbus_get_status },
393 { METHOD_COOL_DOWN_CHANGED, "siss", "i", dbus_device_handler },
396 static void cool_down_init(void *data)
400 ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
402 _E("fail to init edbus method(%d)", ret);
403 register_edbus_signal_handler(COOL_DOWN_DBUS_PATH, COOL_DOWN_DBUS_INTERFACE,
404 COOL_DOWN_DBUS_SIGNAL,
405 cool_down_edbus_signal_handler);
406 register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, cool_down_booting_done);
407 hall_ic = find_device(HALL_IC_NAME);
410 static const struct device_ops cool_down_device_ops = {
411 .priority = DEVICE_PRIORITY_NORMAL,
413 .init = cool_down_init,
414 .execute = cool_down_execute,
417 DEVICE_OPS_REGISTER(&cool_down_device_ops)