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