c129269f58961a002bda8b366d183b799e60aad0
[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.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://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: %d", 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::resizeCallback(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::updateContentCallback(ProviderEventArgPtr arg, void* data)
399 {
400     LogD("enter");
401
402     return 0;
403 }
404
405 int BoxDaemonImpl::changePeriodCallback(ProviderEventArgPtr arg, void* data)
406 {
407     LogD("enter");
408     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
409     BoxInfoPtr info = This->initializeBoxInfo(arg);
410     if (!info) {
411         return -1;
412     }
413     info->period = arg->info.set_period.period;
414
415     LogD("--------------------------------------------");
416     LogD("boxId: %s", info->boxId.c_str());
417     LogD("InstanceId: %s", info->instanceId.c_str());
418     LogD("period: %f", info->period);
419     LogD("--------------------------------------------");
420
421     JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_PERIOD, info, This);
422     Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
423
424     return ret ? 0 : -1;
425 }
426
427 void BoxDaemonImpl::setProviderCallbacks(ProviderCallbacks& callbacks)
428 {
429     LogD("enter");
430
431     memset(&callbacks, 0, sizeof(callbacks));
432     callbacks.connected = BoxDaemonImpl::connectedCallback;
433     callbacks.disconnected = BoxDaemonImpl::disconnectedCallback;
434     callbacks.pause = BoxDaemonImpl::pauseCallback;
435     callbacks.resume = BoxDaemonImpl::resumeCallback;
436     callbacks.lb_create = BoxDaemonImpl::boxCreateCallback;
437     callbacks.lb_recreate = BoxDaemonImpl::boxReCreateCallback;
438     callbacks.lb_destroy = BoxDaemonImpl::boxDestroyCallback;
439     callbacks.lb_pause = BoxDaemonImpl::boxPauseCallback;
440     callbacks.lb_resume = BoxDaemonImpl::boxResumeCallback;
441     callbacks.pd_create = BoxDaemonImpl::pdCreateCallback;
442     callbacks.pd_destroy = BoxDaemonImpl::pdDestroyCallback;
443     callbacks.clicked = BoxDaemonImpl::clickedCallback;
444     callbacks.resize = BoxDaemonImpl::resizeCallback;
445     callbacks.update_content = BoxDaemonImpl::updateContentCallback;
446     callbacks.set_period = BoxDaemonImpl::changePeriodCallback;
447 }
448
449 const char* BoxDaemonImpl::getBoxType(const char* boxId)
450 {
451     LogD("enter");
452
453     if (!boxId) {
454         return NULL;
455     }
456     
457     const char* type = web_provider_livebox_get_box_type(boxId);
458     std::string boxType;
459     if (!type) {
460         std::string serviceBoxId(boxId);
461         boxType = m_pluginConnector->getBoxType(serviceBoxId);
462         if (boxType.empty()) {
463             LogD("unrecognized box id");
464             return NULL; 
465         }
466         type = strdup(boxType.c_str());
467     }
468
469     LogD("box id: %s, type: %s", boxId, type);
470     return type;
471 }
472
473 BoxInfoPtr BoxDaemonImpl::initializeBoxInfo(ProviderEventArgPtr arg)
474 {
475     LogD("enter");
476
477     if (!arg) {
478         return BoxInfoPtr();
479     }
480
481     if (!arg->pkgname || !arg->id) {
482         LogD("pkgname or id don't exist");
483         return BoxInfoPtr();
484     }
485
486     const char* type = getBoxType(arg->pkgname);
487     if (!type) {
488         return BoxInfoPtr();
489     }
490
491     BoxInfoPtr infoPtr = BoxInfoPtr(new BoxInfo(type, arg->pkgname, arg->id));
492     delete[] type;
493
494     return infoPtr;
495 }
496
497 Eina_Bool BoxDaemonImpl::pingToMasterCallback(void* data)
498 {
499     LogD("enter");
500
501     provider_send_ping();
502
503     return ECORE_CALLBACK_RENEW;
504 }
505
506 void BoxDaemonImpl::requestBoxJobCallback(void* data)
507 {
508     JobInfo* jobInfo = static_cast<JobInfo*>(data);
509     if (!jobInfo) {
510         LogD("no information for job");
511         return;
512     }
513
514     // just for debugging
515     //volatile int flag = 0;
516     //while(flag == 0) {;}
517
518     // request box job!
519     jobInfo->daemonImpl->m_pluginConnector->requestCommand(
520             jobInfo->cmdType, jobInfo->boxInfo);
521
522     delete jobInfo;
523 }