[Release] livebox.web-provider-1.46
[platform/framework/web/web-provider.git] / src / Daemon / BoxDaemonImpl.cpp
index 1d38bfc..11b17eb 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
  *
- *    Licensed under the Flora License, Version 1.0 (the "License");
+ *    Licensed under the Flora License, Version 1.1 (the "License");
  *    you may not use this file except in compliance with the License.
  *    You may obtain a copy of the License at
  *
@@ -21,6 +21,7 @@
 #include <unistd.h>
 #include <string>
 #include <cstring>
+#include <app.h>
 #include <aul.h>
 #include <Ecore_X.h>
 #include <provider.h>
 
 #define MASTER_PROVIDER_PING_TIME  120.0f
 
+// These are string for handling application service from app
+static const std::string BOX_SERVICE_SCHEME("box-service://");
+static const std::string OPERATION_UPDATE_BOX(
+        "http://tizen.org/appcontrol/operation/dynamicbox/web/update");
+static const std::string CONTENT_INFO_KEY("content-info");
+static const std::string ALARM_CALLER_KEY("__ALARM_MGR_CALLER_APPID");
+
 BoxDaemonImpl::BoxDaemonImpl()
     : m_pluginConnector(BoxPluginConnector::create())
 {
@@ -88,6 +96,37 @@ bool BoxDaemonImpl::stop()
     return true;
 }
 
+bool BoxDaemonImpl::handleAppService(service_h service)
+{
+    LogD("enter");
+    int ret;
+    bool result = false;
+    Ecore_Job* jobResult = NULL;
+    char* operation;
+
+    ret = service_get_operation(service, &operation);
+    if (ret != SERVICE_ERROR_NONE) {
+        LogD("no operation");
+        return false;
+    }
+
+    if (OPERATION_UPDATE_BOX == operation) {
+        BoxInfoPtr info = handleOperationUpdate(service);
+        if (info) {
+            JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, this);
+            jobResult = ecore_job_add(requestBoxJobCallback, jobInfo);
+            if (jobResult) {
+                result = true;
+            }
+        }
+    } else {
+        LogD("unknown operation: %s", operation);
+    }
+
+    delete[] operation;
+    return result;
+}
+
 int BoxDaemonImpl::connectedCallback(ProviderEventArgPtr arg, void* data)
 {
     LogD("enter");
@@ -144,13 +183,13 @@ int BoxDaemonImpl::boxCreateCallback(
     LogD("InstanceId: %s", info->instanceId.c_str());
     LogD("width: %d", info->boxWidth);
     LogD("height: %d", info->boxHeight);
-    LogD("update period: %d", info->period);
+    LogD("update period: %f", info->period);
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                    requestBoxJobCallback,
-                    new JobInfo(REQUEST_CMD_ADD_BOX, info, This))
-                    ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 int BoxDaemonImpl::boxReCreateCallback(ProviderEventArgPtr arg, void* data)
@@ -189,10 +228,10 @@ int BoxDaemonImpl::boxReCreateCallback(ProviderEventArgPtr arg, void* data)
     LogD("update period: %f", info->period);
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                    requestBoxJobCallback,
-                    new JobInfo(REQUEST_CMD_ADD_BOX, info, This))
-                    ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 int BoxDaemonImpl::boxDestroyCallback(ProviderEventArgPtr arg, void* data)
@@ -210,10 +249,10 @@ int BoxDaemonImpl::boxDestroyCallback(ProviderEventArgPtr arg, void* data)
     LogD("InstanceId: %s", info->instanceId.c_str());
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                    requestBoxJobCallback,
-                    new JobInfo(REQUEST_CMD_REMOVE_BOX, info, This))
-                    ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_REMOVE_BOX, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 int BoxDaemonImpl::pdCreateCallback(ProviderEventArgPtr arg, void* data)
@@ -228,8 +267,8 @@ int BoxDaemonImpl::pdCreateCallback(ProviderEventArgPtr arg, void* data)
     if (arg->info.pd_create.w == 0 || arg->info.pd_create.h == 0) {
         return -1;
     }
