[Release] livebox.web-provider-1.59
[platform/framework/web/web-provider.git] / src / Core / Box.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    Box.cpp
18  * @author  Yunchan Cho (yunchan.cho@samsung.com)
19  */
20 #include <string>
21 #include <Ecore.h>
22 #include <Plugin/IBoxPluginFactory.h>
23 #include "Buffer/IRenderBuffer.h"
24 #include "Buffer/RenderBuffer.h"
25 #include "Buffer/RenderBufferFactory.h"
26 #include "Util/Log.h"
27 #include "Util/Util.h"
28 #include "BoxData.h"
29 #include "IBoxState.h"
30 #include "BoxState.h"
31 #include "Util/ITimer.h"
32 #include "BoxUpdateTimer.h"
33 #include "BoxSchemeHandler.h"
34 #include "Box.h"
35
36 // This is used for informing context of box to web content as value of url parameter
37 static const std::string renderTypeCreate("create");
38 static const std::string renderTypeResize("resize");
39 static const std::string renderTypeOpenPd("pdopen");
40 static const std::string renderTypeUpdate("update");
41
42 Box::Box(BoxInfoPtr boxInfo, IBoxPluginFactoryPtr factory, EwkContextPtr ewkContext)
43     : m_boxInfo(boxInfo)
44     , m_factory(factory)
45     , m_currentTab(true)
46     , m_paused(false)
47     , m_updateNeeded(false)
48     , m_lastUpdateRequestTime()
49 {
50     LogD("enter");
51     try {
52         m_boxBuffer = m_factory->createBoxRenderBuffer(
53                             boxInfo->boxId,
54                             boxInfo->instanceId,
55                             boxInfo->boxWidth,
56                             boxInfo->boxHeight,
57                             boxInfo->contentInfo);
58         m_boxBuffer->allocate();
59         m_view = m_factory->createRenderView(
60                 boxInfo->boxId,
61                 boxInfo->instanceId,
62                 ewkContext);
63         m_updateTimer = BoxUpdateTimer::create(
64                 boxInfo->period,
65                 Box::updateCallback,
66                 this);
67         BoxSchemeHandler::Instance()->registerBox(boxInfo->instanceId, this);
68
69         // TODO code regarding state needs more testing
70         //m_state = BoxInitState::create(
71         //           IBoxContextPtr(dynamic_cast<IBoxContext*>(this)));
72     } catch (...) {
73         throw;
74     }
75 }
76
77 Box::~Box()
78 {
79     LogD("enter");
80     BoxSchemeHandler::Instance()->unregisterBox(m_boxInfo->instanceId);
81 }
82
83 bool Box::show()
84 {
85     LogD("enter");
86     CHECK_BOX_STATE(m_state, permitShow);
87
88     try {
89         m_updateTimer->start();
90         RenderInfoPtr renderInfo = makeRenderInfo(renderTypeCreate, URL_TYPE_BOX);
91         m_view->showBox(renderInfo);
92     } catch (...) {
93         return false;
94     }
95
96     SWITCH_BOX_STATE();
97     return true;
98 }
99
100 bool Box::hide()
101 {
102     LogD("enter");
103     CHECK_BOX_STATE(m_state, permitHide);
104
105     try {
106         if (m_pdBuffer) {
107             m_pdBuffer->stopCanvasUpdate();
108             m_view->hidePd();
109             m_pdBuffer->free();
110             m_pdBuffer.reset();
111          }
112
113         m_updateTimer->stop();
114         m_boxBuffer->stopCanvasUpdate();
115         m_view->hideBox();
116         m_boxBuffer->free();
117         m_boxBuffer.reset();
118     } catch (...) {
119         return false;
120     }
121
122     SWITCH_BOX_STATE();
123     return true;
124 }
125
126 bool Box::resize(int width, int height)
127 {
128     LogD("enter");
129     CHECK_BOX_STATE(m_state, permitShow);
130
131     // reset box info to new width, height
132     m_boxInfo->boxWidth = width;
133     m_boxInfo->boxHeight = height;
134
135     try {
136         m_updateTimer->restart();
137         m_boxBuffer->reallocate(
138                 m_boxInfo->boxWidth, m_boxInfo->boxHeight);
139         RenderInfoPtr renderInfo = makeRenderInfo(renderTypeResize, URL_TYPE_BOX);
140         m_view->showBox(renderInfo);
141     } catch (...) {
142         LogD("resize exception");
143         return false;
144     }
145
146     SWITCH_BOX_STATE();
147     return true;
148 }
149
150 bool Box::resume()
151 {
152     LogD("enter");
153     CHECK_BOX_STATE(m_state, permitResume);
154
155     try {
156         m_currentTab = true;
157         m_paused = false;
158
159         if (m_updateNeeded) {
160             m_updateNeeded = false;
161             updateInternal();
162         } else {
163             m_view->resumeBox();
164         }
165     } catch (...) {
166         return false;
167     }
168
169     SWITCH_BOX_STATE();
170     return true;
171 }
172
173 bool Box::pause(bool background)
174 {
175     LogD("enter");
176     CHECK_BOX_STATE(m_state, permitPause);
177
178     try {
179         if (!background) {
180             m_currentTab = false;
181         }
182         m_paused = true;
183         m_view->pauseBox();
184     } catch (...) {
185         return false;
186     }
187
188     SWITCH_BOX_STATE();
189     return true;
190 }
191
192 bool Box::openPd(int width, int height, double x, double y)
193 {
194     LogD("enter");
195     CHECK_BOX_STATE(m_state, permitOpenPd);
196
197     m_boxInfo->pdWidth = width;
198     m_boxInfo->pdHeight = height;
199     m_boxInfo->pdX = x;
200     m_boxInfo->pdY = y;
201
202     try {
203         m_updateTimer->stop();
204         m_pdBuffer = RenderBufferFactory::create(
205                             RenderBufferFactory::RENDER_BUFFER_TYPE_PD,
206                             m_boxInfo->boxId,
207                             m_boxInfo->instanceId,
208                             m_boxInfo->pdWidth,
209                             m_boxInfo->pdHeight);
210         m_pdBuffer->allocate();
211         m_pdBuffer->stopCanvasUpdate();
212         RenderInfoPtr pdRenderInfo = makeRenderInfo(renderTypeOpenPd, URL_TYPE_PD);
213         RenderInfoPtr boxRenderInfo = makeRenderInfo(renderTypeOpenPd, URL_TYPE_BOX);
214         m_view->showPd(pdRenderInfo, boxRenderInfo);
215         ecore_idler_add(startUpdateRenderBufferIdlerCallback, m_pdBuffer.get());
216     } catch (...) {
217         return false;
218     }
219
220     SWITCH_BOX_STATE();
221     return true;
222 }
223
224 bool Box::closePd()
225 {
226     LogD("enter");
227     CHECK_BOX_STATE(m_state, permitClosePd);
228
229     try {
230         if (m_pdBuffer) {
231             m_pdBuffer->stopCanvasUpdate();
232             m_view->hidePd();
233             m_pdBuffer->free();
234             m_pdBuffer.reset();
235         }
236         m_updateTimer->restart();
237     } catch (...) {
238         return false;
239     }
240
241     // if box update is requested during pd opening
242     if (m_updateNeeded) {
243         updateInternal();
244     }
245
246     SWITCH_BOX_STATE();
247     return true;
248 }
249
250 bool Box::update(time_t requestTime, std::string& contentInfo)
251 {
252     LogD("enter");
253
254     m_lastUpdateRequestTime = requestTime;
255     m_boxInfo->contentInfo = contentInfo;
256     if (m_paused || m_pdBuffer) {
257         // update is dalayed
258         //  until this box goes to current tab or pd is closed
259         m_updateNeeded = true;
260         return true;
261     }
262
263     try {
264         updateInternal();
265     } catch (...) {
266         return false;
267     }
268
269     return true;
270 }
271
272 bool Box::changePeriod(float period)
273 {
274     LogD("enter");
275
276     // reset period
277     m_boxInfo->period = period;
278     m_updateTimer->setPeriod(m_boxInfo->period);
279
280     return true;
281 }
282
283 bool Box::isCurrentTab()
284 {
285     return m_currentTab;
286 }
287
288 time_t Box::getLastUpdateRequestTime()
289 {
290     return m_lastUpdateRequestTime;
291 }
292
293 RenderInfoPtr Box::makeRenderInfo(const std::string& renderType, UrlType urlType) const
294 {
295     LogD("enter");
296     RenderInfoPtr renderInfo(new RenderInfo);
297
298     // add width, height, operation type
299     renderInfo->defaultUrlParams = "?type=" + renderType;
300
301     // set width, height
302     switch (urlType) {
303     case URL_TYPE_BOX:
304         renderInfo->window = m_boxBuffer->getWindow();
305         renderInfo->width = m_boxInfo->boxWidth;
306         renderInfo->height = m_boxInfo->boxHeight;
307         break;
308     case URL_TYPE_PD:
309         renderInfo->window = m_pdBuffer->getWindow();
310         renderInfo->width = m_boxInfo->pdWidth;
311         renderInfo->height = m_boxInfo->pdHeight;
312         break;
313     default:
314         LogD("error url type");
315         return RenderInfoPtr();
316     }
317
318     char buff[32];
319     sprintf(buff, "&width=%d&height=%d", renderInfo->width, renderInfo->height);
320     renderInfo->defaultUrlParams += buff;
321
322     // if needed, set pd information
323     if (renderType == renderTypeOpenPd) {
324         renderInfo->defaultUrlParams += "&pdopen-direction=";
325         if (m_boxInfo->pdY == 0.0f) {
326             renderInfo->defaultUrlParams += "down";
327         } else {
328             renderInfo->defaultUrlParams += "up";
329         }
330
331         char buff[32];
332         sprintf(buff, "&pdopen-arrow-xpos=%d",
333                 static_cast<int>((m_boxInfo->pdX) * (m_boxInfo->pdWidth)));
334         renderInfo->defaultUrlParams += buff;
335     }
336
337
338     // add content info
339     if (!m_boxInfo->contentInfo.empty()) {
340         renderInfo->defaultUrlParams += "&" + m_boxInfo->contentInfo;
341     }
342
343     LogD("default url param string: %s", renderInfo->defaultUrlParams.c_str());
344     return renderInfo;
345 }
346
347 void Box::updateInternal()
348 {
349     LogD("enter");
350     RenderInfoPtr renderInfo = makeRenderInfo(renderTypeUpdate, URL_TYPE_BOX);
351     m_view->showBox(renderInfo);
352 }
353
354 void Box::setState(IBoxStatePtr state)
355 {
356     UNUSED_PARAM(state);
357     // assign new state
358     //m_state = state;
359 }
360
361 Eina_Bool Box::updateCallback(void* data)
362 {
363     LogD("enter");
364     Box* This = static_cast<Box*>(data);
365
366     This->updateInternal();
367     return ECORE_CALLBACK_RENEW;
368 }
369
370 Eina_Bool Box::startUpdateRenderBufferIdlerCallback(void* data)
371 {
372     LogD("enter");
373     RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
374     if (!buffer) {
375         LogD("no buffer");
376     } else {
377         buffer->startCanvasUpdate();
378     }
379
380     return ECORE_CALLBACK_CANCEL;
381 }
382
383 BoxInfoPtr Box::getBoxInfo()
384 {
385     LogD("enter");
386     return m_boxInfo;
387 }