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-frame.h>
26 #include <dali/devel-api/adaptor-framework/web-engine-policy-decision.h>
27 #include <dali/devel-api/adaptor-framework/web-engine-settings.h>
28 #include <dali/public-api/adaptor-framework/native-image-source.h>
29 #include <dali/public-api/images/pixel-data.h>
30 #include <dali/public-api/object/any.h>
31 #include <dali/public-api/object/base-object.h>
32 #include <toolkit-application.h>
47 static WebEngine* gInstance = nullptr;
48 static int gInstanceCount = 0;
53 bool OnEvaluteJavaScript();
54 bool OnClearHistory();
55 bool OnPlainTextReceived();
57 static void ConnectToGlobalSignal( bool (*func)() )
59 Dali::Timer timer = Dali::Timer::New( 0 );
60 timer.TickSignal().Connect( func );
63 static void DisconnectFromGlobalSignal( bool (*func)() )
65 Dali::Timer timer = Dali::Timer::New( 0 );
66 timer.TickSignal().Disconnect( func );
70 class MockWebEngineContext : public Dali::WebEngineContext
73 MockWebEngineContext()
74 : mockModel( Dali::WebEngineContext::CacheModel::DOCUMENT_VIEWER )
78 Dali::WebEngineContext::CacheModel GetCacheModel() const override
83 void SetCacheModel( Dali::WebEngineContext::CacheModel cacheModel ) override
85 mockModel = cacheModel;
88 void SetProxyUri( const std::string& uri ) override
92 void SetDefaultProxyAuth( const std::string& username, const std::string& password ) override
96 void SetCertificateFilePath( const std::string& certificatePath ) override
100 void DeleteWebDatabase() override
104 void DeleteWebStorage() override
108 void DeleteLocalFileSystem() override
112 void DisableCache( bool cacheDisabled ) override
116 void ClearCache() override
121 Dali::WebEngineContext::CacheModel mockModel;
124 class MockWebEngineCookieManager : public Dali::WebEngineCookieManager
127 MockWebEngineCookieManager()
128 : mockCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy::NO_THIRD_PARTY )
132 void SetCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy policy ) override
134 mockCookieAcceptPolicy = policy;
137 Dali::WebEngineCookieManager::CookieAcceptPolicy GetCookieAcceptPolicy() const override
139 return mockCookieAcceptPolicy;
142 void ClearCookies() override
146 void SetPersistentStorage( const std::string& path, Dali::WebEngineCookieManager::CookiePersistentStorage storage ) override
151 Dali::WebEngineCookieManager::CookieAcceptPolicy mockCookieAcceptPolicy;
154 class MockWebEngineBackForwardListItem : public Dali::WebEngineBackForwardListItem
157 MockWebEngineBackForwardListItem()
158 : mockUrl( "http://url" ),
159 mockTitle( "title" ),
160 mockOriginalUrl( "http://originalurl" )
164 std::string GetUrl() const override
169 std::string GetTitle() const override
174 std::string GetOriginalUrl() const override
176 return mockOriginalUrl;
181 std::string mockTitle;
182 std::string mockOriginalUrl;
185 class MockWebEngineBackForwardList : public Dali::WebEngineBackForwardList
188 MockWebEngineBackForwardList( )
190 pMockItem( &mockItem )
194 Dali::WebEngineBackForwardListItem& GetCurrentItem() const override
199 Dali::WebEngineBackForwardListItem& GetItemAtIndex( uint32_t index ) const override
204 uint32_t GetItemCount() const override
210 MockWebEngineBackForwardListItem mockItem;
211 WebEngineBackForwardListItem* pMockItem;
214 class MockWebEngineFrame : public Dali::WebEngineFrame
221 bool IsMainFrame() const override
227 class MockWebEnginePolicyDecision : public Dali::WebEnginePolicyDecision
230 MockWebEnginePolicyDecision()
234 std::string GetUrl() const override
236 return "http://test.html";
239 std::string GetCookie() const override
244 Dali::WebEnginePolicyDecision::DecisionType GetDecisionType() const
246 return Dali::WebEnginePolicyDecision::DecisionType::USE;
249 std::string GetResponseMime() const
254 int32_t GetResponseStatusCode() const
259 Dali::WebEnginePolicyDecision::NavigationType GetNavigationType() const
261 return Dali::WebEnginePolicyDecision::NavigationType::LINK_CLICKED;
264 Dali::WebEngineFrame& GetFrame() const
266 return *(Dali::WebEngineFrame*)(&mockWebFrame);
269 std::string GetScheme() const
290 MockWebEngineFrame mockWebFrame;
293 class MockWebEngineSettings : public WebEngineSettings
296 MockWebEngineSettings()
297 : mockDefaultFontSize( 16 ),
298 mockJavaScriptEnabled( true ),
299 mockImageLoadedAutomatically( true ),
300 mockDefaultTextEncodingName()
304 uint32_t GetDefaultFontSize() const override
306 return mockDefaultFontSize;
309 void SetDefaultFontSize( uint32_t size ) override
311 mockDefaultFontSize = size;
314 bool IsJavaScriptEnabled() const override
316 return mockJavaScriptEnabled;
319 void EnableJavaScript( bool enabled ) override
321 mockJavaScriptEnabled = enabled;
324 bool AreImagesLoadedAutomatically() const override
326 return mockImageLoadedAutomatically;
329 void AllowImagesLoadAutomatically( bool automatic ) override
331 mockImageLoadedAutomatically = automatic;
334 std::string GetDefaultTextEncodingName() const override
336 return mockDefaultTextEncodingName;
339 void SetDefaultTextEncodingName( const std::string& defaultTextEncodingName ) override
341 mockDefaultTextEncodingName = defaultTextEncodingName;
344 void AllowMixedContents( bool allowed ) override
348 void EnableSpatialNavigation( bool enabled ) override
352 void EnableWebSecurity( bool enabled ) override
356 void AllowFileAccessFromExternalUrl( bool allowed ) override
360 void AllowScriptsOpenWindows( bool allowed ) override
365 int mockDefaultFontSize;
366 bool mockJavaScriptEnabled;
367 bool mockImageLoadedAutomatically;
368 std::string mockDefaultTextEncodingName;
371 class WebEngine: public Dali::BaseObject
377 , mCurrentPlusOnePos( 0 )
379 , mEvaluating( false )
380 , mScrollPosition( 0, 0 )
381 , mScrollSize( 500, 500 )
382 , mContentSize( 500, 500 )
387 mockWebEngineSettings = new MockWebEngineSettings();
388 mockWebEngineContext = new MockWebEngineContext();
389 mockWebEngineCookieManager = new MockWebEngineCookieManager();
390 mockWebEngineBackForwardList = new MockWebEngineBackForwardList();
396 if( !gInstanceCount )
401 delete mockWebEngineSettings;
402 delete mockWebEngineContext;
403 delete mockWebEngineCookieManager;
404 delete mockWebEngineBackForwardList;
407 Dali::WebEngineSettings& GetSettings() const
409 return *mockWebEngineSettings;
412 Dali::WebEngineContext& GetContext() const
414 return *mockWebEngineContext;
417 Dali::WebEngineCookieManager& GetCookieManager() const
419 return *mockWebEngineCookieManager;
422 Dali::WebEngineBackForwardList& GetBackForwardList() const
424 return *mockWebEngineBackForwardList;
427 void LoadUrl( const std::string& url )
430 ConnectToGlobalSignal( &OnLoadUrl );
433 const std::string& GetUrl() const
438 std::string GetTitle() const
440 return std::string("title");
443 Dali::PixelData GetFavicon() const
445 uint8_t* faviconData = new uint8_t[ 16 ];
447 faviconData[ 0 ] = 0xff;
448 faviconData[ 1 ] = 0x00;
449 faviconData[ 2 ] = 0x00;
450 faviconData[ 3 ] = 0xff;
451 faviconData[ 4 ] = 0xff;
452 faviconData[ 5 ] = 0x00;
453 faviconData[ 6 ] = 0x00;
454 faviconData[ 7 ] = 0xff;
455 faviconData[ 8 ] = 0xff;
456 faviconData[ 9 ] = 0x00;
457 faviconData[ 10 ] = 0x00;
458 faviconData[ 11 ] = 0xff;
459 faviconData[ 12 ] = 0xff;
460 faviconData[ 13 ] = 0x00;
461 faviconData[ 14 ] = 0x00;
462 faviconData[ 15 ] = 0xff;
464 return Dali::PixelData::New( faviconData, 16, 2, 2,
465 Dali::Pixel::Format::RGBA8888,
466 Dali::PixelData::ReleaseFunction::DELETE_ARRAY );
469 bool CanGoForward() const
471 return mHistory.size() > mCurrentPlusOnePos;
476 ConnectToGlobalSignal( &OnGoForward );
479 bool CanGoBack() const
481 return mCurrentPlusOnePos > 1;
486 ConnectToGlobalSignal( &OnGoBack );
489 void EvaluateJavaScript( const std::string& script, Dali::WebEnginePlugin::JavaScriptMessageHandlerCallback resultHandler )
495 ConnectToGlobalSignal( &OnEvaluteJavaScript );
497 mResultCallbacks.push_back( resultHandler );
503 ConnectToGlobalSignal( &OnClearHistory );
506 const std::string& GetUserAgent() const
511 void SetUserAgent( const std::string& userAgent )
513 mUserAgent = userAgent;
516 void ScrollBy( int dx, int dy )
518 mScrollPosition += Dali::Vector2( dx, dy );
519 if ( mScrollPosition.y + mScrollSize.height > mContentSize.height )
521 gInstance->mScrollEdgeReachedCallback( Dali::WebEnginePlugin::ScrollEdge::BOTTOM );
525 void SetScrollPosition( int x, int y )
527 mScrollPosition.x = x;
528 mScrollPosition.y = y;
531 void GetScrollPosition( int& x, int& y ) const
533 x = mScrollPosition.x;
534 y = mScrollPosition.y;
537 void GetScrollSize( int& w, int& h ) const
539 w = mScrollSize.width;
540 h = mScrollSize.height;
543 void GetContentSize( int& w, int& h ) const
545 w = mContentSize.width;
546 h = mContentSize.height;
549 void RegisterPageLoadStartedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
551 mPageLoadStartedCallback = callback;
554 void RegisterPageLoadFinishedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
556 mPageLoadFinishedCallback = callback;
559 void RegisterPageLoadErrorCallback(Dali::WebEnginePlugin::WebEnginePageLoadErrorCallback callback)
561 mPageLoadErrorCallback = callback;
564 void RegisterScrollEdgeReachedCallback(Dali::WebEnginePlugin::WebEngineScrollEdgeReachedCallback callback)
566 mScrollEdgeReachedCallback = callback;
569 void RegisterUrlChangedCallback(Dali::WebEnginePlugin::WebEngineUrlChangedCallback callback)
571 mUrlChangedCallback = callback;
574 void RegisterNavigationPolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineNavigationPolicyDecidedCallback callback)
576 mNavigationPolicyDecisionCallback = callback;
579 void GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
583 ConnectToGlobalSignal(&OnPlainTextReceived);
584 mPlainTextReceivedCallback = callback;
589 std::vector< std::string > mHistory;
590 size_t mCurrentPlusOnePos;
591 std::string mUserAgent;
593 Dali::WebEnginePlugin::WebEnginePageLoadCallback mPageLoadStartedCallback;
594 Dali::WebEnginePlugin::WebEnginePageLoadCallback mPageLoadFinishedCallback;
595 Dali::WebEnginePlugin::WebEnginePageLoadErrorCallback mPageLoadErrorCallback;
596 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedCallback mScrollEdgeReachedCallback;
597 Dali::WebEnginePlugin::WebEngineUrlChangedCallback mUrlChangedCallback;
598 Dali::WebEnginePlugin::WebEngineNavigationPolicyDecidedCallback mNavigationPolicyDecisionCallback;
600 std::vector<Dali::WebEnginePlugin::JavaScriptMessageHandlerCallback> mResultCallbacks;
603 Dali::Vector2 mScrollPosition;
604 Dali::Vector2 mScrollSize;
605 Dali::Vector2 mContentSize;
606 WebEngineBackForwardList* mockWebEngineBackForwardList;
607 WebEngineContext* mockWebEngineContext;
608 WebEngineCookieManager* mockWebEngineCookieManager;
609 WebEngineSettings* mockWebEngineSettings;
610 Dali::WebEnginePlugin::PlainTextReceivedCallback mPlainTextReceivedCallback;
613 inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
615 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
616 BaseObject& handle = webEngine.GetBaseObject();
617 return static_cast< Internal::Adaptor::WebEngine& >( handle );
620 inline const WebEngine& GetImplementation( const Dali::WebEngine& webEngine )
622 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
623 const BaseObject& handle = webEngine.GetBaseObject();
624 return static_cast< const Internal::Adaptor::WebEngine& >( handle );
632 DisconnectFromGlobalSignal( &OnGoBack );
634 if( gInstance && gInstance->CanGoBack() )
636 gInstance->mCurrentPlusOnePos--;
643 DisconnectFromGlobalSignal( &OnGoForward );
645 if( gInstance && gInstance->CanGoForward() )
647 gInstance->mCurrentPlusOnePos++;
654 DisconnectFromGlobalSignal( &OnLoadUrl );
658 if( gInstance->mHistory.size() > gInstance->mCurrentPlusOnePos )
660 gInstance->mHistory.erase( gInstance->mHistory.begin() + gInstance->mCurrentPlusOnePos, gInstance->mHistory.end() );
662 gInstance->mHistory.push_back( gInstance->mUrl );
663 gInstance->mCurrentPlusOnePos++;
664 if (gInstance->mPageLoadStartedCallback)
666 gInstance->mPageLoadStartedCallback( gInstance->mUrl );
668 if (gInstance->mPageLoadFinishedCallback)
670 gInstance->mPageLoadFinishedCallback( gInstance->mUrl );
672 if (gInstance->mPageLoadErrorCallback)
674 gInstance->mPageLoadErrorCallback(gInstance->mUrl, WebView::LoadErrorCode::UNKNOWN);
676 if (gInstance->mUrlChangedCallback)
678 gInstance->mUrlChangedCallback("http://new-test");
680 if (gInstance->mNavigationPolicyDecisionCallback)
682 std::unique_ptr<Dali::WebEnginePolicyDecision> policyDecision(new MockWebEnginePolicyDecision());
683 gInstance->mNavigationPolicyDecisionCallback(std::move(policyDecision));
689 bool OnEvaluteJavaScript()
691 DisconnectFromGlobalSignal( &OnEvaluteJavaScript );
695 for( auto& func : gInstance->mResultCallbacks )
699 gInstance->mResultCallbacks.clear();
704 bool OnClearHistory()
706 DisconnectFromGlobalSignal( &OnClearHistory );
708 if( gInstance && gInstance->mCurrentPlusOnePos ) {
709 std::string url = gInstance->mHistory[ gInstance->mCurrentPlusOnePos - 1 ];
710 std::vector< std::string >().swap( gInstance->mHistory );
711 gInstance->mHistory.push_back( url );
712 gInstance->mCurrentPlusOnePos = 1;
717 bool OnPlainTextReceived()
719 DisconnectFromGlobalSignal(&OnPlainTextReceived);
722 std::string dummyResultText;
723 gInstance->mPlainTextReceivedCallback(dummyResultText);
730 } // namespace Adaptor
732 } // namespace Internal
735 // Dali::WebEngine Implementation
736 WebEngine::WebEngine()
740 WebEngine::WebEngine( Internal::Adaptor::WebEngine* internal )
741 : BaseHandle( internal )
745 WebEngine::~WebEngine()
749 WebEngine WebEngine::New()
751 Internal::Adaptor::WebEngine* baseObject = new Internal::Adaptor::WebEngine();
753 return WebEngine( baseObject );
756 WebEngine::WebEngine( const WebEngine& WebEngine )
757 : BaseHandle( WebEngine )
761 WebEngine& WebEngine::operator=( const WebEngine& webEngine )
763 BaseHandle::operator=( webEngine );
767 WebEngine WebEngine::DownCast( BaseHandle handle )
769 return WebEngine( dynamic_cast< Internal::Adaptor::WebEngine* >( handle.GetObjectPtr() ) );
772 void WebEngine::Create( int width, int height, const std::string& locale, const std::string& timezoneId )
776 void WebEngine::Create( int width, int height, int argc, char** argv )
780 void WebEngine::Destroy()
784 WebEngineSettings& WebEngine::GetSettings() const
786 return Internal::Adaptor::GetImplementation( *this ).GetSettings();
789 WebEngineContext& WebEngine::GetContext() const
791 return Internal::Adaptor::GetImplementation( *this ).GetContext();
794 WebEngineCookieManager& WebEngine::GetCookieManager() const
796 return Internal::Adaptor::GetImplementation( *this ).GetCookieManager();
799 WebEngineBackForwardList& WebEngine::GetBackForwardList() const
801 return Internal::Adaptor::GetImplementation( *this ).GetBackForwardList();
804 void WebEngine::LoadUrl( const std::string& url )
806 return Internal::Adaptor::GetImplementation( *this ).LoadUrl( url );
809 std::string WebEngine::GetTitle() const
811 return Internal::Adaptor::GetImplementation( *this ).GetTitle();
814 Dali::PixelData WebEngine::GetFavicon() const
816 return Internal::Adaptor::GetImplementation( *this ).GetFavicon();
819 const std::string& WebEngine::GetUrl()
821 return Internal::Adaptor::GetImplementation( *this ).GetUrl();
824 NativeImageInterfacePtr WebEngine::GetNativeImageSource()
827 Dali::NativeImageSourcePtr sourcePtr = Dali::NativeImageSource::New( source );
831 void WebEngine::LoadHtmlString( const std::string& htmlString )
835 void WebEngine::Reload()
839 void WebEngine::StopLoading()
843 void WebEngine::Suspend()
847 void WebEngine::Resume()
851 bool WebEngine::CanGoForward()
853 return Internal::Adaptor::GetImplementation( *this ).CanGoForward();
856 void WebEngine::GoForward()
858 Internal::Adaptor::GetImplementation( *this ).GoForward();
861 bool WebEngine::CanGoBack()
863 return Internal::Adaptor::GetImplementation( *this ).CanGoBack();
866 void WebEngine::GoBack()
868 Internal::Adaptor::GetImplementation( *this ).GoBack();
871 void WebEngine::EvaluateJavaScript( const std::string& script, Dali::WebEnginePlugin::JavaScriptMessageHandlerCallback resultHandler )
873 Internal::Adaptor::GetImplementation( *this ).EvaluateJavaScript( script, resultHandler );
876 void WebEngine::AddJavaScriptMessageHandler( const std::string& exposedObjectName, Dali::WebEnginePlugin::JavaScriptMessageHandlerCallback handler )
880 void WebEngine::ClearAllTilesResources()
884 void WebEngine::ClearHistory()
886 Internal::Adaptor::GetImplementation( *this ).ClearHistory();
889 const std::string& WebEngine::GetUserAgent() const
891 return Internal::Adaptor::GetImplementation( *this ).GetUserAgent();
894 void WebEngine::SetUserAgent( const std::string& userAgent )
896 Internal::Adaptor::GetImplementation( *this ).SetUserAgent( userAgent );
899 void WebEngine::ScrollBy( int dx, int dy )
901 Internal::Adaptor::GetImplementation( *this ).ScrollBy( dx, dy );
904 void WebEngine::SetScrollPosition( int x, int y )
906 Internal::Adaptor::GetImplementation( *this ).SetScrollPosition( x, y );
909 void WebEngine::GetScrollPosition( int& x, int& y ) const
911 Internal::Adaptor::GetImplementation( *this ).GetScrollPosition( x, y );
914 void WebEngine::GetScrollSize( int& w, int& h ) const
916 Internal::Adaptor::GetImplementation( *this ).GetScrollSize( w, h );
919 void WebEngine::GetContentSize( int& w, int& h ) const
921 Internal::Adaptor::GetImplementation( *this ).GetContentSize( w, h );
924 void WebEngine::SetSize( int width, int height )
928 bool WebEngine::SendTouchEvent( const TouchEvent& touch )
933 bool WebEngine::SendKeyEvent( const KeyEvent& event )
938 void WebEngine::SetFocus( bool focused )
942 void WebEngine::UpdateDisplayArea( Dali::Rect< int > displayArea )
946 void WebEngine::EnableVideoHole( bool enabled )
950 void WebEngine::RegisterPageLoadStartedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
952 Internal::Adaptor::GetImplementation( *this ).RegisterPageLoadStartedCallback(callback);
955 void WebEngine::RegisterPageLoadFinishedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
957 Internal::Adaptor::GetImplementation( *this ).RegisterPageLoadFinishedCallback(callback);
960 void WebEngine::RegisterPageLoadErrorCallback(Dali::WebEnginePlugin::WebEnginePageLoadErrorCallback callback)
962 Internal::Adaptor::GetImplementation( *this ).RegisterPageLoadErrorCallback(callback);
965 void WebEngine::RegisterScrollEdgeReachedCallback(Dali::WebEnginePlugin::WebEngineScrollEdgeReachedCallback callback)
967 Internal::Adaptor::GetImplementation(*this).RegisterScrollEdgeReachedCallback(callback);
970 void WebEngine::RegisterUrlChangedCallback(Dali::WebEnginePlugin::WebEngineUrlChangedCallback callback)
972 Internal::Adaptor::GetImplementation(*this).RegisterUrlChangedCallback(callback);
975 void WebEngine::RegisterNavigationPolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineNavigationPolicyDecidedCallback callback)
977 Internal::Adaptor::GetImplementation(*this).RegisterNavigationPolicyDecidedCallback(callback);
980 void WebEngine::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
982 Internal::Adaptor::GetImplementation(*this).GetPlainTextAsynchronously(callback);