2 * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://floralicense.org/license/
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.
17 * @file BoxDaemonImpl.cpp
18 * @author Yunchan Cho (yunchan.cho@samsung.com)
20 #include <sys/types.h>
28 #include <livebox-service.h>
29 #include <Core/Util/Log.h>
30 #include <Plugin/IBoxPluginConnector.h>
31 #include <Plugin/BoxPluginConnector.h>
32 #include <API/web_provider_livebox_info.h>
33 #include "BoxDaemonUtil.h"
34 #include "BoxDaemonImpl.h"
36 #define MASTER_PROVIDER_PING_TIME 120.0f
38 // These are string for handling application service from app
39 static const std::string BOX_SERVICE_SCHEME("box-service://");
40 static const std::string OPERATION_UPDATE_BOX(
41 "http://tizen.org/appcontrol/operation/dynamicbox/web/update");
42 static const std::string CONTENT_INFO_KEY("content-info");
44 BoxDaemonImpl::BoxDaemonImpl()
45 : m_pluginConnector(BoxPluginConnector::create())
49 BoxDaemonImpl::~BoxDaemonImpl()
53 bool BoxDaemonImpl::start(std::string& name)
57 // initialize existing plugins for web livebox
58 if (!m_pluginConnector->initialize()) {
59 LogD("failed to initialize plugins");
67 ProviderCallbacks callbacks;
68 setProviderCallbacks(callbacks);
70 int ret = provider_init(ecore_x_display_get(),
75 LogD("failed to initialize provider");
82 bool BoxDaemonImpl::stop()
86 // deinitialize provider
89 // deinitialize existing plugins for web livebox
90 if (!m_pluginConnector->shutdown()) {
91 LogD("failed to shutdown plugins");
98 bool BoxDaemonImpl::handleAppService(service_h service)
103 Ecore_Job* jobResult = NULL;
106 ret = service_get_operation(service, &operation);
107 if (ret != SERVICE_ERROR_NONE) {
108 LogD("no operation");
112 if (OPERATION_UPDATE_BOX == operation) {
113 BoxInfoPtr info = handleOperationUpdate(service);
115 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, this);
116 jobResult = ecore_job_add(requestBoxJobCallback, jobInfo);
122 LogD("unknown operation: %s", operation);
129 int BoxDaemonImpl::connectedCallback(ProviderEventArgPtr arg, void* data)
133 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
134 if (!provider_send_hello()) {
136 ecore_timer_add(MASTER_PROVIDER_PING_TIME, pingToMasterCallback, This);
142 int BoxDaemonImpl::disconnectedCallback(ProviderEventArgPtr arg, void* data)
146 aul_terminate_pid(getpid());
151 int BoxDaemonImpl::boxCreateCallback(
152 ProviderEventArgPtr arg,
153 int* width, int* height,
154 double* priority, void* data)
158 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
159 BoxInfoPtr info = This->initializeBoxInfo(arg);
164 if ((arg->info.lb_create.width == 0) || (arg->info.lb_create.height == 0)) {
165 livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
167 *width = arg->info.lb_create.width;
168 *height = arg->info.lb_create.height;
171 info->boxWidth = *width;
172 info->boxHeight = *height;
173 info->priority = 1.0f;
174 info->period = arg->info.lb_create.period;
175 if (arg->info.lb_create.content) {
176 info->contentInfo = std::string(arg->info.lb_create.content);
180 LogD("--------------------------------------------");
181 LogD("boxId: %s", info->boxId.c_str());
182 LogD("InstanceId: %s", info->instanceId.c_str());
183 LogD("width: %d", info->boxWidth);
184 LogD("height: %d", info->boxHeight);
185 LogD("update period: %f", info->period);
186 LogD("--------------------------------------------");
188 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
189 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
194 int BoxDaemonImpl::boxReCreateCallback(ProviderEventArgPtr arg, void* data)
198 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
199 BoxInfoPtr info = This->initializeBoxInfo(arg);
207 if ((arg->info.lb_recreate.width == 0) || (arg->info.lb_recreate.height == 0)) {
208 livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
209 arg->info.lb_recreate.width = *width;
210 arg->info.lb_recreate.height = *height;
213 info->boxWidth = arg->info.lb_recreate.width;
214 info->boxHeight = arg->info.lb_recreate.height;
215 info->priority = 1.0f;
216 info->period = arg->info.lb_recreate.period;
217 if (arg->info.lb_recreate.content) {
218 info->contentInfo = std::string(arg->info.lb_recreate.content);
222 LogD("--------------------------------------------");
223 LogD("boxId: %s", info->boxId.c_str());
224 LogD("InstanceId: %s", info->instanceId.c_str());
225 LogD("width: %d", info->boxWidth);
226 LogD("height: %d", info->boxHeight);
227 LogD("update period: %f", info->period);
228 LogD("--------------------------------------------");
230 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
231 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
236 int BoxDaemonImpl::boxDestroyCallback(ProviderEventArgPtr arg, void* data)
240 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
241 BoxInfoPtr info = This->initializeBoxInfo(arg);
246 LogD("--------------------------------------------");
247 LogD("boxId: %s", info->boxId.c_str());
248 LogD("InstanceId: %s", info->instanceId.c_str());
249 LogD("--------------------------------------------");
251 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_REMOVE_BOX, info, This);
252 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
257 int BoxDaemonImpl::pdCreateCallback(ProviderEventArgPtr arg, void* data)
261 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
262 BoxInfoPtr info = This->initializeBoxInfo(arg);
266 if (arg->info.pd_create.w == 0 || arg->info.pd_create.h == 0) {
269 //Use the screen width to fix the device width
270 ecore_x_window_size_get(0, &info->pdWidth, NULL);
271 info->pdHeight = arg->info.pd_create.h;
272 info->pdX = arg->info.pd_create.x;
273 info->pdY = arg->info.pd_create.y;
275 LogD("--------------------------------------------");
276 LogD("boxId: %s", info->boxId.c_str());
277 LogD("InstanceId: %s", info->instanceId.c_str());
278 LogD("width: %d", info->pdWidth);
279 LogD("height: %d", info->pdHeight);
280 LogD("x: %f", info->pdX);
281 LogD("y: %f", info->pdY);
282 LogD("--------------------------------------------");
284 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_OPEN_PD, info, This);
285 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
290 int BoxDaemonImpl::pdDestroyCallback(ProviderEventArgPtr arg, void* data)
294 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
295 BoxInfoPtr info = This->initializeBoxInfo(arg);
300 LogD("--------------------------------------------");
301 LogD("boxId: %s", info->boxId.c_str());
302 LogD("InstanceId: %s", info->instanceId.c_str());
303 LogD("--------------------------------------------");
305 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CLOSE_PD, info, This);
306 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
311 int BoxDaemonImpl::clickedCallback(ProviderEventArgPtr arg, void* data)
315 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
316 BoxInfoPtr info = This->initializeBoxInfo(arg);
321 int flag = web_provider_livebox_get_auto_launch(info->boxId.c_str());
326 BoxDaemonUtil::launchApplication(info->boxId, info->instanceId);
330 int BoxDaemonImpl::boxResizeCallback(ProviderEventArgPtr arg, void* data)
334 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
335 BoxInfoPtr info = This->initializeBoxInfo(arg);
339 if (arg->info.resize.w == 0 || arg->info.resize.h == 0) {
343 info->boxWidth = arg->info.resize.w;
344 info->boxHeight = arg->info.resize.h;
347 LogD("--------------------------------------------");
348 LogD("boxId: %s", info->boxId.c_str());
349 LogD("InstanceId: %s", info->instanceId.c_str());
350 LogD("width: %d", info->boxWidth);
351 LogD("height: %d", info->boxHeight);
352 LogD("--------------------------------------------");
354 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESIZE_BOX, info, This);
355 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
360 int BoxDaemonImpl::boxPauseCallback(ProviderEventArgPtr arg, void* data)
364 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
365 BoxInfoPtr info = This->initializeBoxInfo(arg);
371 LogD("--------------------------------------------");
372 LogD("boxId: %s", info->boxId.c_str());
373 LogD("InstanceId: %s", info->instanceId.c_str());
374 LogD("--------------------------------------------");
376 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_BOX, info, This);
377 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
382 int BoxDaemonImpl::boxResumeCallback(ProviderEventArgPtr arg, void* data)
386 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
387 BoxInfoPtr info = This->initializeBoxInfo(arg);
393 LogD("--------------------------------------------");
394 LogD("boxId: %s", info->boxId.c_str());
395 LogD("InstanceId: %s", info->instanceId.c_str());
396 LogD("--------------------------------------------");
398 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_BOX, info, This);
399 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
404 int BoxDaemonImpl::pauseCallback(ProviderEventArgPtr arg, void* data)
408 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
410 LogD("--------------------------------------------");
411 LogD("web-provider is paused");
412 LogD("--------------------------------------------");
414 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_ALL, BoxInfoPtr(), This);
415 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
420 int BoxDaemonImpl::resumeCallback(ProviderEventArgPtr arg, void* data)
424 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
426 LogD("--------------------------------------------");
427 LogD("web-provider is resumed");
428 LogD("--------------------------------------------");
430 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_ALL, BoxInfoPtr(), This);
431 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
436 int BoxDaemonImpl::boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data)
439 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
440 BoxInfoPtr info = This->initializeBoxInfo(arg);
444 info->period = arg->info.set_period.period;
446 LogD("--------------------------------------------");
447 LogD("boxId: %s", info->boxId.c_str());
448 LogD("InstanceId: %s", info->instanceId.c_str());
449 LogD("period: %f", info->period);
450 LogD("--------------------------------------------");
452 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_PERIOD, info, This);
453 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
458 int BoxDaemonImpl::boxUpdateCallback(ProviderEventArgPtr arg, void* data)
462 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
463 BoxInfoPtr info = This->initializeBoxInfo(arg);
468 LogD("--------------------------------------------");
469 LogD("boxId: %s", info->boxId.c_str());
470 LogD("InstanceId: %s", info->instanceId.c_str());
471 LogD("--------------------------------------------");
473 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, This);
474 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
479 void BoxDaemonImpl::setProviderCallbacks(ProviderCallbacks& callbacks)
483 memset(&callbacks, 0, sizeof(callbacks));
484 callbacks.connected = BoxDaemonImpl::connectedCallback;
485 callbacks.disconnected = BoxDaemonImpl::disconnectedCallback;
486 callbacks.pause = BoxDaemonImpl::pauseCallback;
487 callbacks.resume = BoxDaemonImpl::resumeCallback;
488 callbacks.lb_create = BoxDaemonImpl::boxCreateCallback;
489 callbacks.lb_recreate = BoxDaemonImpl::boxReCreateCallback;
490 callbacks.lb_destroy = BoxDaemonImpl::boxDestroyCallback;
491 callbacks.lb_pause = BoxDaemonImpl::boxPauseCallback;
492 callbacks.lb_resume = BoxDaemonImpl::boxResumeCallback;
493 callbacks.pd_create = BoxDaemonImpl::pdCreateCallback;
494 callbacks.pd_destroy = BoxDaemonImpl::pdDestroyCallback;
495 callbacks.clicked = BoxDaemonImpl::clickedCallback;
496 callbacks.resize = BoxDaemonImpl::boxResizeCallback;
497 callbacks.update_content = BoxDaemonImpl::boxUpdateCallback;
498 callbacks.set_period = BoxDaemonImpl::boxPeriodChangeCallback;
501 const char* BoxDaemonImpl::getBoxType(const char* boxId)
509 const char* type = web_provider_livebox_get_box_type(boxId);
512 std::string serviceBoxId(boxId);
513 boxType = m_pluginConnector->getBoxType(serviceBoxId);
514 if (boxType.empty()) {
515 LogD("unrecognized box id");
518 type = strdup(boxType.c_str());
521 LogD("box id: %s, type: %s", boxId, type);
525 BoxInfoPtr BoxDaemonImpl::initializeBoxInfo(ProviderEventArgPtr arg)
533 if (!arg->pkgname || !arg->id) {
534 LogD("pkgname or id don't exist");
538 const char* type = getBoxType(arg->pkgname);
542 BoxInfoPtr infoPtr = BoxInfoPtr(new BoxInfo(type, arg->pkgname, arg->id));
548 std::string BoxDaemonImpl::getBoxIdFromService(service_h service)
553 char* serviceUri = NULL;
554 ret = service_get_uri(service, &serviceUri);
555 if (ret != SERVICE_ERROR_NONE) {
557 return std::string();
560 std::string uri(serviceUri);
563 if(uri.compare(0, BOX_SERVICE_SCHEME.size(), BOX_SERVICE_SCHEME)) {
564 // uri is not box-service scheme
565 return std::string();
568 std::string boxId = uri.substr(BOX_SERVICE_SCHEME.size());
572 bool BoxDaemonImpl::isServiceCallerBoxOwner(service_h service)
578 std::string boxId = getBoxIdFromService(service);
580 LogD("error box-id");
584 // check if caller is owner of this box
585 const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
589 std::string ownerAppId(appId);
593 ret = service_get_caller(service, &caller);
594 if (ret != SERVICE_ERROR_NONE) {
597 std::string callerAppId(caller);
602 if (ownerAppId != callerAppId) {
603 LogD("caller is not matched with owner of requested box");
610 BoxInfoPtr BoxDaemonImpl::handleOperationUpdate(service_h service)
616 if (!isServiceCallerBoxOwner(service)) {
620 std::string boxId = getBoxIdFromService(service);
622 LogD("error box-id");
626 char* contentInfo = NULL;
627 service_get_extra_data(service, CONTENT_INFO_KEY.c_str(), &contentInfo);
629 std::string type(getBoxType(boxId.c_str()));
631 LogD("no type for this box");
632 delete[] contentInfo;
635 BoxInfoPtr info = BoxInfoPtr(new BoxInfo(type, boxId, ""));
637 info->contentInfo = std::string(contentInfo);
641 delete[] contentInfo;
646 Eina_Bool BoxDaemonImpl::pingToMasterCallback(void* data)
650 provider_send_ping();
652 return ECORE_CALLBACK_RENEW;
655 void BoxDaemonImpl::requestBoxJobCallback(void* data)
657 JobInfo* jobInfo = static_cast<JobInfo*>(data);
659 LogD("no information for job");
663 // just for debugging
664 //volatile int flag = 0;
665 //while(flag == 0) {;}
668 jobInfo->daemonImpl->m_pluginConnector->requestCommand(
669 jobInfo->cmdType, jobInfo->boxInfo);