-
-    info->pdWidth = arg->info.pd_create.w;
+    //Use the screen width to fix the device width
+    ecore_x_window_size_get(0, &info->pdWidth, NULL);
     info->pdHeight = arg->info.pd_create.h;
     info->pdX = arg->info.pd_create.x;
     info->pdY = arg->info.pd_create.y;
@@ -243,10 +282,10 @@ int BoxDaemonImpl::pdCreateCallback(ProviderEventArgPtr arg, void* data)
     LogD("y: %f", info->pdY);
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                requestBoxJobCallback,
-                new JobInfo(REQUEST_CMD_OPEN_PD, info, This))
-                ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_OPEN_PD, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 int BoxDaemonImpl::pdDestroyCallback(ProviderEventArgPtr arg, void* data)
@@ -264,10 +303,10 @@ int BoxDaemonImpl::pdDestroyCallback(ProviderEventArgPtr arg, void* data)
     LogD("InstanceId: %s", info->instanceId.c_str());
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                requestBoxJobCallback,
-                new JobInfo(REQUEST_CMD_CLOSE_PD, info, This))
-                ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CLOSE_PD, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 int BoxDaemonImpl::clickedCallback(ProviderEventArgPtr arg, void* data)
@@ -289,7 +328,7 @@ int BoxDaemonImpl::clickedCallback(ProviderEventArgPtr arg, void* data)
     return 0;
 }
 
-int BoxDaemonImpl::resizeCallback(ProviderEventArgPtr arg, void* data)
+int BoxDaemonImpl::boxResizeCallback(ProviderEventArgPtr arg, void* data)
 {
     LogD("enter");
 
@@ -313,10 +352,10 @@ int BoxDaemonImpl::resizeCallback(ProviderEventArgPtr arg, void* data)
     LogD("height: %d", info->boxHeight);
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                requestBoxJobCallback,
-                new JobInfo(REQUEST_CMD_RESIZE_BOX, info, This))
-                ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESIZE_BOX, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 int BoxDaemonImpl::boxPauseCallback(ProviderEventArgPtr arg, void* data)
@@ -335,10 +374,10 @@ int BoxDaemonImpl::boxPauseCallback(ProviderEventArgPtr arg, void* data)
     LogD("InstanceId: %s", info->instanceId.c_str());
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                requestBoxJobCallback,
-                new JobInfo(REQUEST_CMD_PAUSE_BOX, info, This))
-                ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_BOX, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 int BoxDaemonImpl::boxResumeCallback(ProviderEventArgPtr arg, void* data)
@@ -357,10 +396,10 @@ int BoxDaemonImpl::boxResumeCallback(ProviderEventArgPtr arg, void* data)
     LogD("InstanceId: %s", info->instanceId.c_str());
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                requestBoxJobCallback,
-                new JobInfo(REQUEST_CMD_RESUME_BOX, info, This))
-                ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_BOX, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 int BoxDaemonImpl::pauseCallback(ProviderEventArgPtr arg, void* data)
@@ -373,10 +412,10 @@ int BoxDaemonImpl::pauseCallback(ProviderEventArgPtr arg, void* data)
     LogD("web-provider is paused");
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                requestBoxJobCallback,
-                new JobInfo(REQUEST_CMD_PAUSE_ALL, BoxInfoPtr(), This))
-                ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_ALL, BoxInfoPtr(), This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 int BoxDaemonImpl::resumeCallback(ProviderEventArgPtr arg, void* data)
@@ -389,39 +428,53 @@ int BoxDaemonImpl::resumeCallback(ProviderEventArgPtr arg, void* data)
     LogD("web-provider is resumed");
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                requestBoxJobCallback,
-                new JobInfo(REQUEST_CMD_RESUME_ALL, BoxInfoPtr(), This))
-                ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_ALL, BoxInfoPtr(), This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
-int BoxDaemonImpl::updateContentCallback(ProviderEventArgPtr arg, void* data)
+int BoxDaemonImpl::boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data)
 {
     LogD("enter");
+    BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+    BoxInfoPtr info = This->initializeBoxInfo(arg);
+    if (!info) {
+        return -1;
+    }
+    info->period = arg->info.set_period.period;
 
-    return 0;
+    LogD("--------------------------------------------");
+    LogD("boxId: %s", info->boxId.c_str());
+    LogD("InstanceId: %s", info->instanceId.c_str());
+    LogD("period: %f", info->period);
+    LogD("--------------------------------------------");
+
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_PERIOD, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
-int BoxDaemonImpl::changePeriodCallback(ProviderEventArgPtr arg, void* data)
+int BoxDaemonImpl::boxUpdateCallback(ProviderEventArgPtr arg, void* data)
 {
     LogD("enter");
+
     BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
     BoxInfoPtr info = This->initializeBoxInfo(arg);
     if (!info) {
         return -1;
     }
-    info->period = arg->info.set_period.period;
 
     LogD("--------------------------------------------");
     LogD("boxId: %s", info->boxId.c_str());
     LogD("InstanceId: %s", info->instanceId.c_str());
-    LogD("period: %f", info->period);
     LogD("--------------------------------------------");
 
-    return ecore_job_add(
-                requestBoxJobCallback,
-                new JobInfo(REQUEST_CMD_CHANGE_PERIOD, info, This))
-                ? 0 : -1;
+    JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, This);
+    Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+    return ret ? 0 : -1;
 }
 
 void BoxDaemonImpl::setProviderCallbacks(ProviderCallbacks& callbacks)
