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();
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 Dali::Vector2 GetScrollPosition() const
451 return mScrollPosition;
454 Dali::Vector2 GetScrollSize() const
459 Dali::Vector2 GetContentSize() const
464 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal()
466 return mPageLoadStartedSignal;
469 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal()
471 return mPageLoadFinishedSignal;
474 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& PageLoadErrorSignal()
476 return mPageLoadErrorSignal;
479 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& ScrollEdgeReachedSignal()
481 return mScrollEdgeReachedSignal;
485 std::vector< std::string > mHistory;
486 size_t mCurrentPlusOnePos;
487 std::string mUserAgent;
488 Dali::WebEnginePlugin::WebEnginePageLoadSignalType mPageLoadStartedSignal;
489 Dali::WebEnginePlugin::WebEnginePageLoadSignalType mPageLoadFinishedSignal;
490 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType mPageLoadErrorSignal;
491 std::vector< std::function< void( const std::string& ) > > mResultCallbacks;
494 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType mScrollEdgeReachedSignal;
495 Dali::Vector2 mScrollPosition;
496 Dali::Vector2 mScrollSize;
497 Dali::Vector2 mContentSize;
498 WebEngineBackForwardList* mockWebEngineBackForwardList;
499 WebEngineContext* mockWebEngineContext;
500 WebEngineCookieManager* mockWebEngineCookieManager;
501 WebEngineSettings* mockWebEngineSettings;
504 inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
506 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
507 BaseObject& handle = webEngine.GetBaseObject();
508 return static_cast< Internal::Adaptor::WebEngine& >( handle );
511 inline const WebEngine& GetImplementation( const Dali::WebEngine& webEngine )
513 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
514 const BaseObject& handle = webEngine.GetBaseObject();
515 return static_cast< const Internal::Adaptor::WebEngine& >( handle );
523 DisconnectFromGlobalSignal( &OnGoBack );
525 if( gInstance && gInstance->CanGoBack() )
527 gInstance->mCurrentPlusOnePos--;
534 DisconnectFromGlobalSignal( &OnGoForward );
536 if( gInstance && gInstance->CanGoForward() )
538 gInstance->mCurrentPlusOnePos++;
545 DisconnectFromGlobalSignal( &OnLoadUrl );
549 if( gInstance->mHistory.size() > gInstance->mCurrentPlusOnePos )
551 gInstance->mHistory.erase( gInstance->mHistory.begin() + gInstance->mCurrentPlusOnePos, gInstance->mHistory.end() );
553 gInstance->mHistory.push_back( gInstance->mUrl );
554 gInstance->mCurrentPlusOnePos++;
555 gInstance->mPageLoadStartedSignal.Emit( gInstance->mUrl );
556 gInstance->mPageLoadFinishedSignal.Emit( gInstance->mUrl );
561 bool OnEvaluteJavaScript()
563 DisconnectFromGlobalSignal( &OnEvaluteJavaScript );
567 for( auto& func : gInstance->mResultCallbacks )
571 gInstance->mResultCallbacks.clear();
576 bool OnClearHistory()
578 DisconnectFromGlobalSignal( &OnClearHistory );
580 if( gInstance && gInstance->mCurrentPlusOnePos ) {
581 std::string url = gInstance->mHistory[ gInstance->mCurrentPlusOnePos - 1 ];
582 std::vector< std::string >().swap( gInstance->mHistory );
583 gInstance->mHistory.push_back( url );
584 gInstance->mCurrentPlusOnePos = 1;
590 } // namespace Adaptor
592 } // namespace Internal
595 // Dali::WebEngine Implementation
596 WebEngine::WebEngine()
600 WebEngine::WebEngine( Internal::Adaptor::WebEngine* internal )
601 : BaseHandle( internal )
605 WebEngine::~WebEngine()
609 WebEngine WebEngine::New()
611 Internal::Adaptor::WebEngine* baseObject = new Internal::Adaptor::WebEngine();
613 return WebEngine( baseObject );
616 WebEngine::WebEngine( const WebEngine& WebEngine )
617 : BaseHandle( WebEngine )
621 WebEngine& WebEngine::operator=( const WebEngine& webEngine )
623 BaseHandle::operator=( webEngine );
627 WebEngine WebEngine::DownCast( BaseHandle handle )
629 return WebEngine( dynamic_cast< Internal::Adaptor::WebEngine* >( handle.GetObjectPtr() ) );
632 void WebEngine::Create( int width, int height, const std::string& locale, const std::string& timezoneId )
636 void WebEngine::Create( int width, int height, int argc, char** argv )
640 void WebEngine::Destroy()
644 WebEngineSettings& WebEngine::GetSettings() const
646 return Internal::Adaptor::GetImplementation( *this ).GetSettings();
649 WebEngineContext& WebEngine::GetContext() const
651 return Internal::Adaptor::GetImplementation( *this ).GetContext();
654 WebEngineCookieManager& WebEngine::GetCookieManager() const
656 return Internal::Adaptor::GetImplementation( *this ).GetCookieManager();
659 WebEngineBackForwardList& WebEngine::GetBackForwardList() const
661 return Internal::Adaptor::GetImplementation( *this ).GetBackForwardList();
664 void WebEngine::LoadUrl( const std::string& url )
666 return Internal::Adaptor::GetImplementation( *this ).LoadUrl( url );
669 std::string WebEngine::GetTitle() const
671 return Internal::Adaptor::GetImplementation( *this ).GetTitle();
674 Dali::PixelData WebEngine::GetFavicon() const
676 return Internal::Adaptor::GetImplementation( *this ).GetFavicon();
679 const std::string& WebEngine::GetUrl()
681 return Internal::Adaptor::GetImplementation( *this ).GetUrl();
684 NativeImageInterfacePtr WebEngine::GetNativeImageSource()
687 Dali::NativeImageSourcePtr sourcePtr = Dali::NativeImageSource::New( source );
691 void WebEngine::LoadHtmlString( const std::string& htmlString )
695 void WebEngine::Reload()
699 void WebEngine::StopLoading()
703 void WebEngine::Suspend()
707 void WebEngine::Resume()
711 bool WebEngine::CanGoForward()
713 return Internal::Adaptor::GetImplementation( *this ).CanGoForward();
716 void WebEngine::GoForward()
718 Internal::Adaptor::GetImplementation( *this ).GoForward();
721 bool WebEngine::CanGoBack()
723 return Internal::Adaptor::GetImplementation( *this ).CanGoBack();
726 void WebEngine::GoBack()
728 Internal::Adaptor::GetImplementation( *this ).GoBack();
731 void WebEngine::EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
733 Internal::Adaptor::GetImplementation( *this ).EvaluateJavaScript( script, resultHandler );
736 void WebEngine::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void(const std::string&) > handler )
740 void WebEngine::ClearAllTilesResources()
744 void WebEngine::ClearHistory()
746 Internal::Adaptor::GetImplementation( *this ).ClearHistory();
749 const std::string& WebEngine::GetUserAgent() const
751 return Internal::Adaptor::GetImplementation( *this ).GetUserAgent();
754 void WebEngine::SetUserAgent( const std::string& userAgent )
756 Internal::Adaptor::GetImplementation( *this ).SetUserAgent( userAgent );
759 void WebEngine::ScrollBy( int dx, int dy )
761 Internal::Adaptor::GetImplementation( *this ).ScrollBy( dx, dy );
764 void WebEngine::SetScrollPosition( int x, int y )
766 Internal::Adaptor::GetImplementation( *this ).SetScrollPosition( x, y );
769 Dali::Vector2 WebEngine::GetScrollPosition() const
771 return Internal::Adaptor::GetImplementation( *this ).GetScrollPosition();
774 Dali::Vector2 WebEngine::GetScrollSize() const
776 return Internal::Adaptor::GetImplementation( *this ).GetScrollSize();
779 Dali::Vector2 WebEngine::GetContentSize() const
781 return Internal::Adaptor::GetImplementation( *this ).GetContentSize();
784 void WebEngine::SetSize( int width, int height )
788 bool WebEngine::SendTouchEvent( const TouchEvent& touch )
793 bool WebEngine::SendKeyEvent( const KeyEvent& event )
798 void WebEngine::SetFocus( bool focused )
802 void WebEngine::UpdateDisplayArea( Dali::Rect< int > displayArea )
806 void WebEngine::EnableVideoHole( bool enabled )
810 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadStartedSignal()
812 return Internal::Adaptor::GetImplementation( *this ).PageLoadStartedSignal();
815 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadFinishedSignal()
817 return Internal::Adaptor::GetImplementation( *this ).PageLoadFinishedSignal();
820 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& WebEngine::PageLoadErrorSignal()
822 return Internal::Adaptor::GetImplementation( *this ).PageLoadErrorSignal();
825 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& WebEngine::ScrollEdgeReachedSignal()
827 return Internal::Adaptor::GetImplementation( *this ).ScrollEdgeReachedSignal();