e467559e3e03d1baffe9912ee4f51c38975b31dc
[platform/core/api/device.git] / src / display.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <stdio.h>
19 #include <errno.h>
20
21 #include <vconf.h>
22 #include <libsyscommon/libgdbus.h>
23 #include <system_info.h>
24 #include <glib.h>
25
26 #include "display.h"
27 #include "display-internal.h"
28 #include "common.h"
29
30 #define DISPLAY_FEATURE     "http://tizen.org/feature/display"
31 #define DISPLAY_STATE_FEATURE     "http://tizen.org/feature/display.state"
32
33 #define METHOD_GET_DISPLAY_COUNT        "GetDisplayCount"
34 #define METHOD_GET_MAX_BRIGHTNESS       "GetMaxBrightness"
35 #define METHOD_GET_BRIGHTNESS           "GetBrightness"
36 #define METHOD_SET_BRIGHTNESS           "SetBrightness"
37 #define METHOD_CHANGE_STATE             "changestate"
38 #define METHOD_CHANGE_STATE_BY_REASON   "ChangeStateByReason"
39 #define METHOD_GET_WHITE_BALANCE        "GetWhiteBalance"
40 #define METHOD_SET_WHITE_BALANCE        "SetWhiteBalance"
41 #define METHOD_GET_ROTATION_ANGLE       "GetRotationAngle"
42 #define METHOD_SET_ROTATION_ANGLE       "SetRotationAngle"
43
44 #define STR_LCD_OFF   "lcdoff"
45 #define STR_LCD_DIM   "lcddim"
46 #define STR_LCD_ON    "lcdon"
47
48 #define DISPLAY_WHITE_BALANCE_GAIN_MAX      2047
49 #define DISPLAY_WHITE_BALANCE_GAIN_MIN      0
50 #define DISPLAY_WHITE_BALANCE_OFFSET_MAX    2047
51 #define DISPLAY_WHITE_BALANCE_OFFSET_MIN    0
52
53 #define ROTATION_ANGLE_DEGREE_MAX           360
54
55 static int display_cnt = -1;
56 struct display {
57         int normal_max;
58         int dim_max;
59 } *display_arr;
60
61 static int alloc_display(void)
62 {
63         int i;
64
65         if (display_cnt < 0)
66                 return -ENODEV;
67
68         display_arr = malloc(sizeof(struct display) * display_cnt);
69         if (!display_arr)
70                 return -ENOMEM;
71
72         for (i = 0; i < display_cnt; ++i) {
73                 display_arr[i].normal_max = -1;
74                 display_arr[i].dim_max = -1;
75         }
76
77         return 0;
78 }
79
80 int device_display_get_numbers(int *device_number)
81 {
82         int ret_val, reply;
83
84         ret_val = is_feature_display_supported();
85         if (!ret_val)
86                 return DEVICE_ERROR_NOT_SUPPORTED;
87
88         if (!device_number)
89                 return DEVICE_ERROR_INVALID_PARAMETER;
90
91         /* if it is a first request */
92         if (display_cnt < 0) {
93                 ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
94                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
95                                 METHOD_GET_DISPLAY_COUNT, NULL, &reply);
96                 if (ret_val < 0)
97                         return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
98                 display_cnt = reply;
99                 alloc_display();
100         }
101
102         *device_number = display_cnt;
103         _I("device_number : %d", *device_number);
104         return DEVICE_ERROR_NONE;
105 }
106
107 int device_display_get_max_brightness(int display_index, int *max_brightness)
108 {
109         int ret_val, reply;
110
111         ret_val = is_feature_display_supported();
112         if (!ret_val)
113                 return DEVICE_ERROR_NOT_SUPPORTED;
114
115         if (!max_brightness)
116                 return DEVICE_ERROR_INVALID_PARAMETER;
117
118         if (display_cnt < 0) {
119                 ret_val = device_display_get_numbers(&display_cnt);
120                 if (ret_val != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
121                         return ret_val;
122         }
123
124         if (display_index < 0 || display_index >= display_cnt)
125                 return DEVICE_ERROR_INVALID_PARAMETER;
126
127         if (!display_arr && alloc_display() < 0)
128                 return DEVICE_ERROR_OPERATION_FAILED;
129
130         if (display_arr[display_index].normal_max < 0) {
131                 ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
132                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
133                                 METHOD_GET_MAX_BRIGHTNESS, g_variant_new("(i)", (int)DISPLAY_STATE_NORMAL),
134                                 &reply);
135                 if (ret_val < 0)
136                         return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
137                 display_arr[display_index].normal_max = reply;
138         }
139
140         *max_brightness = display_arr[display_index].normal_max;
141         return DEVICE_ERROR_NONE;
142 }
143
144 int device_display_get_brightness(int display_index, int *brightness)
145 {
146         int ret_val, reply;
147
148         ret_val = is_feature_display_supported();
149         if (!ret_val)
150                 return DEVICE_ERROR_NOT_SUPPORTED;
151
152         if (!brightness)
153                 return DEVICE_ERROR_INVALID_PARAMETER;
154
155         if (display_cnt < 0) {
156                 ret_val = device_display_get_numbers(&display_cnt);
157                 if (ret_val != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
158                         return ret_val;
159         }
160
161         if (display_index < 0 || display_index >= display_cnt)
162                 return DEVICE_ERROR_INVALID_PARAMETER;
163
164         ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
165                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
166                         METHOD_GET_BRIGHTNESS, g_variant_new("(i)", (int)DISPLAY_STATE_NORMAL),
167                         &reply);
168         if (ret_val < 0)
169                 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
170
171         *brightness = reply;
172         return DEVICE_ERROR_NONE;
173 }
174
175 int device_display_set_brightness(int display_index, int brightness)
176 {
177         int ret_val, max;
178         int ret_dbus;
179
180         ret_val = is_feature_display_supported();
181         if (!ret_val)
182                 return DEVICE_ERROR_NOT_SUPPORTED;
183
184         if (display_cnt < 0) {
185                 ret_val = device_display_get_numbers(&display_cnt);
186                 if (ret_val != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
187                         return ret_val;
188         }
189
190         if (display_index < 0 || display_index >= display_cnt)
191                 return DEVICE_ERROR_INVALID_PARAMETER;
192
193         if (display_arr[display_index].normal_max < 0)
194                 device_display_get_max_brightness(display_index, &max);
195
196         if (brightness < 0 || brightness > display_arr[display_index].normal_max)
197                 return DEVICE_ERROR_INVALID_PARAMETER;
198
199         ret_dbus = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
200                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
201                         METHOD_SET_BRIGHTNESS, g_variant_new("(ii)", (int)DISPLAY_STATE_NORMAL, brightness),
202                         &ret_val);
203
204         if (ret_dbus < 0)
205                 return DEVICE_ERROR_OPERATION_FAILED;
206
207         if (ret_val < 0)
208                 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
209
210         return DEVICE_ERROR_NONE;
211 }
212
213 int device_display_get_state(display_state_e *state)
214 {
215         int ret_val, val;
216
217         ret_val = is_feature_display_supported();
218         if (!ret_val)
219                 return DEVICE_ERROR_NOT_SUPPORTED;
220
221         if (!state)
222                 return DEVICE_ERROR_INVALID_PARAMETER;
223
224         ret_val = vconf_get_int(VCONFKEY_PM_STATE, &val);
225         if (ret_val < 0)
226                 return DEVICE_ERROR_OPERATION_FAILED;
227
228         if (val == VCONFKEY_PM_STATE_NORMAL)
229                 *state = DISPLAY_STATE_NORMAL;
230         else if (val == VCONFKEY_PM_STATE_LCDDIM)
231                 *state = DISPLAY_STATE_SCREEN_DIM;
232         else if (val == VCONFKEY_PM_STATE_LCDOFF || val == VCONFKEY_PM_STATE_SLEEP)
233                 *state = DISPLAY_STATE_SCREEN_OFF;
234         else
235                 return DEVICE_ERROR_OPERATION_FAILED;
236
237         return DEVICE_ERROR_NONE;
238 }
239
240 static char *get_state_str(display_state_e state)
241 {
242         switch (state) {
243         case DISPLAY_STATE_NORMAL:
244                 return STR_LCD_ON;
245         case DISPLAY_STATE_SCREEN_DIM:
246                 return STR_LCD_DIM;
247         case DISPLAY_STATE_SCREEN_OFF:
248                 return STR_LCD_OFF;
249         default:
250                 break;
251         }
252         return NULL;
253 }
254
255 static void change_cb(GVariant *result, void *data, GError *err)
256 {
257         int val;
258
259         if (!result) {
260 //LCOV_EXCL_START System Error
261                 _E("no message : %s", err->message);
262                 return;
263 //LCOV_EXCL_STOP
264         }
265
266         g_variant_get(result, "(i)", &val);
267         _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_CHANGE_STATE, val);
268 }
269
270 int device_display_change_state(display_state_e state)
271 {
272         char *str;
273         int ret;
274         static int privilege = -1;
275         static long num_calls = 0;
276
277         ret = is_feature_display_state_supported();
278         if (!ret)
279                 return DEVICE_ERROR_NOT_SUPPORTED;
280
281         if (check_async_call_rate(&num_calls) < 0) {
282 //LCOV_EXCL_START System Error
283                 _E("Rejected by too frequent calls; %d (calls per sec.) limit is violated."
284                                 , CHECK_RATE_THRESHOLD);
285                 return DEVICE_ERROR_OPERATION_FAILED;
286 //LCOV_EXCL_STOP
287         }
288
289         if (state < DISPLAY_STATE_NORMAL || state > DISPLAY_STATE_SCREEN_OFF)
290                 return DEVICE_ERROR_INVALID_PARAMETER;
291
292         if (privilege < 0) {
293                 ret = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
294                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
295                                 METHOD_CHANGE_STATE, g_variant_new("(s)", "privilege check"),
296                                 NULL);
297 //LCOV_EXCL_START System Error
298                 if (ret < 0)
299                         return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
300 //LCOV_EXCL_STOP
301                 else
302                         privilege = 1;
303         }
304
305         str = get_state_str(state);
306         if (!str)
307                 return DEVICE_ERROR_INVALID_PARAMETER;
308
309         ret = gdbus_call_async_with_reply(DEVICED_BUS_NAME,
310                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
311                         METHOD_CHANGE_STATE, g_variant_new("(s)", str), change_cb, -1, NULL);
312
313         if (ret < 0)
314                 ret = errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
315
316         return ret;
317 }
318
319 //LCOV_EXCL_START Not tested API
320 int device_display_get_max_brightness_state(int display_index, display_state_e state, int *brightness)
321 {
322         int ret_val, reply;
323
324         ret_val = is_feature_display_supported();
325         if (!ret_val)
326                 return DEVICE_ERROR_NOT_SUPPORTED;
327
328         if (!brightness)
329                 return DEVICE_ERROR_INVALID_PARAMETER;
330
331         if (state > DISPLAY_STATE_SCREEN_DIM)
332                 return DEVICE_ERROR_INVALID_PARAMETER;
333
334         if (display_cnt < 0) {
335                 ret_val = device_display_get_numbers(&display_cnt);
336                 if (ret_val != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
337                         return ret_val;
338         }
339
340         if (display_index < 0 || display_index >= display_cnt)
341                 return DEVICE_ERROR_INVALID_PARAMETER;
342
343         if (!display_arr && alloc_display() < 0)
344                 return DEVICE_ERROR_OPERATION_FAILED;
345
346         ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
347                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
348                                 METHOD_GET_MAX_BRIGHTNESS, g_variant_new("(i)", (int)state),
349                                 &reply);
350         if (ret_val < 0)
351                 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
352
353         if (state == DISPLAY_STATE_NORMAL) {
354                 display_arr[display_index].normal_max = reply;
355                 *brightness = display_arr[display_index].normal_max;
356         } else {
357                 display_arr[display_index].dim_max = reply;
358                 *brightness = display_arr[display_index].dim_max;
359         }
360
361         return DEVICE_ERROR_NONE;
362 }
363 //LCOV_EXCL_STOP
364
365 //LCOV_EXCL_START Not tested API
366 int device_display_get_brightness_state(int display_index, display_state_e state, int *brightness)
367 {
368         int ret_val, reply;
369
370         ret_val = is_feature_display_supported();
371         if (!ret_val)
372                 return DEVICE_ERROR_NOT_SUPPORTED;
373
374         if (!brightness)
375                 return DEVICE_ERROR_INVALID_PARAMETER;
376
377         if (state > DISPLAY_STATE_SCREEN_DIM)
378                 return DEVICE_ERROR_INVALID_PARAMETER;
379
380         if (display_cnt < 0) {
381                 ret_val = device_display_get_numbers(&display_cnt);
382                 if (ret_val != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
383                         return ret_val;
384         }
385
386         if (display_index < 0 || display_index >= display_cnt)
387                 return DEVICE_ERROR_INVALID_PARAMETER;
388
389         ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
390                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
391                         METHOD_GET_BRIGHTNESS, g_variant_new("(i)", (int)state),
392                         &reply);
393         if (ret_val < 0)
394                 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
395
396         *brightness = reply;
397
398         return DEVICE_ERROR_NONE;
399 }
400 //LCOV_EXCL_STOP
401
402 //LCOV_EXCL_START Not tested API
403 int device_display_set_brightness_state(int display_index, display_state_e state, int brightness)
404 {
405         int ret_val, max;
406
407         ret_val = is_feature_display_supported();
408         if (!ret_val)
409                 return DEVICE_ERROR_NOT_SUPPORTED;
410
411         if (display_cnt < 0) {
412                 ret_val = device_display_get_numbers(&display_cnt);
413                 if (ret_val != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
414                         return ret_val;
415         }
416
417         if (state > DISPLAY_STATE_SCREEN_DIM)
418                 return DEVICE_ERROR_INVALID_PARAMETER;
419
420         if (display_index < 0 || display_index >= display_cnt)
421                 return DEVICE_ERROR_INVALID_PARAMETER;
422
423         switch (state) {
424         case DISPLAY_STATE_NORMAL:
425                 if (display_arr[display_index].normal_max < 0)
426                         device_display_get_max_brightness_state(display_index, DISPLAY_STATE_NORMAL, &max);
427                 if (brightness < 0 || brightness > display_arr[display_index].normal_max)
428                         return DEVICE_ERROR_INVALID_PARAMETER;
429                 break;
430         case DISPLAY_STATE_SCREEN_DIM:
431                 if (display_arr[display_index].dim_max < 0)
432                         device_display_get_max_brightness_state(display_index, DISPLAY_STATE_SCREEN_DIM, &max);
433                 if (brightness < 0 || brightness > display_arr[display_index].dim_max)
434                         return DEVICE_ERROR_INVALID_PARAMETER;
435                 break;
436         default:
437                 break;
438         }
439
440         ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
441                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
442                         METHOD_SET_BRIGHTNESS, g_variant_new("(ii)", (int)state, brightness),
443                         NULL);
444         if (ret_val < 0)
445                 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
446
447         return DEVICE_ERROR_NONE;
448 }
449 //LCOV_EXCL_STOP
450
451 //LCOV_EXCL_START Not tested API
452 int device_display_change_state_by_reason(display_state_e type, const char *reason, int timeout, dbus_pending_cb cb)
453 {
454         int ret;
455
456         ret = gdbus_call_async_with_reply(DEVICED_BUS_NAME,
457                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
458                         METHOD_CHANGE_STATE_BY_REASON, g_variant_new("(isi)", (int)type, reason, timeout), cb, -1, NULL);
459
460         return errno_to_device_error(ret);
461 }
462 //LCOV_EXCL_STOP
463
464 int is_feature_display_supported(void)
465 {
466         int ret_val;
467         bool display_avail;
468
469         ret_val = system_info_get_platform_bool(DISPLAY_FEATURE, &display_avail);
470         if (ret_val < 0) {
471 //LCOV_EXCL_START System Error
472                 _E("Failed to get value of display feature");
473                 return false;
474 //LCOV_EXCL_STOP
475         } else if (ret_val == 0 && !display_avail) {
476 //LCOV_EXCL_START System Error
477                 _D("Display feature is not supported");
478                 return false;
479 //LCOV_EXCL_STOP
480         } else
481                 return true;
482 }
483
484 int device_display_get_rotation_angle(int display_index,
485                                 device_display_rotation_angle_e *angle,
486                                 device_display_init_direction_e *init_direction)
487 {
488         int ret = 0, reply_angle, reply_init_direction;
489         GVariant *reply;
490
491         ret = is_feature_display_supported();
492         if (!ret)
493                 return DEVICE_ERROR_NOT_SUPPORTED;
494
495         if (display_cnt < 0) {
496                 ret = device_display_get_numbers(&display_cnt);
497                 if (ret < 0)
498                         return ret;
499         }
500
501         if (display_index < 0 || display_index >= display_cnt || !angle || !init_direction)
502                 return DEVICE_ERROR_INVALID_PARAMETER;
503
504         /* Get the display rotation angle from deviced */
505         ret = gdbus_call_sync_with_reply(DEVICED_BUS_NAME,
506                                         DEVICED_PATH_DISPLAY,
507                                         DEVICED_INTERFACE_DISPLAY,
508                                         METHOD_GET_ROTATION_ANGLE,
509                                         g_variant_new("(i)", display_index),
510                                         &reply);
511
512         if (ret < 0) {
513                 _E("Failed to call dbus method to get the rotation angle");
514                 return ret;
515         }
516
517         g_variant_get(reply, "(iii)", &ret, &reply_angle, &reply_init_direction);
518         g_variant_unref(reply);
519
520         if (ret == -ENODEV) {
521                 _E("Get display rotation is not supported");
522                 return DEVICE_ERROR_OPERATION_FAILED;
523         } else if (ret < 0) {
524                 _E("Failed to get display rotation angle");
525                 return DEVICE_ERROR_OPERATION_FAILED;
526         }
527
528         *angle = reply_angle;
529         *init_direction = reply_init_direction;
530
531         return DEVICE_ERROR_NONE;
532 }
533
534 int device_display_set_rotation_angle(int display_index,
535                                 device_display_rotation_angle_e angle,
536                                 device_display_rotation_direction_e rotation_direction)
537 {
538         int ret, reply;
539
540         ret = is_feature_display_supported();
541         if (!ret)
542                 return DEVICE_ERROR_NOT_SUPPORTED;
543
544         if (display_cnt < 0) {
545                 ret = device_display_get_numbers(&display_cnt);
546                 if (ret < 0)
547                         return ret;
548         }
549
550         if (display_index < 0 || display_index >= display_cnt)
551                 return DEVICE_ERROR_INVALID_PARAMETER;
552
553         if (angle < DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_0
554                 || angle > ROTATION_ANGLE_DEGREE_MAX)
555                 return DEVICE_ERROR_INVALID_PARAMETER;
556
557         switch (rotation_direction) {
558         case DEVICE_DISPLAY_ROTATION_DIRECTION_CLOCKWISE:
559         case DEVICE_DISPLAY_ROTATION_DIRECTION_COUNTER_CLOCKWISE:
560                 break;
561         default:
562                 return DEVICE_ERROR_INVALID_PARAMETER;
563         }
564
565         ret = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
566                                         DEVICED_PATH_DISPLAY,
567                                         DEVICED_INTERFACE_DISPLAY,
568                                         METHOD_SET_ROTATION_ANGLE,
569                                         g_variant_new("(iii)", display_index, angle, rotation_direction),
570                                         &reply);
571
572         if (ret < 0) {
573                 _E("Failed to call dbus method to set the rotation angle");
574                 return ret;
575         }
576
577         if (reply == -ENODEV) {
578                 _E("Set display rotation is not supported");
579                 return DEVICE_ERROR_OPERATION_FAILED;
580         } else if (reply < 0) {
581                 _E("Failed to set display rotation angle");
582                 return DEVICE_ERROR_OPERATION_FAILED;
583         }
584
585         return DEVICE_ERROR_NONE;
586 }
587
588 int is_feature_display_state_supported(void)
589 {
590         int ret_val;
591         bool display_state_avail;
592
593         ret_val = system_info_get_platform_bool(DISPLAY_STATE_FEATURE, &display_state_avail);
594         if (ret_val < 0) {
595 //LCOV_EXCL_START System Error
596                 _E("Failed to get value of display state feature");
597                 return false;
598 //LCOV_EXCL_STOP
599         } else if (ret_val == 0 && !display_state_avail) {
600 //LCOV_EXCL_START System Error
601                 _D("Display state feature is not supported");
602                 return false;
603 //LCOV_EXCL_STOP
604         } else
605                 return true;
606 }
607
608 int device_display_set_white_balance(int display_index, display_white_balance_e white_balance_type, int value)
609 {
610         int ret;
611
612         if (!is_feature_display_supported())
613                 return DEVICE_ERROR_NOT_SUPPORTED;
614
615         if (display_cnt < 0) {
616                 ret = device_display_get_numbers(&display_cnt);
617                 if (ret != DEVICE_ERROR_NONE)
618                         return ret;
619         }
620
621         if (display_index < 0 || display_index >= display_cnt)
622                 return DEVICE_ERROR_INVALID_PARAMETER;
623
624         switch (white_balance_type) {
625         case DISPLAY_WHITE_BALANCE_R_GAIN:
626         case DISPLAY_WHITE_BALANCE_G_GAIN:
627         case DISPLAY_WHITE_BALANCE_B_GAIN:
628                 if (value < DISPLAY_WHITE_BALANCE_GAIN_MIN || value > DISPLAY_WHITE_BALANCE_GAIN_MAX) {
629                         _E("Invalid value of white balance gain (%d)", white_balance_type);
630                         return DEVICE_ERROR_INVALID_PARAMETER;
631                 }
632                 break;
633         case DISPLAY_WHITE_BALANCE_R_OFFSET:
634         case DISPLAY_WHITE_BALANCE_G_OFFSET:
635         case DISPLAY_WHITE_BALANCE_B_OFFSET:
636                 if (value < DISPLAY_WHITE_BALANCE_OFFSET_MIN || value > DISPLAY_WHITE_BALANCE_OFFSET_MAX) {
637                         _E("Invalid value of white balance offset (%d)", white_balance_type);
638                         return DEVICE_ERROR_INVALID_PARAMETER;
639                 }
640                 break;
641         default:
642                 _E("Unknown white balance type");
643                 return DEVICE_ERROR_INVALID_PARAMETER;
644         }
645
646         ret = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
647                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
648                                 METHOD_SET_WHITE_BALANCE, g_variant_new("(ii)",
649                                 (int)white_balance_type, value),
650                                 NULL);
651
652         if (ret < 0)
653                 return errno_to_device_error(ret);
654
655         return DEVICE_ERROR_NONE;
656 }
657
658 int device_display_get_white_balance(int display_index, display_white_balance_e white_balance_type, int *value)
659 {
660         int ret, reply;
661
662         if (!is_feature_display_supported())
663                 return DEVICE_ERROR_NOT_SUPPORTED;
664
665         if (display_cnt < 0) {
666                 ret = device_display_get_numbers(&display_cnt);
667                 if (ret != DEVICE_ERROR_NONE)
668                         return ret;
669         }
670
671         if (display_index < 0 || display_index >= display_cnt)
672                 return DEVICE_ERROR_INVALID_PARAMETER;
673
674         switch (white_balance_type) {
675         case DISPLAY_WHITE_BALANCE_R_GAIN:
676         case DISPLAY_WHITE_BALANCE_G_GAIN:
677         case DISPLAY_WHITE_BALANCE_B_GAIN:
678         case DISPLAY_WHITE_BALANCE_R_OFFSET:
679         case DISPLAY_WHITE_BALANCE_G_OFFSET:
680         case DISPLAY_WHITE_BALANCE_B_OFFSET:
681                 break;
682         default:
683                 _E("Unknown white balance type");
684                 return DEVICE_ERROR_INVALID_PARAMETER;
685         }
686
687         ret = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
688                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
689                                 METHOD_GET_WHITE_BALANCE, g_variant_new("(i)",
690                                 (int)white_balance_type),
691                                 &reply);
692
693         if (ret < 0)
694                 return errno_to_device_error(ret);
695
696         if (reply < 0)
697                 return DEVICE_ERROR_OPERATION_FAILED;
698
699         *value = reply;
700
701         return DEVICE_ERROR_NONE;
702 }