4 * Copyright (c) 2012 - 2013 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>
29 #include <vconf-keys.h>
31 #include "core/devices.h"
33 #include "core/common.h"
34 #include "proc/proc-handler.h"
35 #include "device-interface.h"
37 #define VCONFKEY_ENHANCE_MODE "db/private/sysman/enhance_mode"
38 #define VCONFKEY_ENHANCE_SCENARIO "db/private/sysman/enhance_scenario"
39 #define VCONFKEY_ENHANCE_TONE "db/private/sysman/enhance_tone"
40 #define VCONFKEY_ENHANCE_OUTDOOR "db/private/sysman/enhance_outdoor"
41 #define VCONFKEY_ENHANCE_PID "memory/private/sysman/enhance_pid"
43 #ifndef VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT
44 #define VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT "db/setting/auto_display_adjustment"
47 #define SETTING_NAME "setting"
48 #define CLUSTER_HOME "cluster-home"
49 #define BROWSER_NAME "browser"
51 #define SIGNAL_GLOVEMODE_ON "GloveModeOn"
52 #define SIGNAL_GLOVEMODE_OFF "GloveModeOff"
54 enum lcd_enhance_type{
62 struct enhance_entry_t{
64 int type[ENHANCE_MAX];
67 static Eina_List *enhance_ctl_list;
68 static struct enhance_entry_t default_enhance;
70 int get_glove_state(void)
74 ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &val);
81 void switch_glove_key(int val)
85 ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, &exval);
86 if (ret < 0 || exval != val) {
87 ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, val);
89 _E("fail to set touch key glove mode");
91 _D("glove key mode is %s", (val ? "on" : "off"));
95 static void broadcast_glove_mode(int state)
97 broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
98 (state ? SIGNAL_GLOVEMODE_ON : SIGNAL_GLOVEMODE_OFF), NULL, NULL);
101 static int check_default_process(int pid, char *default_name)
103 char exe_name[PATH_MAX];
104 if (get_cmdline_name(pid, exe_name, PATH_MAX) != 0) {
105 _E("fail to check cmdline: %d (%s)", pid, default_name);
108 if (strncmp(exe_name, default_name, strlen(default_name)) != 0) {
114 static void restore_enhance_status(struct enhance_entry_t *entry)
120 if (pid == entry->pid)
125 ret = device_get_property(DEVICE_TYPE_DISPLAY,
126 PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO, &scenario);
128 _E("fail to get status");
131 if (entry->type[ENHANCE_SCENARIO] == scenario)
132 goto restore_enhance;
134 _D("clear tone and outdoor");
135 device_set_property(DEVICE_TYPE_DISPLAY,
136 PROP_DISPLAY_IMAGE_ENHANCE_TONE, 0);
137 device_set_property(DEVICE_TYPE_DISPLAY,
138 PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR, 0);
141 _D("restore [%d:%d:%d:%d]",
142 entry->type[ENHANCE_MODE], entry->type[ENHANCE_SCENARIO],
143 entry->type[ENHANCE_TONE], entry->type[ENHANCE_OUTDOOR]);
145 device_set_property(DEVICE_TYPE_DISPLAY,
146 PROP_DISPLAY_IMAGE_ENHANCE_MODE,
147 entry->type[ENHANCE_MODE]);
148 device_set_property(DEVICE_TYPE_DISPLAY,
149 PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO,
150 entry->type[ENHANCE_SCENARIO]);
151 device_set_property(DEVICE_TYPE_DISPLAY,
152 PROP_DISPLAY_IMAGE_ENHANCE_TONE,
153 entry->type[ENHANCE_TONE]);
154 device_set_property(DEVICE_TYPE_DISPLAY,
155 PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR,
156 entry->type[ENHANCE_OUTDOOR]);
159 static int find_entry_from_enhance_ctl_list(int pid)
163 struct enhance_entry_t* entry;
164 char exe_name[PATH_MAX];
166 EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
167 if (entry != NULL && entry->pid == pid && get_cmdline_name(entry->pid, exe_name, PATH_MAX) == 0) {
168 _D("find enhance list");
169 restore_enhance_status(entry);
176 static void remove_entry_from_enhance_ctl_list(int pid)
180 struct enhance_entry_t *entry;
181 char exe_name[PATH_MAX];
186 EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
188 (get_cmdline_name(entry->pid, exe_name, PATH_MAX) != 0 || (entry->pid == pid))) {
189 _D("remove enhance list");
190 enhance_ctl_list = eina_list_remove(enhance_ctl_list, entry);
196 static int check_entry_to_enhance_ctl_list(int pid)
202 if (get_oom_score_adj(pid, &oom_score_adj) < 0) {
203 _E("fail to get adj value of pid: %d (%d)", pid);
207 switch (oom_score_adj) {
208 case OOMADJ_FOREGRD_LOCKED:
209 case OOMADJ_FOREGRD_UNLOCKED:
210 if (!find_entry_from_enhance_ctl_list(pid))
213 case OOMADJ_BACKGRD_LOCKED:
214 case OOMADJ_BACKGRD_UNLOCKED:
215 remove_entry_from_enhance_ctl_list(pid);
218 if (check_default_process(pid, CLUSTER_HOME) != 0)
226 static void update_enhance_status(struct enhance_entry_t *entry, int index)
228 char exe_name[PATH_MAX];
231 if (index == ENHANCE_MODE)
232 type = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
233 else if (index == ENHANCE_SCENARIO)
234 type = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
235 else if (index == ENHANCE_TONE)
236 type = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
237 else if (index == ENHANCE_OUTDOOR)
238 type = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
240 _E("abnormal type is inserted(%d)", index);
244 _I("[ENHANCE(%d)] %d", index, entry->type[index]);
245 device_set_property(DEVICE_TYPE_DISPLAY, type, entry->type[index]);
248 static int change_default_enhance_status(int pid, int index, int val)
251 struct enhance_entry_t *entry;
252 char exe_name[PATH_MAX];
254 if (check_default_process(pid, SETTING_NAME) != 0)
256 default_enhance.pid = pid;
257 default_enhance.type[index] = val;
260 vconf_set_int(VCONFKEY_ENHANCE_MODE, val);
261 EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
264 entry->type[index] = default_enhance.type[index];
267 case ENHANCE_SCENARIO:
268 vconf_set_int(VCONFKEY_ENHANCE_SCENARIO, val);
271 vconf_set_int(VCONFKEY_ENHANCE_TONE, val);
273 case ENHANCE_OUTDOOR:
274 vconf_set_int(VCONFKEY_ENHANCE_OUTDOOR, val);
277 _E("input index is abnormal value");
280 update_enhance_status(&default_enhance, index);
284 static int add_entry_to_enhance_ctl_list(int pid, int index, int val)
288 struct enhance_entry_t *entry;
289 struct enhance_entry_t *entry_buf;
295 EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
296 if (entry != NULL && entry->pid == pid) {
302 entry_buf = malloc(sizeof(struct enhance_entry_t));
309 memcpy(entry_buf, entry, sizeof(struct enhance_entry_t));
310 entry_buf->type[index] = val;
311 remove_entry_from_enhance_ctl_list(pid);
313 memset(entry_buf, 0, sizeof(struct enhance_entry_t));
314 entry_buf->type[ENHANCE_MODE] = default_enhance.type[ENHANCE_MODE];
315 entry_buf->pid = pid;
316 entry_buf->type[index] = val;
319 enhance_ctl_list = eina_list_prepend(enhance_ctl_list, entry_buf);
320 if (!enhance_ctl_list) {
321 _E("eina_list_prepend failed");
325 if (get_oom_score_adj(entry_buf->pid, &oom_score_adj) < 0) {
326 _E("fail to get adj value of pid: %d (%d)", pid);
332 static void enhance_control_pid_cb(keynode_t *in_key, void *data)
336 if (vconf_get_int(VCONFKEY_ENHANCE_PID, &pid) != 0)
339 if (check_entry_to_enhance_ctl_list(pid) == 0)
342 restore_enhance_status(&default_enhance);
345 static void enhance_auto_control_cb(keynode_t *in_key, void *data)
349 if (vconf_get_bool(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT, &val) != 0) {
350 _E("fail to get %s", VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT);
354 _I("set auto adjust screen tone (%d)", val);
355 device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_AUTO_SCREEN_TONE, val);
356 device_set_property(DEVICE_TYPE_DISPLAY,
357 PROP_DISPLAY_IMAGE_ENHANCE_MODE,
358 default_enhance.type[ENHANCE_MODE]);
361 static void init_colorblind_status(void)
363 struct color_blind_info info;
365 int val, cnt, cmd, ret, sum;
366 unsigned int color[9];
368 /* get the status if colorblind is ON or not */
369 if (vconf_get_bool(VCONFKEY_SETAPPL_COLORBLIND_STATUS_BOOL, &val) != 0)
373 _D("color blind status is FALSE");
377 /* get the value of color blind */
378 str = vconf_get_str(VCONFKEY_SETAPPL_COLORBLIND_LAST_RGBCMY_STR);
382 cnt = strlen(str)/4 - 1;
386 /* token the color blind value string to integer */
388 for (it = str+cnt*4; cnt >= 0 && it; --cnt, it -= 4) {
389 color[cnt] = strtol(it, NULL, 16);
392 _D("color[%d] : %d", cnt, color[cnt]);
395 /* ignore colorblind when all of value is invalid */
401 info.RrCr = color[cnt++];
402 info.RgCg = color[cnt++];
403 info.RbCb = color[cnt++];
404 info.GrMr = color[cnt++];
405 info.GgMg = color[cnt++];
406 info.GbMb = color[cnt++];
407 info.BrYr = color[cnt++];
408 info.BgYg = color[cnt++];
409 info.BbYb = color[cnt++];
411 /* write to the kernel node */
412 cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_COLOR_BLIND, DEFAULT_DISPLAY);
413 ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, (int)&info);
415 _E("fail to set color blind value : %d", ret);
418 static void reset_default_enhance_status(struct enhance_entry_t *entry)
420 _D("reset [%d:%d:%d:%d]",
421 entry->type[ENHANCE_MODE], entry->type[ENHANCE_SCENARIO],
422 entry->type[ENHANCE_TONE], entry->type[ENHANCE_OUTDOOR]);
424 device_set_property(DEVICE_TYPE_DISPLAY,
425 PROP_DISPLAY_IMAGE_ENHANCE_MODE,
426 entry->type[ENHANCE_MODE]);
427 device_set_property(DEVICE_TYPE_DISPLAY,
428 PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO,
429 entry->type[ENHANCE_SCENARIO]);
430 device_set_property(DEVICE_TYPE_DISPLAY,
431 PROP_DISPLAY_IMAGE_ENHANCE_TONE,
432 entry->type[ENHANCE_TONE]);
433 device_set_property(DEVICE_TYPE_DISPLAY,
434 PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR,
435 entry->type[ENHANCE_OUTDOOR]);
438 static void init_default_enhance_status(void)
442 memset(&default_enhance, 0, sizeof(struct enhance_entry_t));
444 if (vconf_get_bool(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT, &val) == 0) {
445 _I("set auto adjust screen tone (%d)", val);
446 device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_AUTO_SCREEN_TONE, val);
449 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT,
450 (void *)enhance_auto_control_cb, NULL) < 0) {
451 _E("failed to set : KEY(%s)", VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT);
454 if (vconf_get_int(VCONFKEY_ENHANCE_MODE, &val) == 0 && val >= 0) {
455 default_enhance.type[ENHANCE_MODE] = val;
457 if (vconf_get_int(VCONFKEY_ENHANCE_SCENARIO, &val) == 0 && val >= 0) {
458 default_enhance.type[ENHANCE_SCENARIO] = val;
460 if (vconf_get_int(VCONFKEY_ENHANCE_TONE, &val) == 0 && val >= 0) {
461 default_enhance.type[ENHANCE_TONE] = val;
463 if (vconf_get_int(VCONFKEY_ENHANCE_OUTDOOR, &val) == 0 && val >= 0) {
464 default_enhance.type[ENHANCE_OUTDOOR] = val;
466 reset_default_enhance_status(&default_enhance);
469 int changed_enhance_value(int pid, int prop, int val)
473 index = prop - PROP_DISPLAY_IMAGE_ENHANCE_MODE;
475 if (change_default_enhance_status(pid, index, val) == 0)
477 if (add_entry_to_enhance_ctl_list(pid, index, val) == 0)
480 _E("fail to set enhance (p:%d,t:%d,v:%d)", pid, index, val);
484 int set_enhance_pid(int pid)
486 return vconf_set_int(VCONFKEY_ENHANCE_PID, pid);
489 static DBusMessage *edbus_getenhancesupported(E_DBus_Object *obj, DBusMessage *msg)
491 DBusMessageIter iter;
495 cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_INFO, DEFAULT_DISPLAY);
496 ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &val);
500 _I("get imange enhance supported %d, %d", val, ret);
502 reply = dbus_message_new_method_return(msg);
503 dbus_message_iter_init_append(reply, &iter);
504 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
508 static DBusMessage *edbus_getimageenhance(E_DBus_Object *obj, DBusMessage *msg)
510 DBusMessageIter iter;
512 int type, prop, cmd, val, ret;
514 dbus_message_iter_init(msg, &iter);
515 dbus_message_iter_get_basic(&iter, &type);
517 _I("get image enhance type %d", type);
521 prop = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
523 case ENHANCE_SCENARIO:
524 prop = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
527 prop = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
529 case ENHANCE_OUTDOOR:
530 prop = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
537 cmd = DISP_CMD(prop, DEFAULT_DISPLAY);
538 ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &val);
543 reply = dbus_message_new_method_return(msg);
544 dbus_message_iter_init_append(reply, &iter);
545 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
549 static DBusMessage *edbus_setimageenhance(E_DBus_Object *obj, DBusMessage *msg)
551 DBusMessageIter iter;
553 int type, prop, cmd, val, ret;
556 ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &type, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
558 _I("there is no message");
563 _I("set image enhance type %d, %d", type, val);
567 prop = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
569 case ENHANCE_SCENARIO:
570 prop = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
573 prop = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
575 case ENHANCE_OUTDOOR:
576 prop = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
583 cmd = DISP_CMD(prop, DEFAULT_DISPLAY);
584 ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, val);
586 /* notify to deviced with the purpose of stroing latest enhance value */
587 pid = get_edbus_sender_pid(msg);
588 changed_enhance_value(pid, prop, val);
591 reply = dbus_message_new_method_return(msg);
592 dbus_message_iter_init_append(reply, &iter);
593 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
597 static DBusMessage *edbus_getenhancedtouch(E_DBus_Object *obj, DBusMessage *msg)
601 DBusMessageIter iter;
604 ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &val);
609 reply = dbus_message_new_method_return(msg);
610 dbus_message_iter_init_append(reply, &iter);
611 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &val);
615 static DBusMessage *edbus_setenhancedtouch(E_DBus_Object *obj, DBusMessage *msg)
617 DBusMessageIter iter;
621 ret = dbus_message_get_args(msg, NULL,
622 DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
624 _I("there is no message");
630 ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, val);
632 _E("fail to off touch key glove mode");
634 ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &exval);
635 if (ret < 0 || exval != val)
636 ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, val);
638 _E("fail to set touch screen glove mode (%d)", val);
641 broadcast_glove_mode(val);
644 reply = dbus_message_new_method_return(msg);
645 dbus_message_iter_init_append(reply, &iter);
646 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
650 static const struct edbus_method edbus_methods[] = {
651 { "getimageenhance", "i", "i", edbus_getimageenhance }, /* deprecated */
652 { "setimageenhance", "ii", "i", edbus_setimageenhance }, /* deprecated */
653 { "GetEnhanceSupported", NULL, "i", edbus_getenhancesupported },
654 { "GetImageEnhance", "i", "i", edbus_getimageenhance },
655 { "SetImageEnhance", "ii", "i", edbus_setimageenhance },
656 { "GetEnhancedTouch", NULL, "i", edbus_getenhancedtouch },
657 { "SetEnhancedTouch", "i", "i", edbus_setenhancedtouch },
660 static void enhance_init(void *data)
664 ret = register_edbus_method(DEVICED_PATH_DISPLAY,
665 edbus_methods, ARRAY_SIZE(edbus_methods));
667 _E("Failed to register edbus method! %d", ret);
669 if (vconf_notify_key_changed(VCONFKEY_ENHANCE_PID,
670 (void *)enhance_control_pid_cb, NULL) < 0) {
671 _E("failed to set : KEY(%s)", VCONFKEY_ENHANCE_PID);
674 init_default_enhance_status();
675 init_colorblind_status();
678 static const struct device_ops enhance_device_ops = {
679 .priority = DEVICE_PRIORITY_NORMAL,
681 .init = enhance_init,
684 DEVICE_OPS_REGISTER(&enhance_device_ops)