2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <libsyscommon/libgdbus.h>
23 #include <system_info.h>
27 #include "display-internal.h"
30 #define DISPLAY_FEATURE "http://tizen.org/feature/display"
31 #define DISPLAY_STATE_FEATURE "http://tizen.org/feature/display.state"
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"
44 #define STR_LCD_OFF "lcdoff"
45 #define STR_LCD_DIM "lcddim"
46 #define STR_LCD_ON "lcdon"
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
53 #define ROTATION_ANGLE_DEGREE_MAX 360
55 static int display_cnt = -1;
61 static int alloc_display(void)
68 display_arr = malloc(sizeof(struct display) * display_cnt);
72 for (i = 0; i < display_cnt; ++i) {
73 display_arr[i].normal_max = -1;
74 display_arr[i].dim_max = -1;
80 int device_display_get_numbers(int *device_number)
84 ret_val = is_feature_display_supported();
86 return DEVICE_ERROR_NOT_SUPPORTED;
89 return DEVICE_ERROR_INVALID_PARAMETER;
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);
97 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
102 *device_number = display_cnt;
103 _I("device_number : %d", *device_number);
104 return DEVICE_ERROR_NONE;
107 int device_display_get_max_brightness(int display_index, int *max_brightness)
111 ret_val = is_feature_display_supported();
113 return DEVICE_ERROR_NOT_SUPPORTED;
116 return DEVICE_ERROR_INVALID_PARAMETER;
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
124 if (display_index < 0 || display_index >= display_cnt)
125 return DEVICE_ERROR_INVALID_PARAMETER;
127 if (!display_arr && alloc_display() < 0)
128 return DEVICE_ERROR_OPERATION_FAILED;
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),
136 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
137 display_arr[display_index].normal_max = reply;
140 *max_brightness = display_arr[display_index].normal_max;
141 return DEVICE_ERROR_NONE;
144 int device_display_get_brightness(int display_index, int *brightness)
148 ret_val = is_feature_display_supported();
150 return DEVICE_ERROR_NOT_SUPPORTED;
153 return DEVICE_ERROR_INVALID_PARAMETER;
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
161 if (display_index < 0 || display_index >= display_cnt)
162 return DEVICE_ERROR_INVALID_PARAMETER;
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),
169 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
172 return DEVICE_ERROR_NONE;
175 int device_display_set_brightness(int display_index, int brightness)
180 ret_val = is_feature_display_supported();
182 return DEVICE_ERROR_NOT_SUPPORTED;
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
190 if (display_index < 0 || display_index >= display_cnt)
191 return DEVICE_ERROR_INVALID_PARAMETER;
193 if (display_arr[display_index].normal_max < 0)
194 device_display_get_max_brightness(display_index, &max);
196 if (brightness < 0 || brightness > display_arr[display_index].normal_max)
197 return DEVICE_ERROR_INVALID_PARAMETER;
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),
205 return DEVICE_ERROR_OPERATION_FAILED;
208 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
210 return DEVICE_ERROR_NONE;
213 int device_display_get_state(display_state_e *state)
217 ret_val = is_feature_display_supported();
219 return DEVICE_ERROR_NOT_SUPPORTED;
222 return DEVICE_ERROR_INVALID_PARAMETER;
224 ret_val = vconf_get_int(VCONFKEY_PM_STATE, &val);
226 return DEVICE_ERROR_OPERATION_FAILED;
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;
235 return DEVICE_ERROR_OPERATION_FAILED;
237 return DEVICE_ERROR_NONE;
240 static char *get_state_str(display_state_e state)
243 case DISPLAY_STATE_NORMAL:
245 case DISPLAY_STATE_SCREEN_DIM:
247 case DISPLAY_STATE_SCREEN_OFF:
255 int device_display_change_state(display_state_e state)
260 static int privilege = -1;
261 static long num_calls = 0;
262 GVariant *reply = NULL;
264 ret = is_feature_display_state_supported();
266 return DEVICE_ERROR_NOT_SUPPORTED;
268 if (check_async_call_rate(&num_calls) < 0) {
269 //LCOV_EXCL_START System Error
270 _E("Rejected by too frequent calls; %d (calls per sec.) limit is violated."
271 , CHECK_RATE_THRESHOLD);
272 return DEVICE_ERROR_OPERATION_FAILED;
276 if (state < DISPLAY_STATE_NORMAL || state > DISPLAY_STATE_SCREEN_OFF)
277 return DEVICE_ERROR_INVALID_PARAMETER;
280 ret = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
281 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
282 METHOD_CHANGE_STATE, g_variant_new("(s)", "privilege check"),
284 //LCOV_EXCL_START System Error
286 return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
292 str = get_state_str(state);
294 return DEVICE_ERROR_INVALID_PARAMETER;
296 ret = gdbus_call_sync_with_reply(DEVICED_BUS_NAME,
297 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
298 METHOD_CHANGE_STATE, g_variant_new("(s)", str), &reply);
301 ret = errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
304 g_variant_get(reply, "(i)", &val);
305 _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_CHANGE_STATE, val);
308 return errno_to_device_error(val);
314 //LCOV_EXCL_START Not tested API
315 int device_display_get_max_brightness_state(int display_index, display_state_e state, int *brightness)
319 ret_val = is_feature_display_supported();
321 return DEVICE_ERROR_NOT_SUPPORTED;
324 return DEVICE_ERROR_INVALID_PARAMETER;
326 if (state > DISPLAY_STATE_SCREEN_DIM)
327 return DEVICE_ERROR_INVALID_PARAMETER;
329 if (display_cnt < 0) {
330 ret_val = device_display_get_numbers(&display_cnt);
331 if (ret_val != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
335 if (display_index < 0 || display_index >= display_cnt)
336 return DEVICE_ERROR_INVALID_PARAMETER;
338 if (!display_arr && alloc_display() < 0)
339 return DEVICE_ERROR_OPERATION_FAILED;
341 ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
342 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
343 METHOD_GET_MAX_BRIGHTNESS, g_variant_new("(i)", (int)state),
346 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
348 if (state == DISPLAY_STATE_NORMAL) {
349 display_arr[display_index].normal_max = reply;
350 *brightness = display_arr[display_index].normal_max;
352 display_arr[display_index].dim_max = reply;
353 *brightness = display_arr[display_index].dim_max;
356 return DEVICE_ERROR_NONE;
360 //LCOV_EXCL_START Not tested API
361 int device_display_get_brightness_state(int display_index, display_state_e state, int *brightness)
365 ret_val = is_feature_display_supported();
367 return DEVICE_ERROR_NOT_SUPPORTED;
370 return DEVICE_ERROR_INVALID_PARAMETER;
372 if (state > DISPLAY_STATE_SCREEN_DIM)
373 return DEVICE_ERROR_INVALID_PARAMETER;
375 if (display_cnt < 0) {
376 ret_val = device_display_get_numbers(&display_cnt);
377 if (ret_val != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
381 if (display_index < 0 || display_index >= display_cnt)
382 return DEVICE_ERROR_INVALID_PARAMETER;
384 ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
385 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
386 METHOD_GET_BRIGHTNESS, g_variant_new("(i)", (int)state),
389 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
393 return DEVICE_ERROR_NONE;
397 //LCOV_EXCL_START Not tested API
398 int device_display_set_brightness_state(int display_index, display_state_e state, int brightness)
402 ret_val = is_feature_display_supported();
404 return DEVICE_ERROR_NOT_SUPPORTED;
406 if (display_cnt < 0) {
407 ret_val = device_display_get_numbers(&display_cnt);
408 if (ret_val != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
412 if (state > DISPLAY_STATE_SCREEN_DIM)
413 return DEVICE_ERROR_INVALID_PARAMETER;
415 if (display_index < 0 || display_index >= display_cnt)
416 return DEVICE_ERROR_INVALID_PARAMETER;
419 case DISPLAY_STATE_NORMAL:
420 if (display_arr[display_index].normal_max < 0)
421 device_display_get_max_brightness_state(display_index, DISPLAY_STATE_NORMAL, &max);
422 if (brightness < 0 || brightness > display_arr[display_index].normal_max)
423 return DEVICE_ERROR_INVALID_PARAMETER;
425 case DISPLAY_STATE_SCREEN_DIM:
426 if (display_arr[display_index].dim_max < 0)
427 device_display_get_max_brightness_state(display_index, DISPLAY_STATE_SCREEN_DIM, &max);
428 if (brightness < 0 || brightness > display_arr[display_index].dim_max)
429 return DEVICE_ERROR_INVALID_PARAMETER;
435 ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
436 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
437 METHOD_SET_BRIGHTNESS, g_variant_new("(ii)", (int)state, brightness),
440 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
442 return DEVICE_ERROR_NONE;
446 //LCOV_EXCL_START Not tested API
447 int device_display_change_state_by_reason(display_state_e type, const char *reason, int timeout, dbus_pending_cb cb)
451 ret = gdbus_call_async_with_reply(DEVICED_BUS_NAME,
452 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
453 METHOD_CHANGE_STATE_BY_REASON, g_variant_new("(isi)", (int)type, reason, timeout), cb, -1, NULL);
455 return errno_to_device_error(ret);
459 int is_feature_display_supported(void)
464 ret_val = system_info_get_platform_bool(DISPLAY_FEATURE, &display_avail);
466 //LCOV_EXCL_START System Error
467 _E("Failed to get value of display feature");
470 } else if (ret_val == 0 && !display_avail) {
471 //LCOV_EXCL_START System Error
472 _D("Display feature is not supported");
479 //LCOV_EXCL_START Internal function
480 int device_display_get_rotation_angle(int display_index,
481 device_display_rotation_angle_e *angle,
482 device_display_init_direction_e *init_direction)
484 int ret = 0, reply_angle, reply_init_direction;
487 ret = is_feature_display_supported();
489 return DEVICE_ERROR_NOT_SUPPORTED;
491 if (display_cnt < 0) {
492 ret = device_display_get_numbers(&display_cnt);
497 if (display_index < 0 || display_index >= display_cnt || !angle || !init_direction)
498 return DEVICE_ERROR_INVALID_PARAMETER;
500 /* Get the display rotation angle from deviced */
501 ret = gdbus_call_sync_with_reply(DEVICED_BUS_NAME,
502 DEVICED_PATH_DISPLAY,
503 DEVICED_INTERFACE_DISPLAY,
504 METHOD_GET_ROTATION_ANGLE,
505 g_variant_new("(i)", display_index),
509 _E("Failed to call dbus method to get the rotation angle");
513 g_variant_get(reply, "(iii)", &ret, &reply_angle, &reply_init_direction);
514 g_variant_unref(reply);
516 if (ret == -ENODEV) {
517 _E("Get display rotation is not supported");
518 return DEVICE_ERROR_OPERATION_FAILED;
519 } else if (ret < 0) {
520 _E("Failed to get display rotation angle");
521 return DEVICE_ERROR_OPERATION_FAILED;
524 *angle = reply_angle;
525 *init_direction = reply_init_direction;
527 return DEVICE_ERROR_NONE;
531 //LCOV_EXCL_START Internal function
532 int device_display_set_rotation_angle(int display_index,
533 device_display_rotation_angle_e angle,
534 device_display_rotation_direction_e rotation_direction)
538 ret = is_feature_display_supported();
540 return DEVICE_ERROR_NOT_SUPPORTED;
542 if (display_cnt < 0) {
543 ret = device_display_get_numbers(&display_cnt);
548 if (display_index < 0 || display_index >= display_cnt)
549 return DEVICE_ERROR_INVALID_PARAMETER;
551 if (angle < DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_0
552 || angle > ROTATION_ANGLE_DEGREE_MAX)
553 return DEVICE_ERROR_INVALID_PARAMETER;
555 switch (rotation_direction) {
556 case DEVICE_DISPLAY_ROTATION_DIRECTION_CLOCKWISE:
557 case DEVICE_DISPLAY_ROTATION_DIRECTION_COUNTER_CLOCKWISE:
560 return DEVICE_ERROR_INVALID_PARAMETER;
563 ret = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
564 DEVICED_PATH_DISPLAY,
565 DEVICED_INTERFACE_DISPLAY,
566 METHOD_SET_ROTATION_ANGLE,
567 g_variant_new("(iii)", display_index, angle, rotation_direction),
571 _E("Failed to call dbus method to set the rotation angle");
575 if (reply == -ENODEV) {
576 _E("Set display rotation is not supported");
577 return DEVICE_ERROR_OPERATION_FAILED;
578 } else if (reply < 0) {
579 _E("Failed to set display rotation angle");
580 return DEVICE_ERROR_OPERATION_FAILED;
583 return DEVICE_ERROR_NONE;
587 int is_feature_display_state_supported(void)
590 bool display_state_avail;
592 ret_val = system_info_get_platform_bool(DISPLAY_STATE_FEATURE, &display_state_avail);
594 //LCOV_EXCL_START System Error
595 _E("Failed to get value of display state feature");
598 } else if (ret_val == 0 && !display_state_avail) {
599 //LCOV_EXCL_START System Error
600 _D("Display state feature is not supported");
607 //LCOV_EXCL_START Internal function
608 int device_display_set_white_balance(int display_index, display_white_balance_e white_balance_type, int value)
612 if (!is_feature_display_supported())
613 return DEVICE_ERROR_NOT_SUPPORTED;
615 if (display_cnt < 0) {
616 ret = device_display_get_numbers(&display_cnt);
617 if (ret != DEVICE_ERROR_NONE)
621 if (display_index < 0 || display_index >= display_cnt)
622 return DEVICE_ERROR_INVALID_PARAMETER;
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;
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;
642 _E("Unknown white balance type");
643 return DEVICE_ERROR_INVALID_PARAMETER;
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),
653 return errno_to_device_error(ret);
655 return DEVICE_ERROR_NONE;
659 //LCOV_EXCL_START Internal function
660 int device_display_get_white_balance(int display_index, display_white_balance_e white_balance_type, int *value)
664 if (!is_feature_display_supported())
665 return DEVICE_ERROR_NOT_SUPPORTED;
667 if (display_cnt < 0) {
668 ret = device_display_get_numbers(&display_cnt);
669 if (ret != DEVICE_ERROR_NONE)
673 if (display_index < 0 || display_index >= display_cnt)
674 return DEVICE_ERROR_INVALID_PARAMETER;
676 switch (white_balance_type) {
677 case DISPLAY_WHITE_BALANCE_R_GAIN:
678 case DISPLAY_WHITE_BALANCE_G_GAIN:
679 case DISPLAY_WHITE_BALANCE_B_GAIN:
680 case DISPLAY_WHITE_BALANCE_R_OFFSET:
681 case DISPLAY_WHITE_BALANCE_G_OFFSET:
682 case DISPLAY_WHITE_BALANCE_B_OFFSET:
685 _E("Unknown white balance type");
686 return DEVICE_ERROR_INVALID_PARAMETER;
689 ret = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
690 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
691 METHOD_GET_WHITE_BALANCE, g_variant_new("(i)",
692 (int)white_balance_type),
696 return errno_to_device_error(ret);
699 return DEVICE_ERROR_OPERATION_FAILED;
703 return DEVICE_ERROR_NONE;