[IMPROVE] Implement freezing/unfreezing apps
[platform/core/system/swap-manager.git] / daemon / daemon.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Jaewon Lim <jaewon81.lim@samsung.com>
9  * Woojin Jung <woojin2.jung@samsung.com>
10  * Juyoung Kim <j0.kim@samsung.com>
11  * Cherepanov Vitaliy <v.cherepanov@samsung.com>
12  * Nikita Kalyazin    <n.kalyazin@samsung.com>
13  *
14  * Licensed under the Apache License, Version 2.0 (the "License");
15  * you may not use this file except in compliance with the License.
16  * You may obtain a copy of the License at
17  *
18  * http://www.apache.org/licenses/LICENSE-2.0
19  *
20  * Unless required by applicable law or agreed to in writing, software
21  * distributed under the License is distributed on an "AS IS" BASIS,
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23  * See the License for the specific language governing permissions and
24  * limitations under the License.
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  * - Samsung RnD Institute Russia
29  *
30  */
31 #define __STDC_FORMAT_MACROS
32 #include <stdio.h>
33 #include <stdlib.h>             // for realpath
34 #include <string.h>             // for strtok, strcpy, strncpy
35 #include <limits.h>             // for realpath
36 #include <inttypes.h>
37
38 #include <errno.h>              // for errno
39 #include <sys/types.h>          // for accept, mkdir, opendir, readdir
40 #include <sys/socket.h>         // for accept
41 #include <sys/stat.h>           // for mkdir
42 #include <sys/eventfd.h>        // for eventfd
43 #include <sys/timerfd.h>        // for timerfd
44 #include <unistd.h>             // for access, sleep
45 #include <stdbool.h>
46 #include <linux/netlink.h>
47 #include <linux/connector.h>
48
49 #include <ctype.h>
50
51 #include <fcntl.h>
52
53 #include <assert.h>
54
55 #include <Ecore.h>
56
57 #include "daemon.h"
58 #include "sys_stat.h"
59 #include "utils.h"
60 #include "da_protocol.h"
61 #include "da_inst.h"
62 #include "da_data.h"
63 #include "input_events.h"
64 #include "smack.h"
65 #include "us_interaction_msg.h"
66 #include "freezing.h"
67 #include "debug.h"
68
69 #define DA_WORK_DIR                     "/home/developer/sdk_tools/da/"
70 #define DA_READELF_PATH                 "/home/developer/sdk_tools/da/readelf"
71 #define SCREENSHOT_DIR                  "/tmp/da"
72
73 #define MAX_APP_LAUNCH_TIME             60
74 #define MAX_CONNECT_TIMEOUT_TIME        5*60
75
76 uint64_t get_total_alloc_size(void)
77 {
78         int i;
79         uint64_t allocsize = 0;
80
81         for (i = 0; i < MAX_TARGET_COUNT; i++) {
82                 if (manager.target[i].socket != -1 &&
83                     manager.target[i].allocmem > 0)
84                         allocsize += manager.target[i].allocmem;
85         }
86         return allocsize;
87 }
88
89 static int getEmptyTargetSlot()
90 {
91         int i;
92         for (i = 0; i < MAX_TARGET_COUNT; i++) {
93                 if (manager.target[i].socket == -1)
94                         break;
95         }
96
97         return i;
98 }
99
100 static void setEmptyTargetSlot(int index)
101 {
102         if (index >= 0 && index < MAX_TARGET_COUNT) {
103                 manager.target[index].pid = -1;
104                 manager.target[index].recv_thread = -1;
105                 manager.target[index].allocmem = 0;
106                 manager.target[index].initial_log = 0;
107                 if (manager.target[index].event_fd != -1)
108                         close(manager.target[index].event_fd);
109                 manager.target[index].event_fd = -1;
110                 if (manager.target[index].socket != -1)
111                         close(manager.target[index].socket);
112                 manager.target[index].socket = -1;
113         }
114 }
115
116 // =============================================================================
117 // start and terminate control functions
118 // =============================================================================
119
120 static Ecore_Fd_Handler *launch_timer_handler;
121
122 //stop application launch timer
123 static int stop_app_launch_timer()
124 {
125         close(manager.app_launch_timerfd);
126         manager.app_launch_timerfd = -1;
127
128         return 0;
129 }
130
131 static Eina_Bool launch_timer_cb(void *data, Ecore_Fd_Handler *fd_handler)
132 {
133         LOGE("Failed to launch application\n");
134         if (stop_app_launch_timer() < 0)
135                 LOGE("cannot stop app launch timer\n");
136
137         return ECORE_CALLBACK_CANCEL;
138 }
139
140 //start application launch timer function
141 static int start_app_launch_timer(int apps_count)
142 {
143         int res = 0;
144
145         assert(apps_count >= 0 && "negative apps count");
146
147         if (apps_count == 0)
148                 return res;
149
150         manager.app_launch_timerfd =
151             timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
152         if (manager.app_launch_timerfd > 0) {
153                 struct itimerspec ctime;
154                 ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME * apps_count;
155                 ctime.it_value.tv_nsec = 0;
156                 ctime.it_interval.tv_sec = 0;
157                 ctime.it_interval.tv_nsec = 0;
158                 if (timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL) < 0) {
159                         LOGE("fail to set app launch timer\n");
160                         stop_app_launch_timer();
161                         res = -1;
162                 } else {
163                         launch_timer_handler =
164                                 ecore_main_fd_handler_add(manager.app_launch_timerfd,
165                                                           ECORE_FD_READ,
166                                                           launch_timer_cb,
167                                                           NULL,
168                                                           NULL, NULL);
169                         if (!launch_timer_handler) {
170                                 LOGE("fail to add app launch timer fd to \n");
171                                 stop_app_launch_timer();
172                                 res = -2;
173                         } else {
174                                 LOGI("application launch time started\n");
175                         }
176                 }
177         } else {
178                 LOGE("cannot create launch timer\n");
179                 res = -3;
180         }
181
182         return res;
183 }
184
185 static inline void inc_apps_to_run()
186 {
187         manager.apps_to_run++;
188 }
189
190 static inline void dec_apps_to_run()
191 {
192         if (manager.apps_to_run > 0)
193                 manager.apps_to_run--;
194 }
195
196 static inline int get_apps_to_run()
197 {
198         return manager.apps_to_run;
199 }
200
201 static int kill_app_by_info(const struct app_info_t *app_info)
202 {
203         int res = 0;
204
205         if (app_info == NULL) {
206                 LOGE("Cannot exec app. app_info is NULL");
207                 return -1;
208         }
209
210         switch (app_info->app_type) {
211         case APP_TYPE_TIZEN:
212                 res = kill_app(app_info->exe_path);
213                 break;
214         case APP_TYPE_RUNNING:
215                 // TODO: nothing, it's running
216                 LOGI("already started\n");
217                 break;
218         case APP_TYPE_COMMON:
219                 res = kill_app(app_info->exe_path);
220                 break;
221         default:
222                 LOGE("Unknown app type %d\n", app_info->app_type);
223                 res = -1;
224                 break;
225         }
226
227         return res;
228 }
229
230 static int exec_app(const struct app_info_t *app_info)
231 {
232         int res = 0;
233
234         if (app_info == NULL) {
235                 LOGE("Cannot exec app. app_info is NULL");
236                 return -1;
237         }
238
239         switch (app_info->app_type) {
240         case APP_TYPE_TIZEN:
241                 if (exec_app_tizen(app_info->app_id, app_info->exe_path)) {
242                         LOGE("Cannot exec tizen app %s\n", app_info->app_id);
243                         res = -1;
244                 } else {
245                         inc_apps_to_run();
246                 }
247                 break;
248         case APP_TYPE_RUNNING:
249                 // TODO: nothing, it's running
250                 LOGI("already started\n");
251                 break;
252         case APP_TYPE_COMMON:
253                 if (exec_app_common(app_info->exe_path)) {
254                         LOGE("Cannot exec common app %s\n", app_info->exe_path);
255                         res = -1;
256                 } else {
257                         inc_apps_to_run();
258                 }
259                 break;
260         default:
261                 LOGE("Unknown app type %d\n", app_info->app_type);
262                 res = -1;
263                 break;
264         }
265
266         LOGI("ret=%d\n", res);
267         return res;
268 }
269
270 // just send stop message to all target process
271 static void terminate_all_target()
272 {
273         int i;
274         ssize_t sendlen;
275         msg_target_t sendlog;
276
277         sendlog.type = MSG_STOP;
278         sendlog.length = 0;
279
280         for (i = 0; i < MAX_TARGET_COUNT; i++) {
281                 if (manager.target[i].socket != -1) {
282                         sendlen = send(manager.target[i].socket, &sendlog,
283                                        sizeof(sendlog.type) +
284                                        sizeof(sendlog.length), MSG_NOSIGNAL);
285                         if (sendlen != -1) {
286                                 LOGI("TERMINATE send exit msg (socket %d) "
287                                      "by terminate_all_target()\n",
288                                      manager.target[i].socket);
289                         }
290                 }
291         }
292 }
293
294 // terminate all target and wait for threads
295 void terminate_all()
296 {
297         int i;
298         terminate_all_target();
299
300         // wait for all other thread exit
301         for (i = 0; i < MAX_TARGET_COUNT; i++) {
302                 if (manager.target[i].recv_thread != -1) {
303                         LOGI("join recv thread [%d] is started\n", i);
304                         pthread_join(manager.target[i].recv_thread, NULL);
305                         LOGI("join recv thread %d. done\n", i);
306                 }
307         }
308 }
309
310 // terminate all profiling by critical error
311 // TODO: don't send data to host
312 static void terminate_error(char *errstr, int send_to_host)
313 {
314         LOGE("termination all with err '%s'\n", errstr);
315         struct msg_data_t *msg = NULL;
316         if (send_to_host != 0) {
317                 msg = gen_message_error(errstr);
318                 if (msg) {
319                         write_to_buf(msg);
320                         free_msg_data(msg);
321                 } else {
322                         LOGI("cannot generate error message\n");
323                 }
324         }
325         terminate_all();
326 }
327
328 static Ecore_Fd_Handler *connect_timer_handler;
329
330 static Eina_Bool connect_timer_cb(void *data, Ecore_Fd_Handler *fd_handler)
331 {
332         terminate_error("no incoming connections", 1);
333         close(manager.connect_timeout_timerfd);
334         manager.connect_timeout_timerfd = -1;
335         LOGE("No connection in %d sec. shutdown.\n",
336              MAX_CONNECT_TIMEOUT_TIME);
337         ecore_main_loop_quit();
338
339         return ECORE_CALLBACK_CANCEL;
340 }
341
342 static int launch_timer_start(void)
343 {
344         int res = 0;
345
346         manager.connect_timeout_timerfd =
347             timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
348         if (manager.connect_timeout_timerfd > 0) {
349                 struct itimerspec ctime;
350                 ctime.it_value.tv_sec = MAX_CONNECT_TIMEOUT_TIME;
351                 ctime.it_value.tv_nsec = 0;
352                 ctime.it_interval.tv_sec = 0;
353                 ctime.it_interval.tv_nsec = 0;
354                 if (timerfd_settime(manager.connect_timeout_timerfd, 0, &ctime, NULL) < 0) {
355                         LOGE("fail to set connect timeout timer\n");
356                         close(manager.connect_timeout_timerfd);
357                         manager.connect_timeout_timerfd = -1;
358                 } else {
359                         connect_timer_handler =
360                                 ecore_main_fd_handler_add(manager.connect_timeout_timerfd,
361                                                           ECORE_FD_READ,
362                                                           connect_timer_cb,
363                                                           NULL,
364                                                           NULL, NULL);
365                         if (!connect_timer_handler) {
366                                 LOGE("fail to add app connection timeout timer fd\n");
367                                 close(manager.connect_timeout_timerfd);
368                                 manager.connect_timeout_timerfd = -1;
369                         } else {
370                                 LOGI("connection timeout timer started\n");
371                         }
372                 }
373         } else {
374                 LOGE("cannot create connection timeout timer\n");
375         }
376
377         LOGI("ret=%d\n", res);
378         return res;
379 }
380
381 int prepare_profiling(void)
382 {
383         struct app_list_t *app = NULL;
384         const struct app_info_t *app_info = NULL;
385
386         app_info = app_info_get_first(&app);
387         if (app_info == NULL) {
388                 LOGE("No app info found\n");
389                 return -1;
390         }
391
392         //all apps
393         while (app_info != NULL) {
394                 if (kill_app_by_info(app_info) != 0) {
395                         LOGE("kill app failed\n");
396                         return -1;
397                 }
398                 app_info = app_info_get_next(&app);
399         }
400         //init rw for systeminfo
401         //init recv send network systeminfo
402         sys_stat_prepare();
403         return 0;
404
405 }
406
407 int start_profiling(void)
408 {
409         struct app_list_t *app = NULL;
410         const struct app_info_t *app_info = NULL;
411         int res = 0;
412
413         app_info = app_info_get_first(&app);
414         if (app_info == NULL) {
415                 LOGE("No app info found\n");
416                 return -1;
417         }
418         // remove previous screen capture files
419         remove_indir(SCREENSHOT_DIR);
420         if (mkdir(SCREENSHOT_DIR, 0777) == -1 && errno != EEXIST)
421                 LOGW("Failed to create directory for screenshot : %s\n",
422                      strerror(errno));
423
424         set_label_for_all(SCREENSHOT_DIR);
425
426         if (samplingStart() < 0) {
427                 LOGE("Cannot start sampling\n");
428                 res = -1;
429                 goto exit;
430         }
431
432         if (IS_OPT_SET(FL_RECORDING))
433                 add_input_events();
434
435         while (app_info != NULL) {
436                 if (exec_app(app_info)) {
437                         LOGE("Cannot exec app\n");
438                         res = -1;
439                         goto recording_stop;
440                 }
441                 app_info = app_info_get_next(&app);
442         }
443
444         if (start_app_launch_timer(get_apps_to_run()) < 0) {
445                 res = -1;
446                 goto recording_stop;
447         }
448
449         goto exit;
450
451  recording_stop:
452         if (IS_OPT_SET(FL_RECORDING))
453                 del_input_events();
454         samplingStop();
455
456  exit:
457         LOGI("return %d\n", res);
458         return res;
459 }
460
461 void stop_profiling(void)
462 {
463         if (IS_OPT_SET(FL_RECORDING))
464                 del_input_events();
465         samplingStop();
466 }
467
468 static void reconfigure_recording(struct conf_t conf)
469 {
470         uint64_t old_features = prof_session.conf.use_features0;
471         uint64_t new_features = conf.use_features0;
472         uint64_t to_enable = (new_features ^ old_features) & new_features;
473         uint64_t to_disable = (new_features ^ old_features) & old_features;
474
475         if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) {
476                 del_input_events();
477                 prof_session.conf.use_features0 &= ~FL_RECORDING;
478         }
479
480         if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) {
481                 add_input_events();
482                 prof_session.conf.use_features0 |= FL_RECORDING;
483         }
484
485 }
486
487 int reconfigure(struct conf_t conf)
488 {
489         reconfigure_recording(conf);
490
491         samplingStop();
492         memcpy(&prof_session.conf, &conf, sizeof(conf));
493         if (samplingStart() < 0) {
494                 LOGE("Cannot start sampling\n");
495                 return -1;
496         }
497
498         return 0;
499 }
500
501 static Ecore_Fd_Handler *target_handlers[MAX_TARGET_COUNT];
502
503 static int target_event_pid_handler(int index, uint64_t msg)
504 {
505         struct app_list_t *app = NULL;
506         struct app_info_t *app_info = NULL;
507         if (index == 0) {       // main application
508                 app_info = app_info_get_first(&app);
509                 if (app_info == NULL) {
510                         LOGE("No app info found\n");
511                         return -1;
512                 }
513
514                 while (app_info != NULL) {
515                         if (is_same_app_process(app_info->exe_path,
516                                                 manager.target[index].pid))
517                                 break;
518                         app_info = app_info_get_next(&app);
519                 }
520
521                 if (app_info == NULL) {
522                         LOGE("pid %d not found in app list\n",
523                              manager.target[index].pid);
524                         return -1;
525                 }
526
527                 if (start_replay() != 0) {
528                         LOGE("Cannot start replay thread\n");
529                         return -1;
530                 }
531         }
532         manager.target[index].initial_log = 1;
533         return 0;
534 }
535
536 static int target_event_stop_handler(int index, uint64_t msg)
537 {
538         LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
539              manager.target[index].socket, manager.target[index].pid,
540              manager.target_count - 1);
541
542         if (index == 0)         // main application
543                 stop_replay();
544
545         ecore_main_fd_handler_del(target_handlers[index]);
546
547         setEmptyTargetSlot(index);
548         // all target client are closed
549         if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) {
550                 LOGI("all targets are stopped\n");
551                 if (stop_all() != ERR_NO)
552                         LOGE("Stop failed\n");
553                 return -11;
554         }
555
556         return 0;
557 }
558
559 // return 0 if normal case
560 // return plus value if non critical error occur
561 // return minus value if critical error occur
562 // return -11 if all target process closed
563 static int target_event_handler(int index, uint64_t msg)
564 {
565         int err = 0;
566         if (msg & EVENT_PID)
567                 err = target_event_pid_handler(index, msg);
568         if (err)
569                 return err;
570
571         if (msg & EVENT_STOP || msg & EVENT_ERROR)
572                 err = target_event_stop_handler(index, msg);
573
574         return err;
575 }
576
577 static Eina_Bool target_event_cb(void *data, Ecore_Fd_Handler *fd_handler)
578 {
579         uint64_t u;
580         ssize_t recvLen;
581         int index = (int)data;
582
583         recvLen = read(manager.target[index].event_fd, &u, sizeof(uint64_t));
584         if (recvLen != sizeof(uint64_t)) {
585                 // maybe closed, but ignoring is more safe then
586                 // removing fd from event loop
587         } else {
588                 if (-11 == target_event_handler(index, u)) {
589                         LOGI("all target process is closed\n");
590                 }
591         }
592
593         return ECORE_CALLBACK_RENEW;
594 }
595
596 /**
597  * return 0 if normal case
598  * return plus value if non critical error occur
599  * return minus value if critical error occur
600  */
601 static int targetServerHandler(void)
602 {
603         msg_target_t log, pid_msg;
604         ssize_t recvlen;
605
606         int index = getEmptyTargetSlot();
607         if (index == MAX_TARGET_COUNT) {
608                 LOGW("Max target number(8) reached, no more target can connected\n");
609                 return 1;
610         }
611
612         manager.target[index].socket =
613                 accept(manager.target_server_socket, NULL, NULL);
614
615         if (manager.target[index].socket >= 0) {
616                 /* accept succeed */
617                 fd_setup_attributes(manager.target[index].socket);
618
619                 /* send config message to target process */
620                 log.type = MSG_OPTION;
621                 log.length = sprintf(log.data, "%llu",
622                                      prof_session.conf.use_features0);
623                 if (0 > send(manager.target[index].socket, &log,
624                              sizeof(log.type) + sizeof(log.length) + log.length,
625                              MSG_NOSIGNAL))
626                         LOGE("fail to send data to target index(%d)\n", index);
627
628                 // make event fd
629                 manager.target[index].event_fd = eventfd(EFD_CLOEXEC, EFD_NONBLOCK);
630                 if (manager.target[index].event_fd == -1) {
631                         // fail to make event fd
632                         LOGE("fail to make event fd for socket (%d)\n",
633                              manager.target[index].socket);
634                         goto TARGET_CONNECT_FAIL;
635                 }
636
637                 target_handlers[index] =
638                         ecore_main_fd_handler_add(manager.target[index].event_fd,
639                                                   ECORE_FD_READ,
640                                                   target_event_cb,
641                                                   (void *)index,
642                                                   NULL, NULL);
643                 if (!target_handlers[index]) {
644                         LOGE("fail to add event fd for socket (%d)\n",
645                              manager.target[index].socket);
646                         goto TARGET_CONNECT_FAIL;
647                 }
648
649                 // make recv thread for target
650                 if (makeRecvThread(index) != 0) {
651                         // fail to make recv thread
652                         LOGE("fail to make recv thread for socket (%d)\n",
653                              manager.target[index].socket);
654                         ecore_main_fd_handler_del(target_handlers[index]);
655                         goto TARGET_CONNECT_FAIL;
656                 }
657
658                 dec_apps_to_run();
659
660                 if ((manager.app_launch_timerfd > 0) && (get_apps_to_run() == 0)) {
661                         if (stop_app_launch_timer() < 0)
662                                 LOGE("cannot stop app launch timer\n");
663                 }
664
665                 LOGI("target connected = %d(running %d target)\n",
666                      manager.target[index].socket, manager.target_count + 1);
667
668                 manager.target_count++;
669                 return 0;
670         } else {
671                 // accept error
672                 LOGE("Failed to accept at target server socket\n");
673         }
674
675  TARGET_CONNECT_FAIL:
676         if (manager.target_count == 0) {
677                 // if this connection is main connection
678                 return -1;
679         } else {
680                 // if this connection is not main connection then ignore process by error
681                 setEmptyTargetSlot(index);
682                 return 1;
683         }
684 }
685
686 static Ecore_Fd_Handler *host_ctrl_handler;
687 static Ecore_Fd_Handler *host_data_handler;
688
689 // return plus value if non critical error occur
690 // return minus value if critical error occur
691 // return -11 if socket closed
692 static int controlSocketHandler(int efd)
693 {
694         ssize_t recv_len;
695         struct msg_t msg_head;
696         struct msg_t *msg;
697         int res = 0;
698
699         if (manager.connect_timeout_timerfd >= 0) {
700                 LOGI("release connect timeout timer\n");
701                 close(manager.connect_timeout_timerfd);
702                 manager.connect_timeout_timerfd = -1;
703         }
704         // Receive header
705         recv_len = recv(manager.host.control_socket,
706                         &msg_head, MSG_CMD_HDR_LEN, 0);
707         // error or close request from host
708         if (recv_len == -1 || recv_len == 0)
709                 return -11;
710         else {
711                 msg = malloc(MSG_CMD_HDR_LEN + msg_head.len);
712                 if (!msg) {
713                         LOGE("Cannot alloc msg\n");
714                         sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
715                         return -1;
716                 }
717                 msg->id = msg_head.id;
718                 msg->len = msg_head.len;
719                 if (msg->len > 0) {
720                         // Receive payload (if exists)
721                         recv_len = recv(manager.host.control_socket,
722                                         msg->payload, msg->len, MSG_WAITALL);
723                         if (recv_len == -1)
724                                 return -11;
725                 }
726                 printBuf((char *)msg, MSG_CMD_HDR_LEN + msg->len);
727                 res = host_message_handler(msg);
728                 free(msg);
729         }
730
731         return res;
732 }
733
734 static Eina_Bool host_ctrl_cb(void *data, Ecore_Fd_Handler *fd_handler)
735 {
736         int result = controlSocketHandler(manager.efd);
737         if (result == -11) {
738                 // socket close
739                 //if the host disconnected.
740                 //In all other cases daemon must report an error and continue the loop
741                 //close connect_timeoutt and host socket and quit
742                 LOGI("Connection closed. Termination. (%d)\n",
743                      manager.host.control_socket);
744                 ecore_main_loop_quit();
745         } else if (result < 0) {
746                 LOGE("Control socket handler.\n");
747         }
748
749         return ECORE_CALLBACK_RENEW;
750 }
751
752 static Eina_Bool host_data_cb(void *data, Ecore_Fd_Handler *fd_handler)
753 {
754         ssize_t recvLen;
755         char recvBuf[32];
756
757         recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
758         if (recvLen == 0) {
759                 // close data socket
760                 ecore_main_fd_handler_del(host_data_handler);
761                 close(manager.host.data_socket);
762                 manager.host.data_socket = -1;
763                 // TODO: finish transfer thread
764         }
765
766         LOGI("host message from data socket %d\n", recvLen);
767
768         return ECORE_CALLBACK_RENEW;
769 }
770
771 // return 0 if normal case
772 // return plus value if non critical error occur
773 // return minus value if critical error occur
774 static int hostServerHandler(void)
775 {
776         static int hostserverorder = 0;
777         int csocket;
778
779         if (hostserverorder > 1)        // control and data socket connected already
780                 return 1;               // ignore
781
782         csocket = accept(manager.host_server_socket, NULL, NULL);
783
784         if (csocket >= 0) {
785                 // accept succeed
786
787                 if (hostserverorder == 0) {
788                         manager.host.control_socket = csocket;
789                         unlink_portfile();
790                         LOGI("host control socket connected = %d\n", csocket);
791                         host_ctrl_handler =
792                                 ecore_main_fd_handler_add(manager.host.control_socket,
793                                                           ECORE_FD_READ,
794                                                           host_ctrl_cb,
795                                                           NULL,
796                                                           NULL, NULL);
797                         if (!host_ctrl_handler) {
798                                 LOGE("Failed to add host control socket fd\n");
799                                 close(csocket);
800                                 return -1;
801                         }
802                 } else {
803                         manager.host.data_socket = csocket;
804                         LOGI("host data socket connected = %d\n", csocket);
805
806                         host_data_handler =
807                                 ecore_main_fd_handler_add(manager.host.data_socket,
808                                                           ECORE_FD_READ,
809                                                           host_data_cb,
810                                                           NULL,
811                                                           NULL, NULL);
812                         if (!host_data_handler) {
813                                 LOGE("Failed to add host data socket fd\n");
814                                 close(csocket);
815                                 return -1;
816                         }
817                 }
818
819                 hostserverorder++;
820                 return 0;
821         } else {
822                 // accept error
823                 LOGE("Failed to accept from host server socket\n");
824                 return -1;
825         }
826 }
827
828 static int kernel_handler(void)
829 {
830         int res, size, ret;
831         socklen_t optlen;
832         struct nlmsghdr *nlh;
833         struct cn_msg *msg;
834         ssize_t len;
835
836         /* Get buffer size */
837         optlen = sizeof(size);
838
839         /* We're using SOCK_DGRAM, so, get it maximum size */
840         res = getsockopt(manager.kernel_socket, SOL_SOCKET, SO_SNDBUF, &size,
841                          &optlen);
842
843         if (res == -1) {
844                 LOGE("Get maximum buffer size failed\n");
845                 return -1;
846         }
847
848         /* Alloc mem for nlh message struct and receive it */
849         nlh = malloc(size);
850         if (nlh == NULL)
851                 return -1;
852         len = recv(manager.kernel_socket, nlh, size, 0);
853         if ((len <= 0) || (nlh->nlmsg_len == 0)) {
854                 ret = -1;
855                 goto free_and_end;
856         }
857
858         /* nlh data field contains connectors message */
859         msg = NLMSG_DATA(nlh);
860         if (msg->len == 0) {
861                 ret = -1;
862                 goto free_and_end;
863         }
864
865         switch(*(enum us_interaction_k2u_msg_t *) msg->data) {
866         case US_INT_PAUSE_APPS:
867                 freeze_subgroup();
868                 break;
869         case US_INT_CONT_APPS:
870                 thaw_subgroup();
871                 break;
872         default:
873                 LOGE("Unknown command\n");
874         }
875
876         /* Insert your message handler here */
877
878         ret = 0;
879
880 free_and_end:
881         free(nlh);
882
883         return ret;
884 }
885
886
887 static Ecore_Fd_Handler *host_connect_handler;
888 static Ecore_Fd_Handler *target_connect_handler;
889 static Ecore_Fd_Handler *kernel_connect_handler;
890
891 static Eina_Bool host_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
892 {
893         // connect request from host
894         int result = hostServerHandler();
895         if (result < 0) {
896                 LOGE("Internal DA framework error (hostServerHandler)\n");
897         }
898
899         return ECORE_CALLBACK_RENEW;
900 }
901
902 static Eina_Bool target_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
903 {
904         if (targetServerHandler() < 0) {
905                 // critical error
906                 terminate_error("Internal DA framework error, "
907                                 "Please re-run the profiling "
908                                 "(targetServerHandler)\n", 1);
909         }
910
911         return ECORE_CALLBACK_RENEW;
912 }
913
914 static Eina_Bool kernel_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
915 {
916         if (kernel_handler() < 0) {
917                 LOGE("Internal DA framework error (kernel_handler)\n");
918         }
919
920         return ECORE_CALLBACK_RENEW;
921 }
922
923 static bool initialize_events(void)
924 {
925         host_connect_handler =
926                 ecore_main_fd_handler_add(manager.host_server_socket,
927                                           ECORE_FD_READ,
928                                           host_connect_cb,
929                                           NULL,
930                                           NULL, NULL);
931         if (!host_connect_handler) {
932                 LOGE("Host server socket add error\n");
933                 return false;
934         }
935
936         target_connect_handler =
937                 ecore_main_fd_handler_add(manager.target_server_socket,
938                                           ECORE_FD_READ,
939                                           target_connect_cb,
940                                           NULL,
941                                           NULL, NULL);
942         if (!target_connect_handler) {
943                 LOGE("Target server socket add error\n");
944                 return false;
945         }
946
947         kernel_connect_handler =
948             ecore_main_fd_handler_add(manager.kernel_socket,
949                                       ECORE_FD_READ,
950                                       kernel_connect_cb,
951                                       NULL,
952                                       NULL, NULL);
953         if (!kernel_connect_handler) {
954                 LOGE("Kernel socket add error\n");
955                 return false;
956         }
957
958         return true;
959 }
960
961 // return 0 for normal case
962 int daemonLoop(void)
963 {
964         int return_value = 0;
965
966         ecore_init();
967
968         if (init_input_events() == -1) {
969                 return_value = -1;
970                 goto END_EVENT;
971         }
972
973         if (!initialize_events()) {
974                 return_value = -1;
975                 goto END_EFD;
976         }
977
978         if (launch_timer_start() < 0) {
979                 LOGE("Launch timer start failed\n");
980                 return_value = -1;
981                 goto END_EFD;
982         }
983
984         init_prof_session(&prof_session);
985
986         ecore_main_loop_begin();
987         ecore_shutdown();
988
989  END_EFD:
990         LOGI("close efd\n");
991         close(manager.efd);
992  END_EVENT:
993         return return_value;
994 }