57f9c7064d662889c4961a1a00900943df554c1b
[platform/core/system/deviced.git] / src / extcon / cradle.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
5  *
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
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19
20 #include <stdio.h>
21 #include <vconf.h>
22 #include <libsyscommon/libgdbus.h>
23 #include <system/syscommon-plugin-deviced-common-interface.h>
24
25 #include "core/log.h"
26 #include "shared/device-notifier.h"
27 #include "core/udev.h"
28 #include "core.h"
29 #include "display-lock.h"
30 #include "display-ops.h"
31 #include "display-plugin.h"
32 #include "display-state-transition.h"
33 #include "extcon/extcon.h"
34 #include "shared/plugin.h"
35
36 #define METHOD_GET_CRADLE       "GetCradle"
37 #define SIGNAL_CRADLE_STATE     "ChangedCradle"
38
39 static struct extcon_ops cradle_extcon_ops;
40
41 static void cradle_send_broadcast(int status)
42 {
43         static int old;
44         int ret;
45
46         if (old == status)
47                 return;
48
49         _I("Broadcast cradle status(%d).", status);
50         old = status;
51
52         ret = gdbus_signal_emit(NULL,
53                                                 DEVICED_PATH_SYSNOTI,
54                                                 DEVICED_INTERFACE_SYSNOTI,
55                                                 SIGNAL_CRADLE_STATE,
56                                                 g_variant_new("(i)", status));
57         if (ret < 0)
58                 _E("Failed to send dbus signal(%s)", SIGNAL_CRADLE_STATE);
59 }
60
61 static int cradle_update(const char *index, int status)
62 {
63         int ret;
64
65         _I("Cradle changed. status=%d", status);
66         display_state_transition_request_state_transition_with_option(DEVICED_EVENT_EXTCON_CRADLE, LCD_NORMAL);
67         cradle_send_broadcast(status);
68         ret = vconf_set_int(VCONFKEY_SYSMAN_CRADLE_STATUS, status);
69         if (ret < 0) {
70                 _E("Failed to set vconf value for cradle status: %d", vconf_get_ext_errno());
71                 return -EIO;
72         }
73
74         if (status == DOCK_SOUND) {
75                 display_lock_request_lock_with_option(DEVICED_EVENT_EXTCON_CRADLE, LCD_DIM, STAY_CUR_STATE, 0);
76         } else if (status == DOCK_NONE) {
77                 display_lock_request_unlock_with_option(DEVICED_EVENT_EXTCON_CRADLE, LCD_DIM, PM_SLEEP_MARGIN);
78         }
79
80         return 0;
81 }
82
83 static int display_changed(void *data)
84 {
85         enum deviced_display_state state;
86         int cradle;
87
88         if (!data)
89                 return 0;
90
91         state = *(int *)data;
92         if (state != DEVICED_DISPLAY_STATE_ON)
93                 return 0;
94
95         cradle = cradle_extcon_ops.status;
96         if (cradle == DOCK_SOUND) {
97                 display_lock_request_lock_with_option(DEVICED_EVENT_EXTCON_CRADLE, LCD_DIM, STAY_CUR_STATE, 0);
98                 _I("Sound dock is connected. Dim lock is on.");
99         }
100
101         return 0;
102 }
103
104 static GVariant *dbus_cradle_handler(GDBusConnection *conn,
105         const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
106         GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
107 {
108         return g_variant_new("(i)", cradle_extcon_ops.status);
109 }
110
111 static const dbus_method_s dbus_methods[] = {
112         { METHOD_GET_CRADLE,     NULL, "i", dbus_cradle_handler },
113         /* Add methods here */
114 };
115
116 static const dbus_interface_u dbus_interface = {
117         .oh = NULL,
118         .name = DEVICED_INTERFACE_SYSNOTI,
119         .methods = dbus_methods,
120         .nr_methods = ARRAY_SIZE(dbus_methods),
121 };
122
123 static void cradle_init(void *data)
124 {
125         int ret;
126
127         syscommon_notifier_subscribe_notify(DEVICE_NOTIFIER_LCD, display_changed);
128
129         ret = gdbus_add_object(NULL, DEVICED_PATH_SYSNOTI, &dbus_interface);
130         if (ret < 0)
131                 _E("Failed to init dbus method: %d", ret);
132 }
133
134 static void cradle_exit(void *data)
135 {
136         syscommon_notifier_unsubscribe_notify(DEVICE_NOTIFIER_LCD, display_changed);
137 }
138
139 static struct extcon_ops cradle_extcon_ops = {
140         .name   = EXTCON_CABLE_DOCK,
141         .init   = cradle_init,
142         .exit   = cradle_exit,
143         .update = cradle_update,
144 };
145
146 EXTCON_OPS_REGISTER(cradle_extcon_ops)