Support updating box from web application using tizen.application
[platform/framework/web/web-provider.git] / src / Core / BoxManager.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    BoxManager.cpp
18  * @author  Yunchan Cho (yunchan.cho@samsung.com)
19  */
20 #include <string>
21 #include <map>
22 #include <ctime>
23 #include <ewk_context.h>
24 #include <Plugin/IBoxPluginFactory.h>
25 #include <Plugin/box_plugin_interface.h>
26 #include "Util/Log.h"
27 #include "IBox.h"
28 #include "Box.h"
29 #include "BoxData.h"
30 #include "BoxManager.h"
31
32 #define UPDATE_REQUEST_MIN_TIME    60 // seconds
33
34 BoxManager::BoxManager(IBoxPluginFactoryPtr factory)
35     : m_boxFactory(factory)
36 {
37     LogD("enter");
38 }
39
40 BoxManager::~BoxManager()
41 {
42     LogD("enter");
43 }
44
45 bool BoxManager::doCommand(const request_cmd_type type, const BoxInfoPtr& boxInfo)
46 {
47     bool result = false;
48
49     switch (type) {
50     case REQUEST_CMD_ADD_BOX:
51         result = requestAddBox(boxInfo, m_defaultContext);
52         break;
53     case REQUEST_CMD_REMOVE_BOX:
54         result = requestRemoveBox(boxInfo->instanceId);
55         break;
56     case REQUEST_CMD_RESIZE_BOX:
57         result = requestResizeBox(boxInfo->instanceId, boxInfo->boxWidth, boxInfo->boxHeight);
58         break;
59     case REQUEST_CMD_RESUME_BOX:
60         result = requestResumeBox(boxInfo->instanceId);
61         break;
62     case REQUEST_CMD_PAUSE_BOX:
63         result = requestPauseBox(boxInfo->instanceId);
64         break;
65     case REQUEST_CMD_RESUME_ALL:
66         result = requestResumeAll();
67         break;
68     case REQUEST_CMD_PAUSE_ALL:
69         result = requestPauseAll();
70         break;
71     case REQUEST_CMD_OPEN_PD:
72         result = requestOpenPd(boxInfo->instanceId,
73                     boxInfo->pdWidth, boxInfo->pdHeight,
74                     boxInfo->pdX, boxInfo->pdY);
75         break;
76     case REQUEST_CMD_CLOSE_PD:
77         result = requestClosePd(boxInfo->instanceId);
78         break;
79     case REQUEST_CMD_CHANGE_PERIOD:
80         result = requestChangePeriod(boxInfo->instanceId, boxInfo->period);
81         break;
82     case REQUEST_CMD_UPDATE_BOX:
83         result = requestUpdateBox(boxInfo->boxId, boxInfo->contentInfo);
84         break;
85     default:
86         LogD("not available request type");
87         break;
88     }
89
90     return result;
91 }
92
93 bool BoxManager::requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext)
94 {
95     IBoxPtr box;
96
97     // create new box
98     try {
99         if (!ewkContext) {
100             if (!m_defaultContext) {
101                 m_defaultContext = EwkContextPtr(ewk_context_new(), EwkContextDeleter());
102             }
103             ewkContext = m_defaultContext;
104         }
105         box = Box::create(boxInfo, m_boxFactory, ewkContext); 
106     } catch (...) {
107         LogD("exection occurs during adding box");
108         return false;
109     }
110
111     // show new box
112     if (!box->show()) {
113         LogD("problem occurs during rendering box");
114         return false;
115     }
116
117     insertBoxMap(boxInfo->instanceId, box); 
118     return true;
119 }
120
121 bool BoxManager::requestRemoveBox(std::string& instanceId)
122 {
123     IBoxPtr box = searchBoxMap(instanceId);
124     if (!box) {
125         return false;
126     }
127     
128     if (!box->hide()) { 
129         return false;
130     }
131
132     eraseBoxMap(instanceId);
133     return true;
134 }
135
136 bool BoxManager::requestResizeBox(std::string& instanceId, int width, int height)
137 {
138     LogD("enter");
139     IBoxPtr box = searchBoxMap(instanceId);
140     if (!box) {
141         return false;
142     }
143     
144     return box->resize(width, height);
145 }
146
147 bool BoxManager::requestResumeBox(std::string& instanceId)
148 {
149     LogD("enter");
150     IBoxPtr box = searchBoxMap(instanceId);
151     if (!box) {
152         return false;
153     }
154     
155     return box->resume();
156 }
157
158 bool BoxManager::requestPauseBox(std::string& instanceId)
159 {
160     LogD("enter");
161     IBoxPtr box = searchBoxMap(instanceId);
162     if (!box) {
163         return false;
164     }
165     
166     // paused by switching other page
167     return box->pause(false);
168 }
169
170 bool BoxManager::requestResumeAll()
171 {
172     LogD("enter");
173     for (auto it = m_boxMap.begin(); it != m_boxMap.end(); it++) {
174         if (it->second->isCurrentTab()) {
175             it->second->resume();
176         }
177     }
178
179     return true;
180 }
181
182 bool BoxManager::requestPauseAll()
183 {
184     LogD("enter");
185     for (auto it = m_boxMap.begin(); it != m_boxMap.end(); it++) {
186         if (it->second->isCurrentTab()) {
187             // paused by entering background
188             it->second->pause(true);
189         }
190     }
191
192     return true;
193 }
194
195 bool BoxManager::requestOpenPd(
196         std::string& instanceId,
197         int width, int height, double x, double y)
198 {
199     LogD("enter");
200     IBoxPtr box = searchBoxMap(instanceId);
201     if (!box) {
202         return false;
203     }
204     
205     return box->openPd(width, height, x, y);
206 }
207
208 bool BoxManager::requestClosePd(std::string& instanceId)
209 {
210     LogD("enter");
211     IBoxPtr box = searchBoxMap(instanceId);
212     if (!box) {
213         return false;
214     }
215
216     return box->closePd();
217 }
218
219 bool BoxManager::requestChangePeriod(std::string& instanceId, float period)
220 {
221     LogD("enter");
222     IBoxPtr box = searchBoxMap(instanceId);
223     if (!box) {
224         return false;
225     }
226
227     return box->changePeriod(period);
228 }
229
230 bool BoxManager::requestUpdateBox(std::string& boxId, std::string& contentInfo)
231 {
232     LogD("enter");
233
234     IBoxPtr box;
235     box.reset();
236
237     time_t requestTime = time(NULL);
238
239     for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) {
240         if (it->first.find(boxId) == std::string::npos) {
241             continue;
242         }
243         box = it->second;
244         int interval = requestTime - box->getLastUpdateRequestTime();
245         if (interval < UPDATE_REQUEST_MIN_TIME) {
246             LogD("this update request is skipped");
247             continue;
248         }
249         // set last request time to new one
250         box->update(requestTime, contentInfo);
251     }
252
253     return true;
254 }
255
256 void BoxManager::insertBoxMap(std::string& instanceId, IBoxPtr box)
257 {
258     if (!searchBoxMap(instanceId)) {
259         LogD("insert box to map: %s", instanceId.c_str());
260         m_boxMap.insert(BoxMapPair(instanceId, box));
261     } else {
262         LogD("this box was already inserted!");
263     }
264 }
265
266 void BoxManager::eraseBoxMap(std::string& instanceId)
267 {
268     LogD("erase box to map");
269     if (!searchBoxMap(instanceId)) {
270         LogD("not available box");
271         return;
272     }
273
274     m_boxMap.erase(instanceId);
275 }
276
277 void BoxManager::updateBoxMap(std::string& instanceId, IBoxPtr box)
278 {
279     if (searchBoxMap(instanceId)) {
280         eraseBoxMap(instanceId);
281     }
282
283     insertBoxMap(instanceId, box);
284 }
285
286 IBoxPtr BoxManager::searchBoxMap(std::string& instanceId)
287 {
288     LogD("enter");
289     IBoxPtr box;
290     box.reset();
291     auto it = m_boxMap.find(instanceId);
292     if (it != m_boxMap.end()) {
293         LogD("found box: %s (%p)", it->first.c_str(), it->second.get());
294         box = it->second;
295     }
296
297     return box;
298 }
299
300 void BoxManager::clearBoxMap()
301 {
302     m_boxMap.clear();
303 }
304
305 void BoxManager::EwkContextDeleter::operator()(Ewk_Context* ptr)
306 {
307     LogD("ewk context delete");
308     if (ptr) {
309         ewk_context_delete(ptr);
310     }
311 }
312