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 static void change_cb(GVariant *result, void *data, GError *err)
260 //LCOV_EXCL_START System Error
261 _E("no message : %s", err->message);
266 g_variant_get(result, "(i)", &val);
267 _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_CHANGE_STATE, val);
270 int device_display_change_state(display_state_e state)
274 static int privilege = -1;
275 static long num_calls = 0;
277 ret = is_feature_display_state_supported();
279 return DEVICE_ERROR_NOT_SUPPORTED;
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;
289 if (state < DISPLAY_STATE_NORMAL || state > DISPLAY_STATE_SCREEN_OFF)
290 return DEVICE_ERROR_INVALID_PARAMETER;
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"),
297 //LCOV_EXCL_START System Error
299 return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
305 str = get_state_str(state);
307 return DEVICE_ERROR_INVALID_PARAMETER;
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);
314 ret = errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
319 //LCOV_EXCL_START Not tested API
320 int device_display_get_max_brightness_state(int display_index, display_state_e state, int *brightness)
324 ret_val = is_feature_display_supported();
326 return DEVICE_ERROR_NOT_SUPPORTED;
329 return DEVICE_ERROR_INVALID_PARAMETER;
331 if (state > DISPLAY_STATE_SCREEN_DIM)
332 return DEVICE_ERROR_INVALID_PARAMETER;
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
340 if (display_index < 0 || display_index >= display_cnt)
341 return DEVICE_ERROR_INVALID_PARAMETER;
343 if (!display_arr && alloc_display() < 0)
344 return DEVICE_ERROR_OPERATION_FAILED;
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),
351 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
353 if (state == DISPLAY_STATE_NORMAL) {
354 display_arr[display_index].normal_max = reply;
355 *brightness = display_arr[display_index].normal_max;
357 display_arr[display_index].dim_max = reply;
358 *brightness = display_arr[display_index].dim_max;
361 return DEVICE_ERROR_NONE;
365 //LCOV_EXCL_START Not tested API
366 int device_display_get_brightness_state(int display_index, display_state_e state, int *brightness)
370 ret_val = is_feature_display_supported();
372 return DEVICE_ERROR_NOT_SUPPORTED;
375 return DEVICE_ERROR_INVALID_PARAMETER;
377 if (state > DISPLAY_STATE_SCREEN_DIM)
378 return DEVICE_ERROR_INVALID_PARAMETER;
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
386 if (display_index < 0 || display_index >= display_cnt)
387 return DEVICE_ERROR_INVALID_PARAMETER;
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),
394 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
398 return DEVICE_ERROR_NONE;
402 //LCOV_EXCL_START Not tested API
403 int device_display_set_brightness_state(int display_index, display_state_e state, int brightness)
407 ret_val = is_feature_display_supported();
409 return DEVICE_ERROR_NOT_SUPPORTED;
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
417 if (state > DISPLAY_STATE_SCREEN_DIM)
418 return DEVICE_ERROR_INVALID_PARAMETER;
420 if (display_index < 0 || display_index >= display_cnt)
421 return DEVICE_ERROR_INVALID_PARAMETER;
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;
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;
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),
445 return errno_to_device_error(ret_val); //LCOV_EXCL_LINE System Error
447 return DEVICE_ERROR_NONE;
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)
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);
460 return errno_to_device_error(ret);
464 int is_feature_display_supported(void)
469 ret_val = system_info_get_platform_bool(DISPLAY_FEATURE, &display_avail);
471 //LCOV_EXCL_START System Error
472 _E("Failed to get value of display feature");
475 } else if (ret_val == 0 && !display_avail) {
476 //LCOV_EXCL_START System Error
477 _D("Display feature is not supported");
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)
488 int ret = 0, reply_angle, reply_init_direction;
491 ret = is_feature_display_supported();
493 return DEVICE_ERROR_NOT_SUPPORTED;
495 if (display_cnt < 0) {
496 ret = device_display_get_numbers(&display_cnt);
501 if (display_index < 0 || display_index >= display_cnt || !angle || !init_direction)
502 return DEVICE_ERROR_INVALID_PARAMETER;
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),
513 _E("Failed to call dbus method to get the rotation angle");
517 g_variant_get(reply, "(iii)", &ret, &reply_angle, &reply_init_direction);
518 g_variant_unref(reply);
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;
528 *angle = reply_angle;
529 *init_direction = reply_init_direction;
531 return DEVICE_ERROR_NONE;
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)
540 ret = is_feature_display_supported();
542 return DEVICE_ERROR_NOT_SUPPORTED;
544 if (display_cnt < 0) {
545 ret = device_display_get_numbers(&display_cnt);
550 if (display_index < 0 || display_index >= display_cnt)
551 return DEVICE_ERROR_INVALID_PARAMETER;
553 if (angle < DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_0
554 || angle > ROTATION_ANGLE_DEGREE_MAX)
555 return DEVICE_ERROR_INVALID_PARAMETER;
557 switch (rotation_direction) {
558 case DEVICE_DISPLAY_ROTATION_DIRECTION_CLOCKWISE:
559 case DEVICE_DISPLAY_ROTATION_DIRECTION_COUNTER_CLOCKWISE:
562 return DEVICE_ERROR_INVALID_PARAMETER;
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),
573 _E("Failed to call dbus method to set the rotation angle");
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;
585 return DEVICE_ERROR_NONE;
588 int is_feature_display_state_supported(void)
591 bool display_state_avail;
593 ret_val = system_info_get_platform_bool(DISPLAY_STATE_FEATURE, &display_state_avail);
595 //LCOV_EXCL_START System Error
596 _E("Failed to get value of display state feature");
599 } else if (ret_val == 0 && !display_state_avail) {
600 //LCOV_EXCL_START System Error
601 _D("Display state feature is not supported");
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;
658 int device_display_get_white_balance(int display_index, display_white_balance_e white_balance_type, int *value)
662 if (!is_feature_display_supported())
663 return DEVICE_ERROR_NOT_SUPPORTED;
665 if (display_cnt < 0) {
666 ret = device_display_get_numbers(&display_cnt);
667 if (ret != DEVICE_ERROR_NONE)
671 if (display_index < 0 || display_index >= display_cnt)
672 return DEVICE_ERROR_INVALID_PARAMETER;
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:
683 _E("Unknown white balance type");
684 return DEVICE_ERROR_INVALID_PARAMETER;
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),
694 return errno_to_device_error(ret);
697 return DEVICE_ERROR_OPERATION_FAILED;
701 return DEVICE_ERROR_NONE;