[Release] livebox.web-provider-1.9
[platform/framework/web/web-provider.git] / src / Plugin / BoxPluginConnector.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    BoxPluginConnector.cpp
18  * @author  Yunchan Cho (yunchan.cho@samsung.com)
19  */
20 #include <map>
21 #include <dlfcn.h>
22 #include <Core/Util/Log.h>
23 #include <Core/BoxData.h>
24 #include <API/web_provider_plugin_info.h>
25 #include "box_plugin_interface.h"
26 #include "BoxPluginConnector.h"
27
28 BoxPluginConnector::BoxPluginConnector()
29 {
30 }
31
32 BoxPluginConnector::~BoxPluginConnector()
33 {
34 }
35
36 bool BoxPluginConnector::initialize()
37 {
38     LogD("enter");
39
40     int count;
41     web_provider_plugin_info** pluginList = NULL;
42     pluginList = web_provider_plugin_get_installed_list(&count);
43
44     if (!pluginList) {
45         LogD("failed to get installed plugin's information");
46         return false;
47     }
48
49     if (count <= 0) {
50         LogD("There is no available livebox plugins");
51         web_provider_plugin_release_installed_list(pluginList, count);
52         return false;
53     }
54
55     m_pluginMap.clear();
56
57     // get information of installed plugin
58     LogD("get information of installed plugin");
59     for (int i = 0; i < count; i++) {
60         if (!pluginList[i]) {
61             continue;
62         }
63
64         LogD("plugin path: %s", pluginList[i]->path);
65         void* handle = dlopen(pluginList[i]->path, RTLD_LAZY);
66         if (!handle) {
67             LogD("failed to load plugin so: %s", dlerror());
68             continue;
69         }
70
71         std::shared_ptr<plugin_interfaces> pluginInfo(new plugin_interfaces);
72         
73         pluginInfo->handle = handle;
74         pluginInfo->service_boxid = NULL;
75         if (pluginList[i]->service_boxid) {
76             pluginInfo->service_boxid = strdup(pluginList[i]->service_boxid);
77         }
78
79         pluginInfo->initialize = 
80             reinterpret_cast<plugin_interface_func_initialize>(
81                     dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_INITIALIZE));
82         pluginInfo->command = 
83             reinterpret_cast<plugin_interface_func_command>(
84                     dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_COMMAND));
85         pluginInfo->shutdown = 
86             reinterpret_cast<plugin_interface_func_shutdown>(
87                 dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_SHUTDOWN));
88
89         if (!pluginInfo->initialize || !pluginInfo->command ||
90                 !pluginInfo->shutdown) 
91         {
92             LogD("symbol for plugin interface is not found");
93             continue;
94         }
95         
96         m_pluginMap[std::string(pluginList[i]->type)] = pluginInfo;
97     }
98
99     // initialize plugins 
100     for (auto it = m_pluginMap.begin(); 
101             it != m_pluginMap.end(); ++it) 
102     {
103         if (it->second) {
104             // TODO add exception or abnormal action on loading plugin
105             if (it->second->initialize() < 0) {
106                 LogD("fail to intialize plugin");
107                 continue;
108             }
109         }
110     }
111
112     // release information
113     LogD("release json data of plugins"); 
114     web_provider_plugin_release_installed_list(pluginList, count);
115
116     return true;
117 }
118
119 bool BoxPluginConnector::shutdown()
120 {
121     LogD("enter");
122     // if needed, unload each plugin's DSO.
123     for (auto it = m_pluginMap.begin(); 
124             it != m_pluginMap.end(); ++it) 
125     {
126         if (it->second) {
127             it->second->shutdown();
128             dlclose(it->second->handle);
129         }
130     }
131
132     return true;
133 }
134
135 bool BoxPluginConnector::requestCommand(
136         const request_cmd_type type, const BoxInfoPtr& boxInfo)
137 {
138     LogD("enter");
139
140     // in case of request of resume all or pause all, all plugins should handle that.
141     if (type == REQUEST_CMD_RESUME_ALL || type == REQUEST_CMD_PAUSE_ALL) {
142         for (auto it = m_pluginMap.begin(); 
143                 it != m_pluginMap.end(); ++it) 
144         {
145             if (it->second) {
146                 // In this case, boxInfo doesn't have any meaning 
147                 it->second->command(type, boxInfo);
148             }
149         }
150         return true;
151     }
152
153     const std::shared_ptr<plugin_interfaces> plugin = m_pluginMap[boxInfo->boxType];
154     if (!plugin) {
155         LogD("not available livebox type");
156         return false;
157     }
158
159     int ret = plugin->command(type, boxInfo); 
160     if (ret < 0) {
161         LogD("failed to request command");
162         return false;
163     }
164
165     return true;
166 }
167
168 std::string BoxPluginConnector::getBoxType(std::string& serviceBoxId)
169 {
170     LogD("enter");
171
172     std::string type; 
173     for (auto it = m_pluginMap.begin(); 
174             it != m_pluginMap.end(); ++it) 
175     {
176         if (it->second && it->second->service_boxid) {
177             if (serviceBoxId == it->second->service_boxid) {
178                 LogD("service box id is matched!: %s", it->first.c_str());
179                 type = it->first;
180                 break;
181             }
182         }
183     }
184
185     return type;
186 }