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/config-parser.h"
39 #include "core/udev.h"
40 #include "hall/hall-handler.h"
41 #include "display/poll.h"
43 #define COOL_DOWN_DBUS_INTERFACE "org.tizen.trm.siop"
44 #define COOL_DOWN_DBUS_PATH "/Org/Tizen/Trm/Siop"
45 #define COOL_DOWN_DBUS_SIGNAL "ChangedCooldownMode"
47 #define COOL_DOWN_POPUP_NAME "cooldown-syspopup"
49 #define SIGNAL_COOL_DOWN_SHUT_DOWN "ShutDown"
50 #define SIGNAL_COOL_DOWN_LIMIT_ACTION "LimitAction"
51 #define SIGNAL_COOL_DOWN_WARNING_ACTION "WarningAction"
52 #define SIGNAL_COOL_DOWN_RELEASE "Release"
53 #define SIGNAL_COOL_DOWN_RESPONSE "CoolDownResponse"
55 #define METHOD_COOL_DOWN_STATUS "GetCoolDownStatus"
56 #define METHOD_COOL_DOWN_CHANGED "CoolDownChanged"
58 #define SIGNAL_STRING_MAX_LEN 30
60 #define COOL_DOWN_LIMIT_ACTION_WAIT 60
61 #define COOL_DOWN_SHUTDOWN_POPUP_WAIT 60
62 #define COOL_DOWN_SHUTDOWN_FORCE_WAIT 30
63 #define SYSTEMD_STOP_POWER_OFF 4
65 #define VCONFKEY_SYSMAN_COOL_DOWN_MODE "db/private/sysman/cool_down_mode"
67 enum cool_down_status_type {
70 COOL_DOWN_WARNING_ACTION,
71 COOL_DOWN_LIMIT_ACTION,
80 static int cool_down_level = 0;
81 static const char *cool_down_status = NULL;
82 static const struct device_ops *hall_ic = NULL;
83 static int cool_down_lock = 0;
85 static int hall_ic_status(void)
89 ret = device_get_status(hall_ic);
91 return HALL_IC_OPENED;
95 static int telephony_execute(void *data)
97 static const struct device_ops *ops = NULL;
98 int mode = *(int *)data;
101 vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &old);
102 if ((old == 0 && mode == 1) ||
103 (old == 1 && mode == 0))
106 FIND_DEVICE_INT(ops, "telephony");
108 return ops->execute(data);
111 static void flight_mode_off(void)
115 telephony_execute(&mode);
118 static void flight_mode_on(void)
122 telephony_execute(&mode);
125 static int cool_down_popup(char *type)
127 struct popup_data *params;
128 static const struct device_ops *apps = NULL;
131 val = hall_ic_status();
132 if (val == HALL_IC_CLOSED) {
133 _I("cover is closed");
137 FIND_DEVICE_INT(apps, "apps");
139 params = malloc(sizeof(struct popup_data));
140 if (params == NULL) {
145 pm_change_internal(getpid(), LCD_NORMAL);
146 pm_lock_internal(INTERNAL_LOCK_COOL_DOWN, LCD_OFF, STAY_CUR_STATE, 0);
147 params->name = COOL_DOWN_POPUP_NAME;
149 apps->init((void *)params);
154 static void broadcast_cool_down_status(int status)
157 char buf[SIGNAL_STRING_MAX_LEN];
159 static int old = COOL_DOWN_NONE_INIT;
165 if (cool_down_lock) {
167 pm_unlock_internal(INTERNAL_LOCK_COOL_DOWN, LCD_OFF, STAY_CUR_STATE);
172 case COOL_DOWN_RELEASE:
173 cool_down_status = SIGNAL_COOL_DOWN_RELEASE;
175 case COOL_DOWN_WARNING_ACTION:
176 cool_down_status = SIGNAL_COOL_DOWN_WARNING_ACTION;
178 case COOL_DOWN_LIMIT_ACTION:
179 cool_down_status = SIGNAL_COOL_DOWN_LIMIT_ACTION;
181 case COOL_DOWN_SHUT_DOWN:
184 _E("abnormal value %d", status);
188 snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
191 broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
192 METHOD_COOL_DOWN_CHANGED, "s", param);
193 device_notify(DEVICE_NOTIFIER_COOL_DOWN, (void *)status);
194 _I("%s", cool_down_status);
197 static int cool_down_booting_done(void *data)
208 switch (cool_down_level)
210 case COOL_DOWN_RELEASE:
211 broadcast_cool_down_status(COOL_DOWN_RELEASE);
213 case COOL_DOWN_WARNING_ACTION:
214 broadcast_cool_down_status(COOL_DOWN_WARNING_ACTION);
216 case COOL_DOWN_LIMIT_ACTION:
218 broadcast_cool_down_status(COOL_DOWN_LIMIT_ACTION);
220 case COOL_DOWN_SHUT_DOWN:
221 cool_down_popup(SIGNAL_COOL_DOWN_SHUT_DOWN);
224 _E("abnormal value %d", cool_down_level);
231 static int cool_down_execute(void *data)
234 static int old = COOL_DOWN_NONE_INIT;
236 cool_down_level = *(int *)data;
237 if (old == cool_down_level)
239 _I("status %d", cool_down_level);
240 booting_done = cool_down_booting_done(NULL);
243 vconf_set_int(VCONFKEY_SYSMAN_COOL_DOWN_MODE, cool_down_level);
244 old = cool_down_level;
246 switch (cool_down_level)
248 case COOL_DOWN_RELEASE:
250 broadcast_cool_down_status(COOL_DOWN_RELEASE);
252 case COOL_DOWN_WARNING_ACTION:
253 broadcast_cool_down_status(COOL_DOWN_WARNING_ACTION);
255 case COOL_DOWN_LIMIT_ACTION:
256 cool_down_popup(SIGNAL_COOL_DOWN_LIMIT_ACTION);
258 case COOL_DOWN_SHUT_DOWN:
259 cool_down_popup(SIGNAL_COOL_DOWN_SHUT_DOWN);
265 static int changed_device(int level)
271 cool_down_execute((void *)state);
276 static void cool_down_popup_response_signal_handler(void *data, DBusMessage *msg)
279 broadcast_cool_down_status(COOL_DOWN_LIMIT_ACTION);
282 static int get_action_id(char *action)
286 if (MATCH(action, SIGNAL_COOL_DOWN_RELEASE))
287 val = COOL_DOWN_RELEASE;
288 else if (MATCH(action, SIGNAL_COOL_DOWN_WARNING_ACTION))
289 val = COOL_DOWN_WARNING_ACTION;
290 else if (MATCH(action, SIGNAL_COOL_DOWN_LIMIT_ACTION))
291 val = COOL_DOWN_LIMIT_ACTION;
292 else if (MATCH(action, SIGNAL_COOL_DOWN_SHUT_DOWN))
293 val = COOL_DOWN_SHUT_DOWN;
300 static void cool_down_edbus_signal_handler(void *data, DBusMessage *msg)
306 if (dbus_message_is_signal(msg, COOL_DOWN_DBUS_INTERFACE, COOL_DOWN_DBUS_SIGNAL) == 0) {
307 _E("there is no cool down signal");
311 dbus_error_init(&err);
313 if (dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &action, DBUS_TYPE_INVALID) == 0) {
314 _E("there is no message");
318 val = get_action_id(action);
321 _E("Invalid argument! %s", action);
326 static DBusMessage *dbus_get_status(E_DBus_Object *obj, DBusMessage *msg)
328 DBusMessageIter iter;
330 char buf[SIGNAL_STRING_MAX_LEN];
333 switch(cool_down_level)
335 case COOL_DOWN_SHUT_DOWN:
336 cool_down_status = SIGNAL_COOL_DOWN_SHUT_DOWN;
338 case COOL_DOWN_LIMIT_ACTION:
339 cool_down_status = SIGNAL_COOL_DOWN_LIMIT_ACTION;
342 cool_down_status = SIGNAL_COOL_DOWN_RELEASE;
346 snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
347 reply = dbus_message_new_method_return(msg);
348 dbus_message_iter_init_append(reply, &iter);
349 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, ¶m);
353 static DBusMessage *dbus_device_handler(E_DBus_Object *obj, DBusMessage *msg)
356 DBusMessageIter iter;
365 dbus_error_init(&err);
367 if (!dbus_message_get_args(msg, &err,
368 DBUS_TYPE_STRING, &type_str,
369 DBUS_TYPE_INT32, &argc,
370 DBUS_TYPE_STRING, &argv[0],
371 DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
372 _E("there is no message");
377 if (argc < 0 || !argv[0] || !argv[1]){
378 _E("message is invalid!");
383 pid = get_edbus_sender_pid(msg);
384 if (kill(pid, 0) == -1) {
385 _E("%d process does not exist, dbus ignored!", pid);
390 val = get_action_id(argv[1]);
393 _E("Invalid argument! %s", argv[1]);
400 reply = dbus_message_new_method_return(msg);
401 dbus_message_iter_init_append(reply, &iter);
402 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
407 static const struct edbus_method edbus_methods[] = {
408 { METHOD_COOL_DOWN_STATUS, NULL, "s", dbus_get_status },
409 { METHOD_COOL_DOWN_CHANGED, "siss", "i", dbus_device_handler },
412 static void cool_down_init(void *data)
416 ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
418 _E("fail to init edbus method(%d)", ret);
419 register_edbus_signal_handler(COOL_DOWN_DBUS_PATH, COOL_DOWN_DBUS_INTERFACE,
420 COOL_DOWN_DBUS_SIGNAL,
421 cool_down_edbus_signal_handler);
422 register_edbus_signal_handler(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
423 SIGNAL_COOL_DOWN_RESPONSE,
424 cool_down_popup_response_signal_handler);
425 register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, cool_down_booting_done);
426 hall_ic = find_device(HALL_IC_NAME);
429 static const struct device_ops cool_down_device_ops = {
430 .priority = DEVICE_PRIORITY_NORMAL,
432 .init = cool_down_init,
433 .execute = cool_down_execute,
436 DEVICE_OPS_REGISTER(&cool_down_device_ops)