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 <API/web_provider_livebox_info.h>
22 #include <appcore-efl.h>
24 #include <Core/Util/Log.h>
25 #include <Core/Util/Util.h>
28 #include <Elementary.h>
29 #include <livebox-service.h>
30 #include <Plugin/IBoxPluginConnector.h>
31 #include <Plugin/BoxPluginConnector.h>
33 #include <sys/types.h>
38 #include "BoxDaemonUtil.h"
39 #include "BoxDaemonImpl.h"
41 #define MASTER_PROVIDER_PING_TIME 120.0f
43 // These are string for handling application service from app
44 static const std::string BOX_SERVICE_SCHEME("box-service://");
45 static const std::string OPERATION_UPDATE_BOX(
46 "http://tizen.org/appcontrol/operation/dynamicbox/web/update");
47 static const std::string CONTENT_INFO_KEY("content-info");
48 static const std::string ALARM_CALLER_KEY("__ALARM_MGR_CALLER_APPID");
50 BoxDaemonImpl::BoxDaemonImpl()
51 : m_pluginConnector(BoxPluginConnector::create())
53 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, requestChangeLanguageCallback, this);
54 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, requestLowMemoryCallback, this);
55 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, requestChangeRegionCallback, this);
57 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, NULL, NULL);
59 if (vconf_notify_key_changed("db/setting/accessibility/font_name", requestChangeFontCallback, this) != true) {
60 LogD("vconf_notify_key_changed returned FALSE!");
62 if (vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, requestChangeTimeCallback, this) != true) {
63 LogD("vconf_notify_key_changed returned FALSE!");
67 BoxDaemonImpl::~BoxDaemonImpl()
71 bool BoxDaemonImpl::start(std::string& name)
75 // initialize existing plugins for web livebox
76 if (!m_pluginConnector->initialize()) {
77 LogD("failed to initialize plugins");
85 ProviderCallbacks callbacks;
86 setProviderCallbacks(callbacks);
88 int ret = provider_init(ecore_x_display_get(),
93 LogD("failed to initialize provider");
100 bool BoxDaemonImpl::stop()
104 // deinitialize provider
107 // deinitialize existing plugins for web livebox
108 if (!m_pluginConnector->shutdown()) {
109 LogD("failed to shutdown plugins");
116 bool BoxDaemonImpl::handleAppService(service_h service)
122 if (service_get_operation(service, &operation) != SERVICE_ERROR_NONE) {
123 LogD("no operation");
127 if (OPERATION_UPDATE_BOX == operation) {
128 BoxInfoPtr info = handleOperationUpdate(service);
130 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, this);
131 if (ecore_job_add(requestBoxJobCallback, jobInfo)) {
136 LogD("unknown operation: %s", operation);
143 int BoxDaemonImpl::connectedCallback(ProviderEventArgPtr arg, void* data)
148 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
149 if (!provider_send_hello()) {
151 ecore_timer_add(MASTER_PROVIDER_PING_TIME, pingToMasterCallback, This);
157 int BoxDaemonImpl::disconnectedCallback(ProviderEventArgPtr arg, void* data)
163 aul_terminate_pid(getpid());
168 int BoxDaemonImpl::boxCreateCallback(
169 ProviderEventArgPtr arg,
170 int* width, int* height,
171 double* priority, void* data)
174 UNUSED_PARAM(priority);
176 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
177 BoxInfoPtr info = This->initializeBoxInfo(arg);
182 if ((arg->info.lb_create.width == 0) || (arg->info.lb_create.height == 0)) {
183 livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
185 *width = arg->info.lb_create.width;
186 *height = arg->info.lb_create.height;
189 info->boxWidth = *width;
190 info->boxHeight = *height;
191 info->priority = 1.0f;
192 info->period = arg->info.lb_create.period;
193 if (arg->info.lb_create.content) {
194 info->contentInfo = std::string(arg->info.lb_create.content);
198 LogD("--------------------------------------------");
199 LogD("boxId: %s", info->boxId.c_str());
200 LogD("InstanceId: %s", info->instanceId.c_str());
201 LogD("width: %d", info->boxWidth);
202 LogD("height: %d", info->boxHeight);
203 LogD("update period: %f", info->period);
204 LogD("--------------------------------------------");
206 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
207 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
212 int BoxDaemonImpl::boxReCreateCallback(ProviderEventArgPtr arg, void* data)
216 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
217 BoxInfoPtr info = This->initializeBoxInfo(arg);
225 if ((arg->info.lb_recreate.width == 0) || (arg->info.lb_recreate.height == 0)) {
226 livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
227 arg->info.lb_recreate.width = *width;
228 arg->info.lb_recreate.height = *height;
231 info->boxWidth = arg->info.lb_recreate.width;
232 info->boxHeight = arg->info.lb_recreate.height;
233 info->priority = 1.0f;
234 info->period = arg->info.lb_recreate.period;
235 if (arg->info.lb_recreate.content) {
236 info->contentInfo = std::string(arg->info.lb_recreate.content);
240 LogD("--------------------------------------------");
241 LogD("boxId: %s", info->boxId.c_str());
242 LogD("InstanceId: %s", info->instanceId.c_str());
243 LogD("width: %d", info->boxWidth);
244 LogD("height: %d", info->boxHeight);
245 LogD("update period: %f", info->period);
246 LogD("--------------------------------------------");
248 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
249 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
254 int BoxDaemonImpl::boxDestroyCallback(ProviderEventArgPtr arg, void* data)
258 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
259 BoxInfoPtr info = This->initializeBoxInfo(arg);
264 LogD("--------------------------------------------");
265 LogD("boxId: %s", info->boxId.c_str());
266 LogD("InstanceId: %s", info->instanceId.c_str());
267 LogD("--------------------------------------------");
269 This->m_pluginConnector->requestCommand(REQUEST_CMD_REMOVE_BOX, info);
274 int BoxDaemonImpl::pdCreateCallback(ProviderEventArgPtr arg, void* data)
278 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
279 BoxInfoPtr info = This->initializeBoxInfo(arg);
283 if (arg->info.pd_create.w == 0 || arg->info.pd_create.h == 0) {
287 //Use the screen width to fix the device width
288 ecore_x_window_size_get(0, &info->pdWidth, NULL);
289 info->pdHeight = arg->info.pd_create.h;
290 info->pdX = arg->info.pd_create.x;
291 info->pdY = arg->info.pd_create.y;
293 LogD("--------------------------------------------");
294 LogD("boxId: %s", info->boxId.c_str());
295 LogD("InstanceId: %s", info->instanceId.c_str());
296 LogD("width: %d", info->pdWidth);
297 LogD("height: %d", info->pdHeight);
298 LogD("x: %f", info->pdX);
299 LogD("y: %f", info->pdY);
300 LogD("--------------------------------------------");
302 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_OPEN_PD, info, This);
303 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
308 int BoxDaemonImpl::pdDestroyCallback(ProviderEventArgPtr arg, void* data)
312 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
313 BoxInfoPtr info = This->initializeBoxInfo(arg);
318 LogD("--------------------------------------------");
319 LogD("boxId: %s", info->boxId.c_str());
320 LogD("InstanceId: %s", info->instanceId.c_str());
321 LogD("--------------------------------------------");
323 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CLOSE_PD, info, This);
324 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
329 int BoxDaemonImpl::clickedCallback(ProviderEventArgPtr arg, void* data)
333 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
334 BoxInfoPtr info = This->initializeBoxInfo(arg);
339 int flag = web_provider_livebox_get_auto_launch(info->boxId.c_str());
344 BoxDaemonUtil::launchApplication(info->boxId, info->instanceId);
348 int BoxDaemonImpl::boxResizeCallback(ProviderEventArgPtr arg, void* data)
352 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
353 BoxInfoPtr info = This->initializeBoxInfo(arg);
357 if (arg->info.resize.w == 0 || arg->info.resize.h == 0) {
361 info->boxWidth = arg->info.resize.w;
362 info->boxHeight = arg->info.resize.h;
365 LogD("--------------------------------------------");
366 LogD("boxId: %s", info->boxId.c_str());
367 LogD("InstanceId: %s", info->instanceId.c_str());
368 LogD("width: %d", info->boxWidth);
369 LogD("height: %d", info->boxHeight);
370 LogD("--------------------------------------------");
372 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESIZE_BOX, info, This);
373 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
378 int BoxDaemonImpl::boxPauseCallback(ProviderEventArgPtr arg, void* data)
382 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
383 BoxInfoPtr info = This->initializeBoxInfo(arg);
389 LogD("--------------------------------------------");
390 LogD("boxId: %s", info->boxId.c_str());
391 LogD("InstanceId: %s", info->instanceId.c_str());
392 LogD("--------------------------------------------");
394 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_BOX, info, This);
395 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
400 int BoxDaemonImpl::boxResumeCallback(ProviderEventArgPtr arg, void* data)
404 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
405 BoxInfoPtr info = This->initializeBoxInfo(arg);
411 LogD("--------------------------------------------");
412 LogD("boxId: %s", info->boxId.c_str());
413 LogD("InstanceId: %s", info->instanceId.c_str());
414 LogD("--------------------------------------------");
416 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_BOX, info, This);
417 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
422 int BoxDaemonImpl::pauseCallback(ProviderEventArgPtr arg, void* data)
427 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
429 LogD("--------------------------------------------");
430 LogD("web-provider is paused");
431 LogD("--------------------------------------------");
433 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_ALL, BoxInfoPtr(), This);
434 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
439 int BoxDaemonImpl::resumeCallback(ProviderEventArgPtr arg, void* data)
444 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
446 LogD("--------------------------------------------");
447 LogD("web-provider is resumed");
448 LogD("--------------------------------------------");
450 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_ALL, BoxInfoPtr(), This);
451 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
456 int BoxDaemonImpl::boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data)
459 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
460 BoxInfoPtr info = This->initializeBoxInfo(arg);
464 info->period = arg->info.set_period.period;
466 LogD("--------------------------------------------");
467 LogD("boxId: %s", info->boxId.c_str());
468 LogD("InstanceId: %s", info->instanceId.c_str());
469 LogD("period: %f", info->period);
470 LogD("--------------------------------------------");
472 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_PERIOD, info, This);
473 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
478 int BoxDaemonImpl::boxUpdateCallback(ProviderEventArgPtr arg, void* data)
482 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
483 BoxInfoPtr info = This->initializeBoxInfo(arg);
488 LogD("--------------------------------------------");
489 LogD("boxId: %s", info->boxId.c_str());
490 LogD("InstanceId: %s", info->instanceId.c_str());
491 LogD("--------------------------------------------");
493 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, This);
494 Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
499 void BoxDaemonImpl::setProviderCallbacks(ProviderCallbacks& callbacks)
503 memset(&callbacks, 0, sizeof(callbacks));
504 callbacks.connected = BoxDaemonImpl::connectedCallback;
505 callbacks.disconnected = BoxDaemonImpl::disconnectedCallback;
506 callbacks.pause = BoxDaemonImpl::pauseCallback;
507 callbacks.resume = BoxDaemonImpl::resumeCallback;
508 callbacks.lb_create = BoxDaemonImpl::boxCreateCallback;
509 callbacks.lb_recreate = BoxDaemonImpl::boxReCreateCallback;
510 callbacks.lb_destroy = BoxDaemonImpl::boxDestroyCallback;
511 callbacks.lb_pause = BoxDaemonImpl::boxPauseCallback;
512 callbacks.lb_resume = BoxDaemonImpl::boxResumeCallback;
513 callbacks.pd_create = BoxDaemonImpl::pdCreateCallback;
514 callbacks.pd_destroy = BoxDaemonImpl::pdDestroyCallback;
515 callbacks.clicked = BoxDaemonImpl::clickedCallback;
516 callbacks.resize = BoxDaemonImpl::boxResizeCallback;
517 callbacks.update_content = BoxDaemonImpl::boxUpdateCallback;
518 callbacks.set_period = BoxDaemonImpl::boxPeriodChangeCallback;
521 std::string BoxDaemonImpl::getBoxType(const char* boxId)
526 return std::string();
529 const char* type = web_provider_livebox_get_box_type(boxId);
531 std::string boxType = m_pluginConnector->getBoxType(boxId);
532 if (boxType.empty()) {
533 LogD("unrecognized box id");
535 LogD("box id: %s, type: %s", boxId, boxType.c_str());
540 LogD("box id: %s, type: %s", boxId, type);
541 std::string result{type};
542 free(const_cast<char*>(type));
546 BoxInfoPtr BoxDaemonImpl::initializeBoxInfo(ProviderEventArgPtr arg)
554 if (!arg->pkgname || !arg->id) {
555 LogD("pkgname or id don't exist");
559 std::string type = getBoxType(arg->pkgname);
563 BoxInfoPtr infoPtr = BoxInfoPtr(new BoxInfo(type, arg->pkgname, arg->id));
568 std::string BoxDaemonImpl::getBoxIdFromService(service_h service)
573 char* serviceUri = NULL;
574 ret = service_get_uri(service, &serviceUri);
575 if (ret != SERVICE_ERROR_NONE) {
577 return std::string();
580 std::string uri(serviceUri);
583 if(uri.compare(0, BOX_SERVICE_SCHEME.size(), BOX_SERVICE_SCHEME)) {
584 // uri is not box-service scheme
585 return std::string();
588 std::string boxId = uri.substr(BOX_SERVICE_SCHEME.size());
592 bool BoxDaemonImpl::isServiceCallerBoxOwner(service_h service)
598 std::string boxId = getBoxIdFromService(service);
600 LogD("error box-id");
604 // check if caller is owner of this box
605 const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
609 std::string ownerAppId(appId);
613 ret = service_get_caller(service, &caller);
614 if (ret != SERVICE_ERROR_NONE) {
615 ret = service_get_extra_data(
616 service, ALARM_CALLER_KEY.c_str(), &caller);
617 if (ret != SERVICE_ERROR_NONE) {
618 LogD("failed to get caller's appid from service");
622 std::string callerAppId(caller);
627 if (ownerAppId != callerAppId) {
628 LogD("caller is not matched with owner of requested box");
635 BoxInfoPtr BoxDaemonImpl::handleOperationUpdate(service_h service)
639 if (!isServiceCallerBoxOwner(service)) {
643 std::string boxId = getBoxIdFromService(service);
645 LogD("error box-id");
649 char* contentInfo = NULL;
650 service_get_extra_data(service, CONTENT_INFO_KEY.c_str(), &contentInfo);
652 std::string type(getBoxType(boxId.c_str()));
654 LogD("no type for this box");
655 delete[] contentInfo;
658 BoxInfoPtr info = BoxInfoPtr(new BoxInfo(type, boxId, ""));
660 info->contentInfo = std::string(contentInfo);
664 delete[] contentInfo;
669 Eina_Bool BoxDaemonImpl::pingToMasterCallback(void* data)
674 provider_send_ping();
676 return ECORE_CALLBACK_RENEW;
679 void BoxDaemonImpl::requestBoxJobCallback(void* data)
681 JobInfo* jobInfo = static_cast<JobInfo*>(data);
683 LogD("no information for job");
687 // just for debugging
688 //volatile int flag = 0;
689 //while(flag == 0) {;}
692 jobInfo->daemonImpl->m_pluginConnector->requestCommand(
693 jobInfo->cmdType, jobInfo->boxInfo);
698 int BoxDaemonImpl::requestChangeLanguageCallback(void* data)
702 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
703 BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
704 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_LANGUAGE, info, This);
706 ecore_job_add(requestBoxJobCallback, jobInfo);
710 int BoxDaemonImpl::requestChangeRegionCallback(void* data)
714 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
715 BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
716 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_LANGUAGE, info, This);
718 ecore_job_add(requestBoxJobCallback, jobInfo);
721 int BoxDaemonImpl::requestLowMemoryCallback(void* data)
726 // terminate box daemon and revive
731 void BoxDaemonImpl::requestChangeFontCallback(keynode_t* key, void* data)
736 char* fontstr = vconf_get_str("db/setting/accessibility/font_name");
738 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
739 BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
740 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_LANGUAGE, info, This);
743 ecore_job_add(requestBoxJobCallback, jobInfo);
746 void BoxDaemonImpl::requestChangeTimeCallback(keynode_t* key, void* data)
751 char* timestr = vconf_get_str(VCONFKEY_SYSTEM_TIME_CHANGED);
753 BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
754 BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
755 JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_LANGUAGE, info, This);
758 ecore_job_add(requestBoxJobCallback, jobInfo);