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/data.h"
32 #include "core/devices.h"
33 #include "core/queue.h"
35 #include "core/common.h"
36 #include "proc/proc-handler.h"
37 #include "device-interface.h"
39 #define VCONFKEY_ENHANCE_MODE "db/private/sysman/enhance_mode"
40 #define VCONFKEY_ENHANCE_SCENARIO "db/private/sysman/enhance_scenario"
41 #define VCONFKEY_ENHANCE_TONE "db/private/sysman/enhance_tone"
42 #define VCONFKEY_ENHANCE_OUTDOOR "db/private/sysman/enhance_outdoor"
43 #define VCONFKEY_ENHANCE_PID "memory/private/sysman/enhance_pid"
45 #ifndef VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT
46 #define VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT "db/setting/auto_display_adjustment"
49 #define SETTING_NAME "setting"
50 #define CLUSTER_HOME "cluster-home"
51 #define BROWSER_NAME "browser"
53 enum lcd_enhance_type{
61 struct enhance_entry_t{
63 int type[ENHANCE_MAX];
66 static Eina_List *enhance_ctl_list;
67 static struct enhance_entry_t default_enhance;
69 int get_glove_state(void)
73 ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &val);
80 void switch_glove_key(int val)
84 ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, &exval);
85 if (ret < 0 || exval != val) {
86 ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, val);
88 _E("fail to set touch key glove mode");
90 _D("glove key mode is %s", (val ? "on" : "off"));
94 static int check_default_process(int pid, char *default_name)
96 char exe_name[PATH_MAX];
97 if (get_cmdline_name(pid, exe_name, PATH_MAX) != 0) {
98 _E("fail to check cmdline: %d (%s)", pid, default_name);
101 if (strncmp(exe_name, default_name, strlen(default_name)) != 0) {
107 static void restore_enhance_status(struct enhance_entry_t *entry)
113 if (pid == entry->pid)
118 ret = device_get_property(DEVICE_TYPE_DISPLAY,
119 PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO, &scenario);
121 _E("fail to get status");
124 if (entry->type[ENHANCE_SCENARIO] == scenario)
125 goto restore_enhance;
127 _D("clear tone and outdoor");
128 device_set_property(DEVICE_TYPE_DISPLAY,
129 PROP_DISPLAY_IMAGE_ENHANCE_TONE, 0);
130 device_set_property(DEVICE_TYPE_DISPLAY,
131 PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR, 0);
134 _D("restore [%d:%d:%d:%d]",
135 entry->type[ENHANCE_MODE], entry->type[ENHANCE_SCENARIO],
136 entry->type[ENHANCE_TONE], entry->type[ENHANCE_OUTDOOR]);
138 device_set_property(DEVICE_TYPE_DISPLAY,
139 PROP_DISPLAY_IMAGE_ENHANCE_MODE,
140 entry->type[ENHANCE_MODE]);
141 device_set_property(DEVICE_TYPE_DISPLAY,
142 PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO,
143 entry->type[ENHANCE_SCENARIO]);
144 device_set_property(DEVICE_TYPE_DISPLAY,
145 PROP_DISPLAY_IMAGE_ENHANCE_TONE,
146 entry->type[ENHANCE_TONE]);
147 device_set_property(DEVICE_TYPE_DISPLAY,
148 PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR,
149 entry->type[ENHANCE_OUTDOOR]);
152 static int find_entry_from_enhance_ctl_list(int pid)
156 struct enhance_entry_t* entry;
157 char exe_name[PATH_MAX];
159 EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
160 if (entry != NULL && entry->pid == pid && get_cmdline_name(entry->pid, exe_name, PATH_MAX) == 0) {
161 _D("find enhance list");
162 restore_enhance_status(entry);
169 static void remove_entry_from_enhance_ctl_list(int pid)
173 struct enhance_entry_t *entry;
174 char exe_name[PATH_MAX];
179 EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
181 (get_cmdline_name(entry->pid, exe_name, PATH_MAX) != 0 || (entry->pid == pid))) {
182 _D("remove enhance list");
183 enhance_ctl_list = eina_list_remove(enhance_ctl_list, entry);
189 static int check_entry_to_enhance_ctl_list(int pid)
195 if (get_oom_score_adj(pid, &oom_score_adj) < 0) {
196 _E("fail to get adj value of pid: %d (%d)", pid);
200 switch (oom_score_adj) {
201 case OOMADJ_FOREGRD_LOCKED:
202 case OOMADJ_FOREGRD_UNLOCKED:
203 if (!find_entry_from_enhance_ctl_list(pid))
206 case OOMADJ_BACKGRD_LOCKED:
207 case OOMADJ_BACKGRD_UNLOCKED:
208 remove_entry_from_enhance_ctl_list(pid);
211 if (check_default_process(pid, CLUSTER_HOME) != 0)
219 static void update_enhance_status(struct enhance_entry_t *entry, int index)
221 char exe_name[PATH_MAX];
224 if (index == ENHANCE_MODE)
225 type = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
226 else if (index == ENHANCE_SCENARIO)
227 type = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
228 else if (index == ENHANCE_TONE)
229 type = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
230 else if (index == ENHANCE_OUTDOOR)
231 type = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
233 _E("abnormal type is inserted(%d)", index);
237 _I("[ENHANCE(%d)] %d", index, entry->type[index]);
238 device_set_property(DEVICE_TYPE_DISPLAY, type, entry->type[index]);
241 static int change_default_enhance_status(int pid, int index, int val)
244 struct enhance_entry_t *entry;
245 char exe_name[PATH_MAX];
247 if (check_default_process(pid, SETTING_NAME) != 0)
249 default_enhance.pid = pid;
250 default_enhance.type[index] = val;
253 vconf_set_int(VCONFKEY_ENHANCE_MODE, val);
254 EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
257 entry->type[index] = default_enhance.type[index];
260 case ENHANCE_SCENARIO:
261 vconf_set_int(VCONFKEY_ENHANCE_SCENARIO, val);
264 vconf_set_int(VCONFKEY_ENHANCE_TONE, val);
266 case ENHANCE_OUTDOOR:
267 vconf_set_int(VCONFKEY_ENHANCE_OUTDOOR, val);
270 _E("input index is abnormal value");
273 update_enhance_status(&default_enhance, index);
277 static int add_entry_to_enhance_ctl_list(int pid, int index, int val)
281 struct enhance_entry_t *entry;
282 struct enhance_entry_t *entry_buf;
288 EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
289 if (entry != NULL && entry->pid == pid) {
295 entry_buf = malloc(sizeof(struct enhance_entry_t));
302 memcpy(entry_buf, entry, sizeof(struct enhance_entry_t));
303 entry_buf->type[index] = val;
304 remove_entry_from_enhance_ctl_list(pid);
306 memset(entry_buf, 0, sizeof(struct enhance_entry_t));
307 entry_buf->type[ENHANCE_MODE] = default_enhance.type[ENHANCE_MODE];
308 entry_buf->pid = pid;
309 entry_buf->type[index] = val;
312 enhance_ctl_list = eina_list_prepend(enhance_ctl_list, entry_buf);
313 if (!enhance_ctl_list) {
314 _E("eina_list_prepend failed");
318 if (get_oom_score_adj(entry_buf->pid, &oom_score_adj) < 0) {
319 _E("fail to get adj value of pid: %d (%d)", pid);
325 static void enhance_control_pid_cb(keynode_t *in_key, struct main_data *ad)
329 if (vconf_get_int(VCONFKEY_ENHANCE_PID, &pid) != 0)
332 if (check_entry_to_enhance_ctl_list(pid) == 0)
335 restore_enhance_status(&default_enhance);
338 static void enhance_auto_control_cb(keynode_t *in_key, struct main_data *ad)
342 if (vconf_get_bool(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT, &val) != 0) {
343 _E("fail to get %s", VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT);
347 _I("set auto adjust screen tone (%d)", val);
348 device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_AUTO_SCREEN_TONE, val);
349 device_set_property(DEVICE_TYPE_DISPLAY,
350 PROP_DISPLAY_IMAGE_ENHANCE_MODE,
351 default_enhance.type[ENHANCE_MODE]);
354 static void init_colorblind_status(void)
356 struct color_blind_info info;
358 int val, cnt, cmd, ret, sum;
359 unsigned int color[9];
361 /* get the status if colorblind is ON or not */
362 if (vconf_get_bool(VCONFKEY_SETAPPL_COLORBLIND_STATUS_BOOL, &val) != 0)
366 _D("color blind status is FALSE");
370 /* get the value of color blind */
371 str = vconf_get_str(VCONFKEY_SETAPPL_COLORBLIND_LAST_RGBCMY_STR);
375 cnt = strlen(str)/4 - 1;
379 /* token the color blind value string to integer */
381 for (it = str+cnt*4; cnt >= 0 && it; --cnt, it -= 4) {
382 color[cnt] = strtol(it, NULL, 16);
385 _D("color[%d] : %d", cnt, color[cnt]);
388 /* ignore colorblind when all of value is invalid */
394 info.RrCr = color[cnt++];
395 info.RgCg = color[cnt++];
396 info.RbCb = color[cnt++];
397 info.GrMr = color[cnt++];
398 info.GgMg = color[cnt++];
399 info.GbMb = color[cnt++];
400 info.BrYr = color[cnt++];
401 info.BgYg = color[cnt++];
402 info.BbYb = color[cnt++];
404 /* write to the kernel node */
405 cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_COLOR_BLIND, DEFAULT_DISPLAY);
406 ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, (int)&info);
408 _E("fail to set color blind value : %d", ret);
411 static void reset_default_enhance_status(struct enhance_entry_t *entry)
413 _D("reset [%d:%d:%d:%d]",
414 entry->type[ENHANCE_MODE], entry->type[ENHANCE_SCENARIO],
415 entry->type[ENHANCE_TONE], entry->type[ENHANCE_OUTDOOR]);
417 device_set_property(DEVICE_TYPE_DISPLAY,
418 PROP_DISPLAY_IMAGE_ENHANCE_MODE,
419 entry->type[ENHANCE_MODE]);
420 device_set_property(DEVICE_TYPE_DISPLAY,
421 PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO,
422 entry->type[ENHANCE_SCENARIO]);
423 device_set_property(DEVICE_TYPE_DISPLAY,
424 PROP_DISPLAY_IMAGE_ENHANCE_TONE,
425 entry->type[ENHANCE_TONE]);
426 device_set_property(DEVICE_TYPE_DISPLAY,
427 PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR,
428 entry->type[ENHANCE_OUTDOOR]);
431 static void init_default_enhance_status(void)
435 memset(&default_enhance, 0, sizeof(struct enhance_entry_t));
437 if (vconf_get_bool(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT, &val) == 0) {
438 _I("set auto adjust screen tone (%d)", val);
439 device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_AUTO_SCREEN_TONE, val);
442 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT,
443 (void *)enhance_auto_control_cb, NULL) < 0) {
444 _E("failed to set : KEY(%s)", VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT);
447 if (vconf_get_int(VCONFKEY_ENHANCE_MODE, &val) == 0 && val >= 0) {
448 default_enhance.type[ENHANCE_MODE] = val;
450 if (vconf_get_int(VCONFKEY_ENHANCE_SCENARIO, &val) == 0 && val >= 0) {
451 default_enhance.type[ENHANCE_SCENARIO] = val;
453 if (vconf_get_int(VCONFKEY_ENHANCE_TONE, &val) == 0 && val >= 0) {
454 default_enhance.type[ENHANCE_TONE] = val;
456 if (vconf_get_int(VCONFKEY_ENHANCE_OUTDOOR, &val) == 0 && val >= 0) {
457 default_enhance.type[ENHANCE_OUTDOOR] = val;
459 reset_default_enhance_status(&default_enhance);
462 int changed_enhance_value(int pid, int prop, int val)
466 index = prop - PROP_DISPLAY_IMAGE_ENHANCE_MODE;
468 if (change_default_enhance_status(pid, index, val) == 0)
470 if (add_entry_to_enhance_ctl_list(pid, index, val) == 0)
473 _E("fail to set enhance (p:%d,t:%d,v:%d)", pid, index, val);
477 int set_enhance_pid(int pid)
479 return vconf_set_int(VCONFKEY_ENHANCE_PID, pid);
482 static DBusMessage *edbus_getenhancesupported(E_DBus_Object *obj, DBusMessage *msg)
484 DBusMessageIter iter;
488 cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_INFO, DEFAULT_DISPLAY);
489 ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &val);
493 _I("get imange enhance supported %d, %d", val, ret);
495 reply = dbus_message_new_method_return(msg);
496 dbus_message_iter_init_append(reply, &iter);
497 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
501 static DBusMessage *edbus_getimageenhance(E_DBus_Object *obj, DBusMessage *msg)
503 DBusMessageIter iter;
505 int type, prop, cmd, val, ret;
507 dbus_message_iter_init(msg, &iter);
508 dbus_message_iter_get_basic(&iter, &type);
510 _I("get image enhance type %d", type);
514 prop = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
516 case ENHANCE_SCENARIO:
517 prop = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
520 prop = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
522 case ENHANCE_OUTDOOR:
523 prop = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
530 cmd = DISP_CMD(prop, DEFAULT_DISPLAY);
531 ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &val);
536 reply = dbus_message_new_method_return(msg);
537 dbus_message_iter_init_append(reply, &iter);
538 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
542 static DBusMessage *edbus_setimageenhance(E_DBus_Object *obj, DBusMessage *msg)
544 DBusMessageIter iter;
546 int type, prop, cmd, val, ret;
549 ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &type, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
551 _I("there is no message");
556 _I("set image enhance type %d, %d", type, val);
560 prop = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
562 case ENHANCE_SCENARIO:
563 prop = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
566 prop = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
568 case ENHANCE_OUTDOOR:
569 prop = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
576 cmd = DISP_CMD(prop, DEFAULT_DISPLAY);
577 ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, val);
579 /* notify to deviced with the purpose of stroing latest enhance value */
580 pid = get_edbus_sender_pid(msg);
581 changed_enhance_value(pid, prop, val);
584 reply = dbus_message_new_method_return(msg);
585 dbus_message_iter_init_append(reply, &iter);
586 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
590 static DBusMessage *edbus_getenhancedtouch(E_DBus_Object *obj, DBusMessage *msg)
594 DBusMessageIter iter;
597 ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &val);
602 reply = dbus_message_new_method_return(msg);
603 dbus_message_iter_init_append(reply, &iter);
604 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &val);
608 static DBusMessage *edbus_setenhancedtouch(E_DBus_Object *obj, DBusMessage *msg)
610 DBusMessageIter iter;
614 ret = dbus_message_get_args(msg, NULL,
615 DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
617 _I("there is no message");
623 ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, val);
625 _E("fail to off touch key glove mode");
627 ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &exval);
628 if (ret < 0 || exval != val)
629 ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, val);
631 _E("fail to set touch screen glove mode (%d)", val);
636 reply = dbus_message_new_method_return(msg);
637 dbus_message_iter_init_append(reply, &iter);
638 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
642 static const struct edbus_method edbus_methods[] = {
643 { "getimageenhance", "i", "i", edbus_getimageenhance }, /* deprecated */
644 { "setimageenhance", "ii", "i", edbus_setimageenhance }, /* deprecated */
645 { "GetEnhanceSupported", NULL, "i", edbus_getenhancesupported },
646 { "GetImageEnhance", "i", "i", edbus_getimageenhance },
647 { "SetImageEnhance", "ii", "i", edbus_setimageenhance },
648 { "GetEnhancedTouch", NULL, "i", edbus_getenhancedtouch },
649 { "SetEnhancedTouch", "i", "i", edbus_setenhancedtouch },
652 static void enhance_init(void *data)
656 ret = register_edbus_method(DEVICED_PATH_DISPLAY,
657 edbus_methods, ARRAY_SIZE(edbus_methods));
659 _E("Failed to register edbus method! %d", ret);
661 if (vconf_notify_key_changed(VCONFKEY_ENHANCE_PID,
662 (void *)enhance_control_pid_cb, NULL) < 0) {
663 _E("failed to set : KEY(%s)", VCONFKEY_ENHANCE_PID);
666 init_default_enhance_status();
667 init_colorblind_status();
670 static const struct device_ops enhance_device_ops = {
671 .priority = DEVICE_PRIORITY_NORMAL,
673 .init = enhance_init,
676 DEVICE_OPS_REGISTER(&enhance_device_ops)