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");
43 static const std::string ALARM_CALLER_KEY("__ALARM_MGR_CALLER_APPID");
45 BoxDaemonImpl::BoxDaemonImpl()
46 : m_pluginConnector(BoxPluginConnector::create())
50 BoxDaemonImpl::~BoxDaemonImpl()
54 bool BoxDaemonImpl::start(std::string& name)
58 // initialize existing plugins for web livebox
59 if (!m_pluginConnector->initialize()) {
60 LogD("failed to initialize plugins");
68 ProviderCallbacks callbacks;
69 setProviderCallbacks(callbacks);
71 int ret = provider_init(ecore_x_display_get(),
76 LogD("failed to initialize provider");
83 bool BoxDaemonImpl::stop()
87 // deinitialize provider
90 // deinitialize existing plugins for web livebox
91 if (!m_pluginConnector->shutdown()) {
92 LogD("failed to shutdown plugins");
99 bool BoxDaemonImpl::handleAppService(service_h service)
104 Ecore_Job* jobResult = NULL;
107 ret = service_get_operation(service, &operation);
108 if (ret != SERVICE_ERROR_NONE) {
109 LogD("no operation");
113 if (OPERATION_UPDATE_BOX == operation) {
114 BoxInfoPtr info = handleOperationUpdate(service);
116 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, this);
117 jobResult = ecore_job_add(requestBoxJobCallback, jobInfo);
123 LogD("unknown operation: %s", operation);
130 int BoxDaemonImpl::connectedCallback(ProviderEventArgPtr arg, void* data)
134 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
135 if (!provider_send_hello()) {
137 ecore_timer_add(MASTER_PROVIDER_PING_TIME, pingToMasterCallback, This);
143 int BoxDaemonImpl::disconnectedCallback(ProviderEventArgPtr arg, void* data)
147 aul_terminate_pid(getpid());
152 int BoxDaemonImpl::boxCreateCallback(
153 ProviderEventArgPtr arg,
154 int* width, int* height,
155 double* priority, void* data)
159 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
160 BoxInfoPtr info = This->initializeBoxInfo(arg);
165 if ((arg->info.lb_create.width == 0) || (arg->info.lb_create.height == 0)) {
166 livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
168 *width = arg->info.lb_create.width;
169 *height = arg->info.lb_create.height;
172 info->boxWidth = *width;
173 info->boxHeight = *height;
174 info->priority = 1.0f;
175 info->period = arg->info.lb_create.period;
176 if (arg->info.lb_create.content) {
177 info->contentInfo = std::string(arg->info.lb_create.content);
181 LogD("--------------------------------------------");
182 LogD("boxId: %s", info->boxId.c_str());
183 LogD("InstanceId: %s", info->instanceId.c_str());
184 LogD("width: %d", info->boxWidth);
185 LogD("height: %d", info->boxHeight);
186 LogD("update period: %f", info->period);
187 LogD("--------------------------------------------");
189 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
190 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
195 int BoxDaemonImpl::boxReCreateCallback(ProviderEventArgPtr arg, void* data)
199 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
200 BoxInfoPtr info = This->initializeBoxInfo(arg);
208 if ((arg->info.lb_recreate.width == 0) || (arg->info.lb_recreate.height == 0)) {
209 livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
210 arg->info.lb_recreate.width = *width;
211 arg->info.lb_recreate.height = *height;
214 info->boxWidth = arg->info.lb_recreate.width;
215 info->boxHeight = arg->info.lb_recreate.height;
216 info->priority = 1.0f;
217 info->period = arg->info.lb_recreate.period;
218 if (arg->info.lb_recreate.content) {
219 info->contentInfo = std::string(arg->info.lb_recreate.content);
223 LogD("--------------------------------------------");
224 LogD("boxId: %s", info->boxId.c_str());
225 LogD("InstanceId: %s", info->instanceId.c_str());
226 LogD("width: %d", info->boxWidth);
227 LogD("height: %d", info->boxHeight);
228 LogD("update period: %f", info->period);
229 LogD("--------------------------------------------");
231 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
232 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
237 int BoxDaemonImpl::boxDestroyCallback(ProviderEventArgPtr arg, void* data)
241 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
242 BoxInfoPtr info = This->initializeBoxInfo(arg);
247 LogD("--------------------------------------------");
248 LogD("boxId: %s", info->boxId.c_str());
249 LogD("InstanceId: %s", info->instanceId.c_str());
250 LogD("--------------------------------------------");
252 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_REMOVE_BOX, info, This);
253 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
258 int BoxDaemonImpl::pdCreateCallback(ProviderEventArgPtr arg, void* data)
262 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
263 BoxInfoPtr info = This->initializeBoxInfo(arg);
267 if (arg->info.pd_create.w == 0 || arg->info.pd_create.h == 0) {
270 //Use the screen width to fix the device width
271 ecore_x_window_size_get(0, &info->pdWidth, NULL);
272 info->pdHeight = arg->info.pd_create.h;
273 info->pdX = arg->info.pd_create.x;
274 info->pdY = arg->info.pd_create.y;
276 LogD("--------------------------------------------");
277 LogD("boxId: %s", info->boxId.c_str());
278 LogD("InstanceId: %s", info->instanceId.c_str());
279 LogD("width: %d", info->pdWidth);
280 LogD("height: %d", info->pdHeight);
281 LogD("x: %f", info->pdX);
282 LogD("y: %f", info->pdY);
283 LogD("--------------------------------------------");
285 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_OPEN_PD, info, This);
286 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
291 int BoxDaemonImpl::pdDestroyCallback(ProviderEventArgPtr arg, void* data)
295 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
296 BoxInfoPtr info = This->initializeBoxInfo(arg);
301 LogD("--------------------------------------------");
302 LogD("boxId: %s", info->boxId.c_str());
303 LogD("InstanceId: %s", info->instanceId.c_str());
304 LogD("--------------------------------------------");
306 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CLOSE_PD, info, This);
307 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
312 int BoxDaemonImpl::clickedCallback(ProviderEventArgPtr arg, void* data)
316 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
317 BoxInfoPtr info = This->initializeBoxInfo(arg);
322 int flag = web_provider_livebox_get_auto_launch(info->boxId.c_str());
327 BoxDaemonUtil::launchApplication(info->boxId, info->instanceId);
331 int BoxDaemonImpl::boxResizeCallback(ProviderEventArgPtr arg, void* data)
335 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
336 BoxInfoPtr info = This->initializeBoxInfo(arg);
340 if (arg->info.resize.w == 0 || arg->info.resize.h == 0) {
344 info->boxWidth = arg->info.resize.w;
345 info->boxHeight = arg->info.resize.h;
348 LogD("--------------------------------------------");
349 LogD("boxId: %s", info->boxId.c_str());
350 LogD("InstanceId: %s", info->instanceId.c_str());
351 LogD("width: %d", info->boxWidth);
352 LogD("height: %d", info->boxHeight);
353 LogD("--------------------------------------------");
355 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESIZE_BOX, info, This);
356 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
361 int BoxDaemonImpl::boxPauseCallback(ProviderEventArgPtr arg, void* data)
365 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
366 BoxInfoPtr info = This->initializeBoxInfo(arg);
372 LogD("--------------------------------------------");
373 LogD("boxId: %s", info->boxId.c_str());
374 LogD("InstanceId: %s", info->instanceId.c_str());
375 LogD("--------------------------------------------");
377 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_BOX, info, This);
378 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
383 int BoxDaemonImpl::boxResumeCallback(ProviderEventArgPtr arg, void* data)
387 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
388 BoxInfoPtr info = This->initializeBoxInfo(arg);
394 LogD("--------------------------------------------");
395 LogD("boxId: %s", info->boxId.c_str());
396 LogD("InstanceId: %s", info->instanceId.c_str());
397 LogD("--------------------------------------------");
399 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_BOX, info, This);
400 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
405 int BoxDaemonImpl::pauseCallback(ProviderEventArgPtr arg, void* data)
409 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
411 LogD("--------------------------------------------");
412 LogD("web-provider is paused");
413 LogD("--------------------------------------------");
415 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_ALL, BoxInfoPtr(), This);
416 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
421 int BoxDaemonImpl::resumeCallback(ProviderEventArgPtr arg, void* data)
425 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
427 LogD("--------------------------------------------");
428 LogD("web-provider is resumed");
429 LogD("--------------------------------------------");
431 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_ALL, BoxInfoPtr(), This);
432 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
437 int BoxDaemonImpl::boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data)
440 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
441 BoxInfoPtr info = This->initializeBoxInfo(arg);
445 info->period = arg->info.set_period.period;
447 LogD("--------------------------------------------");
448 LogD("boxId: %s", info->boxId.c_str());
449 LogD("InstanceId: %s", info->instanceId.c_str());
450 LogD("period: %f", info->period);
451 LogD("--------------------------------------------");
453 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_PERIOD, info, This);
454 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
459 int BoxDaemonImpl::boxUpdateCallback(ProviderEventArgPtr arg, void* data)
463 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
464 BoxInfoPtr info = This->initializeBoxInfo(arg);
469 LogD("--------------------------------------------");
470 LogD("boxId: %s", info->boxId.c_str());
471 LogD("InstanceId: %s", info->instanceId.c_str());
472 LogD("--------------------------------------------");
474 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, This);
475 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
480 void BoxDaemonImpl::setProviderCallbacks(ProviderCallbacks& callbacks)
484 memset(&callbacks, 0, sizeof(callbacks));
485 callbacks.connected = BoxDaemonImpl::connectedCallback;
486 callbacks.disconnected = BoxDaemonImpl::disconnectedCallback;
487 callbacks.pause = BoxDaemonImpl::pauseCallback;
488 callbacks.resume = BoxDaemonImpl::resumeCallback;
489 callbacks.lb_create = BoxDaemonImpl::boxCreateCallback;
490 callbacks.lb_recreate = BoxDaemonImpl::boxReCreateCallback;
491 callbacks.lb_destroy = BoxDaemonImpl::boxDestroyCallback;
492 callbacks.lb_pause = BoxDaemonImpl::boxPauseCallback;
493 callbacks.lb_resume = BoxDaemonImpl::boxResumeCallback;
494 callbacks.pd_create = BoxDaemonImpl::pdCreateCallback;
495 callbacks.pd_destroy = BoxDaemonImpl::pdDestroyCallback;
496 callbacks.clicked = BoxDaemonImpl::clickedCallback;
497 callbacks.resize = BoxDaemonImpl::boxResizeCallback;
498 callbacks.update_content = BoxDaemonImpl::boxUpdateCallback;
499 callbacks.set_period = BoxDaemonImpl::boxPeriodChangeCallback;
502 std::string BoxDaemonImpl::getBoxType(const char* boxId)
507 return std::string();
510 const char* type = web_provider_livebox_get_box_type(boxId);
512 std::string boxType = m_pluginConnector->getBoxType(boxId);
513 if (boxType.empty()) {
514 LogD("unrecognized box id");
516 LogD("box id: %s, type: %s", boxId, boxType.c_str());
521 LogD("box id: %s, type: %s", boxId, type);
522 std::string result{type};
523 free(const_cast<char*>(type));
527 BoxInfoPtr BoxDaemonImpl::initializeBoxInfo(ProviderEventArgPtr arg)
535 if (!arg->pkgname || !arg->id) {
536 LogD("pkgname or id don't exist");
540 std::string type = getBoxType(arg->pkgname);
544 BoxInfoPtr infoPtr = BoxInfoPtr(new BoxInfo(type, arg->pkgname, arg->id));
549 std::string BoxDaemonImpl::getBoxIdFromService(service_h service)
554 char* serviceUri = NULL;
555 ret = service_get_uri(service, &serviceUri);
556 if (ret != SERVICE_ERROR_NONE) {
558 return std::string();
561 std::string uri(serviceUri);
564 if(uri.compare(0, BOX_SERVICE_SCHEME.size(), BOX_SERVICE_SCHEME)) {
565 // uri is not box-service scheme
566 return std::string();
569 std::string boxId = uri.substr(BOX_SERVICE_SCHEME.size());
573 bool BoxDaemonImpl::isServiceCallerBoxOwner(service_h service)
579 std::string boxId = getBoxIdFromService(service);
581 LogD("error box-id");
585 // check if caller is owner of this box
586 const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
590 std::string ownerAppId(appId);
594 ret = service_get_caller(service, &caller);
595 if (ret != SERVICE_ERROR_NONE) {
596 ret = service_get_extra_data(
597 service, ALARM_CALLER_KEY.c_str(), &caller);
598 if (ret != SERVICE_ERROR_NONE) {
599 LogD("failed to get caller's appid from service");
603 std::string callerAppId(caller);
608 if (ownerAppId != callerAppId) {
609 LogD("caller is not matched with owner of requested box");
616 BoxInfoPtr BoxDaemonImpl::handleOperationUpdate(service_h service)
622 if (!isServiceCallerBoxOwner(service)) {
626 std::string boxId = getBoxIdFromService(service);
628 LogD("error box-id");
632 char* contentInfo = NULL;
633 service_get_extra_data(service, CONTENT_INFO_KEY.c_str(), &contentInfo);
635 std::string type(getBoxType(boxId.c_str()));
637 LogD("no type for this box");
638 delete[] contentInfo;
641 BoxInfoPtr info = BoxInfoPtr(new BoxInfo(type, boxId, ""));
643 info->contentInfo = std::string(contentInfo);
647 delete[] contentInfo;
652 Eina_Bool BoxDaemonImpl::pingToMasterCallback(void* data)
656 provider_send_ping();
658 return ECORE_CALLBACK_RENEW;
661 void BoxDaemonImpl::requestBoxJobCallback(void* data)
663 JobInfo* jobInfo = static_cast<JobInfo*>(data);
665 LogD("no information for job");
669 // just for debugging
670 //volatile int flag = 0;
671 //while(flag == 0) {;}
674 jobInfo->daemonImpl->m_pluginConnector->requestCommand(
675 jobInfo->cmdType, jobInfo->boxInfo);