2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "toolkit-timer.h"
20 #include <dali/devel-api/adaptor-framework/web-engine.h>
21 #include <dali/devel-api/adaptor-framework/web-engine-back-forward-list.h>
22 #include <dali/devel-api/adaptor-framework/web-engine-back-forward-list-item.h>
23 #include <dali/devel-api/adaptor-framework/web-engine-context.h>
24 #include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
25 #include <dali/devel-api/adaptor-framework/web-engine-settings.h>
26 #include <dali/public-api/adaptor-framework/native-image-source.h>
27 #include <dali/public-api/images/pixel-data.h>
28 #include <dali/public-api/object/any.h>
29 #include <dali/public-api/object/base-object.h>
30 #include <toolkit-application.h>
45 static WebEngine* gInstance = NULL;
46 static int gInstanceCount = 0;
51 bool OnEvaluteJavaScript();
52 bool OnClearHistory();
53 bool OnPlainTextReceived();
55 static void ConnectToGlobalSignal( bool (*func)() )
57 Dali::Timer timer = Dali::Timer::New( 0 );
58 timer.TickSignal().Connect( func );
61 static void DisconnectFromGlobalSignal( bool (*func)() )
63 Dali::Timer timer = Dali::Timer::New( 0 );
64 timer.TickSignal().Disconnect( func );
68 class MockWebEngineContext : public Dali::WebEngineContext
71 MockWebEngineContext()
72 : mockModel( Dali::WebEngineContext::CacheModel::DOCUMENT_VIEWER )
76 Dali::WebEngineContext::CacheModel GetCacheModel() const override
81 void SetCacheModel( Dali::WebEngineContext::CacheModel cacheModel ) override
83 mockModel = cacheModel;
86 void SetProxyUri( const std::string& uri ) override
90 void SetDefaultProxyAuth( const std::string& username, const std::string& password ) override
94 void SetCertificateFilePath( const std::string& certificatePath ) override
98 void DeleteWebDatabase() override
102 void DeleteWebStorage() override
106 void DeleteLocalFileSystem() override
110 void DisableCache( bool cacheDisabled ) override
114 void ClearCache() override
119 Dali::WebEngineContext::CacheModel mockModel;
122 class MockWebEngineCookieManager : public Dali::WebEngineCookieManager
125 MockWebEngineCookieManager()
126 : mockCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy::NO_THIRD_PARTY )
130 void SetCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy policy ) override
132 mockCookieAcceptPolicy = policy;
135 Dali::WebEngineCookieManager::CookieAcceptPolicy GetCookieAcceptPolicy() const override
137 return mockCookieAcceptPolicy;
140 void ClearCookies() override
144 void SetPersistentStorage( const std::string& path, Dali::WebEngineCookieManager::CookiePersistentStorage storage ) override
149 Dali::WebEngineCookieManager::CookieAcceptPolicy mockCookieAcceptPolicy;
152 class MockWebEngineBackForwardListItem : public Dali::WebEngineBackForwardListItem
155 MockWebEngineBackForwardListItem()
156 : mockUrl( "http://url" ),
157 mockTitle( "title" ),
158 mockOriginalUrl( "http://originalurl" )
162 std::string GetUrl() const override
167 std::string GetTitle() const override
172 std::string GetOriginalUrl() const override
174 return mockOriginalUrl;
179 std::string mockTitle;
180 std::string mockOriginalUrl;
183 class MockWebEngineBackForwardList : public Dali::WebEngineBackForwardList
186 MockWebEngineBackForwardList( )
188 pMockItem( &mockItem )
192 Dali::WebEngineBackForwardListItem& GetCurrentItem() const override
197 Dali::WebEngineBackForwardListItem& GetItemAtIndex( uint32_t index ) const override
202 uint32_t GetItemCount() const override
208 MockWebEngineBackForwardListItem mockItem;
209 WebEngineBackForwardListItem* pMockItem;
212 class MockWebEngineSettings : public WebEngineSettings
215 MockWebEngineSettings()
216 : mockDefaultFontSize( 16 ),
217 mockJavaScriptEnabled( true ),
218 mockImageLoadedAutomatically( true ),
219 mockDefaultTextEncodingName()
223 uint32_t GetDefaultFontSize() const override
225 return mockDefaultFontSize;
228 void SetDefaultFontSize( uint32_t size ) override
230 mockDefaultFontSize = size;
233 bool IsJavaScriptEnabled() const override
235 return mockJavaScriptEnabled;
238 void EnableJavaScript( bool enabled ) override
240 mockJavaScriptEnabled = enabled;
243 bool AreImagesLoadedAutomatically() const override
245 return mockImageLoadedAutomatically;
248 void AllowImagesLoadAutomatically( bool automatic ) override
250 mockImageLoadedAutomatically = automatic;
253 std::string GetDefaultTextEncodingName() const override
255 return mockDefaultTextEncodingName;
258 void SetDefaultTextEncodingName( const std::string& defaultTextEncodingName ) override
260 mockDefaultTextEncodingName = defaultTextEncodingName;
263 void AllowMixedContents( bool allowed ) override
267 void EnableSpatialNavigation( bool enabled ) override
271 void EnableWebSecurity( bool enabled ) override
275 void AllowFileAccessFromExternalUrl( bool allowed ) override
279 void AllowScriptsOpenWindows( bool allowed ) override
284 int mockDefaultFontSize;
285 bool mockJavaScriptEnabled;
286 bool mockImageLoadedAutomatically;
287 std::string mockDefaultTextEncodingName;
290 class WebEngine: public Dali::BaseObject
296 , mCurrentPlusOnePos( 0 )
298 , mEvaluating( false )
299 , mScrollPosition( 0, 0 )
300 , mScrollSize( 500, 500 )
301 , mContentSize( 500, 500 )
306 mockWebEngineSettings = new MockWebEngineSettings();
307 mockWebEngineContext = new MockWebEngineContext();
308 mockWebEngineCookieManager = new MockWebEngineCookieManager();
309 mockWebEngineBackForwardList = new MockWebEngineBackForwardList();
315 if( !gInstanceCount )
320 delete mockWebEngineSettings;
321 delete mockWebEngineContext;
322 delete mockWebEngineCookieManager;
323 delete mockWebEngineBackForwardList;
326 Dali::WebEngineSettings& GetSettings() const
328 return *mockWebEngineSettings;
331 Dali::WebEngineContext& GetContext() const
333 return *mockWebEngineContext;
336 Dali::WebEngineCookieManager& GetCookieManager() const
338 return *mockWebEngineCookieManager;
341 Dali::WebEngineBackForwardList& GetBackForwardList() const
343 return *mockWebEngineBackForwardList;
346 void LoadUrl( const std::string& url )
349 ConnectToGlobalSignal( &OnLoadUrl );
352 const std::string& GetUrl() const
357 std::string GetTitle() const
359 return std::string("title");
362 Dali::PixelData GetFavicon() const
364 uint8_t* faviconData = new uint8_t[ 16 ];
366 faviconData[ 0 ] = 0xff;
367 faviconData[ 1 ] = 0x00;
368 faviconData[ 2 ] = 0x00;
369 faviconData[ 3 ] = 0xff;
370 faviconData[ 4 ] = 0xff;
371 faviconData[ 5 ] = 0x00;
372 faviconData[ 6 ] = 0x00;
373 faviconData[ 7 ] = 0xff;
374 faviconData[ 8 ] = 0xff;
375 faviconData[ 9 ] = 0x00;
376 faviconData[ 10 ] = 0x00;
377 faviconData[ 11 ] = 0xff;
378 faviconData[ 12 ] = 0xff;
379 faviconData[ 13 ] = 0x00;
380 faviconData[ 14 ] = 0x00;
381 faviconData[ 15 ] = 0xff;
383 return Dali::PixelData::New( faviconData, 16, 2, 2,
384 Dali::Pixel::Format::RGBA8888,
385 Dali::PixelData::ReleaseFunction::DELETE_ARRAY );
388 bool CanGoForward() const
390 return mHistory.size() > mCurrentPlusOnePos;
395 ConnectToGlobalSignal( &OnGoForward );
398 bool CanGoBack() const
400 return mCurrentPlusOnePos > 1;
405 ConnectToGlobalSignal( &OnGoBack );
408 void EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
414 ConnectToGlobalSignal( &OnEvaluteJavaScript );
416 mResultCallbacks.push_back( resultHandler );
422 ConnectToGlobalSignal( &OnClearHistory );
425 const std::string& GetUserAgent() const
430 void SetUserAgent( const std::string& userAgent )
432 mUserAgent = userAgent;
435 void ScrollBy( int dx, int dy )
437 mScrollPosition += Dali::Vector2( dx, dy );
438 if ( mScrollPosition.y + mScrollSize.height > mContentSize.height )
440 gInstance->mScrollEdgeReachedSignal.Emit( Dali::WebEnginePlugin::ScrollEdge::BOTTOM );
444 void SetScrollPosition( int x, int y )
446 mScrollPosition.x = x;
447 mScrollPosition.y = y;
450 void GetScrollPosition( int& x, int& y ) const
452 x = mScrollPosition.x;
453 y = mScrollPosition.y;
456 void GetScrollSize( int& w, int& h ) const
458 w = mScrollSize.width;
459 h = mScrollSize.height;
462 void GetContentSize( int& w, int& h ) const
464 w = mContentSize.width;
465 h = mContentSize.height;
468 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal()
470 return mPageLoadStartedSignal;
473 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal()
475 return mPageLoadFinishedSignal;
478 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& PageLoadErrorSignal()
480 return mPageLoadErrorSignal;
483 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& ScrollEdgeReachedSignal()
485 return mScrollEdgeReachedSignal;
488 void GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
492 ConnectToGlobalSignal(&OnPlainTextReceived);
493 mPlainTextReceivedCallback = callback;
498 std::vector< std::string > mHistory;
499 size_t mCurrentPlusOnePos;
500 std::string mUserAgent;
501 Dali::WebEnginePlugin::WebEnginePageLoadSignalType mPageLoadStartedSignal;
502 Dali::WebEnginePlugin::WebEnginePageLoadSignalType mPageLoadFinishedSignal;
503 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType mPageLoadErrorSignal;
504 std::vector< std::function< void( const std::string& ) > > mResultCallbacks;
507 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType mScrollEdgeReachedSignal;
508 Dali::Vector2 mScrollPosition;
509 Dali::Vector2 mScrollSize;
510 Dali::Vector2 mContentSize;
511 WebEngineBackForwardList* mockWebEngineBackForwardList;
512 WebEngineContext* mockWebEngineContext;
513 WebEngineCookieManager* mockWebEngineCookieManager;
514 WebEngineSettings* mockWebEngineSettings;
515 Dali::WebEnginePlugin::PlainTextReceivedCallback mPlainTextReceivedCallback;
518 inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
520 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
521 BaseObject& handle = webEngine.GetBaseObject();
522 return static_cast< Internal::Adaptor::WebEngine& >( handle );
525 inline const WebEngine& GetImplementation( const Dali::WebEngine& webEngine )
527 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
528 const BaseObject& handle = webEngine.GetBaseObject();
529 return static_cast< const Internal::Adaptor::WebEngine& >( handle );
537 DisconnectFromGlobalSignal( &OnGoBack );
539 if( gInstance && gInstance->CanGoBack() )
541 gInstance->mCurrentPlusOnePos--;
548 DisconnectFromGlobalSignal( &OnGoForward );
550 if( gInstance && gInstance->CanGoForward() )
552 gInstance->mCurrentPlusOnePos++;
559 DisconnectFromGlobalSignal( &OnLoadUrl );
563 if( gInstance->mHistory.size() > gInstance->mCurrentPlusOnePos )
565 gInstance->mHistory.erase( gInstance->mHistory.begin() + gInstance->mCurrentPlusOnePos, gInstance->mHistory.end() );
567 gInstance->mHistory.push_back( gInstance->mUrl );
568 gInstance->mCurrentPlusOnePos++;
569 gInstance->mPageLoadStartedSignal.Emit( gInstance->mUrl );
570 gInstance->mPageLoadFinishedSignal.Emit( gInstance->mUrl );
575 bool OnEvaluteJavaScript()
577 DisconnectFromGlobalSignal( &OnEvaluteJavaScript );
581 for( auto& func : gInstance->mResultCallbacks )
585 gInstance->mResultCallbacks.clear();
590 bool OnClearHistory()
592 DisconnectFromGlobalSignal( &OnClearHistory );
594 if( gInstance && gInstance->mCurrentPlusOnePos ) {
595 std::string url = gInstance->mHistory[ gInstance->mCurrentPlusOnePos - 1 ];
596 std::vector< std::string >().swap( gInstance->mHistory );
597 gInstance->mHistory.push_back( url );
598 gInstance->mCurrentPlusOnePos = 1;
603 bool OnPlainTextReceived()
605 DisconnectFromGlobalSignal(&OnPlainTextReceived);
608 std::string dummyResultText;
609 gInstance->mPlainTextReceivedCallback(dummyResultText);
616 } // namespace Adaptor
618 } // namespace Internal
621 // Dali::WebEngine Implementation
622 WebEngine::WebEngine()
626 WebEngine::WebEngine( Internal::Adaptor::WebEngine* internal )
627 : BaseHandle( internal )
631 WebEngine::~WebEngine()
635 WebEngine WebEngine::New()
637 Internal::Adaptor::WebEngine* baseObject = new Internal::Adaptor::WebEngine();
639 return WebEngine( baseObject );
642 WebEngine::WebEngine( const WebEngine& WebEngine )
643 : BaseHandle( WebEngine )
647 WebEngine& WebEngine::operator=( const WebEngine& webEngine )
649 BaseHandle::operator=( webEngine );
653 WebEngine WebEngine::DownCast( BaseHandle handle )
655 return WebEngine( dynamic_cast< Internal::Adaptor::WebEngine* >( handle.GetObjectPtr() ) );
658 void WebEngine::Create( int width, int height, const std::string& locale, const std::string& timezoneId )
662 void WebEngine::Create( int width, int height, int argc, char** argv )
666 void WebEngine::Destroy()
670 WebEngineSettings& WebEngine::GetSettings() const
672 return Internal::Adaptor::GetImplementation( *this ).GetSettings();
675 WebEngineContext& WebEngine::GetContext() const
677 return Internal::Adaptor::GetImplementation( *this ).GetContext();
680 WebEngineCookieManager& WebEngine::GetCookieManager() const
682 return Internal::Adaptor::GetImplementation( *this ).GetCookieManager();
685 WebEngineBackForwardList& WebEngine::GetBackForwardList() const
687 return Internal::Adaptor::GetImplementation( *this ).GetBackForwardList();
690 void WebEngine::LoadUrl( const std::string& url )
692 return Internal::Adaptor::GetImplementation( *this ).LoadUrl( url );
695 std::string WebEngine::GetTitle() const
697 return Internal::Adaptor::GetImplementation( *this ).GetTitle();
700 Dali::PixelData WebEngine::GetFavicon() const
702 return Internal::Adaptor::GetImplementation( *this ).GetFavicon();
705 const std::string& WebEngine::GetUrl()
707 return Internal::Adaptor::GetImplementation( *this ).GetUrl();
710 NativeImageInterfacePtr WebEngine::GetNativeImageSource()
713 Dali::NativeImageSourcePtr sourcePtr = Dali::NativeImageSource::New( source );
717 void WebEngine::LoadHtmlString( const std::string& htmlString )
721 void WebEngine::Reload()
725 void WebEngine::StopLoading()
729 void WebEngine::Suspend()
733 void WebEngine::Resume()
737 bool WebEngine::CanGoForward()
739 return Internal::Adaptor::GetImplementation( *this ).CanGoForward();
742 void WebEngine::GoForward()
744 Internal::Adaptor::GetImplementation( *this ).GoForward();
747 bool WebEngine::CanGoBack()
749 return Internal::Adaptor::GetImplementation( *this ).CanGoBack();
752 void WebEngine::GoBack()
754 Internal::Adaptor::GetImplementation( *this ).GoBack();
757 void WebEngine::EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
759 Internal::Adaptor::GetImplementation( *this ).EvaluateJavaScript( script, resultHandler );
762 void WebEngine::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void(const std::string&) > handler )
766 void WebEngine::ClearAllTilesResources()
770 void WebEngine::ClearHistory()
772 Internal::Adaptor::GetImplementation( *this ).ClearHistory();
775 const std::string& WebEngine::GetUserAgent() const
777 return Internal::Adaptor::GetImplementation( *this ).GetUserAgent();
780 void WebEngine::SetUserAgent( const std::string& userAgent )
782 Internal::Adaptor::GetImplementation( *this ).SetUserAgent( userAgent );
785 void WebEngine::ScrollBy( int dx, int dy )
787 Internal::Adaptor::GetImplementation( *this ).ScrollBy( dx, dy );
790 void WebEngine::SetScrollPosition( int x, int y )
792 Internal::Adaptor::GetImplementation( *this ).SetScrollPosition( x, y );
795 void WebEngine::GetScrollPosition( int& x, int& y ) const
797 Internal::Adaptor::GetImplementation( *this ).GetScrollPosition( x, y );
800 void WebEngine::GetScrollSize( int& w, int& h ) const
802 Internal::Adaptor::GetImplementation( *this ).GetScrollSize( w, h );
805 void WebEngine::GetContentSize( int& w, int& h ) const
807 Internal::Adaptor::GetImplementation( *this ).GetContentSize( w, h );
810 void WebEngine::SetSize( int width, int height )
814 bool WebEngine::SendTouchEvent( const TouchEvent& touch )
819 bool WebEngine::SendKeyEvent( const KeyEvent& event )
824 void WebEngine::SetFocus( bool focused )
828 void WebEngine::UpdateDisplayArea( Dali::Rect< int > displayArea )
832 void WebEngine::EnableVideoHole( bool enabled )
836 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadStartedSignal()
838 return Internal::Adaptor::GetImplementation( *this ).PageLoadStartedSignal();
841 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadFinishedSignal()
843 return Internal::Adaptor::GetImplementation( *this ).PageLoadFinishedSignal();
846 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& WebEngine::PageLoadErrorSignal()
848 return Internal::Adaptor::GetImplementation( *this ).PageLoadErrorSignal();
851 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& WebEngine::ScrollEdgeReachedSignal()
853 return Internal::Adaptor::GetImplementation( *this ).ScrollEdgeReachedSignal();
856 void WebEngine::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
858 Internal::Adaptor::GetImplementation(*this).GetPlainTextAsynchronously(callback);