#include "core/device-notifier.h"
#include "core/devices.h"
-static struct thermal_device *thermal_dev;
static int noti;
-#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+/* Core service: get/set device status operations about device */
+#ifdef PASS
+#define THERMAL_PATH "/Org/Tizen/System/Pass/Monitor/Thermal"
+#define THERMAL_INTERFACE "org.tizen.system.pass.monitor.thermal"
+#define THERMAL_METHOD_TEMP_CHANGED "ChangedSiop"
+#else
+#define THERMAL_PATH "/Org/Tizen/Trm/Siop"
+#define THERMAL_INTERFACE "org.tizen.trm.siop"
+#define THERMAL_METHOD_TEMP_CHANGED "ChangedSiop"
+#endif
+
#define SIGNAL_OVERHEAT_TIME "TimeUpdate"
#define OVERHEAT_CALLBACK_TIME 1 //seconds
#define OVERHEAT_POWEROFF_TIME 30
-enum thermal_trend_type {
- NO_CHANGE,
- LOW_TO_HIGH,
- HIGH_TO_LOW,
- HIGH_TO_HIGH
-};
-
-enum thermal_action_type {
- NOTHING,
+/* Temp level */
+#define LEVEL_DANGER "Danger"
+#define LEVEL_CRITICAL "Critical"
+#define LEVEL_HIGH "High"
+#define LEVEL_LOW "Low"
+#define LEVEL_NORMAL "Normal"
+
+/* Action type */
+#define SHUTDOWN_ACTION "ShutDownAction"
+#define LIMIT_ACTION "LimitAction"
+#define WARNING_ACTION "WarningAction"
+#define RELEASE_ACTION "ReleaseAction"
+#define NORMAL_ACTION "NormalAction"
+
+enum thermal_enum_type {
+ LOW,
+ NORMAL,
WARNING,
CRITICAL,
- RECOVER
-};
-
-enum thermal_level_update_type {
- UPDATE,
- KEEP
-};
-
-struct thermal_state {
- thermal_state_e old_state;
- thermal_state_e new_state;
- enum thermal_action_type status;
-};
-
-struct thermal_level {
- thermal_level_e old_level;
- thermal_level_e new_level;
- enum thermal_action_type status;
- enum thermal_level_update_type level;
-};
-
-static struct thermal_state temp_state[] = {
- { THERMAL_STATE_LOW, THERMAL_STATE_LOW, NO_CHANGE},
- { THERMAL_STATE_LOW, THERMAL_STATE_NORMAL, NO_CHANGE},
- { THERMAL_STATE_LOW, THERMAL_STATE_HIGH, LOW_TO_HIGH},
- { THERMAL_STATE_NORMAL, THERMAL_STATE_LOW, NO_CHANGE},
- { THERMAL_STATE_NORMAL, THERMAL_STATE_NORMAL, NO_CHANGE},
- { THERMAL_STATE_NORMAL, THERMAL_STATE_HIGH, LOW_TO_HIGH},
- { THERMAL_STATE_HIGH, THERMAL_STATE_LOW, HIGH_TO_LOW},
- { THERMAL_STATE_HIGH, THERMAL_STATE_NORMAL, HIGH_TO_LOW},
- { THERMAL_STATE_HIGH, THERMAL_STATE_HIGH, HIGH_TO_HIGH}
-};
-
-static struct thermal_level lowhigh_temp_level[] = {
- { THERMAL_LEVEL_NORMAL, THERMAL_LEVEL_WARNING, WARNING, UPDATE},
- { THERMAL_LEVEL_NORMAL, THERMAL_LEVEL_CRITICAL, CRITICAL, UPDATE},
- { THERMAL_LEVEL_NORMAL, THERMAL_LEVEL_POWEROFF, CRITICAL, UPDATE}
-};
-
-static struct thermal_level highlow_temp_level[] = {
- { THERMAL_LEVEL_POWEROFF, THERMAL_LEVEL_NORMAL, NOTHING, KEEP},
- { THERMAL_LEVEL_CRITICAL, THERMAL_LEVEL_NORMAL, NOTHING, KEEP},
- { THERMAL_LEVEL_WARNING, THERMAL_LEVEL_NORMAL, RECOVER, UPDATE}
-};
-
-static struct thermal_level highhigh_temp_level[] = {
- { THERMAL_LEVEL_WARNING, THERMAL_LEVEL_WARNING, NOTHING, UPDATE},
- { THERMAL_LEVEL_WARNING, THERMAL_LEVEL_CRITICAL, CRITICAL, UPDATE},
- { THERMAL_LEVEL_WARNING, THERMAL_LEVEL_POWEROFF, CRITICAL, UPDATE},
- { THERMAL_LEVEL_CRITICAL, THERMAL_LEVEL_WARNING, NOTHING, KEEP},
- { THERMAL_LEVEL_CRITICAL, THERMAL_LEVEL_CRITICAL, NOTHING, UPDATE},
- { THERMAL_LEVEL_CRITICAL, THERMAL_LEVEL_POWEROFF, NOTHING, UPDATE},
- { THERMAL_LEVEL_POWEROFF, THERMAL_LEVEL_WARNING, NOTHING, KEEP},
- { THERMAL_LEVEL_POWEROFF, THERMAL_LEVEL_CRITICAL, NOTHING, KEEP},
- { THERMAL_LEVEL_POWEROFF, THERMAL_LEVEL_POWEROFF, NOTHING, UPDATE}
+ DANGER
};
static int power_off(void)
return power->execute("poweroff");
}
-static int thermal_state_check(int old_state, int new_state)
-{
- int i, ret = -1;
-
- for (i = 0; i < ARRAY_SIZE(temp_state); i++) {
- if (old_state == temp_state[i].old_state &&
- new_state == temp_state[i].new_state) {
- ret = temp_state[i].status;
- break;
- }
- }
-
- return ret;
-}
-
-static void thermal_up_check(int old_level, int new_level, int *out_status, int *out_level)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(lowhigh_temp_level); i++) {
- if (old_level == lowhigh_temp_level[i].old_level &&
- new_level == lowhigh_temp_level[i].new_level) {
- *out_status = lowhigh_temp_level[i].status;
- *out_level = lowhigh_temp_level[i].level;
- break;
- }
- }
-}
-
-static void thermal_down_check(int old_level, int new_level, int *out_status, int *out_level)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(highlow_temp_level); i++) {
- if (old_level == highlow_temp_level[i].old_level &&
- new_level == highlow_temp_level[i].new_level) {
- *out_status = highlow_temp_level[i].status;
- *out_level = highlow_temp_level[i].level;
- break;
- }
- }
-}
-
-static void thermal_high_check(int old_level, int new_level, int *out_status, int *out_level)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(highhigh_temp_level); i++) {
- if (old_level == highhigh_temp_level[i].old_level &&
- new_level == highhigh_temp_level[i].new_level) {
- *out_status = highhigh_temp_level[i].status;
- *out_level = highhigh_temp_level[i].level;
- break;
- }
- }
-}
-
static void thermal_remove_noti(void)
{
+ int ret = 0;
+
if (noti) {
- remove_notification("TempCooldownNotiOff", noti);
- noti = 0;
+ ret = remove_notification("TempCooldownNotiOff", noti);
+ if (ret < 0)
+ _E("Fail to remove cooldown noti : %d", noti);
+ else
+ noti = 0;
}
}
static void thermal_remove_popup(void)
{
- launch_system_app(APP_DEFAULT, 2,
+ int temp;
+
+ temp = launch_system_app(APP_DEFAULT, 2,
APP_KEY_TYPE, "remove_cooldown_popups");
+ if (temp < 0)
+ _E("Fail to launch remove_cooldown_popups");
}
static void thermal_add_noti(void)
{
+ thermal_remove_noti();
if (!noti)
noti = add_notification("TempCooldownNotiOn", NULL, NULL);
}
-static void broadcast_thermal_state_legacy(int state, int level)
+static void broadcast_thermal_state_legacy(char *action_type)
{
- static int old = NOTHING;
- int type;
char *param[1];
- switch (state) {
- case THERMAL_STATE_LOW:
- case THERMAL_STATE_NORMAL:
- type = NOTHING;
- break;
- case THERMAL_STATE_HIGH:
- if (level == THERMAL_LEVEL_WARNING)
- type = WARNING;
- else if (level == THERMAL_LEVEL_CRITICAL ||
- level == THERMAL_LEVEL_POWEROFF)
- type = CRITICAL;
- else
- type = NOTHING;
- break;
- default:
- _E("Invalid state(%d)", state);
- return;
- }
-
- if (old == type)
- return;
-
- switch (type) {
- case NOTHING:
- param[0] = "CoolDownRelease";
- break;
- case WARNING:
- param[0] = "WarningAction";
- break;
- case CRITICAL:
- param[0] = "LimitAction";
- break;
- default:
- _I("Invalid type (%d)", type);
+ if (!action_type) {
+ _E("Invalid action type");
return;
}
+ param[0] = action_type;
- old = type;
-
+ _D("action_type = %s", param[0]);
broadcast_edbus_signal(DEVICED_PATH_SYSNOTI,
DEVICED_INTERFACE_SYSNOTI,
"CoolDownChanged",
return ECORE_CALLBACK_RENEW;
}
-static void thermal_add_popup(void)
+static void thermal_overheat_popup(void)
{
int ret;
Ecore_Timer *timer;
static void thermal_add_recovery_popup(void)
{
- int ret;
+ int temp;
- ret = launch_system_app(APP_DEFAULT, 2,
+ temp = launch_system_app(APP_DEFAULT, 2,
APP_KEY_TYPE, "cooled_down");
- if (ret < 0)
+ if (temp < 0)
_E("Fail to launch recovery popup");
}
-static void thermal_action(struct thermal_info *info, void *data)
+static int change_templevel_to_enum(char *string)
{
- static int old_state = -1, old_level = -1;
- static int therm_state = -1, therm_action = -1, update = -1;
+ int temp = -1;
- if (!info)
- return;
+ if (!string) {
+ _E("Invalid temp level");
+ return temp;
+ }
+
+ if (!strncmp(string, LEVEL_NORMAL, strlen(LEVEL_NORMAL)))
+ temp = NORMAL;
+ else if (!strncmp(string, LEVEL_LOW, strlen(LEVEL_LOW)))
+ temp = LOW;
+ else if (!strncmp(string, LEVEL_HIGH, strlen(LEVEL_HIGH)))
+ temp = WARNING;
+ else if (!strncmp(string, LEVEL_CRITICAL, strlen(LEVEL_CRITICAL)))
+ temp = CRITICAL;
+ else if (!strncmp(string, LEVEL_DANGER, strlen(LEVEL_DANGER)))
+ temp = DANGER;
+
+ return temp;
+}
- if (old_state < 0) {
- old_state = info->state;
- old_level = info->level;
+static void thermal_action(char *state)
+{
+ static int old_state = NORMAL;
+ int new_state;
+ char *action = NULL;
+
+ new_state = change_templevel_to_enum(state);
+ if (new_state < 0) {
+ _E("Invalid thermal state : %d", new_state);
+ goto out;
}
- therm_state = thermal_state_check(old_state, info->state);
+ _D("old_state = %d, new_state = %d", old_state, new_state);
+ if (old_state == DANGER)
+ goto out;
- if (therm_state == NO_CHANGE)
- update = UPDATE;
- else if (therm_state == LOW_TO_HIGH) {
- thermal_up_check(old_level, info->level, &therm_action, &update);
- if (therm_action == WARNING) {
- thermal_remove_noti();
- thermal_remove_popup();
- thermal_add_noti();
- } else if (therm_action == CRITICAL) {
- thermal_remove_noti();
- thermal_remove_popup();
- thermal_add_popup();
- }
- } else if (therm_state == HIGH_TO_LOW) {
- thermal_down_check(old_level, info->level, &therm_action, &update);
- if (therm_action == RECOVER) {
- thermal_remove_popup();
+ switch (new_state) {
+ case NORMAL:
+ case LOW:
+ if (old_state == WARNING || old_state == CRITICAL) {
thermal_remove_noti();
thermal_add_recovery_popup();
- }
- } else if (therm_state == HIGH_TO_HIGH) {
- thermal_high_check(old_level, info->level, &therm_action, &update);
- if (therm_action == CRITICAL) {
- thermal_remove_noti();
- thermal_remove_popup();
- thermal_add_popup();
- }
- }
-
- broadcast_thermal_state_legacy(info->state, info->level);
+ action = strdup(RELEASE_ACTION);
+ } else
+ action = strdup(NORMAL_ACTION);
+ break;
- if (update == UPDATE) {
- old_state = info->state;
- old_level = info->level;
- }
+ case WARNING:
+ thermal_remove_popup();
+ thermal_add_noti();
+ action = strdup(WARNING_ACTION);
+ break;
- _I("Last old_state = %d old_level=%d", old_state, old_level);
-}
+ case CRITICAL:
+ thermal_remove_popup();
+ thermal_add_noti();
+ action = strdup(LIMIT_ACTION);
+ break;
-static int thermal_service_start(void)
-{
- int ret;
+ case DANGER:
+ thermal_remove_popup();
+ thermal_remove_noti();
+ thermal_overheat_popup();
+ action = strdup(SHUTDOWN_ACTION);
+ break;
- if (!thermal_dev) {
- _E("Thermal service is not supported");
- return -ENOTSUP;
+ default:
+ _E("invalid state : %d", new_state);
+ goto out;
}
- ret = thermal_dev->register_changed_event(thermal_action, NULL);
- if (ret < 0)
- _E("Failed to register thermal event (%d)", ret);
+ old_state = new_state;
+ broadcast_thermal_state_legacy(action);
+ free(action);
- return ret;
+out:
+ _D("Last old_state = %d, new_state = %d", old_state, new_state);
}
-static int thermal_service_stop(void)
+static void temp_signal_handler(void *data, DBusMessage *msg)
{
- int ret;
+ DBusError err;
+ char *temp_str = NULL;
- if (!thermal_dev) {
- _E("Thermal service is not supported");
- return -ENOTSUP;
+ if (dbus_message_is_signal(msg, THERMAL_INTERFACE, THERMAL_METHOD_TEMP_CHANGED) == 0) {
+ _E("The signal is not for temp changed");
+ return;
}
- ret = thermal_dev->unregister_changed_event(thermal_action);
- if (ret < 0)
- _E("Failed to unregister thermal event (%d)", ret);
+ dbus_error_init(&err);
+
+ if (dbus_message_get_args(msg, &err,
+ DBUS_TYPE_STRING, &temp_str,
+ DBUS_TYPE_INVALID) == 0) {
+ _E("Failed to get temperature info");
+ dbus_error_free(&err);
+ return;
+ }
+ dbus_error_free(&err);
- return ret;
+ _D("temp_str = %s", temp_str);
+ thermal_action(temp_str);
}
static int booting_done(void *data)
{
static int done;
+ int ret;
if (data == NULL)
return done;
return done;
_I("booting done");
- thermal_service_start();
+ ret = register_edbus_signal_handler(THERMAL_PATH,
+ THERMAL_INTERFACE,
+ THERMAL_METHOD_TEMP_CHANGED,
+ temp_signal_handler);
+ if (ret < 0)
+ _E("Fail to register sig handler for temperature");
return done;
}
static void thermal_init(void *data)
{
- register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
-}
+ int ret;
-static void thermal_exit(void *data)
-{
- unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
- thermal_service_stop();
+ ret = register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+ if (ret < 0)
+ _E("Fail to register booting done Notifier");
}
-static int thermal_probe(void *data)
+static void thermal_exit(void *data)
{
- struct hw_info *info;
int ret;
- if (thermal_dev)
- return 0;
-
- ret = hw_get_info(THERMAL_HARDWARE_DEVICE_ID,
- (const struct hw_info **)&info);
- if (ret < 0) {
- _E("There is no HAL for Thermal");
- return ret;
- }
-
- if (!info->open) {
- _E("Failed to open thermal device; open(NULL)");
- return -ENODEV;
- }
+ ret = unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+ if (ret < 0)
+ _E("Fail to unregister booting done Notifier");
- ret = info->open(info, NULL, (struct hw_common**)&thermal_dev);
- if (ret < 0) {
- _E("Failed to get thermal device structure (%d)", ret);
- return ret;
+ ret = unregister_edbus_signal_handler(THERMAL_PATH,
+ THERMAL_INTERFACE,
+ THERMAL_METHOD_TEMP_CHANGED);
+ if (ret < 0)
+ _E("Fail to unregister sig handler for temperature");
}
- if (!thermal_dev ||
- !thermal_dev->get_state ||
- !thermal_dev->register_changed_event ||
- !thermal_dev->unregister_changed_event) {
- _E("Thermal HAL does not support event handler");
- return -ENODEV;
- }
+static int thermal_probe(void *data)
+{
+ /* device-manager-plugin-xxx is not used for the information of temperature.
+ instead, pass is used */
_I("Thermal device structure load success");
return 0;