315cb0ed78fa64af8a9ebeea5362bb2d2354ac19
[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 #include <vconf.h>
21 #include <libsyscommon/dbus-system.h>
22
23 #include "display.h"
24 #include "display-internal.h"
25 #include "common.h"
26
27 #define METHOD_GET_DISPLAY_COUNT        "GetDisplayCount"
28 #define METHOD_GET_MAX_BRIGHTNESS       "GetMaxBrightness"
29 #define METHOD_GET_BRIGHTNESS           "GetBrightness"
30 #define METHOD_SET_BRIGHTNESS           "SetBrightness"
31 #define METHOD_CHANGE_STATE             "changestate"
32 #define METHOD_CHANGE_STATE_BY_REASON   "ChangeStateByReason"
33
34 #define STR_LCD_OFF   "lcdoff"
35 #define STR_LCD_DIM   "lcddim"
36 #define STR_LCD_ON    "lcdon"
37
38 static int display_cnt = -1;
39 struct display {
40         int normal_max;
41         int dim_max;
42 } *display_arr;
43
44 static int alloc_display(void)
45 {
46         int i;
47
48         if (display_cnt < 0)
49                 return -ENODEV;
50
51         display_arr = malloc(sizeof(struct display) * display_cnt);
52         if (!display_arr)
53                 return -ENOMEM;
54
55         for (i = 0; i < display_cnt; ++i) {
56                 display_arr[i].normal_max = -1;
57                 display_arr[i].dim_max = -1;
58         }
59
60         return 0;
61 }
62
63 int device_display_get_numbers(int *device_number)
64 {
65         int ret;
66
67         ret = is_display_supported();
68         if (!ret)
69                 return DEVICE_ERROR_NOT_SUPPORTED;
70
71         if (!device_number)
72                 return DEVICE_ERROR_INVALID_PARAMETER;
73
74         /* if it is a first request */
75         if (display_cnt < 0) {
76                 ret = dbus_handle_method_sync_var(DEVICED_BUS_NAME,
77                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
78                                 METHOD_GET_DISPLAY_COUNT, NULL);
79                 if (ret < 0)
80                         return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
81                 display_cnt = ret;
82                 alloc_display();
83         }
84
85         *device_number = display_cnt;
86         _I("device_number : %d", *device_number);
87         return DEVICE_ERROR_NONE;
88 }
89
90 int device_display_get_max_brightness(int display_index, int *max_brightness)
91 {
92         int ret;
93
94         ret = is_display_supported();
95         if (!ret)
96                 return DEVICE_ERROR_NOT_SUPPORTED;
97
98         if (!max_brightness)
99                 return DEVICE_ERROR_INVALID_PARAMETER;
100
101         if (display_cnt < 0) {
102                 ret = device_display_get_numbers(&display_cnt);
103                 if (ret != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
104                         return ret;
105         }
106
107         if (display_index < 0 || display_index >= display_cnt)
108                 return DEVICE_ERROR_INVALID_PARAMETER;
109
110         if (!display_arr && alloc_display() < 0)
111                 return DEVICE_ERROR_OPERATION_FAILED;
112
113         if (display_arr[display_index].normal_max < 0) {
114                 ret = dbus_handle_method_sync_var(DEVICED_BUS_NAME,
115                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
116                                 METHOD_GET_MAX_BRIGHTNESS, g_variant_new("(i)", (int)DISPLAY_STATE_NORMAL));
117                 if (ret < 0)
118                         return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
119                 display_arr[display_index].normal_max = ret;
120         }
121
122         *max_brightness = display_arr[display_index].normal_max;
123         return DEVICE_ERROR_NONE;
124 }
125
126 int device_display_get_brightness(int display_index, int *brightness)
127 {
128         int ret;
129
130         ret = is_display_supported();
131         if (!ret)
132                 return DEVICE_ERROR_NOT_SUPPORTED;
133
134         if (!brightness)
135                 return DEVICE_ERROR_INVALID_PARAMETER;
136
137         if (display_cnt < 0) {
138                 ret = device_display_get_numbers(&display_cnt);
139                 if (ret != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
140                         return ret;
141         }
142
143         if (display_index < 0 || display_index >= display_cnt)
144                 return DEVICE_ERROR_INVALID_PARAMETER;
145
146         ret = dbus_handle_method_sync_var(DEVICED_BUS_NAME,
147                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
148                         METHOD_GET_BRIGHTNESS, g_variant_new("(i)", (int)DISPLAY_STATE_NORMAL));
149         if (ret < 0)
150                 return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
151
152         *brightness = ret;
153         return DEVICE_ERROR_NONE;
154 }
155
156 int device_display_set_brightness(int display_index, int brightness)
157 {
158         int ret, max;
159
160         ret = is_display_supported();
161         if (!ret)
162                 return DEVICE_ERROR_NOT_SUPPORTED;
163
164         if (display_cnt < 0) {
165                 ret = device_display_get_numbers(&display_cnt);
166                 if (ret != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
167                         return ret;
168         }
169
170         if (display_index < 0 || display_index >= display_cnt)
171                 return DEVICE_ERROR_INVALID_PARAMETER;
172
173         if (display_arr[display_index].normal_max < 0)
174                 device_display_get_max_brightness(display_index, &max);
175
176         if (brightness < 0 || brightness > display_arr[display_index].normal_max)
177                 return DEVICE_ERROR_INVALID_PARAMETER;
178
179         ret = dbus_handle_method_sync_var(DEVICED_BUS_NAME,
180                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
181                         METHOD_SET_BRIGHTNESS, g_variant_new("(ii)", (int)DISPLAY_STATE_NORMAL, brightness));
182         if (ret < 0)
183                 return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
184
185         return DEVICE_ERROR_NONE;
186 }
187
188 int device_display_get_state(display_state_e *state)
189 {
190         int ret, val;
191
192         ret = is_display_supported();
193         if (!ret)
194                 return DEVICE_ERROR_NOT_SUPPORTED;
195
196         if (!state)
197                 return DEVICE_ERROR_INVALID_PARAMETER;
198
199         ret = vconf_get_int(VCONFKEY_PM_STATE, &val);
200         if (ret < 0)
201                 return DEVICE_ERROR_OPERATION_FAILED;
202
203         if (val == VCONFKEY_PM_STATE_NORMAL)
204                 *state = DISPLAY_STATE_NORMAL;
205         else if (val == VCONFKEY_PM_STATE_LCDDIM)
206                 *state = DISPLAY_STATE_SCREEN_DIM;
207         else if (val == VCONFKEY_PM_STATE_LCDOFF || val == VCONFKEY_PM_STATE_SLEEP)
208                 *state = DISPLAY_STATE_SCREEN_OFF;
209         else
210                 return DEVICE_ERROR_OPERATION_FAILED;
211
212         return DEVICE_ERROR_NONE;
213 }
214
215 static char *get_state_str(display_state_e state)
216 {
217         switch (state) {
218         case DISPLAY_STATE_NORMAL:
219                 return STR_LCD_ON;
220         case DISPLAY_STATE_SCREEN_DIM:
221                 return STR_LCD_DIM;
222         case DISPLAY_STATE_SCREEN_OFF:
223                 return STR_LCD_OFF;
224         default:
225                 break;
226         }
227         return NULL;
228 }
229
230 static void change_cb(GVariant *result, void *data, GError *err)
231 {
232         int ret;
233
234         if (!result) {
235 //LCOV_EXCL_START System Error
236                 _E("no message : %s", err->message);
237                 return;
238 //LCOV_EXCL_STOP
239         }
240
241         g_variant_get(result, "(i)", &ret);
242         _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_CHANGE_STATE, ret);
243 }
244
245 int device_display_change_state(display_state_e state)
246 {
247         char *str;
248         int ret;
249         static int privilege = -1;
250         static long num_calls = 0;
251
252         ret = is_display_state_supported();
253         if (!ret)
254                 return DEVICE_ERROR_NOT_SUPPORTED;
255
256         if (check_async_call_rate(&num_calls) < 0) {
257 //LCOV_EXCL_START System Error
258                 _E("Rejected by too frequent calls; %d (calls per sec.) limit is violated."
259                                 , CHECK_RATE_THRESHOLD);
260                 return DEVICE_ERROR_OPERATION_FAILED;
261 //LCOV_EXCL_STOP
262         }
263
264         if (state < DISPLAY_STATE_NORMAL || state > DISPLAY_STATE_SCREEN_OFF)
265                 return DEVICE_ERROR_INVALID_PARAMETER;
266
267         if (privilege < 0) {
268                 ret = dbus_handle_method_sync_var(DEVICED_BUS_NAME,
269                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
270                                 METHOD_CHANGE_STATE, g_variant_new("(s)", "privilege check"));
271 //LCOV_EXCL_START System Error
272                 if (ret < 0)
273                         return ret;
274 //LCOV_EXCL_STOP
275                 else
276                         privilege = 1;
277         }
278
279         str = get_state_str(state);
280         if (!str)
281                 return DEVICE_ERROR_INVALID_PARAMETER;
282
283         return dbus_handle_method_async_with_reply_var(DEVICED_BUS_NAME,
284                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
285                         METHOD_CHANGE_STATE, g_variant_new("(s)", str), change_cb, -1, NULL);
286 }
287
288 int device_display_get_max_brightness_state(int display_index, display_state_e state, int *brightness)
289 {
290         int ret;
291
292         ret = is_display_supported();
293         if (!ret)
294                 return DEVICE_ERROR_NOT_SUPPORTED;
295
296         if (!brightness)
297                 return DEVICE_ERROR_INVALID_PARAMETER;
298
299         if (state > DISPLAY_STATE_SCREEN_DIM)
300                 return DEVICE_ERROR_INVALID_PARAMETER;
301
302         if (display_cnt < 0) {
303                 ret = device_display_get_numbers(&display_cnt);
304                 if (ret != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
305                         return ret;
306         }
307
308         if (display_index < 0 || display_index >= display_cnt)
309                 return DEVICE_ERROR_INVALID_PARAMETER;
310
311         if (!display_arr && alloc_display() < 0)
312                 return DEVICE_ERROR_OPERATION_FAILED;
313
314         ret = dbus_handle_method_sync_var(DEVICED_BUS_NAME,
315                                 DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
316                                 METHOD_GET_MAX_BRIGHTNESS, g_variant_new("(i)", (int)state));
317         if (ret < 0)
318                 return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
319
320         if (state == DISPLAY_STATE_NORMAL) {
321                 display_arr[display_index].normal_max = ret;
322                 *brightness = display_arr[display_index].normal_max;
323         } else {
324                 display_arr[display_index].dim_max = ret;
325                 *brightness = display_arr[display_index].dim_max;
326         }
327
328         return DEVICE_ERROR_NONE;
329 }
330 //LCOV_EXCL_STOP
331
332 int device_display_get_brightness_state(int display_index, display_state_e state, int *brightness)
333 {
334         int ret;
335
336         ret = is_display_supported();
337         if (!ret)
338                 return DEVICE_ERROR_NOT_SUPPORTED;
339
340         if (!brightness)
341                 return DEVICE_ERROR_INVALID_PARAMETER;
342
343         if (state > DISPLAY_STATE_SCREEN_DIM)
344                 return DEVICE_ERROR_INVALID_PARAMETER;
345
346         if (display_cnt < 0) {
347                 ret = device_display_get_numbers(&display_cnt);
348                 if (ret != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
349                         return ret;
350         }
351
352         if (display_index < 0 || display_index >= display_cnt)
353                 return DEVICE_ERROR_INVALID_PARAMETER;
354
355         ret = dbus_handle_method_sync_var(DEVICED_BUS_NAME,
356                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
357                         METHOD_GET_BRIGHTNESS, g_variant_new("(i)", (int)state));
358         if (ret < 0)
359                 return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
360
361         *brightness = ret;
362
363         return DEVICE_ERROR_NONE;
364 }
365
366 int device_display_set_brightness_state(int display_index, display_state_e state, int brightness)
367 {
368         int ret, max;
369
370         ret = is_display_supported();
371         if (!ret)
372                 return DEVICE_ERROR_NOT_SUPPORTED;
373
374         if (display_cnt < 0) {
375                 ret = device_display_get_numbers(&display_cnt);
376                 if (ret != DEVICE_ERROR_NONE) //LCOV_EXCL_LINE System Error
377                         return ret;
378         }
379
380         if (state > DISPLAY_STATE_SCREEN_DIM)
381                 return DEVICE_ERROR_INVALID_PARAMETER;
382
383         if (display_index < 0 || display_index >= display_cnt)
384                 return DEVICE_ERROR_INVALID_PARAMETER;
385
386         switch (state) {
387         case DISPLAY_STATE_NORMAL:
388                 if (display_arr[display_index].normal_max < 0)
389                         device_display_get_max_brightness_state(display_index, DISPLAY_STATE_NORMAL, &max);
390                 if (brightness < 0 || brightness > display_arr[display_index].normal_max)
391                         return DEVICE_ERROR_INVALID_PARAMETER;
392                 break;
393         case DISPLAY_STATE_SCREEN_DIM:
394                 if (display_arr[display_index].dim_max < 0)
395                         device_display_get_max_brightness_state(display_index, DISPLAY_STATE_SCREEN_DIM, &max);
396                 if (brightness < 0 || brightness > display_arr[display_index].dim_max)
397                         return DEVICE_ERROR_INVALID_PARAMETER;
398                 break;
399         default:
400                 break;
401         }
402
403         ret = dbus_handle_method_sync_var(DEVICED_BUS_NAME,
404                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
405                         METHOD_SET_BRIGHTNESS, g_variant_new("(ii)", (int)state, brightness));
406         if (ret < 0)
407                 return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
408
409         return DEVICE_ERROR_NONE;
410 }
411
412 int device_display_change_state_by_reason(display_state_e type, const char *reason, int timeout, dbus_pending_cb cb)
413 {
414         int ret;
415
416         ret = dbus_handle_method_async_with_reply_var(DEVICED_BUS_NAME,
417                         DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
418                         METHOD_CHANGE_STATE_BY_REASON, g_variant_new("(isi)", (int)type, reason, timeout), cb, -1, NULL);
419
420         return errno_to_device_error(ret);
421 }