@@ -441,33 +494,34 @@ void BoxDaemonImpl::setProviderCallbacks(ProviderCallbacks& callbacks)
     callbacks.pd_create = BoxDaemonImpl::pdCreateCallback;
     callbacks.pd_destroy = BoxDaemonImpl::pdDestroyCallback;
     callbacks.clicked = BoxDaemonImpl::clickedCallback;
-    callbacks.resize = BoxDaemonImpl::resizeCallback;
-    callbacks.update_content = BoxDaemonImpl::updateContentCallback;
-    callbacks.set_period = BoxDaemonImpl::changePeriodCallback;
+    callbacks.resize = BoxDaemonImpl::boxResizeCallback;
+    callbacks.update_content = BoxDaemonImpl::boxUpdateCallback;
+    callbacks.set_period = BoxDaemonImpl::boxPeriodChangeCallback;
 }
 
-const char* BoxDaemonImpl::getBoxType(const char* boxId)
+std::string BoxDaemonImpl::getBoxType(const char* boxId)
 {
     LogD("enter");
 
     if (!boxId) {
-        return NULL;
+        return std::string();
     }
     
     const char* type = web_provider_livebox_get_box_type(boxId);
-    std::string boxType;
     if (!type) {
-        std::string serviceBoxId(boxId);
-        boxType = m_pluginConnector->getBoxType(serviceBoxId);
+        std::string boxType = m_pluginConnector->getBoxType(boxId);
         if (boxType.empty()) {
             LogD("unrecognized box id");
-            return NULL; 
+        } else {
+            LogD("box id: %s, type: %s", boxId, boxType.c_str());
         }
-        type = strdup(boxType.c_str());
+        return boxType;
     }
 
     LogD("box id: %s, type: %s", boxId, type);
-    return type;
+    std::string result{type};
+    free(const_cast<char*>(type));
+    return result;
 }
 
 BoxInfoPtr BoxDaemonImpl::initializeBoxInfo(ProviderEventArgPtr arg)
