Task TT-75 Implement "Main page loading UI" view
[profile/tv/apps/web/browser.git] / services / WebKitEngineService / WebKitEngineService.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
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 /*
18  * WebKitEngineService.cpp
19  *
20  *  Created on: Apr 1, 2014
21  *      Author: p.rafalski
22  */
23
24 #include "browser_config.h"
25 #include "WebKitEngineService.h"
26 #include "AbstractWebEngine/TabThumbCache.h"
27
28 #include <Evas.h>
29 #include <memory>
30 #include <BrowserImage.h>
31 #include <app.h>
32
33 #include "BrowserAssert.h"
34 #include "BrowserLogger.h"
35 #include "WebView.h"
36
37 namespace tizen_browser {
38 namespace basic_webengine {
39 namespace webkitengine_service {
40
41 EXPORT_SERVICE(WebKitEngineService, "org.tizen.browser.webkitengineservice")
42
43 WebKitEngineService::WebKitEngineService()
44     : m_initialised(false)
45     , m_privateMode(false)
46     , m_guiParent(nullptr)
47     , m_currentTabId(TabId::NONE)
48 {
49     m_mostRecentTab.clear();
50     m_tabs.clear();
51     m_chronoTabs.clear();
52 }
53
54 WebKitEngineService::~WebKitEngineService()
55 {
56 }
57
58 Evas_Object * WebKitEngineService::getLayout()
59 {
60     M_ASSERT(m_currentWebView);
61     return m_currentWebView->getLayout();
62 }
63
64 void WebKitEngineService::init(void * guiParent)
65 {
66     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
67     if (!m_initialised) {
68         m_guiParent = guiParent;
69         m_initialised = true;
70     }
71 }
72
73 void WebKitEngineService::connectSignals(std::shared_ptr<WebView> webView)
74 {
75     M_ASSERT(webView);
76     webView->favIconChanged.connect(boost::bind(&WebKitEngineService::_favIconChanged, this, _1));
77     webView->titleChanged.connect(boost::bind(&WebKitEngineService::_titleChanged, this, _1));
78     webView->uriChanged.connect(boost::bind(&WebKitEngineService::_uriChanged, this, _1));
79     webView->loadFinished.connect(boost::bind(&WebKitEngineService::_loadFinished, this));
80     webView->loadStarted.connect(boost::bind(&WebKitEngineService::_loadStarted, this));
81     webView->loadStop.connect(boost::bind(&WebKitEngineService::_loadStop, this));
82     webView->loadProgress.connect(boost::bind(&WebKitEngineService::_loadProgress, this, _1));
83     webView->loadError.connect(boost::bind(&WebKitEngineService::_loadError, this));
84     webView->forwardEnableChanged.connect(boost::bind(&WebKitEngineService::_forwardEnableChanged, this, _1));
85     webView->backwardEnableChanged.connect(boost::bind(&WebKitEngineService::_backwardEnableChanged, this, _1));
86     webView->cofirmationRequest.connect(boost::bind(&WebKitEngineService::_confirmationRequest, this, _1));
87     webView->ewkViewClicked.connect(boost::bind(&WebKitEngineService::webViewClicked, this));
88     webView->IMEStateChanged.connect(boost::bind(&WebKitEngineService::_IMEStateChanged, this, _1));
89 }
90
91 void WebKitEngineService::disconnectSignals(std::shared_ptr<WebView> webView)
92 {
93     M_ASSERT(webView);
94     webView->favIconChanged.disconnect(boost::bind(&WebKitEngineService::_favIconChanged, this));
95     webView->titleChanged.disconnect(boost::bind(&WebKitEngineService::_titleChanged, this, _1));
96     webView->uriChanged.disconnect(boost::bind(&WebKitEngineService::_uriChanged, this, _1));
97     webView->loadFinished.disconnect(boost::bind(&WebKitEngineService::_loadFinished, this));
98     webView->loadStarted.disconnect(boost::bind(&WebKitEngineService::_loadStarted, this));
99     webView->loadStop.disconnect(boost::bind(&WebKitEngineService::_loadStop, this));
100     webView->loadProgress.disconnect(boost::bind(&WebKitEngineService::_loadProgress, this, _1));
101     webView->loadError.disconnect(boost::bind(&WebKitEngineService::_loadError, this));
102     webView->forwardEnableChanged.disconnect(boost::bind(&WebKitEngineService::_forwardEnableChanged, this, _1));
103     webView->backwardEnableChanged.disconnect(boost::bind(&WebKitEngineService::_backwardEnableChanged, this, _1));
104     webView->cofirmationRequest.disconnect(boost::bind(&WebKitEngineService::_confirmationRequest, this, _1));
105     webView->ewkViewClicked.disconnect(boost::bind(&WebKitEngineService::webViewClicked, this));
106     webView->IMEStateChanged.disconnect(boost::bind(&WebKitEngineService::_IMEStateChanged, this, _1));
107 }
108
109 void WebKitEngineService::disconnectCurrentWebViewSignals()
110 {
111     if(m_currentWebView.get())
112         disconnectSignals(m_currentWebView);
113 }
114
115 void WebKitEngineService::setURI(const std::string & uri)
116 {
117     BROWSER_LOGD("%s:%d %s uri=%s", __FILE__, __LINE__, __func__, uri.c_str());
118     M_ASSERT(m_currentWebView);
119     m_currentWebView->setURI(uri);
120 }
121
122 std::string WebKitEngineService::getURI() const
123 {
124     M_ASSERT(m_currentWebView);
125     if(m_currentWebView)
126         return m_currentWebView->getURI();
127     else
128         return std::string("");
129 }
130
131 bool WebKitEngineService::isLoadError() const
132 {
133     return m_currentWebView->isLoadError();
134 }
135
136
137 std::string WebKitEngineService::getTitle() const
138 {
139     M_ASSERT(m_currentWebView);
140     if(m_currentWebView)
141         return m_currentWebView->getTitle();
142     else
143         return std::string("");
144 }
145
146 void WebKitEngineService::stopLoading(void)
147 {
148     M_ASSERT(m_currentWebView);
149     m_currentWebView->stopLoading();
150 }
151
152 void WebKitEngineService::reload(void)
153 {
154     M_ASSERT(m_currentWebView);
155     m_currentWebView->reload();
156 }
157
158 void WebKitEngineService::back(void)
159 {
160     M_ASSERT(m_currentWebView);
161     m_currentWebView->back();
162 }
163
164 void WebKitEngineService::forward(void)
165 {
166     M_ASSERT(m_currentWebView);
167     m_currentWebView->forward();
168 }
169
170 bool WebKitEngineService::isBackEnabled() const
171 {
172     M_ASSERT(m_currentWebView);
173     return m_currentWebView->isBackEnabled();
174 }
175
176 bool WebKitEngineService::isForwardEnabled() const
177 {
178     M_ASSERT(m_currentWebView);
179     return m_currentWebView->isForwardEnabled();
180 }
181
182 bool WebKitEngineService::isLoading() const
183 {
184     M_ASSERT(m_currentWebView);
185     return m_currentWebView->isBackEnabled();
186 }
187
188 void WebKitEngineService::_favIconChanged(std::shared_ptr<tizen_browser::tools::BrowserImage> bi)
189 {
190     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
191     favIconChanged(bi);
192 }
193
194 void WebKitEngineService::_titleChanged(const std::string & title)
195 {
196     titleChanged(title);
197 }
198
199 void WebKitEngineService::_uriChanged(const std::string & uri)
200 {
201     uriChanged(uri);
202 }
203
204 void WebKitEngineService::_uriChangedOnTab(TabId id)
205 {
206     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
207     uriOnTabChanged(id);
208 }
209
210 void WebKitEngineService::_loadFinished()
211 {
212     loadFinished();
213 }
214
215 void WebKitEngineService::_loadStarted()
216 {
217     loadStarted();
218 }
219
220 void WebKitEngineService::_loadStop()
221 {
222     loadStop();
223 }
224
225 void WebKitEngineService::_loadError()
226 {
227     loadError();
228 }
229
230
231 void WebKitEngineService::_forwardEnableChanged(bool enable)
232 {
233     forwardEnableChanged(enable);
234 }
235
236 void WebKitEngineService::_backwardEnableChanged(bool enable)
237 {
238     backwardEnableChanged(enable);
239 }
240
241 void WebKitEngineService::_loadProgress(double d)
242 {
243     loadProgress(d);
244 }
245
246 void WebKitEngineService::_confirmationRequest(WebConfirmationPtr c)
247 {
248     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
249     confirmationRequest(c);
250 }
251
252 int WebKitEngineService::tabsCount() const
253 {
254     return m_tabs.size();
255 }
256
257 TabId WebKitEngineService::currentTabId() const
258 {
259     return m_currentTabId;
260 }
261
262 std::list<TabId> WebKitEngineService::listTabs() const
263 {
264     return m_mostRecentTab;
265 }
266
267 std::vector<std::shared_ptr<TabContent> > WebKitEngineService::getTabContents() const {
268     std::vector<std::shared_ptr<TabContent>> result;
269     for(std::list<TabId>::const_iterator it = m_chronoTabs.begin(); it != m_chronoTabs.end(); it++){
270         WebViewPtr item = m_tabs.find(*it)->second;
271
272         tizen_browser::services::TabThumbCache* thumbCache = tizen_browser::services::TabThumbCache::getInstance();
273         std::shared_ptr<tizen_browser::tools::BrowserImage> thumbnail = thumbCache->getThumb(*it);
274
275         auto tabContent = std::make_shared<TabContent>(*it, item->getTitle(), thumbnail);
276         result.push_back(tabContent);
277     }
278     return result;
279 }
280
281 TabId WebKitEngineService::addTab(const std::string & uri, const TabId * openerId)
282 {
283     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
284
285     // searching for next available tabId
286     TabId newTabId;
287     WebViewPtr p = std::make_shared<WebView>(reinterpret_cast<Evas_Object *>(m_guiParent), newTabId);
288     if (openerId)
289         p->init(getTabView(*openerId));
290     else
291         p->init();
292
293     m_tabs[newTabId] = p;
294
295     if (!uri.empty()) {
296         p->setURI(uri);
297     }
298
299     p->tabIdChecker.connect(boost::bind(&WebKitEngineService::_uriChangedOnTab,this,_1));
300
301     // if it is first tab
302     if (m_tabs.size() == 1) {
303         switchToTab(newTabId);
304     }
305
306     AbstractWebEngine::tabCreated();
307
308     m_chronoTabs.push_front(newTabId);
309
310     return newTabId;
311 }
312
313 Evas_Object* WebKitEngineService::getTabView(TabId id){
314     return m_tabs[id]->getLayout();
315 }
316
317 bool WebKitEngineService::switchToTab(tizen_browser::basic_webengine::TabId newTabId)
318 {
319     BROWSER_LOGD("[%s:%d] newTabId=%s", __PRETTY_FUNCTION__, __LINE__, newTabId.toString().c_str());
320
321     // if there was any running WebView
322     if (m_currentWebView) {
323         disconnectSignals(m_currentWebView);
324     }
325
326     m_currentWebView = m_tabs[newTabId];
327     m_currentTabId = newTabId;
328     m_mostRecentTab.remove(newTabId);
329     m_mostRecentTab.push_back(newTabId);
330
331     connectSignals(m_currentWebView);
332
333     titleChanged(m_currentWebView->getTitle());
334     uriChanged(m_currentWebView->getURI());
335     forwardEnableChanged(m_currentWebView->isForwardEnabled());
336     backwardEnableChanged(m_currentWebView->isBackEnabled());
337     favIconChanged(m_currentWebView->getFavicon());
338     currentTabChanged(m_currentTabId);
339
340     return true;
341 }
342
343 bool WebKitEngineService::closeTab()
344 {
345     BROWSER_LOGD("%s:%d %s closing tab=%s", __FILE__, __LINE__, __func__, m_currentTabId.toString().c_str());
346     bool res = closeTab(m_currentTabId);
347     return res;
348 }
349
350 bool WebKitEngineService::closeTab(TabId id) {
351     BROWSER_LOGD("%s:%d %s closing tab=%s", __FILE__, __LINE__, __func__, id.toString().c_str());
352     BROWSER_LOGD("%s:%d %s NONE tab=%s", __FILE__, __LINE__, __func__, TabId::NONE.toString().c_str());
353
354     TabId closingTabId = id;
355     bool res = true;
356     if(closingTabId == TabId::NONE){
357         return res;
358     }
359     m_tabs.erase(closingTabId);
360     m_chronoTabs.remove(closingTabId);
361     m_mostRecentTab.remove(closingTabId);
362     if (m_tabs.size() == 0) {
363         m_currentTabId = TabId::NONE;
364     }
365     else if (closingTabId == m_currentTabId && m_mostRecentTab.size()){
366         res = switchToTab(m_mostRecentTab.back());
367     }
368
369     tabClosed(closingTabId);
370
371     return res;
372 }
373
374 bool WebKitEngineService::nextTab()
375 {
376     // Empty implementation, with random UUID as ID we cannot distinguish between previous and next tab. Functionality not used.
377     return false;
378 }
379
380 bool WebKitEngineService::prevTab()
381 {
382     // Empty implementation, with random UUID as ID we cannot distinguish between previous and next tab. Functionality not used.
383     return false;
384 }
385
386 void WebKitEngineService::confirmationResult(WebConfirmationPtr c)
387 {
388     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
389     // tabId MUST be set
390     M_ASSERT(c && c->getTabId() != TabId());
391
392     // check if still exists
393     if (m_tabs.find(c->getTabId()) == m_tabs.end()) {
394         return;
395     }
396
397     m_tabs[c->getTabId()]->confirmationResult(c);
398 }
399
400 void WebKitEngineService::setPrivateMode(bool state)
401 {
402     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
403
404     if (m_privateMode == state) {
405         BROWSER_LOGD("%s:%d %s new privateMode is the same", __FILE__, __LINE__, __func__);
406         return;
407     }
408
409     m_privateMode = state;
410
411     for(std::map<TabId, WebViewPtr>::iterator it = m_tabs.begin(), end = m_tabs.end(); it != end; ++it)
412         it->second->setPrivateMode(state);
413 }
414
415 bool WebKitEngineService::isPrivateMode() const
416 {
417     return m_privateMode;
418 }
419
420 std::shared_ptr<tizen_browser::tools::BrowserImage> WebKitEngineService::getSnapshotData(int width, int height)
421 {
422     M_ASSERT(m_currentWebView);
423     if(m_currentWebView)
424         return m_currentWebView->captureSnapshot(width, height);
425     else
426         return std::make_shared<tizen_browser::tools::BrowserImage>();
427
428 }
429
430 std::shared_ptr<tizen_browser::tools::BrowserImage> WebKitEngineService::getSnapshotData(TabId id, int width, int height){
431    return m_tabs[id]->captureSnapshot(width,height);
432 }
433
434 void WebKitEngineService::setFocus()
435 {
436     M_ASSERT(m_currentWebView);
437     m_currentWebView->setFocus();
438 }
439
440 void WebKitEngineService::clearFocus()
441 {
442     M_ASSERT(m_currentWebView);
443     m_currentWebView->clearFocus();
444 }
445
446 bool WebKitEngineService::hasFocus() const
447 {
448     M_ASSERT(m_currentWebView);
449     return m_currentWebView->hasFocus();
450 }
451
452
453 std::shared_ptr<tizen_browser::tools::BrowserImage> WebKitEngineService::getFavicon()
454 {
455     M_ASSERT(m_currentWebView);
456     if(m_currentWebView)
457         return m_currentWebView->getFavicon();
458     else
459         return std::make_shared<tizen_browser::tools::BrowserImage>();
460 }
461
462 void WebKitEngineService::webViewClicked()
463 {
464     AbstractWebEngine::webViewClicked();
465 }
466
467
468 int WebKitEngineService::getZoomFactor() const
469 {
470     if(!m_currentWebView)
471         return 0;
472     return static_cast<int>(m_currentWebView->getZoomFactor()*100);
473
474 }
475
476 void WebKitEngineService::setZoomFactor(int zoomFactor)
477 {
478     M_ASSERT(m_currentWebView);
479     m_currentWebView->setZoomFactor(0.01*zoomFactor);
480
481 }
482
483 void WebKitEngineService::clearPrivateData()
484 {
485     for(std::map<TabId, WebViewPtr>::const_iterator it = m_tabs.begin(); it != m_tabs.end(); it++){
486             it->second->clearPrivateData();
487         }
488 }
489
490 void WebKitEngineService::searchOnWebsite(const std::string & searchString, int flags)
491 {
492     m_currentWebView->searchOnWebsite(searchString, flags);
493 }
494
495 void WebKitEngineService::_IMEStateChanged(bool enable)
496 {
497     IMEStateChanged(enable);
498 }
499
500 void WebKitEngineService::backButtonClicked() const
501 {
502     M_ASSERT(m_currentWebView);
503     if (isBackEnabled()) {
504         m_currentWebView->back();
505     } else {
506         app_efl_exit();
507     }
508 }
509
510 } /* end of webkitengine_service */
511 } /* end of basic_webengine */
512 } /* end of tizen_browser */