47dda0634f40d49528494c64f639fa8487f127bc
[platform/framework/web/web-provider.git] / src / Daemon / BoxDaemonImpl.cpp
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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  * @file    BoxDaemonImpl.cpp
18  * @author  Yunchan Cho (yunchan.cho@samsung.com)
19  */
20 #include <sys/types.h>
21 #include <unistd.h>
22 #include <string>
23 #include <cstring>
24 #include <aul.h>
25 #include <Ecore_X.h>
26 #include <provider.h>
27 #include <livebox-service.h>
28 #include <Core/Util/Log.h>
29 #include <Plugin/IBoxPluginConnector.h>
30 #include <Plugin/BoxPluginConnector.h>
31 #include <API/web_provider_livebox_info.h>
32 #include "BoxDaemonUtil.h"
33 #include "BoxDaemonImpl.h"
34
35 #define MASTER_PROVIDER_PING_TIME  120.0f
36
37 BoxDaemonImpl::BoxDaemonImpl()
38     : m_pluginConnector(BoxPluginConnector::create())
39 {
40 }
41
42 BoxDaemonImpl::~BoxDaemonImpl()
43 {
44 }
45
46 bool BoxDaemonImpl::start(std::string& name)
47 {
48     LogD("enter");
49
50     // initialize existing plugins for web livebox
51     if (!m_pluginConnector->initialize()) { 
52         LogD("failed to initialize plugins");
53         return false;
54     }
55         
56     // set name
57     m_daemonName = name;
58
59     // provider init
60     ProviderCallbacks callbacks;
61     setProviderCallbacks(callbacks);
62
63     int ret = provider_init(ecore_x_display_get(),
64                             m_daemonName.c_str(),
65                             &callbacks,
66                             this);
67     if (ret < 0) {
68         LogD("failed to initialize provider");
69         return false;
70     }
71
72     return true;
73 }
74
75 bool BoxDaemonImpl::stop()
76 {
77     LogD("enter");
78
79     // deinitialize provider
80     provider_fini();
81
82     // deinitialize existing plugins for web livebox
83     if (!m_pluginConnector->shutdown()) { 
84         LogD("failed to shutdown plugins");
85         return false;
86     }
87
88     return true;
89 }
90
91 int BoxDaemonImpl::connectedCallback(ProviderEventArgPtr arg, void* data)
92 {
93     LogD("enter");
94
95     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
96     if (!provider_send_hello()) {
97         This->m_pingTimer = 
98             ecore_timer_add(MASTER_PROVIDER_PING_TIME, pingToMasterCallback, This);
99     }
100
101     return 0;
102 }
103
104 int BoxDaemonImpl::disconnectedCallback(ProviderEventArgPtr arg, void* data)
105 {
106     LogD("enter");
107
108         aul_terminate_pid(getpid());
109
110     return 0;
111 }
112
113 int BoxDaemonImpl::boxCreateCallback( 
114         ProviderEventArgPtr arg, 
115         int* width, int* height, 
116         double* priority, void* data)
117 {
118     LogD("enter");
119
120     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
121     BoxInfoPtr info = This->initializeBoxInfo(arg);
122     if (!info) {
123         return -1;
124     }
125
126     if ((arg->info.lb_create.width == 0) || (arg->info.lb_create.height == 0)) {
127         livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
128     } else {
129         *width = arg->info.lb_create.width;
130         *height = arg->info.lb_create.height;
131     }
132
133     info->boxWidth = *width;
134     info->boxHeight = *height;
135     info->priority = 1.0f;
136     info->period = arg->info.lb_create.period;
137     if (arg->info.lb_create.content) {
138         info->contentInfo = std::string(arg->info.lb_create.content);
139     }
140
141     // box information
142     LogD("--------------------------------------------");
143     LogD("boxId: %s", info->boxId.c_str());
144     LogD("InstanceId: %s", info->instanceId.c_str());
145     LogD("width: %d", info->boxWidth);
146     LogD("height: %d", info->boxHeight);
147     LogD("update period: %f", info->period);
148     LogD("--------------------------------------------");
149
150     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
151     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
152
153     return ret ? 0 : -1;
154 }
155
156 int BoxDaemonImpl::boxReCreateCallback(ProviderEventArgPtr arg, void* data)
157 {
158     LogD("enter");
159
160     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
161     BoxInfoPtr info = This->initializeBoxInfo(arg);
162     if (!info) {
163         return -1;
164     }
165
166     int* width;
167     int* height;
168
169     if ((arg->info.lb_recreate.width == 0) || (arg->info.lb_recreate.height == 0)) {
170         livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
171         arg->info.lb_recreate.width = *width;
172         arg->info.lb_recreate.height = *height;
173     }
174
175     info->boxWidth = arg->info.lb_recreate.width;
176     info->boxHeight = arg->info.lb_recreate.height;
177     info->priority = 1.0f;
178     info->period = arg->info.lb_recreate.period;
179     if (arg->info.lb_recreate.content) {
180         info->contentInfo = std::string(arg->info.lb_recreate.content);
181     }
182
183     // box information
184     LogD("--------------------------------------------");
185     LogD("boxId: %s", info->boxId.c_str());
186     LogD("InstanceId: %s", info->instanceId.c_str());
187     LogD("width: %d", info->boxWidth);
188     LogD("height: %d", info->boxHeight);
189     LogD("update period: %f", info->period);
190     LogD("--------------------------------------------");
191
192     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
193     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
194
195     return ret ? 0 : -1;
196 }
197
198 int BoxDaemonImpl::boxDestroyCallback(ProviderEventArgPtr arg, void* data)
199 {
200     LogD("enter");
201
202     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
203     BoxInfoPtr info = This->initializeBoxInfo(arg);
204     if (!info) {
205         return -1;
206     }
207
208     LogD("--------------------------------------------");
209     LogD("boxId: %s", info->boxId.c_str());
210     LogD("InstanceId: %s", info->instanceId.c_str());
211     LogD("--------------------------------------------");
212
213     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_REMOVE_BOX, info, This);
214     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
215
216     return ret ? 0 : -1;
217 }
218
219 int BoxDaemonImpl::pdCreateCallback(ProviderEventArgPtr arg, void* data)
220 {
221     LogD("enter");
222
223     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
224     BoxInfoPtr info = This->initializeBoxInfo(arg);
225     if (!info) {
226         return -1;
227     }
228     if (arg->info.pd_create.w == 0 || arg->info.pd_create.h == 0) {
229         return -1;
230     }
231
232     info->pdWidth = arg->info.pd_create.w;
233     info->pdHeight = arg->info.pd_create.h;
234     info->pdX = arg->info.pd_create.x;
235     info->pdY = arg->info.pd_create.y;
236
237     LogD("--------------------------------------------");
238     LogD("boxId: %s", info->boxId.c_str());
239     LogD("InstanceId: %s", info->instanceId.c_str());
240     LogD("width: %d", info->pdWidth);
241     LogD("height: %d", info->pdHeight);
242     LogD("x: %f", info->pdX);
243     LogD("y: %f", info->pdY);
244     LogD("--------------------------------------------");
245
246     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_OPEN_PD, info, This);
247     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
248
249     return ret ? 0 : -1;
250 }
251
252 int BoxDaemonImpl::pdDestroyCallback(ProviderEventArgPtr arg, void* data)
253 {
254     LogD("enter");
255
256     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
257     BoxInfoPtr info = This->initializeBoxInfo(arg);
258     if (!info) {
259         return -1;
260     }
261
262     LogD("--------------------------------------------");
263     LogD("boxId: %s", info->boxId.c_str());
264     LogD("InstanceId: %s", info->instanceId.c_str());
265     LogD("--------------------------------------------");
266
267     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CLOSE_PD, info, This);
268     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
269
270     return ret ? 0 : -1;
271 }
272
273 int BoxDaemonImpl::clickedCallback(ProviderEventArgPtr arg, void* data)
274 {
275     LogD("enter");
276
277     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
278     BoxInfoPtr info = This->initializeBoxInfo(arg);
279     if (!info) {
280         return -1;
281     }
282
283     int flag = web_provider_livebox_get_auto_launch(info->boxId.c_str());
284     if (!flag) {
285         return -1;
286     }
287
288     BoxDaemonUtil::launchApplication(info->boxId, info->instanceId);
289     return 0;
290 }
291
292 int BoxDaemonImpl::boxResizeCallback(ProviderEventArgPtr arg, void* data)
293 {
294     LogD("enter");
295
296     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
297     BoxInfoPtr info = This->initializeBoxInfo(arg);
298     if (!info) {
299         return -1;
300     }
301     if (arg->info.resize.w == 0 || arg->info.resize.h == 0) {
302         return -1;
303     }
304
305     info->boxWidth = arg->info.resize.w;
306     info->boxHeight = arg->info.resize.h;
307
308     // box information
309     LogD("--------------------------------------------");
310     LogD("boxId: %s", info->boxId.c_str());
311     LogD("InstanceId: %s", info->instanceId.c_str());
312     LogD("width: %d", info->boxWidth);
313     LogD("height: %d", info->boxHeight);
314     LogD("--------------------------------------------");
315
316     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESIZE_BOX, info, This);
317     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
318
319     return ret ? 0 : -1;
320 }
321
322 int BoxDaemonImpl::boxPauseCallback(ProviderEventArgPtr arg, void* data)
323 {
324     LogD("enter");
325
326     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
327     BoxInfoPtr info = This->initializeBoxInfo(arg);
328     if (!info) {
329         return -1;
330     }
331
332     // box information
333     LogD("--------------------------------------------");
334     LogD("boxId: %s", info->boxId.c_str());
335     LogD("InstanceId: %s", info->instanceId.c_str());
336     LogD("--------------------------------------------");
337
338     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_BOX, info, This);
339     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
340
341     return ret ? 0 : -1;
342 }
343
344 int BoxDaemonImpl::boxResumeCallback(ProviderEventArgPtr arg, void* data)
345 {
346     LogD("enter");
347
348     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
349     BoxInfoPtr info = This->initializeBoxInfo(arg);
350     if (!info) {
351         return -1;
352     }
353
354     // box information
355     LogD("--------------------------------------------");
356     LogD("boxId: %s", info->boxId.c_str());
357     LogD("InstanceId: %s", info->instanceId.c_str());
358     LogD("--------------------------------------------");
359
360     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_BOX, info, This);
361     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
362
363     return ret ? 0 : -1;
364 }
365
366 int BoxDaemonImpl::pauseCallback(ProviderEventArgPtr arg, void* data)
367 {
368     LogD("enter");
369
370     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
371
372     LogD("--------------------------------------------");
373     LogD("web-provider is paused");
374     LogD("--------------------------------------------");
375
376     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_ALL, BoxInfoPtr(), This);
377     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
378
379     return ret ? 0 : -1;
380 }
381
382 int BoxDaemonImpl::resumeCallback(ProviderEventArgPtr arg, void* data)
383 {
384     LogD("enter");
385
386     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
387
388     LogD("--------------------------------------------");
389     LogD("web-provider is resumed");
390     LogD("--------------------------------------------");
391
392     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_ALL, BoxInfoPtr(), This);
393     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
394
395     return ret ? 0 : -1;
396 }
397
398 int BoxDaemonImpl::boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data)
399 {
400     LogD("enter");
401     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
402     BoxInfoPtr info = This->initializeBoxInfo(arg);
403     if (!info) {
404         return -1;
405     }
406     info->period = arg->info.set_period.period;
407
408     LogD("--------------------------------------------");
409     LogD("boxId: %s", info->boxId.c_str());
410     LogD("InstanceId: %s", info->instanceId.c_str());
411     LogD("period: %f", info->period);
412     LogD("--------------------------------------------");
413
414     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_PERIOD, info, This);
415     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
416
417     return ret ? 0 : -1;
418 }
419
420 int BoxDaemonImpl::boxUpdateCallback(ProviderEventArgPtr arg, void* data)
421 {
422     LogD("enter");
423
424     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
425     BoxInfoPtr info = This->initializeBoxInfo(arg);
426     if (!info) {
427         return -1;
428     }
429
430     LogD("--------------------------------------------");
431     LogD("boxId: %s", info->boxId.c_str());
432     LogD("InstanceId: %s", info->instanceId.c_str());
433     LogD("--------------------------------------------");
434
435     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, This);
436     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
437
438     return ret ? 0 : -1;
439 }
440
441 void BoxDaemonImpl::setProviderCallbacks(ProviderCallbacks& callbacks)
442 {
443     LogD("enter");
444
445     memset(&callbacks, 0, sizeof(callbacks));
446     callbacks.connected = BoxDaemonImpl::connectedCallback;
447     callbacks.disconnected = BoxDaemonImpl::disconnectedCallback;
448     callbacks.pause = BoxDaemonImpl::pauseCallback;
449     callbacks.resume = BoxDaemonImpl::resumeCallback;
450     callbacks.lb_create = BoxDaemonImpl::boxCreateCallback;
451     callbacks.lb_recreate = BoxDaemonImpl::boxReCreateCallback;
452     callbacks.lb_destroy = BoxDaemonImpl::boxDestroyCallback;
453     callbacks.lb_pause = BoxDaemonImpl::boxPauseCallback;
454     callbacks.lb_resume = BoxDaemonImpl::boxResumeCallback;
455     callbacks.pd_create = BoxDaemonImpl::pdCreateCallback;
456     callbacks.pd_destroy = BoxDaemonImpl::pdDestroyCallback;
457     callbacks.clicked = BoxDaemonImpl::clickedCallback;
458     callbacks.resize = BoxDaemonImpl::boxResizeCallback;
459     callbacks.update_content = BoxDaemonImpl::boxUpdateCallback;
460     callbacks.set_period = BoxDaemonImpl::boxPeriodChangeCallback;
461 }
462
463 const char* BoxDaemonImpl::getBoxType(const char* boxId)
464 {
465     LogD("enter");
466
467     if (!boxId) {
468         return NULL;
469     }
470     
471     const char* type = web_provider_livebox_get_box_type(boxId);
472     std::string boxType;
473     if (!type) {
474         std::string serviceBoxId(boxId);
475         boxType = m_pluginConnector->getBoxType(serviceBoxId);
476         if (boxType.empty()) {
477             LogD("unrecognized box id");
478             return NULL; 
479         }
480         type = strdup(boxType.c_str());
481     }
482
483     LogD("box id: %s, type: %s", boxId, type);
484     return type;
485 }
486
487 BoxInfoPtr BoxDaemonImpl::initializeBoxInfo(ProviderEventArgPtr arg)
488 {
489     LogD("enter");
490
491     if (!arg) {
492         return BoxInfoPtr();
493     }
494
495     if (!arg->pkgname || !arg->id) {
496         LogD("pkgname or id don't exist");
497         return BoxInfoPtr();
498     }
499
500     const char* type = getBoxType(arg->pkgname);
501     if (!type) {
502         return BoxInfoPtr();
503     }
504
505     BoxInfoPtr infoPtr = BoxInfoPtr(new BoxInfo(type, arg->pkgname, arg->id));
506     delete[] type;
507
508     return infoPtr;
509 }
510
511 Eina_Bool BoxDaemonImpl::pingToMasterCallback(void* data)
512 {
513     LogD("enter");
514
515     provider_send_ping();
516
517     return ECORE_CALLBACK_RENEW;
518 }
519
520 void BoxDaemonImpl::requestBoxJobCallback(void* data)
521 {
522     JobInfo* jobInfo = static_cast<JobInfo*>(data);
523     if (!jobInfo) {
524         LogD("no information for job");
525         return;
526     }
527
528     // just for debugging
529     //volatile int flag = 0;
530     //while(flag == 0) {;}
531
532     // request box job!
533     jobInfo->daemonImpl->m_pluginConnector->requestCommand(
534             jobInfo->cmdType, jobInfo->boxInfo);
535
536     delete jobInfo;
537 }