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