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/images/pixel-data.h>
27 #include <dali/public-api/object/any.h>
28 #include <dali/public-api/object/base-object.h>
29 #include <dali/public-api/adaptor-framework/native-image-source.h>
30 #include <toolkit-application.h>
45 static WebEngine* gInstance = NULL;
46 static int gInstanceCount = 0;
51 bool OnEvaluteJavaScript();
52 bool OnClearHistory();
54 static void ConnectToGlobalSignal( bool (*func)() )
56 Dali::Timer timer = Dali::Timer::New( 0 );
57 timer.TickSignal().Connect( func );
60 static void DisconnectFromGlobalSignal( bool (*func)() )
62 Dali::Timer timer = Dali::Timer::New( 0 );
63 timer.TickSignal().Disconnect( func );
67 class MockWebEngineContext : public Dali::WebEngineContext
70 MockWebEngineContext()
71 : mockModel( Dali::WebEngineContext::CacheModel::DOCUMENT_VIEWER )
75 Dali::WebEngineContext::CacheModel GetCacheModel() const override
80 void SetCacheModel( Dali::WebEngineContext::CacheModel cacheModel ) override
82 mockModel = cacheModel;
85 void SetProxyUri( const std::string& uri ) override
89 void SetDefaultProxyAuth( const std::string& username, const std::string& password ) override
93 void SetCertificateFilePath( const std::string& certificatePath ) override
97 void DeleteWebDatabase() override
101 void DeleteWebStorage() override
105 void DeleteLocalFileSystem() override
109 void DisableCache( bool cacheDisabled ) override
113 void ClearCache() override
118 Dali::WebEngineContext::CacheModel mockModel;
121 class MockWebEngineCookieManager : public Dali::WebEngineCookieManager
124 MockWebEngineCookieManager()
125 : mockCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy::NO_THIRD_PARTY )
129 void SetCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy policy ) override
131 mockCookieAcceptPolicy = policy;
134 Dali::WebEngineCookieManager::CookieAcceptPolicy GetCookieAcceptPolicy() const override
136 return mockCookieAcceptPolicy;
139 void ClearCookies() override
143 void SetPersistentStorage( const std::string& path, Dali::WebEngineCookieManager::CookiePersistentStorage storage ) override
148 Dali::WebEngineCookieManager::CookieAcceptPolicy mockCookieAcceptPolicy;
151 class MockWebEngineBackForwardListItem : public Dali::WebEngineBackForwardListItem
154 MockWebEngineBackForwardListItem()
155 : mockUrl( "http://url" ),
156 mockTitle( "title" ),
157 mockOriginalUrl( "http://originalurl" )
161 std::string GetUrl() const override
166 std::string GetTitle() const override
171 std::string GetOriginalUrl() const override
173 return mockOriginalUrl;
178 std::string mockTitle;
179 std::string mockOriginalUrl;
182 class MockWebEngineBackForwardList : public Dali::WebEngineBackForwardList
185 MockWebEngineBackForwardList( )
187 pMockItem( &mockItem )
191 Dali::WebEngineBackForwardListItem& GetCurrentItem() const override
196 Dali::WebEngineBackForwardListItem& GetItemAtIndex( uint32_t index ) const override
201 uint32_t GetItemCount() const override
207 MockWebEngineBackForwardListItem mockItem;
208 WebEngineBackForwardListItem* pMockItem;
211 class MockWebEngineSettings : public WebEngineSettings
214 MockWebEngineSettings()
215 : mockDefaultFontSize( 16 ),
216 mockJavaScriptEnabled( true ),
217 mockImageLoadedAutomatically( true ),
218 mockDefaultTextEncodingName()
222 uint32_t GetDefaultFontSize() const override
224 return mockDefaultFontSize;
227 void SetDefaultFontSize( uint32_t size ) override
229 mockDefaultFontSize = size;
232 bool IsJavaScriptEnabled() const override
234 return mockJavaScriptEnabled;
237 void EnableJavaScript( bool enabled ) override
239 mockJavaScriptEnabled = enabled;
242 bool AreImagesLoadedAutomatically() const override
244 return mockImageLoadedAutomatically;
247 void AllowImagesLoadAutomatically( bool automatic ) override
249 mockImageLoadedAutomatically = automatic;
252 std::string GetDefaultTextEncodingName() const override
254 return mockDefaultTextEncodingName;
257 void SetDefaultTextEncodingName( const std::string& defaultTextEncodingName ) override
259 mockDefaultTextEncodingName = defaultTextEncodingName;
262 void AllowMixedContents( bool allowed ) override
266 void EnableSpatialNavigation( bool enabled ) override
270 void EnableWebSecurity( bool enabled ) override
274 void AllowFileAccessFromExternalUrl( bool allowed ) override
278 void AllowScriptsOpenWindows( bool allowed ) override
283 int mockDefaultFontSize;
284 bool mockJavaScriptEnabled;
285 bool mockImageLoadedAutomatically;
286 std::string mockDefaultTextEncodingName;
289 class WebEngine: public Dali::BaseObject
295 , mCurrentPlusOnePos( 0 )
297 , mEvaluating( false )
298 , mScrollPosition( 0, 0 )
299 , mScrollSize( 500, 500 )
300 , mContentSize( 500, 500 )
305 mockWebEngineSettings = new MockWebEngineSettings();
306 mockWebEngineContext = new MockWebEngineContext();
307 mockWebEngineCookieManager = new MockWebEngineCookieManager();
308 mockWebEngineBackForwardList = new MockWebEngineBackForwardList();
314 if( !gInstanceCount )
319 delete mockWebEngineSettings;
320 delete mockWebEngineContext;
321 delete mockWebEngineCookieManager;
322 delete mockWebEngineBackForwardList;
325 Dali::WebEngineSettings& GetSettings() const
327 return *mockWebEngineSettings;
330 Dali::WebEngineContext& GetContext() const
332 return *mockWebEngineContext;
335 Dali::WebEngineCookieManager& GetCookieManager() const
337 return *mockWebEngineCookieManager;
340 Dali::WebEngineBackForwardList& GetBackForwardList() const
342 return *mockWebEngineBackForwardList;
345 void LoadUrl( const std::string& url )
348 ConnectToGlobalSignal( &OnLoadUrl );
351 const std::string& GetUrl() const
356 std::string GetTitle() const
358 return std::string("title");
361 Dali::PixelData GetFavicon() const
363 uint8_t* faviconData = new uint8_t[ 16 ];
365 faviconData[ 0 ] = 0xff;
366 faviconData[ 1 ] = 0x00;
367 faviconData[ 2 ] = 0x00;
368 faviconData[ 3 ] = 0xff;
369 faviconData[ 4 ] = 0xff;
370 faviconData[ 5 ] = 0x00;
371 faviconData[ 6 ] = 0x00;
372 faviconData[ 7 ] = 0xff;
373 faviconData[ 8 ] = 0xff;
374 faviconData[ 9 ] = 0x00;
375 faviconData[ 10 ] = 0x00;
376 faviconData[ 11 ] = 0xff;
377 faviconData[ 12 ] = 0xff;
378 faviconData[ 13 ] = 0x00;
379 faviconData[ 14 ] = 0x00;
380 faviconData[ 15 ] = 0xff;
382 return Dali::PixelData::New( faviconData, 16, 2, 2,
383 Dali::Pixel::Format::RGBA8888,
384 Dali::PixelData::ReleaseFunction::DELETE_ARRAY );
387 bool CanGoForward() const
389 return mHistory.size() > mCurrentPlusOnePos;
394 ConnectToGlobalSignal( &OnGoForward );
397 bool CanGoBack() const
399 return mCurrentPlusOnePos > 1;
404 ConnectToGlobalSignal( &OnGoBack );
407 void EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
413 ConnectToGlobalSignal( &OnEvaluteJavaScript );
415 mResultCallbacks.push_back( resultHandler );
421 ConnectToGlobalSignal( &OnClearHistory );
424 const std::string& GetUserAgent() const
429 void SetUserAgent( const std::string& userAgent )
431 mUserAgent = userAgent;
434 void ScrollBy( int dx, int dy )
436 mScrollPosition += Dali::Vector2( dx, dy );
437 if ( mScrollPosition.y + mScrollSize.height > mContentSize.height )
439 gInstance->mScrollEdgeReachedSignal.Emit( Dali::WebEnginePlugin::ScrollEdge::BOTTOM );
443 void SetScrollPosition( int x, int y )
445 mScrollPosition.x = x;
446 mScrollPosition.y = y;
449 void GetScrollPosition( int& x, int& y ) const
451 x = mScrollPosition.x;
452 y = mScrollPosition.y;
455 void GetScrollSize( int& w, int& h ) const
457 w = mScrollSize.width;
458 h = mScrollSize.height;
461 void GetContentSize( int& w, int& h ) const
463 w = mContentSize.width;
464 h = mContentSize.height;
467 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal()
469 return mPageLoadStartedSignal;
472 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal()
474 return mPageLoadFinishedSignal;
477 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& PageLoadErrorSignal()
479 return mPageLoadErrorSignal;
482 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& ScrollEdgeReachedSignal()
484 return mScrollEdgeReachedSignal;
488 std::vector< std::string > mHistory;
489 size_t mCurrentPlusOnePos;
490 std::string mUserAgent;
491 Dali::WebEnginePlugin::WebEnginePageLoadSignalType mPageLoadStartedSignal;
492 Dali::WebEnginePlugin::WebEnginePageLoadSignalType mPageLoadFinishedSignal;
493 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType mPageLoadErrorSignal;
494 std::vector< std::function< void( const std::string& ) > > mResultCallbacks;
497 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType mScrollEdgeReachedSignal;
498 Dali::Vector2 mScrollPosition;
499 Dali::Vector2 mScrollSize;
500 Dali::Vector2 mContentSize;
501 WebEngineBackForwardList* mockWebEngineBackForwardList;
502 WebEngineContext* mockWebEngineContext;
503 WebEngineCookieManager* mockWebEngineCookieManager;
504 WebEngineSettings* mockWebEngineSettings;
507 inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
509 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
510 BaseObject& handle = webEngine.GetBaseObject();
511 return static_cast< Internal::Adaptor::WebEngine& >( handle );
514 inline const WebEngine& GetImplementation( const Dali::WebEngine& webEngine )
516 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
517 const BaseObject& handle = webEngine.GetBaseObject();
518 return static_cast< const Internal::Adaptor::WebEngine& >( handle );
526 DisconnectFromGlobalSignal( &OnGoBack );
528 if( gInstance && gInstance->CanGoBack() )
530 gInstance->mCurrentPlusOnePos--;
537 DisconnectFromGlobalSignal( &OnGoForward );
539 if( gInstance && gInstance->CanGoForward() )
541 gInstance->mCurrentPlusOnePos++;
548 DisconnectFromGlobalSignal( &OnLoadUrl );
552 if( gInstance->mHistory.size() > gInstance->mCurrentPlusOnePos )
554 gInstance->mHistory.erase( gInstance->mHistory.begin() + gInstance->mCurrentPlusOnePos, gInstance->mHistory.end() );
556 gInstance->mHistory.push_back( gInstance->mUrl );
557 gInstance->mCurrentPlusOnePos++;
558 gInstance->mPageLoadStartedSignal.Emit( gInstance->mUrl );
559 gInstance->mPageLoadFinishedSignal.Emit( gInstance->mUrl );
564 bool OnEvaluteJavaScript()
566 DisconnectFromGlobalSignal( &OnEvaluteJavaScript );
570 for( auto& func : gInstance->mResultCallbacks )
574 gInstance->mResultCallbacks.clear();
579 bool OnClearHistory()
581 DisconnectFromGlobalSignal( &OnClearHistory );
583 if( gInstance && gInstance->mCurrentPlusOnePos ) {
584 std::string url = gInstance->mHistory[ gInstance->mCurrentPlusOnePos - 1 ];
585 std::vector< std::string >().swap( gInstance->mHistory );
586 gInstance->mHistory.push_back( url );
587 gInstance->mCurrentPlusOnePos = 1;
593 } // namespace Adaptor
595 } // namespace Internal
598 // Dali::WebEngine Implementation
599 WebEngine::WebEngine()
603 WebEngine::WebEngine( Internal::Adaptor::WebEngine* internal )
604 : BaseHandle( internal )
608 WebEngine::~WebEngine()
612 WebEngine WebEngine::New()
614 Internal::Adaptor::WebEngine* baseObject = new Internal::Adaptor::WebEngine();
616 return WebEngine( baseObject );
619 WebEngine::WebEngine( const WebEngine& WebEngine )
620 : BaseHandle( WebEngine )
624 WebEngine& WebEngine::operator=( const WebEngine& webEngine )
626 BaseHandle::operator=( webEngine );
630 WebEngine WebEngine::DownCast( BaseHandle handle )
632 return WebEngine( dynamic_cast< Internal::Adaptor::WebEngine* >( handle.GetObjectPtr() ) );
635 void WebEngine::Create( int width, int height, const std::string& locale, const std::string& timezoneId )
639 void WebEngine::Create( int width, int height, int argc, char** argv )
643 void WebEngine::Destroy()
647 WebEngineSettings& WebEngine::GetSettings() const
649 return Internal::Adaptor::GetImplementation( *this ).GetSettings();
652 WebEngineContext& WebEngine::GetContext() const
654 return Internal::Adaptor::GetImplementation( *this ).GetContext();
657 WebEngineCookieManager& WebEngine::GetCookieManager() const
659 return Internal::Adaptor::GetImplementation( *this ).GetCookieManager();
662 WebEngineBackForwardList& WebEngine::GetBackForwardList() const
664 return Internal::Adaptor::GetImplementation( *this ).GetBackForwardList();
667 void WebEngine::LoadUrl( const std::string& url )
669 return Internal::Adaptor::GetImplementation( *this ).LoadUrl( url );
672 std::string WebEngine::GetTitle() const
674 return Internal::Adaptor::GetImplementation( *this ).GetTitle();
677 Dali::PixelData WebEngine::GetFavicon() const
679 return Internal::Adaptor::GetImplementation( *this ).GetFavicon();
682 const std::string& WebEngine::GetUrl()
684 return Internal::Adaptor::GetImplementation( *this ).GetUrl();
687 NativeImageInterfacePtr WebEngine::GetNativeImageSource()
690 Dali::NativeImageSourcePtr sourcePtr = Dali::NativeImageSource::New( source );
694 void WebEngine::LoadHtmlString( const std::string& htmlString )
698 void WebEngine::Reload()
702 void WebEngine::StopLoading()
706 void WebEngine::Suspend()
710 void WebEngine::Resume()
714 bool WebEngine::CanGoForward()
716 return Internal::Adaptor::GetImplementation( *this ).CanGoForward();
719 void WebEngine::GoForward()
721 Internal::Adaptor::GetImplementation( *this ).GoForward();
724 bool WebEngine::CanGoBack()
726 return Internal::Adaptor::GetImplementation( *this ).CanGoBack();
729 void WebEngine::GoBack()
731 Internal::Adaptor::GetImplementation( *this ).GoBack();
734 void WebEngine::EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
736 Internal::Adaptor::GetImplementation( *this ).EvaluateJavaScript( script, resultHandler );
739 void WebEngine::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void(const std::string&) > handler )
743 void WebEngine::ClearAllTilesResources()
747 void WebEngine::ClearHistory()
749 Internal::Adaptor::GetImplementation( *this ).ClearHistory();
752 const std::string& WebEngine::GetUserAgent() const
754 return Internal::Adaptor::GetImplementation( *this ).GetUserAgent();
757 void WebEngine::SetUserAgent( const std::string& userAgent )
759 Internal::Adaptor::GetImplementation( *this ).SetUserAgent( userAgent );
762 void WebEngine::ScrollBy( int dx, int dy )
764 Internal::Adaptor::GetImplementation( *this ).ScrollBy( dx, dy );
767 void WebEngine::SetScrollPosition( int x, int y )
769 Internal::Adaptor::GetImplementation( *this ).SetScrollPosition( x, y );
772 void WebEngine::GetScrollPosition( int& x, int& y ) const
774 Internal::Adaptor::GetImplementation( *this ).GetScrollPosition( x, y );
777 void WebEngine::GetScrollSize( int& w, int& h ) const
779 Internal::Adaptor::GetImplementation( *this ).GetScrollSize( w, h );
782 void WebEngine::GetContentSize( int& w, int& h ) const
784 Internal::Adaptor::GetImplementation( *this ).GetContentSize( w, h );
787 void WebEngine::SetSize( int width, int height )
791 bool WebEngine::SendTouchEvent( const TouchEvent& touch )
796 bool WebEngine::SendKeyEvent( const KeyEvent& event )
801 void WebEngine::SetFocus( bool focused )
805 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadStartedSignal()
807 return Internal::Adaptor::GetImplementation( *this ).PageLoadStartedSignal();
810 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadFinishedSignal()
812 return Internal::Adaptor::GetImplementation( *this ).PageLoadFinishedSignal();
815 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& WebEngine::PageLoadErrorSignal()
817 return Internal::Adaptor::GetImplementation( *this ).PageLoadErrorSignal();
820 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& WebEngine::ScrollEdgeReachedSignal()
822 return Internal::Adaptor::GetImplementation( *this ).ScrollEdgeReachedSignal();