change system header file from dd-system to dd-deviced
[platform/core/system/system-server.git] / src / shared / deviced-noti.c
1 /*
2  * libdeviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
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
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/un.h>
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <stdarg.h>
27 #include <errno.h>
28 #include <vconf.h>
29 #include <vconf-keys.h>
30
31 #include "dd-deviced.h"
32 #include "deviced-priv.h"
33 #include "log.h"
34
35 #define PREDEF_PWROFF_POPUP                     "pwroff-popup"
36 #define PREDEF_ENTERSLEEP                       "entersleep"
37 #define PREDEF_LEAVESLEEP                       "leavesleep"
38 #define PREDEF_REBOOT                           "reboot"
39 #define PREDEF_BACKGRD                          "backgrd"
40 #define PREDEF_FOREGRD                          "foregrd"
41 #define PREDEF_ACTIVE                           "active"
42 #define PREDEF_INACTIVE                         "inactive"
43 #define PREDEF_SET_DATETIME                     "set_datetime"
44 #define PREDEF_SET_TIMEZONE                     "set_timezone"
45 #define PREDEF_MOUNT_MMC                        "mountmmc"
46 #define PREDEF_UNMOUNT_MMC                      "unmountmmc"
47 #define PREDEF_FORMAT_MMC                       "formatmmc"
48
49 #define PREDEF_SET_MAX_FREQUENCY                "set_max_frequency"
50 #define PREDEF_SET_MIN_FREQUENCY                "set_min_frequency"
51 #define PREDEF_RELEASE_MAX_FREQUENCY            "release_max_frequency"
52 #define PREDEF_RELEASE_MIN_FREQUENCY            "release_min_frequency"
53
54 enum deviced_noti_cmd {
55         ADD_DEVICED_ACTION,
56         CALL_DEVICED_ACTION
57 };
58
59 #define SYSTEM_NOTI_SOCKET_PATH "/tmp/sn"
60 #define RETRY_READ_COUNT        10
61
62 static inline int send_int(int fd, int val)
63 {
64         return write(fd, &val, sizeof(int));
65 }
66
67 static inline int send_str(int fd, char *str)
68 {
69         int len;
70         int ret;
71         if (str == NULL) {
72                 len = 0;
73                 ret = write(fd, &len, sizeof(int));
74         } else {
75                 len = strlen(str);
76                 if (len > SYSTEM_NOTI_MAXSTR)
77                         len = SYSTEM_NOTI_MAXSTR;
78                 write(fd, &len, sizeof(int));
79                 ret = write(fd, str, len);
80         }
81         return ret;
82 }
83
84 static int deviced_noti_send(struct sysnoti *msg)
85 {
86         _E("--- %s: start", __FUNCTION__);
87         int client_len;
88         int client_sockfd;
89         int result;
90         int r;
91         int retry_count = 0;
92         struct sockaddr_un clientaddr;
93         int i;
94
95         client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
96         if (client_sockfd == -1) {
97                 _E("%s: socket create failed\n", __FUNCTION__);
98                 return -1;
99         }
100         bzero(&clientaddr, sizeof(clientaddr));
101         clientaddr.sun_family = AF_UNIX;
102         strncpy(clientaddr.sun_path, SYSTEM_NOTI_SOCKET_PATH, sizeof(clientaddr.sun_path) - 1);
103         client_len = sizeof(clientaddr);
104
105         if (connect(client_sockfd, (struct sockaddr *)&clientaddr, client_len) <
106             0) {
107                 _E("%s: connect failed\n", __FUNCTION__);
108                 close(client_sockfd);
109                 return -1;
110         }
111
112         send_int(client_sockfd, msg->pid);
113         send_int(client_sockfd, msg->cmd);
114         send_str(client_sockfd, msg->type);
115         send_str(client_sockfd, msg->path);
116         send_int(client_sockfd, msg->argc);
117         for (i = 0; i < msg->argc; i++)
118                 send_str(client_sockfd, msg->argv[i]);
119
120         _E("--- %s: read", __FUNCTION__);
121         while (retry_count < RETRY_READ_COUNT) {
122                 r = read(client_sockfd, &result, sizeof(int));
123                 if (r < 0) {
124                         if (errno == EINTR) {
125                                 _E("Re-read for error(EINTR)");
126                                 retry_count++;
127                                 continue;
128                         }
129                         _E("Read fail for str length");
130                         result = -1;
131                         break;
132
133                 }
134                 break;
135         }
136         if (retry_count == RETRY_READ_COUNT) {
137                 _E("Read retry failed");
138         }
139
140         close(client_sockfd);
141         _E("--- %s: end", __FUNCTION__);
142         return result;
143 }
144
145 API int deviced_call_predef_action(const char *type, int num, ...)
146 {
147         _E("--- %s: start", __FUNCTION__);
148         struct sysnoti *msg;
149         int ret;
150         va_list argptr;
151
152         int i;
153         char *args = NULL;
154
155         if (type == NULL || num > SYSTEM_NOTI_MAXARG) {
156                 errno = EINVAL;
157                 return -1;
158         }
159
160         msg = malloc(sizeof(struct sysnoti));
161
162         if (msg == NULL) {
163                 /* Do something for not enought memory error */
164                 return -1;
165         }
166
167         msg->pid = getpid();
168         msg->cmd = CALL_DEVICED_ACTION;
169         msg->type = (char *)type;
170         msg->path = NULL;
171
172         msg->argc = num;
173         va_start(argptr, num);
174         for (i = 0; i < num; i++) {
175                 args = va_arg(argptr, char *);
176                 msg->argv[i] = args;
177         }
178         va_end(argptr);
179
180         _E("--- %s: send msg", __FUNCTION__);
181         ret = deviced_noti_send(msg);
182         free(msg);
183
184         _E("--- %s: end", __FUNCTION__);
185         return ret;
186 }
187
188 API int deviced_inform_foregrd(void)
189 {
190         char buf[255];
191         snprintf(buf, sizeof(buf), "%d", getpid());
192         return deviced_call_predef_action(PREDEF_FOREGRD, 1, buf);
193 }
194
195 API int deviced_inform_backgrd(void)
196 {
197         char buf[255];
198         snprintf(buf, sizeof(buf), "%d", getpid());
199         return deviced_call_predef_action(PREDEF_BACKGRD, 1, buf);
200 }
201
202 API int deviced_inform_active(pid_t pid)
203 {
204         char buf[255];
205         snprintf(buf, sizeof(buf), "%d", pid);
206         return deviced_call_predef_action(PREDEF_ACTIVE, 1, buf);
207 }
208
209 API int deviced_inform_inactive(pid_t pid)
210 {
211         char buf[255];
212         snprintf(buf, sizeof(buf), "%d", pid);
213         return deviced_call_predef_action(PREDEF_INACTIVE, 1, buf);
214 }
215
216 API int deviced_request_poweroff(void)
217 {
218         return deviced_call_predef_action(PREDEF_PWROFF_POPUP, 0);
219 }
220
221 API int deviced_request_entersleep(void)
222 {
223         return deviced_call_predef_action(PREDEF_ENTERSLEEP, 0);
224 }
225
226 API int deviced_request_leavesleep(void)
227 {
228         return deviced_call_predef_action(PREDEF_LEAVESLEEP, 0);
229 }
230
231 API int deviced_request_reboot(void)
232 {
233         return deviced_call_predef_action(PREDEF_REBOOT, 0);
234 }
235
236 API int deviced_set_datetime(time_t timet)
237 {
238         if (timet < 0L)
239                 return -1;
240         char buf[255] = { 0 };
241         snprintf(buf, sizeof(buf), "%ld", timet);
242         return deviced_call_predef_action(PREDEF_SET_DATETIME, 1, buf);
243 }
244
245 API int deviced_set_timezone(char *tzpath_str)
246 {
247         if (tzpath_str == NULL)
248                 return -1;
249         char buf[255];
250         snprintf(buf, sizeof(buf), "%s", tzpath_str);
251         return deviced_call_predef_action(PREDEF_SET_TIMEZONE, 1, buf);
252 }
253
254 static int deviced_noti_mount_mmc_cb(keynode_t *key_nodes, void *data)
255 {
256         struct mmc_contents *mmc_data;
257         int mmc_err = 0;
258         mmc_data = (struct mmc_contents *)data;
259         _D("mountmmc_cb called");
260         if (vconf_keynode_get_int(key_nodes) ==
261             VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED) {
262                 _D("mount ok");
263                 (mmc_data->mmc_cb)(0, mmc_data->user_data);
264         } else if (vconf_keynode_get_int(key_nodes) ==
265                    VCONFKEY_SYSMAN_MMC_MOUNT_ALREADY) {
266                 _D("mount already");
267                 (mmc_data->mmc_cb)(-2, mmc_data->user_data);
268         } else {
269                 _D("mount fail");
270                 vconf_get_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, &mmc_err);
271                 (mmc_data->mmc_cb)(mmc_err, mmc_data->user_data);
272         }
273         vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_MOUNT,
274                                  (void *)deviced_noti_mount_mmc_cb);
275         return 0;
276 }
277
278 API int deviced_request_mount_mmc(struct mmc_contents *mmc_data)
279 {
280         if (mmc_data != NULL && mmc_data->mmc_cb != NULL)
281                 vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_MOUNT,
282                                          (void *)deviced_noti_mount_mmc_cb, (void *)mmc_data);
283         return deviced_call_predef_action(PREDEF_MOUNT_MMC, 0);
284 }
285
286 static int deviced_noti_unmount_mmc_cb(keynode_t *key_nodes, void *data)
287 {
288         struct mmc_contents *mmc_data;
289         int mmc_err = 0;
290         mmc_data = (struct mmc_contents *)data;
291         _D("unmountmmc_cb called");
292         if (vconf_keynode_get_int(key_nodes) ==
293             VCONFKEY_SYSMAN_MMC_UNMOUNT_COMPLETED) {
294                 _D("unmount ok");
295                 (mmc_data->mmc_cb)(0, mmc_data->user_data);
296         } else {
297                 _D("unmount fail");
298                 vconf_get_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, &mmc_err);
299                 (mmc_data->mmc_cb)(mmc_err, mmc_data->user_data);
300         }
301         vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_UNMOUNT,
302                                  (void *)deviced_noti_unmount_mmc_cb);
303         return 0;
304 }
305
306 API int deviced_request_unmount_mmc(struct mmc_contents *mmc_data, int option)
307 {
308         char buf[255];
309         if (option != 1 && option != 2) {
310                 _D("option is wrong. default option 1 will be used");
311                 option = 1;
312         }
313         snprintf(buf, sizeof(buf), "%d", option);
314
315         if (mmc_data != NULL && mmc_data->mmc_cb != NULL)
316                 vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_UNMOUNT,
317                                          (void *)deviced_noti_unmount_mmc_cb,
318                                          (void *)mmc_data);
319         return deviced_call_predef_action(PREDEF_UNMOUNT_MMC, 1, buf);
320 }
321
322 static int deviced_noti_format_mmc_cb(keynode_t *key_nodes, void *data)
323 {
324         struct mmc_contents *mmc_data;
325         mmc_data = (struct mmc_contents *)data;
326         _D("format_cb called");
327         if (vconf_keynode_get_int(key_nodes) ==
328             VCONFKEY_SYSMAN_MMC_FORMAT_COMPLETED) {
329                 _D("format ok");
330                 (mmc_data->mmc_cb)(0, mmc_data->user_data);
331
332         } else {
333                 _D("format fail");
334                 (mmc_data->mmc_cb)(-1, mmc_data->user_data);
335         }
336         vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_FORMAT,
337                                  (void *)deviced_noti_format_mmc_cb);
338         return 0;
339 }
340
341 API int deviced_request_format_mmc(struct mmc_contents *mmc_data)
342 {
343         if (mmc_data != NULL && mmc_data->mmc_cb != NULL)
344                 vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_FORMAT,
345                                          (void *)deviced_noti_format_mmc_cb,
346                                          (void *)mmc_data);
347         return deviced_call_predef_action(PREDEF_FORMAT_MMC, 0);
348 }
349
350 API int deviced_request_set_cpu_max_frequency(int val)
351 {
352         char buf_pid[8];
353         char buf_freq[256];
354
355         // to do - need to check new frequncy is valid
356         snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
357         snprintf(buf_freq, sizeof(buf_freq), "%d", val * 1000);
358
359         return deviced_call_predef_action(PREDEF_SET_MAX_FREQUENCY, 2, buf_pid, buf_freq);
360 }
361
362 API int deviced_request_set_cpu_min_frequency(int val)
363 {
364         char buf_pid[8];
365         char buf_freq[256];
366
367         // to do - need to check new frequncy is valid
368         snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
369         snprintf(buf_freq, sizeof(buf_freq), "%d", val * 1000);
370
371         return deviced_call_predef_action(PREDEF_SET_MIN_FREQUENCY, 2, buf_pid, buf_freq);
372 }
373
374 API int deviced_release_cpu_max_frequency()
375 {
376         char buf_pid[8];
377
378         snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
379
380         return deviced_call_predef_action(PREDEF_RELEASE_MAX_FREQUENCY, 1, buf_pid);
381 }
382
383 API int deviced_release_cpu_min_frequency()
384 {
385         char buf_pid[8];
386
387         snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
388
389         return deviced_call_predef_action(PREDEF_RELEASE_MIN_FREQUENCY, 1, buf_pid);
390 }