@@ -483,17 +537,118 @@ BoxInfoPtr BoxDaemonImpl::initializeBoxInfo(ProviderEventArgPtr arg)
         return BoxInfoPtr();
     }
 
-    const char* type = getBoxType(arg->pkgname);
-    if (!type) {
+    std::string type = getBoxType(arg->pkgname);
+    if (type.empty()) {
         return BoxInfoPtr();
     }
-
     BoxInfoPtr infoPtr = BoxInfoPtr(new BoxInfo(type, arg->pkgname, arg->id));
-    delete[] type;
 
     return infoPtr;
 }
 
+std::string BoxDaemonImpl::getBoxIdFromService(service_h service)
+{
+    LogD("enter");
+
+    int ret;
+    char* serviceUri = NULL;
+    ret = service_get_uri(service, &serviceUri);
+    if (ret != SERVICE_ERROR_NONE) {
+        LogD("no box uri");
+        return std::string();
+    }
+
+    std::string uri(serviceUri);
+    delete[] serviceUri;
+
+    if(uri.compare(0, BOX_SERVICE_SCHEME.size(), BOX_SERVICE_SCHEME)) {
+        // uri is not box-service scheme
+        return std::string();
+    }
+
+    std::string boxId = uri.substr(BOX_SERVICE_SCHEME.size());
+    return boxId;
+}
+
+bool BoxDaemonImpl::isServiceCallerBoxOwner(service_h service)
+{
+    LogD("enter");
+
+    int ret;
+
+    std::string boxId = getBoxIdFromService(service);
+    if (boxId.empty()) {
+        LogD("error box-id");
+        return false;
+    }
+
+    // check if caller is owner of this box
+    const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
+    if (!appId) {
+        return false;
+    }
+    std::string ownerAppId(appId);
+    delete[] appId;
+
+    char* caller = NULL;
+    ret = service_get_caller(service, &caller);
+    if (ret != SERVICE_ERROR_NONE) {
+        ret = service_get_extra_data(
+                service, ALARM_CALLER_KEY.c_str(), &caller);
+        if (ret != SERVICE_ERROR_NONE) {
+            LogD("failed to get caller's appid from service");
+            return false;
+        }
+    }
+    std::string callerAppId(caller);
+
+    // release strings
+    delete[] caller;
+
+    if (ownerAppId != callerAppId) {
+        LogD("caller is not matched with owner of requested box");
+        return false;
+    }
+
+    return true;
+}
+
+BoxInfoPtr BoxDaemonImpl::handleOperationUpdate(service_h service)
+{
+    LogD("enter");
+
+    int ret;
+
+    if (!isServiceCallerBoxOwner(service)) {
+        return BoxInfoPtr();
+    }
+
+    std::string boxId = getBoxIdFromService(service);
+    if (boxId.empty()) {
+        LogD("error box-id");
+        return BoxInfoPtr();
+    }
+
+    char* contentInfo = NULL;
+    service_get_extra_data(service, CONTENT_INFO_KEY.c_str(), &contentInfo);
+
+    std::string type(getBoxType(boxId.c_str()));
+    if (type.empty()) {
+        LogD("no type for this box");
+        delete[] contentInfo;
+        return BoxInfoPtr();
+    }
+    BoxInfoPtr info = BoxInfoPtr(new BoxInfo(type, boxId, ""));
+    if (contentInfo) {
+        info->contentInfo = std::string(contentInfo);
+    }
+
+    // release string 
+    delete[] contentInfo;
+
+    return info;
+}
+
 Eina_Bool BoxDaemonImpl::pingToMasterCallback(void* data)
 {
     LogD("enter");
@@ -518,4 +673,6 @@ void BoxDaemonImpl::requestBoxJobCallback(void* data)
     // request box job!
     jobInfo->daemonImpl->m_pluginConnector->requestCommand(
             jobInfo->cmdType, jobInfo->boxInfo);
+
+    delete jobInfo;
 }